Merge branch 'develop' into dev/sim_msg_edit_val

This commit is contained in:
Christopher Goes 2018-11-05 11:45:53 +01:00
commit cb3cb27b81
102 changed files with 1301 additions and 921 deletions

View File

@ -752,7 +752,7 @@ Update to Tendermint v0.19.4 (fixes a consensus bug and improves logging)
BREAKING CHANGES
* [stake] MarshalJSON -> MarshalBinary
* [stake] MarshalJSON -> MarshalBinaryLengthPrefixed
* Queries against the store must be prefixed with the path "/store"
FEATURES

74
Gopkg.lock generated
View File

@ -10,6 +10,7 @@
revision = "48b08affede2cea076a3cf13b2e3f72ed262b743"
[[projects]]
branch = "master"
digest = "1:09a7f74eb6bb3c0f14d8926610c87f569c5cff68e978d30e9a3540aeb626fdf0"
name = "github.com/bartekn/go-bip39"
packages = ["."]
@ -38,7 +39,7 @@
name = "github.com/btcsuite/btcd"
packages = ["btcec"]
pruneopts = "UT"
revision = "2a560b2036bee5e3679ec2133eb6520b2f195213"
revision = "67e573d211ace594f1366b4ce9d39726c4b19bd0"
[[projects]]
digest = "1:386de157f7d19259a7f9c81f26ce011223ce0f090353c1152ffdf730d7d10ac2"
@ -62,13 +63,6 @@
revision = "346938d642f2ec3594ed81d874461961cd0faa76"
version = "v1.1.0"
[[projects]]
digest = "1:c7644c73a3d23741fdba8a99b1464e021a224b7e205be497271a8003a15ca41b"
name = "github.com/ebuchman/fail-test"
packages = ["."]
pruneopts = "UT"
revision = "95f809107225be108efcf10a3509e4ea6ceef3c4"
[[projects]]
digest = "1:abeb38ade3f32a92943e5be54f55ed6d6e3b6602761d74b4aab4c9dd45c18abd"
name = "github.com/fsnotify/fsnotify"
@ -171,12 +165,13 @@
version = "v1.2.0"
[[projects]]
digest = "1:ea40c24cdbacd054a6ae9de03e62c5f252479b96c716375aace5c120d68647c8"
digest = "1:c0d19ab64b32ce9fe5cf4ddceba78d5bc9807f0016db6b1183599da3dcc24d10"
name = "github.com/hashicorp/hcl"
packages = [
".",
"hcl/ast",
"hcl/parser",
"hcl/printer",
"hcl/scanner",
"hcl/strconv",
"hcl/token",
@ -245,12 +240,12 @@
version = "v1.0.0"
[[projects]]
digest = "1:e32dfc6abff6a3633ef4d9a1022fd707c8ef26f1e1e8f855dc58dc415ce7c8f3"
digest = "1:53bc4cd4914cd7cd52139990d5170d6dc99067ae31c56530621b18b35fc30318"
name = "github.com/mitchellh/mapstructure"
packages = ["."]
pruneopts = "UT"
revision = "fe40af7a9c397fa3ddba203c38a5042c5d0475ad"
version = "v1.1.1"
revision = "3536a929edddb9a5b34bd6861dc4a9647cb459fe"
version = "v1.1.2"
[[projects]]
digest = "1:95741de3af260a92cc5c7f3f3061e85273f5a81b5db20d4bd68da74bd521675e"
@ -296,7 +291,7 @@
[[projects]]
branch = "master"
digest = "1:63b68062b8968092eb86bedc4e68894bd096ea6b24920faca8b9dcf451f54bb5"
digest = "1:db712fde5d12d6cdbdf14b777f0c230f4ff5ab0be8e35b239fc319953ed577a4"
name = "github.com/prometheus/common"
packages = [
"expfmt",
@ -304,11 +299,11 @@
"model",
]
pruneopts = "UT"
revision = "c7de2306084e37d54b8be01f3541a8464345e9a5"
revision = "7e9e6cabbd393fc208072eedef99188d0ce788b6"
[[projects]]
branch = "master"
digest = "1:ef1dd9945e58ee9b635273d28c0ef3fa3742a7dedc038ebe207fd63e6ce000ef"
digest = "1:ef74914912f99c79434d9c09658274678bc85080ebe3ab32bec3940ebce5e1fc"
name = "github.com/prometheus/procfs"
packages = [
".",
@ -317,7 +312,7 @@
"xfs",
]
pruneopts = "UT"
revision = "418d78d0b9a7b7de3a6bbc8a23def624cc977bb2"
revision = "185b4288413d2a0dd0806f78c90dde719829e5ae"
[[projects]]
digest = "1:ea0700160aca4ef099f4e06686a665a87691f4248dddd40796925eda2e46bd64"
@ -346,12 +341,12 @@
version = "v1.1.2"
[[projects]]
digest = "1:516e71bed754268937f57d4ecb190e01958452336fa73dbac880894164e91c1f"
digest = "1:08d65904057412fc0270fc4812a1c90c594186819243160dc779a402d4b6d0bc"
name = "github.com/spf13/cast"
packages = ["."]
pruneopts = "UT"
revision = "8965335b8c7107321228e3e3702cab9832751bac"
version = "v1.2.0"
revision = "8c9545af88b134710ab1cd196795e7f2388358d7"
version = "v1.3.0"
[[projects]]
digest = "1:7ffc0983035bc7e297da3688d9fe19d60a420e9c38bef23f845c53788ed6a05e"
@ -370,12 +365,12 @@
version = "v1.0.0"
[[projects]]
digest = "1:dab83a1bbc7ad3d7a6ba1a1cc1760f25ac38cdf7d96a5cdd55cd915a4f5ceaf9"
digest = "1:c1b1102241e7f645bc8e0c22ae352e8f0dc6484b6cb4d132fa9f24174e0119e2"
name = "github.com/spf13/pflag"
packages = ["."]
pruneopts = "UT"
revision = "9a97c102cda95a86cec2345a6f09f55a939babf5"
version = "v1.0.2"
revision = "298182f68c66c05229eb03ac171abe6e309ee79a"
version = "v1.0.3"
[[projects]]
digest = "1:f8e1a678a2571e265f4bf91a3e5e32aa6b1474a55cb0ea849750cc177b664d96"
@ -424,35 +419,23 @@
revision = "e5840949ff4fff0c56f9b6a541e22b63581ea9df"
[[projects]]
branch = "master"
digest = "1:087aaa7920e5d0bf79586feb57ce01c35c830396ab4392798112e8aae8c47722"
name = "github.com/tendermint/ed25519"
packages = [
".",
"edwards25519",
"extra25519",
]
pruneopts = "UT"
revision = "d8387025d2b9d158cf4efb07e7ebf814bcce2057"
[[projects]]
digest = "1:2c971a45c89ca2ccc735af50919cdee05fbdc54d4bf50625073693300e31ead8"
digest = "1:10b3a599325740c84a7c81f3f3cb2e1fdb70b3ea01b7fa28495567a2519df431"
name = "github.com/tendermint/go-amino"
packages = ["."]
pruneopts = "UT"
revision = "faa6e731944e2b7b6a46ad202902851e8ce85bee"
version = "v0.12.0"
revision = "6dcc6ddc143e116455c94b25c1004c99e0d0ca12"
version = "v0.14.0"
[[projects]]
digest = "1:53397098d6acb7613358683cc84ae59281a60c6033f0bff62fa8d3f279c6c430"
digest = "1:9f8c4c93658315a795ffd3e0c943d39f78067dd8382b8d7bcfaf6686b92f3978"
name = "github.com/tendermint/iavl"
packages = ["."]
pruneopts = "UT"
revision = "3acc91fb8811db2c5409a855ae1f8e441fe98e2d"
version = "v0.11.0"
revision = "fa74114f764f9827c4ad5573f990ed25bf8c4bac"
version = "v0.11.1"
[[projects]]
digest = "1:f9c7a1f3ee087476f4883c33cc7c1bdbe56b9670b2fb27855ea2f386393272f5"
digest = "1:92d7d1678577fd1a6f3348168cef87880bbc710ef5f4e9a1216f45c56567d734"
name = "github.com/tendermint/tendermint"
packages = [
"abci/client",
@ -485,6 +468,7 @@
"libs/db",
"libs/errors",
"libs/events",
"libs/fail",
"libs/flowrate",
"libs/log",
"libs/pubsub",
@ -505,7 +489,6 @@
"rpc/core",
"rpc/core/types",
"rpc/grpc",
"rpc/lib",
"rpc/lib/client",
"rpc/lib/server",
"rpc/lib/types",
@ -518,8 +501,7 @@
"version",
]
pruneopts = "UT"
revision = "90eda9bfb6e6daeed1c8015df41cb36772d91778"
version = "v0.25.1-rc0"
revision = "ebee4377b15f2958b08994485375dd2ee8a649ac"
[[projects]]
digest = "1:7886f86064faff6f8d08a3eb0e8c773648ff5a2e27730831e2bfbf07467f6666"
@ -530,13 +512,15 @@
version = "v0.1.0"
[[projects]]
digest = "1:aaff04fa01d9b824fde6799759cc597b3ac3671b9ad31924c28b6557d0ee5284"
digest = "1:6f6dc6060c4e9ba73cf28aa88f12a69a030d3d19d518ef8e931879eaa099628d"
name = "golang.org/x/crypto"
packages = [
"bcrypt",
"blowfish",
"chacha20poly1305",
"curve25519",
"ed25519",
"ed25519/internal/edwards25519",
"hkdf",
"internal/chacha20",
"internal/subtle",

View File

@ -1,24 +1,3 @@
# Gopkg.toml example
#
# Refer to https://github.com/golang/dep/blob/master/docs/Gopkg.toml.md
# for detailed Gopkg.toml documentation.
#
# required = ["github.com/user/thing/cmd/thing"]
# ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"]
#
# [[constraint]]
# name = "github.com/user/project"
# version = "1.0.0"
#
# [[override]]
# name = "github.com/x/y"
# version = "2.4.0"
#
# [prune]
# non-go = false
# go-tests = true
# unused-packages = true
[[constraint]]
name = "github.com/bgentry/speakeasy"
version = "~0.1.0"
@ -49,15 +28,15 @@
[[override]]
name = "github.com/tendermint/go-amino"
version = "=v0.12.0"
version = "v0.14.0"
[[override]]
name = "github.com/tendermint/iavl"
version = "=v0.11.0"
version = "=v0.11.1"
[[override]]
name = "github.com/tendermint/tendermint"
version = "=0.25.1-rc0"
revision = "ebee4377b15f2958b08994485375dd2ee8a649ac" # TODO replace w/ 0.26.1
## deps without releases:
@ -89,7 +68,6 @@
version = "1.0.0"
## transitive deps, without releases:
#
[[override]]
name = "github.com/syndtr/goleveldb"

View File

@ -7,12 +7,13 @@ BREAKING CHANGES
* Gaia CLI (`gaiacli`)
* Gaia
* [gaiad init] \#2602 New genesis workflow
* SDK
* [simulation] \#2665 only argument to simulation.Invariant is now app
* Tendermint
* Upgrade to version 0.26.0
FEATURES
@ -42,11 +43,15 @@ IMPROVEMENTS
* Gaia
* SDK
- #2573 [x/distribution] add accum invariance
- \#2573 [x/distribution] add accum invariance
- \#2556 [x/mock/simulation] Fix debugging output
- \#2396 [x/mock/simulation] Change parameters to get more slashes
- \#2617 [x/mock/simulation] Randomize all genesis parameters
- \#2669 [x/stake] Added invarant check to make sure validator's power aligns with its spot in the power store.
- \#1924 [x/mock/simulation] Use a transition matrix for block size
- \#2660 [x/mock/simulation] Staking transactions get tested far more frequently
- #2610 [x/stake] Block redelegation to and from the same validator
- #2652 [x/auth] Add benchmark for get and set account
- \#2610 [x/stake] Block redelegation to and from the same validator
- \#2652 [x/auth] Add benchmark for get and set account
* Tendermint
@ -58,9 +63,10 @@ BUG FIXES
* Gaia CLI (`gaiacli`)
* Gaia
- \#2670 [x/stake] fixed incorrent `IterateBondedValidators` and split into two functions: `IterateBondedValidators` and `IterateLastBlockConsValidators`
* SDK
- #2625 [x/gov] fix AppendTag function usage error
- \#2625 [x/gov] fix AppendTag function usage error
- \#2677 [x/stake, x/distribution] various staking/distribution fixes as found by the simulator
* Tendermint

View File

@ -337,7 +337,7 @@ func handleQueryApp(app *BaseApp, path []string, req abci.RequestQuery) (res abc
}
// Encode with json
value := codec.Cdc.MustMarshalBinary(result)
value := codec.Cdc.MustMarshalBinaryLengthPrefixed(result)
return abci.ResponseQuery{
Code: uint32(sdk.ABCICodeOK),
Value: value,
@ -394,6 +394,7 @@ func handleQueryCustom(app *BaseApp, path []string, req abci.RequestQuery) (res
ctx := sdk.NewContext(app.cms.CacheMultiStore(), app.checkState.ctx.BlockHeader(), true, app.Logger).
WithMinimumFees(app.minimumFees)
// Passes the rest of the path as an argument to the querier.
// For example, in the path "custom/gov/proposal/test", the gov querier gets []string{"proposal", "test"} as the path
resBytes, err := querier(ctx, path[2:], req)

View File

@ -358,7 +358,7 @@ func testTxDecoder(cdc *codec.Codec) sdk.TxDecoder {
if len(txBytes) == 0 {
return nil, sdk.ErrTxDecode("txBytes are empty")
}
err := cdc.UnmarshalBinary(txBytes, &tx)
err := cdc.UnmarshalBinaryLengthPrefixed(txBytes, &tx)
if err != nil {
return nil, sdk.ErrTxDecode("").TraceSDK(err.Error())
}
@ -455,7 +455,7 @@ func TestCheckTx(t *testing.T) {
for i := int64(0); i < nTxs; i++ {
tx := newTxCounter(i, 0)
txBytes, err := codec.MarshalBinary(tx)
txBytes, err := codec.MarshalBinaryLengthPrefixed(tx)
require.NoError(t, err)
r := app.CheckTx(txBytes)
assert.True(t, r.IsOK(), fmt.Sprintf("%v", r))
@ -503,7 +503,7 @@ func TestDeliverTx(t *testing.T) {
for i := 0; i < txPerHeight; i++ {
counter := int64(blockN*txPerHeight + i)
tx := newTxCounter(counter, counter)
txBytes, err := codec.MarshalBinary(tx)
txBytes, err := codec.MarshalBinaryLengthPrefixed(tx)
require.NoError(t, err)
res := app.DeliverTx(txBytes)
require.True(t, res.IsOK(), fmt.Sprintf("%v", res))
@ -544,7 +544,7 @@ func TestMultiMsgDeliverTx(t *testing.T) {
{
app.BeginBlock(abci.RequestBeginBlock{})
tx := newTxCounter(0, 0, 1, 2)
txBytes, err := codec.MarshalBinary(tx)
txBytes, err := codec.MarshalBinaryLengthPrefixed(tx)
require.NoError(t, err)
res := app.DeliverTx(txBytes)
require.True(t, res.IsOK(), fmt.Sprintf("%v", res))
@ -565,7 +565,7 @@ func TestMultiMsgDeliverTx(t *testing.T) {
tx := newTxCounter(1, 3)
tx.Msgs = append(tx.Msgs, msgCounter2{0})
tx.Msgs = append(tx.Msgs, msgCounter2{1})
txBytes, err := codec.MarshalBinary(tx)
txBytes, err := codec.MarshalBinaryLengthPrefixed(tx)
require.NoError(t, err)
res := app.DeliverTx(txBytes)
require.True(t, res.IsOK(), fmt.Sprintf("%v", res))
@ -638,7 +638,7 @@ func TestSimulateTx(t *testing.T) {
require.Equal(t, gasConsumed, result.GasUsed)
// simulate by calling Query with encoded tx
txBytes, err := cdc.MarshalBinary(tx)
txBytes, err := cdc.MarshalBinaryLengthPrefixed(tx)
require.Nil(t, err)
query := abci.RequestQuery{
Path: "/app/simulate",
@ -648,7 +648,7 @@ func TestSimulateTx(t *testing.T) {
require.True(t, queryResult.IsOK(), queryResult.Log)
var res sdk.Result
codec.Cdc.MustUnmarshalBinary(queryResult.Value, &res)
codec.Cdc.MustUnmarshalBinaryLengthPrefixed(queryResult.Value, &res)
require.Nil(t, err, "Result unmarshalling failed")
require.True(t, res.IsOK(), res.Log)
require.Equal(t, gasConsumed, res.GasUsed, res.Log)
@ -729,7 +729,7 @@ func TestRunInvalidTransaction(t *testing.T) {
registerTestCodec(newCdc)
newCdc.RegisterConcrete(&msgNoDecode{}, "cosmos-sdk/baseapp/msgNoDecode", nil)
txBytes, err := newCdc.MarshalBinary(tx)
txBytes, err := newCdc.MarshalBinaryLengthPrefixed(tx)
require.NoError(t, err)
res := app.DeliverTx(txBytes)
require.EqualValues(t, sdk.ToABCICode(sdk.CodespaceRoot, sdk.CodeTxDecode), res.Code)

View File

@ -121,8 +121,13 @@ func createVerifier() tmlite.Verifier {
fmt.Printf("Must specify these options: %s when --trust-node is false\n", errMsg.String())
os.Exit(1)
}
node := rpcclient.NewHTTP(nodeURI, "/websocket")
verifier, err := tmliteProxy.NewVerifier(chainID, filepath.Join(home, ".gaialite"), node, log.NewNopLogger())
cacheSize := 10 // TODO: determine appropriate cache size
verifier, err := tmliteProxy.NewVerifier(
chainID, filepath.Join(home, ".gaialite"),
node, log.NewNopLogger(), cacheSize,
)
if err != nil {
fmt.Printf("Create verifier failed: %s\n", err.Error())

View File

@ -10,9 +10,9 @@ import (
"strings"
"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/store"
abci "github.com/tendermint/tendermint/abci/types"
"github.com/tendermint/tendermint/crypto/merkle"
cmn "github.com/tendermint/tendermint/libs/common"
tmliteErr "github.com/tendermint/tendermint/lite/errors"
tmliteProxy "github.com/tendermint/tendermint/lite/proxy"
@ -54,7 +54,7 @@ func (ctx CLIContext) QuerySubspace(subspace []byte, storeName string) (res []sd
return res, err
}
ctx.Codec.MustUnmarshalBinary(resRaw, &res)
ctx.Codec.MustUnmarshalBinaryLengthPrefixed(resRaw, &res)
return
}
@ -157,8 +157,8 @@ func (ctx CLIContext) query(path string, key cmn.HexBytes) (res []byte, err erro
}
opts := rpcclient.ABCIQueryOptions{
Height: ctx.Height,
Trusted: ctx.TrustNode,
Height: ctx.Height,
Prove: !ctx.TrustNode,
}
result, err := node.ABCIQueryWithOptions(path, key, opts)
@ -198,7 +198,7 @@ func (ctx CLIContext) Verify(height int64) (tmtypes.SignedHeader, error) {
}
// verifyProof perform response proof verification.
func (ctx CLIContext) verifyProof(_ string, resp abci.ResponseQuery) error {
func (ctx CLIContext) verifyProof(queryPath string, resp abci.ResponseQuery) error {
if ctx.Verifier == nil {
return fmt.Errorf("missing valid certifier to verify data from distrusted node")
}
@ -209,25 +209,22 @@ func (ctx CLIContext) verifyProof(_ string, resp abci.ResponseQuery) error {
return err
}
var multiStoreProof store.MultiStoreProof
cdc := codec.New()
// TODO: Instead of reconstructing, stash on CLIContext field?
prt := store.DefaultProofRuntime()
err = cdc.UnmarshalBinary(resp.Proof, &multiStoreProof)
// TODO: Better convention for path?
storeName, err := parseQueryStorePath(queryPath)
if err != nil {
return errors.Wrap(err, "failed to unmarshalBinary rangeProof")
return err
}
// verify the substore commit hash against trusted appHash
substoreCommitHash, err := store.VerifyMultiStoreCommitInfo(
multiStoreProof.StoreName, multiStoreProof.StoreInfos, commit.Header.AppHash,
)
if err != nil {
return errors.Wrap(err, "failed in verifying the proof against appHash")
}
kp := merkle.KeyPath{}
kp = kp.AppendKey([]byte(storeName), merkle.KeyEncodingURL)
kp = kp.AppendKey(resp.Key, merkle.KeyEncodingURL)
err = store.VerifyRangeProof(resp.Key, resp.Value, substoreCommitHash, &multiStoreProof.RangeProof)
err = prt.VerifyValue(resp.Proof, commit.Header.AppHash, kp.String(), resp.Value)
if err != nil {
return errors.Wrap(err, "failed in the range proof verification")
return errors.Wrap(err, "failed to prove merkle proof")
}
return nil
@ -241,20 +238,40 @@ func (ctx CLIContext) queryStore(key cmn.HexBytes, storeName, endPath string) ([
}
// isQueryStoreWithProof expects a format like /<queryType>/<storeName>/<subpath>
// queryType can be app or store.
// queryType must be "store" and subpath must be "key" to require a proof.
func isQueryStoreWithProof(path string) bool {
if !strings.HasPrefix(path, "/") {
return false
}
paths := strings.SplitN(path[1:], "/", 3)
if len(paths) != 3 {
switch {
case len(paths) != 3:
return false
}
if store.RequireProof("/" + paths[2]) {
case paths[0] != "store":
return false
case store.RequireProof("/" + paths[2]):
return true
}
return false
}
// parseQueryStorePath expects a format like /store/<storeName>/key.
func parseQueryStorePath(path string) (storeName string, err error) {
if !strings.HasPrefix(path, "/") {
return "", errors.New("expected path to start with /")
}
paths := strings.SplitN(path[1:], "/", 3)
switch {
case len(paths) != 3:
return "", errors.New("expected format like /store/<storeName>/key")
case paths[0] != "store":
return "", errors.New("expected format like /store/<storeName>/key")
case paths[2] != "key":
return "", errors.New("expected format like /store/<storeName>/key")
}
return paths[1], nil
}

View File

@ -158,11 +158,11 @@ func TestNodeStatus(t *testing.T) {
res, body := Request(t, port, "GET", "/node_info", nil)
require.Equal(t, http.StatusOK, res.StatusCode, body)
var nodeInfo p2p.NodeInfo
var nodeInfo p2p.DefaultNodeInfo
err := cdc.UnmarshalJSON([]byte(body), &nodeInfo)
require.Nil(t, err, "Couldn't parse node info")
require.NotEqual(t, p2p.NodeInfo{}, nodeInfo, "res: %v", res)
require.NotEqual(t, p2p.DefaultNodeInfo{}, nodeInfo, "res: %v", res)
// syncing
res, body = Request(t, port, "GET", "/syncing", nil)

View File

@ -214,6 +214,7 @@ func InitializeTestLCD(
genTxs := []json.RawMessage{}
// append any additional (non-proposing) validators
var accs []gapp.GenesisAccount
for i := 0; i < nValidators; i++ {
operPrivKey := secp256k1.GenPrivKey()
operAddr := operPrivKey.PubKey().Address()
@ -242,9 +243,17 @@ func InitializeTestLCD(
genTxs = append(genTxs, txBytes)
valConsPubKeys = append(valConsPubKeys, pubKey)
valOperAddrs = append(valOperAddrs, sdk.ValAddress(operAddr))
accAuth := auth.NewBaseAccountWithAddress(sdk.AccAddress(operAddr))
accAuth.Coins = sdk.Coins{sdk.NewInt64Coin("steak", 150)}
accs = append(accs, gapp.NewGenesisAccount(&accAuth))
}
genesisState, err := gapp.GaiaAppGenState(cdc, genTxs)
appGenState := gapp.NewDefaultGenesisState()
appGenState.Accounts = accs
genDoc.AppState, err = cdc.MarshalJSON(appGenState)
require.NoError(t, err)
genesisState, err := gapp.GaiaAppGenState(cdc, *genDoc, genTxs)
require.NoError(t, err)
// add some tokens to init accounts

View File

@ -125,7 +125,7 @@ type Info struct {
func parseTx(cdc *codec.Codec, txBytes []byte) (sdk.Tx, error) {
var tx auth.StdTx
err := cdc.UnmarshalBinary(txBytes, &tx)
err := cdc.UnmarshalBinaryLengthPrefixed(txBytes, &tx)
if err != nil {
return nil, err
}

View File

@ -167,7 +167,7 @@ func adjustGasEstimate(estimate int64, adjustment float64) int64 {
func parseQueryResponse(cdc *amino.Codec, rawRes []byte) (int64, error) {
var simulationResult sdk.Result
if err := cdc.UnmarshalBinary(rawRes, &simulationResult); err != nil {
if err := cdc.UnmarshalBinaryLengthPrefixed(rawRes, &simulationResult); err != nil {
return 0, err
}
return simulationResult.GasUsed, nil

View File

@ -12,7 +12,7 @@ import (
func TestParseQueryResponse(t *testing.T) {
cdc := app.MakeCodec()
sdkResBytes := cdc.MustMarshalBinary(sdk.Result{GasUsed: 10})
sdkResBytes := cdc.MustMarshalBinaryLengthPrefixed(sdk.Result{GasUsed: 10})
gas, err := parseQueryResponse(cdc, sdkResBytes)
assert.Equal(t, gas, int64(10))
assert.Nil(t, err)
@ -28,7 +28,7 @@ func TestCalculateGas(t *testing.T) {
if wantErr {
return nil, errors.New("")
}
return cdc.MustMarshalBinary(sdk.Result{GasUsed: gasUsed}), nil
return cdc.MustMarshalBinaryLengthPrefixed(sdk.Result{GasUsed: gasUsed}), nil
}
}
type args struct {

View File

@ -109,7 +109,7 @@ func NewGaiaApp(logger log.Logger, db dbm.DB, traceStore io.Writer, baseAppOptio
app.cdc,
app.keyParams, app.tkeyParams,
)
app.stakeKeeper = stake.NewKeeper(
stakeKeeper := stake.NewKeeper(
app.cdc,
app.keyStake, app.tkeyStake,
app.bankKeeper, app.paramsKeeper.Subspace(stake.DefaultParamspace),
@ -117,30 +117,32 @@ func NewGaiaApp(logger log.Logger, db dbm.DB, traceStore io.Writer, baseAppOptio
)
app.mintKeeper = mint.NewKeeper(app.cdc, app.keyMint,
app.paramsKeeper.Subspace(mint.DefaultParamspace),
app.stakeKeeper, app.feeCollectionKeeper,
&stakeKeeper, app.feeCollectionKeeper,
)
app.distrKeeper = distr.NewKeeper(
app.cdc,
app.keyDistr,
app.paramsKeeper.Subspace(distr.DefaultParamspace),
app.bankKeeper, app.stakeKeeper, app.feeCollectionKeeper,
app.bankKeeper, &stakeKeeper, app.feeCollectionKeeper,
app.RegisterCodespace(stake.DefaultCodespace),
)
app.slashingKeeper = slashing.NewKeeper(
app.cdc,
app.keySlashing,
app.stakeKeeper, app.paramsKeeper.Subspace(slashing.DefaultParamspace),
&stakeKeeper, app.paramsKeeper.Subspace(slashing.DefaultParamspace),
app.RegisterCodespace(slashing.DefaultCodespace),
)
app.govKeeper = gov.NewKeeper(
app.cdc,
app.keyGov,
app.paramsKeeper, app.paramsKeeper.Subspace(gov.DefaultParamspace), app.bankKeeper, app.stakeKeeper,
app.paramsKeeper, app.paramsKeeper.Subspace(gov.DefaultParamspace), app.bankKeeper, &stakeKeeper,
app.RegisterCodespace(gov.DefaultCodespace),
)
// register the staking hooks
app.stakeKeeper = app.stakeKeeper.WithHooks(
// NOTE: stakeKeeper above are passed by reference,
// so that it can be modified like below:
app.stakeKeeper = *stakeKeeper.SetHooks(
NewHooks(app.distrKeeper.Hooks(), app.slashingKeeper.Hooks()))
// register message routes
@ -259,7 +261,7 @@ func (app *GaiaApp) initChainer(ctx sdk.Context, req abci.RequestInitChain) abci
if err != nil {
panic(err)
}
bz := app.cdc.MustMarshalBinary(tx)
bz := app.cdc.MustMarshalBinaryLengthPrefixed(tx)
res := app.BaseApp.DeliverTx(bz)
if !res.IsOK() {
panic(res.Log)
@ -273,7 +275,8 @@ func (app *GaiaApp) initChainer(ctx sdk.Context, req abci.RequestInitChain) abci
// sanity check
if len(req.Validators) > 0 {
if len(req.Validators) != len(validators) {
panic(fmt.Errorf("len(RequestInitChain.Validators) != len(validators) (%d != %d) ", len(req.Validators), len(validators)))
panic(fmt.Errorf("len(RequestInitChain.Validators) != len(validators) (%d != %d)",
len(req.Validators), len(validators)))
}
sort.Sort(abci.ValidatorUpdates(req.Validators))
sort.Sort(abci.ValidatorUpdates(validators))

View File

@ -26,6 +26,7 @@ var (
// bonded tokens given to genesis validators/accounts
freeFermionVal = int64(100)
freeFermionsAcc = sdk.NewInt(150)
bondDenom = "steak"
)
// State to Unmarshal
@ -90,58 +91,60 @@ func GaiaAppInit() server.AppInit {
// Create the core parameters for genesis initialization for gaia
// note that the pubkey input is this machines pubkey
func GaiaAppGenState(cdc *codec.Codec, appGenTxs []json.RawMessage) (genesisState GenesisState, err error) {
if len(appGenTxs) == 0 {
err = errors.New("must provide at least genesis transaction")
return
func GaiaAppGenState(cdc *codec.Codec, genDoc tmtypes.GenesisDoc, appGenTxs []json.RawMessage) (
genesisState GenesisState, err error) {
if err = cdc.UnmarshalJSON(genDoc.AppState, &genesisState); err != nil {
return genesisState, err
}
// start with the default staking genesis state
stakeData := stake.DefaultGenesisState()
slashingData := slashing.DefaultGenesisState()
// get genesis flag account information
genaccs := make([]GenesisAccount, len(appGenTxs))
// if there are no gen txs to be processed, return the default empty state
if len(appGenTxs) == 0 {
return genesisState, errors.New("there must be at least one genesis tx")
}
stakeData := genesisState.StakeData
for i, genTx := range appGenTxs {
var tx auth.StdTx
err = cdc.UnmarshalJSON(genTx, &tx)
if err != nil {
return
if err := cdc.UnmarshalJSON(genTx, &tx); err != nil {
return genesisState, err
}
msgs := tx.GetMsgs()
if len(msgs) != 1 {
err = errors.New("must provide genesis StdTx with exactly 1 CreateValidator message")
return
return genesisState, errors.New(
"must provide genesis StdTx with exactly 1 CreateValidator message")
}
if _, ok := msgs[0].(stake.MsgCreateValidator); !ok {
return genesisState, fmt.Errorf(
"Genesis transaction %v does not contain a MsgCreateValidator", i)
}
msg := msgs[0].(stake.MsgCreateValidator)
// create the genesis account, give'm few steaks and a buncha token with there name
genaccs[i] = genesisAccountFromMsgCreateValidator(msg, freeFermionsAcc)
stakeData.Pool.LooseTokens = stakeData.Pool.LooseTokens.Add(sdk.NewDecFromInt(freeFermionsAcc)) // increase the supply
}
// create the final app state
genesisState = GenesisState{
Accounts: genaccs,
StakeData: stakeData,
for _, acc := range genesisState.Accounts {
// create the genesis account, give'm few steaks and a buncha token with there name
for _, coin := range acc.Coins {
if coin.Denom == bondDenom {
stakeData.Pool.LooseTokens = stakeData.Pool.LooseTokens.
Add(sdk.NewDecFromInt(coin.Amount)) // increase the supply
}
}
}
genesisState.StakeData = stakeData
genesisState.GenTxs = appGenTxs
return genesisState, nil
}
// NewDefaultGenesisState generates the default state for gaia.
func NewDefaultGenesisState() GenesisState {
return GenesisState{
Accounts: nil,
StakeData: stake.DefaultGenesisState(),
MintData: mint.DefaultGenesisState(),
DistrData: distr.DefaultGenesisState(),
GovData: gov.DefaultGenesisState(),
SlashingData: slashingData,
GenTxs: appGenTxs,
SlashingData: slashing.DefaultGenesisState(),
GenTxs: nil,
}
return
}
func genesisAccountFromMsgCreateValidator(msg stake.MsgCreateValidator, amount sdk.Int) GenesisAccount {
accAuth := auth.NewBaseAccountWithAddress(sdk.AccAddress(msg.ValidatorAddr))
accAuth.Coins = []sdk.Coin{
{msg.Description.Moniker + "Token", sdk.NewInt(1000)},
{"steak", amount},
}
return NewGenesisAccount(&accAuth)
}
// GaiaValidateGenesisState ensures that the genesis state obeys the expected invariants
@ -175,27 +178,43 @@ func validateGenesisStateAccounts(accs []GenesisAccount) (err error) {
}
// GaiaAppGenState but with JSON
func GaiaAppGenStateJSON(cdc *codec.Codec, appGenTxs []json.RawMessage) (appState json.RawMessage, err error) {
func GaiaAppGenStateJSON(cdc *codec.Codec, genDoc tmtypes.GenesisDoc, appGenTxs []json.RawMessage) (
appState json.RawMessage, err error) {
// create the final app state
genesisState, err := GaiaAppGenState(cdc, appGenTxs)
genesisState, err := GaiaAppGenState(cdc, genDoc, appGenTxs)
if err != nil {
return nil, err
}
appState, err = codec.MarshalJSONIndent(cdc, genesisState)
return
return codec.MarshalJSONIndent(cdc, genesisState)
}
// CollectStdTxs processes and validates application's genesis StdTxs and returns the list of validators,
// appGenTxs, and persistent peers required to generate genesis.json.
func CollectStdTxs(moniker string, genTxsDir string, cdc *codec.Codec) (
validators []tmtypes.GenesisValidator, appGenTxs []auth.StdTx, persistentPeers string, err error) {
// CollectStdTxs processes and validates application's genesis StdTxs and returns
// the list of appGenTxs, and persistent peers required to generate genesis.json.
func CollectStdTxs(cdc *codec.Codec, moniker string, genTxsDir string, genDoc tmtypes.GenesisDoc) (
appGenTxs []auth.StdTx, persistentPeers string, err error) {
var fos []os.FileInfo
fos, err = ioutil.ReadDir(genTxsDir)
if err != nil {
return
return appGenTxs, persistentPeers, err
}
var addresses []string
// prepare a map of all accounts in genesis state to then validate
// against the validators addresses
var appState GenesisState
if err := cdc.UnmarshalJSON(genDoc.AppState, &appState); err != nil {
return appGenTxs, persistentPeers, err
}
addrMap := make(map[string]GenesisAccount, len(appState.Accounts))
for i := 0; i < len(appState.Accounts); i++ {
acc := appState.Accounts[i]
strAddr := string(acc.Address)
addrMap[strAddr] = acc
}
// addresses and IPs (and port) validator server info
var addressesIPs []string
for _, fo := range fos {
filename := filepath.Join(genTxsDir, fo.Name())
if !fo.IsDir() && (filepath.Ext(filename) != ".json") {
@ -204,48 +223,55 @@ func CollectStdTxs(moniker string, genTxsDir string, cdc *codec.Codec) (
// get the genStdTx
var jsonRawTx []byte
jsonRawTx, err = ioutil.ReadFile(filename)
if err != nil {
return
if jsonRawTx, err = ioutil.ReadFile(filename); err != nil {
return appGenTxs, persistentPeers, err
}
var genStdTx auth.StdTx
err = cdc.UnmarshalJSON(jsonRawTx, &genStdTx)
if err != nil {
return
if err = cdc.UnmarshalJSON(jsonRawTx, &genStdTx); err != nil {
return appGenTxs, persistentPeers, err
}
appGenTxs = append(appGenTxs, genStdTx)
nodeAddr := genStdTx.GetMemo()
if len(nodeAddr) == 0 {
err = fmt.Errorf("couldn't find node's address in %s", fo.Name())
return
// the memo flag is used to store
// the ip and node-id, for example this may be:
// "528fd3df22b31f4969b05652bfe8f0fe921321d5@192.168.2.37:26656"
nodeAddrIP := genStdTx.GetMemo()
if len(nodeAddrIP) == 0 {
return appGenTxs, persistentPeers, fmt.Errorf(
"couldn't find node's address and IP in %s", fo.Name())
}
// genesis transactions must be single-message
msgs := genStdTx.GetMsgs()
if len(msgs) != 1 {
err = errors.New("each genesis transaction must provide a single genesis message")
return
return appGenTxs, persistentPeers, errors.New(
"each genesis transaction must provide a single genesis message")
}
// TODO: this could be decoupled from stake.MsgCreateValidator
// TODO: and we likely want to do it for real world Gaia
// validate the validator address and funds against the accounts in the state
msg := msgs[0].(stake.MsgCreateValidator)
validators = append(validators, tmtypes.GenesisValidator{
PubKey: msg.PubKey,
Power: freeFermionVal,
Name: msg.Description.Moniker,
})
addr := string(sdk.AccAddress(msg.ValidatorAddr))
acc, ok := addrMap[addr]
if !ok {
return appGenTxs, persistentPeers, fmt.Errorf(
"account %v not in genesis.json: %+v", addr, addrMap)
}
if acc.Coins.AmountOf(msg.Delegation.Denom).LT(msg.Delegation.Amount) {
err = fmt.Errorf("insufficient fund for the delegation: %s < %s",
acc.Coins.AmountOf(msg.Delegation.Denom), msg.Delegation.Amount)
}
// exclude itself from persistent peers
if msg.Description.Moniker != moniker {
addresses = append(addresses, nodeAddr)
addressesIPs = append(addressesIPs, nodeAddrIP)
}
}
sort.Strings(addresses)
persistentPeers = strings.Join(addresses, ",")
sort.Strings(addressesIPs)
persistentPeers = strings.Join(addressesIPs, ",")
return
return appGenTxs, persistentPeers, nil
}
func NewDefaultGenesisAccount(addr sdk.AccAddress) GenesisAccount {

View File

@ -1,11 +1,13 @@
package app
import (
"encoding/json"
"github.com/tendermint/tendermint/crypto/secp256k1"
tmtypes "github.com/tendermint/tendermint/types"
"testing"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/auth"
"github.com/cosmos/cosmos-sdk/x/gov"
"github.com/cosmos/cosmos-sdk/x/stake"
stakeTypes "github.com/cosmos/cosmos-sdk/x/stake/types"
"github.com/stretchr/testify/require"
@ -27,7 +29,8 @@ var (
func makeGenesisState(t *testing.T, genTxs []auth.StdTx) GenesisState {
// start with the default staking genesis state
stakeData := stake.DefaultGenesisState()
appState := NewDefaultGenesisState()
stakeData := appState.StakeData
genAccs := make([]GenesisAccount, len(genTxs))
for i, genTx := range genTxs {
@ -35,17 +38,15 @@ func makeGenesisState(t *testing.T, genTxs []auth.StdTx) GenesisState {
require.Equal(t, 1, len(msgs))
msg := msgs[0].(stake.MsgCreateValidator)
// get genesis flag account information
genAccs[i] = genesisAccountFromMsgCreateValidator(msg, freeFermionsAcc)
stakeData.Pool.LooseTokens = stakeData.Pool.LooseTokens.Add(sdk.NewDecFromInt(freeFermionsAcc)) // increase the supply
acc := auth.NewBaseAccountWithAddress(sdk.AccAddress(msg.ValidatorAddr))
acc.Coins = sdk.Coins{sdk.NewInt64Coin(bondDenom, 150)}
genAccs[i] = NewGenesisAccount(&acc)
stakeData.Pool.LooseTokens = stakeData.Pool.LooseTokens.Add(sdk.NewDec(150)) // increase the supply
}
// create the final app state
return GenesisState{
Accounts: genAccs,
StakeData: stakeData,
GovData: gov.DefaultGenesisState(),
}
appState.Accounts = genAccs
return appState
}
func TestToAccount(t *testing.T) {
@ -68,6 +69,19 @@ func TestGaiaAppGenTx(t *testing.T) {
func TestGaiaAppGenState(t *testing.T) {
cdc := MakeCodec()
_ = cdc
var genDoc tmtypes.GenesisDoc
// test unmarshalling error
_, err := GaiaAppGenState(cdc, genDoc, []json.RawMessage{})
require.Error(t, err)
appState := makeGenesisState(t, []auth.StdTx{})
genDoc.AppState, err = json.Marshal(appState)
require.NoError(t, err)
// test validation error
_, err = GaiaAppGenState(cdc, genDoc, []json.RawMessage{})
require.Error(t, err)
// TODO test must provide at least genesis transaction
// TODO test with both one and two genesis transactions:
@ -77,7 +91,8 @@ func TestGaiaAppGenState(t *testing.T) {
func makeMsg(name string, pk crypto.PubKey) auth.StdTx {
desc := stake.NewDescription(name, "", "", "")
comm := stakeTypes.CommissionMsg{}
msg := stake.NewMsgCreateValidator(sdk.ValAddress(pk.Address()), pk, sdk.NewInt64Coin("steak", 50), desc, comm)
msg := stake.NewMsgCreateValidator(sdk.ValAddress(pk.Address()), pk, sdk.NewInt64Coin(bondDenom,
50), desc, comm)
return auth.NewStdTx([]sdk.Msg{msg}, auth.StdFee{}, nil, "")
}
@ -106,3 +121,10 @@ func TestGaiaGenesisValidation(t *testing.T) {
err = GaiaValidateGenesisState(genesisState)
require.NotNil(t, err)
}
func TestNewDefaultGenesisAccount(t *testing.T) {
addr := secp256k1.GenPrivKeySecp256k1([]byte("")).PubKey().Address()
acc := NewDefaultGenesisAccount(sdk.AccAddress(addr))
require.Equal(t, sdk.NewInt(1000), acc.Coins.AmountOf("fooToken"))
require.Equal(t, sdk.NewInt(150), acc.Coins.AmountOf(bondDenom))
}

View File

@ -8,6 +8,7 @@ import (
"math/rand"
"os"
"testing"
"time"
"github.com/stretchr/testify/require"
@ -50,42 +51,93 @@ func init() {
func appStateFn(r *rand.Rand, accs []simulation.Account) json.RawMessage {
var genesisAccounts []GenesisAccount
amt := int64(10000)
amount := int64(r.Intn(1e6))
numInitiallyBonded := int64(r.Intn(250))
numAccs := int64(len(accs))
if numInitiallyBonded > numAccs {
numInitiallyBonded = numAccs
}
fmt.Printf("Selected randomly generated parameters for simulated genesis: {amount of steak per account: %v, initially bonded validators: %v}\n", amount, numInitiallyBonded)
// Randomly generate some genesis accounts
for _, acc := range accs {
coins := sdk.Coins{sdk.Coin{"steak", sdk.NewInt(amt)}}
coins := sdk.Coins{sdk.Coin{"steak", sdk.NewInt(amount)}}
genesisAccounts = append(genesisAccounts, GenesisAccount{
Address: acc.Address,
Coins: coins,
})
}
// Default genesis state
govGenesis := gov.DefaultGenesisState()
stakeGenesis := stake.DefaultGenesisState()
slashingGenesis := slashing.DefaultGenesisState()
// Random genesis states
govGenesis := gov.GenesisState{
StartingProposalID: int64(r.Intn(100)),
DepositProcedure: gov.DepositProcedure{
MinDeposit: sdk.Coins{sdk.NewInt64Coin("steak", int64(r.Intn(1e3)))},
MaxDepositPeriod: time.Duration(r.Intn(2*172800)) * time.Second,
},
VotingProcedure: gov.VotingProcedure{
VotingPeriod: time.Duration(r.Intn(2*172800)) * time.Second,
},
TallyingProcedure: gov.TallyingProcedure{
Threshold: sdk.NewDecWithPrec(5, 1),
Veto: sdk.NewDecWithPrec(334, 3),
GovernancePenalty: sdk.NewDecWithPrec(1, 2),
},
}
fmt.Printf("Selected randomly generated governance parameters: %+v\n", govGenesis)
stakeGenesis := stake.GenesisState{
Pool: stake.InitialPool(),
Params: stake.Params{
UnbondingTime: time.Duration(r.Intn(60*60*24*3*2)) * time.Second,
MaxValidators: uint16(r.Intn(250)),
BondDenom: "steak",
},
}
fmt.Printf("Selected randomly generated staking parameters: %+v\n", stakeGenesis)
slashingGenesis := slashing.GenesisState{
Params: slashing.Params{
MaxEvidenceAge: stakeGenesis.Params.UnbondingTime,
DoubleSignUnbondDuration: time.Duration(r.Intn(60*60*24)) * time.Second,
SignedBlocksWindow: int64(r.Intn(1000)),
DowntimeUnbondDuration: time.Duration(r.Intn(86400)) * time.Second,
MinSignedPerWindow: sdk.NewDecWithPrec(int64(r.Intn(10)), 1),
SlashFractionDoubleSign: sdk.NewDec(1).Quo(sdk.NewDec(int64(r.Intn(50) + 1))),
SlashFractionDowntime: sdk.NewDec(1).Quo(sdk.NewDec(int64(r.Intn(200) + 1))),
},
}
fmt.Printf("Selected randomly generated slashing parameters: %+v\n", slashingGenesis)
mintGenesis := mint.GenesisState{
Minter: mint.Minter{
InflationLastTime: time.Unix(0, 0),
Inflation: sdk.NewDecWithPrec(int64(r.Intn(99)), 2),
},
Params: mint.Params{
MintDenom: "steak",
InflationRateChange: sdk.NewDecWithPrec(int64(r.Intn(99)), 2),
InflationMax: sdk.NewDecWithPrec(20, 2),
InflationMin: sdk.NewDecWithPrec(7, 2),
GoalBonded: sdk.NewDecWithPrec(67, 2),
},
}
fmt.Printf("Selected randomly generated minting parameters: %v\n", mintGenesis)
var validators []stake.Validator
var delegations []stake.Delegation
// XXX Try different numbers of initially bonded validators
numInitiallyBonded := int64(50)
valAddrs := make([]sdk.ValAddress, numInitiallyBonded)
for i := 0; i < int(numInitiallyBonded); i++ {
valAddr := sdk.ValAddress(accs[i].Address)
valAddrs[i] = valAddr
validator := stake.NewValidator(valAddr, accs[i].PubKey, stake.Description{})
validator.Tokens = sdk.NewDec(amt)
validator.DelegatorShares = sdk.NewDec(amt)
delegation := stake.Delegation{accs[i].Address, valAddr, sdk.NewDec(amt), 0}
validator.Tokens = sdk.NewDec(amount)
validator.DelegatorShares = sdk.NewDec(amount)
delegation := stake.Delegation{accs[i].Address, valAddr, sdk.NewDec(amount), 0}
validators = append(validators, validator)
delegations = append(delegations, delegation)
}
stakeGenesis.Pool.LooseTokens = sdk.NewDec(amt*250 + (numInitiallyBonded * amt))
stakeGenesis.Pool.LooseTokens = sdk.NewDec((amount * numAccs) + (numInitiallyBonded * amount))
stakeGenesis.Validators = validators
stakeGenesis.Bonds = delegations
mintGenesis := mint.DefaultGenesisState()
genesis := GenesisState{
Accounts: genesisAccounts,

View File

@ -5,9 +5,11 @@ package clitest
import (
"encoding/json"
"fmt"
"github.com/tendermint/tendermint/types"
"io/ioutil"
"os"
"path"
"path/filepath"
"testing"
"github.com/stretchr/testify/require"
@ -207,7 +209,7 @@ func TestGaiaCLIGasAuto(t *testing.T) {
func TestGaiaCLICreateValidator(t *testing.T) {
chainID, servAddr, port := initializeFixtures(t)
flags := fmt.Sprintf("--home=%s --node=%v --chain-id=%v", gaiacliHome, servAddr, chainID)
flags := fmt.Sprintf("--home=%s --chain-id=%v --node=%s", gaiacliHome, chainID, servAddr)
// start gaiad server
proc := tests.GoExecuteTWithStdout(t, fmt.Sprintf("gaiad start --home=%s --rpc.laddr=%v", gaiadHome, servAddr))
@ -544,7 +546,7 @@ func TestGaiaCLIConfig(t *testing.T) {
servAddr, port, err := server.FreeTCPAddr()
require.NoError(t, err)
node := fmt.Sprintf("%s:%s", servAddr, port)
chainID := executeInit(t, fmt.Sprintf("gaiad init -o --name=foo --home=%s --home-client=%s", gaiadHome, gaiacliHome))
chainID := executeInit(t, fmt.Sprintf("gaiad init -o --moniker=foo --home=%s", gaiadHome))
executeWrite(t, fmt.Sprintf("gaiacli --home=%s config", gaiadHome), gaiacliHome, node, "y")
config, err := ioutil.ReadFile(path.Join(gaiacliHome, "config", "config.toml"))
require.NoError(t, err)
@ -594,12 +596,27 @@ func initializeFixtures(t *testing.T) (chainID, servAddr, port string) {
tests.ExecuteT(t, fmt.Sprintf("gaiad --home=%s unsafe-reset-all", gaiadHome), "")
executeWrite(t, fmt.Sprintf("gaiacli keys delete --home=%s foo", gaiacliHome), app.DefaultKeyPass)
executeWrite(t, fmt.Sprintf("gaiacli keys delete --home=%s bar", gaiacliHome), app.DefaultKeyPass)
chainID = executeInit(t, fmt.Sprintf("gaiad init -o --name=foo --home=%s --home-client=%s", gaiadHome, gaiacliHome))
executeWrite(t, fmt.Sprintf("gaiacli keys add --home=%s foo", gaiacliHome), app.DefaultKeyPass)
executeWrite(t, fmt.Sprintf("gaiacli keys add --home=%s bar", gaiacliHome), app.DefaultKeyPass)
fooAddr, _ := executeGetAddrPK(t, fmt.Sprintf(
"gaiacli keys show foo --output=json --home=%s", gaiacliHome))
chainID = executeInit(t, fmt.Sprintf("gaiad init -o --moniker=foo --home=%s", gaiadHome))
genFile := filepath.Join(gaiadHome, "config", "genesis.json")
genDoc := readGenesisFile(t, genFile)
var appState app.GenesisState
err := codec.Cdc.UnmarshalJSON(genDoc.AppState, &appState)
require.NoError(t, err)
appState.Accounts = []app.GenesisAccount{app.NewDefaultGenesisAccount(fooAddr)}
appStateJSON, err := codec.Cdc.MarshalJSON(appState)
require.NoError(t, err)
genDoc.AppState = appStateJSON
genDoc.SaveAs(genFile)
executeWrite(t, fmt.Sprintf(
"gaiad gentx --name=foo --home=%s --home-client=%s", gaiadHome, gaiacliHome),
app.DefaultKeyPass)
executeWrite(t, fmt.Sprintf("gaiad collect-gentxs --home=%s", gaiadHome), app.DefaultKeyPass)
// get a free port, also setup some common flags
servAddr, port, err := server.FreeTCPAddr()
servAddr, port, err = server.FreeTCPAddr()
require.NoError(t, err)
return
}
@ -618,6 +635,18 @@ func writeToNewTempFile(t *testing.T, s string) *os.File {
return fp
}
func readGenesisFile(t *testing.T, genFile string) types.GenesisDoc {
var genDoc types.GenesisDoc
fp, err := os.Open(genFile)
require.NoError(t, err)
fileContents, err := ioutil.ReadAll(fp)
require.NoError(t, err)
defer fp.Close()
err = codec.Cdc.UnmarshalJSON(fileContents, &genDoc)
require.NoError(t, err)
return genDoc
}
//___________________________________________________________________________________
// executors

View File

@ -39,7 +39,8 @@ func main() {
}
appInit := app.GaiaAppInit()
rootCmd.AddCommand(gaiaInit.InitCmd(ctx, cdc, appInit))
rootCmd.AddCommand(gaiaInit.TestnetFilesCmd(ctx, cdc, appInit))
rootCmd.AddCommand(gaiaInit.CollectGenTxsCmd(ctx, cdc))
rootCmd.AddCommand(gaiaInit.TestnetFilesCmd(ctx, cdc, server.AppInit{}))
rootCmd.AddCommand(gaiaInit.GenTxCmd(ctx, cdc))
server.AddCommands(ctx, cdc, rootCmd, appInit,

View File

@ -220,7 +220,7 @@ func runTxCmd(cmd *cobra.Command, args []string) error {
var tx = auth.StdTx{}
cdc := gaia.MakeCodec()
err = cdc.UnmarshalBinary(txBytes, &tx)
err = cdc.UnmarshalBinaryLengthPrefixed(txBytes, &tx)
if err != nil {
return err
}

119
cmd/gaia/init/collect.go Normal file
View File

@ -0,0 +1,119 @@
package init
import (
"encoding/json"
"io/ioutil"
"path/filepath"
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/cmd/gaia/app"
"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/server"
"github.com/cosmos/cosmos-sdk/x/auth"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"github.com/tendermint/go-amino"
cfg "github.com/tendermint/tendermint/config"
"github.com/tendermint/tendermint/crypto"
"github.com/tendermint/tendermint/libs/cli"
"github.com/tendermint/tendermint/types"
)
type initConfig struct {
ChainID string
GenTxsDir string
Name string
NodeID string
ValPubKey crypto.PubKey
}
// nolint
func CollectGenTxsCmd(ctx *server.Context, cdc *codec.Codec) *cobra.Command {
cmd := &cobra.Command{
Use: "collect-gentxs",
Short: "Collect genesis txs and output a genesis.json file",
RunE: func(_ *cobra.Command, _ []string) error {
config := ctx.Config
config.SetRoot(viper.GetString(cli.HomeFlag))
name := viper.GetString(client.FlagName)
nodeID, valPubKey, err := InitializeNodeValidatorFiles(config)
if err != nil {
return err
}
genDoc, err := loadGenesisDoc(cdc, config.GenesisFile())
if err != nil {
return err
}
toPrint := printInfo{
Moniker: config.Moniker,
ChainID: genDoc.ChainID,
NodeID: nodeID,
}
initCfg := initConfig{
ChainID: genDoc.ChainID,
GenTxsDir: filepath.Join(config.RootDir, "config", "gentx"),
Name: name,
NodeID: nodeID,
ValPubKey: valPubKey,
}
appMessage, err := genAppStateFromConfig(cdc, config, initCfg, genDoc)
if err != nil {
return err
}
toPrint.AppMessage = appMessage
// print out some key information
return displayInfo(cdc, toPrint)
},
}
cmd.Flags().String(cli.HomeFlag, app.DefaultNodeHome, "node's home directory")
return cmd
}
func genAppStateFromConfig(cdc *codec.Codec, config *cfg.Config, initCfg initConfig,
genDoc types.GenesisDoc) (appState json.RawMessage, err error) {
genFile := config.GenesisFile()
// process genesis transactions, else create default genesis.json
var appGenTxs []auth.StdTx
var persistentPeers string
var genTxs []json.RawMessage
var jsonRawTx json.RawMessage
appGenTxs, persistentPeers, err = app.CollectStdTxs(
cdc, config.Moniker, initCfg.GenTxsDir, genDoc)
if err != nil {
return
}
genTxs = make([]json.RawMessage, len(appGenTxs))
config.P2P.PersistentPeers = persistentPeers
for i, stdTx := range appGenTxs {
jsonRawTx, err = cdc.MarshalJSON(stdTx)
if err != nil {
return
}
genTxs[i] = jsonRawTx
}
cfg.WriteConfigFile(filepath.Join(config.RootDir, "config", "config.toml"), config)
appState, err = app.GaiaAppGenStateJSON(cdc, genDoc, genTxs)
if err != nil {
return
}
err = WriteGenesisFile(genFile, initCfg.ChainID, nil, appState)
return
}
func loadGenesisDoc(cdc *amino.Codec, genFile string) (genDoc types.GenesisDoc, err error) {
genContents, err := ioutil.ReadFile(genFile)
if err != nil {
return
}
err = cdc.UnmarshalJSON(genContents, &genDoc)
return
}

View File

@ -55,9 +55,20 @@ following delegation and commission default parameters:
if err != nil {
return err
}
genDoc, err := loadGenesisDoc(cdc, config.GenesisFile())
if err != nil {
return err
}
// Read --pubkey, if empty take it from priv_validator.json
if valPubKeyString := viper.GetString(cli.FlagPubKey); valPubKeyString != "" {
valPubKey, err = sdk.GetConsPubKeyBech32(valPubKeyString)
if err != nil {
return err
}
}
// Run gaiad tx create-validator
prepareFlagsForTxCreateValidator(config, nodeID, ip, valPubKey)
prepareFlagsForTxCreateValidator(config, nodeID, ip, genDoc.ChainID, valPubKey)
createValidatorCmd := cli.GetCmdCreateValidator(cdc)
w, err := ioutil.TempFile("", "gentx")
@ -82,28 +93,41 @@ following delegation and commission default parameters:
},
}
cmd.Flags().String(tmcli.HomeFlag, app.DefaultNodeHome, "node's home directory")
cmd.Flags().String(flagClientHome, app.DefaultCLIHome, "client's home directory")
cmd.Flags().String(client.FlagChainID, "", "genesis file chain-id")
cmd.Flags().String(client.FlagName, "", "name of private key with which to sign the gentx")
cmd.Flags().AddFlagSet(cli.FsCommissionCreate)
cmd.Flags().AddFlagSet(cli.FsAmount)
cmd.Flags().AddFlagSet(cli.FsPk)
cmd.MarkFlagRequired(client.FlagName)
return cmd
}
func prepareFlagsForTxCreateValidator(config *cfg.Config, nodeID, ip string, valPubKey crypto.PubKey) {
viper.Set(tmcli.HomeFlag, viper.GetString(flagClientHome)) // --home
func prepareFlagsForTxCreateValidator(config *cfg.Config, nodeID, ip, chainID string,
valPubKey crypto.PubKey) {
viper.Set(tmcli.HomeFlag, viper.GetString(flagClientHome)) // --home
viper.Set(client.FlagChainID, chainID)
viper.Set(client.FlagFrom, viper.GetString(client.FlagName)) // --from
viper.Set(cli.FlagNodeID, nodeID) // --node-id
viper.Set(cli.FlagIP, ip) // --ip
viper.Set(cli.FlagPubKey, sdk.MustBech32ifyConsPub(valPubKey)) // --pubkey
viper.Set(cli.FlagAmount, defaultAmount) // --amount
viper.Set(cli.FlagCommissionRate, defaultCommissionRate)
viper.Set(cli.FlagCommissionMaxRate, defaultCommissionMaxRate)
viper.Set(cli.FlagCommissionMaxChangeRate, defaultCommissionMaxChangeRate)
viper.Set(cli.FlagGenesisFormat, true) // --genesis-format
viper.Set(cli.FlagMoniker, config.Moniker) // --moniker
viper.Set(cli.FlagGenesisFormat, true) // --genesis-format
viper.Set(cli.FlagMoniker, config.Moniker) // --moniker
if config.Moniker == "" {
viper.Set(cli.FlagMoniker, viper.GetString(client.FlagName))
}
if viper.GetString(cli.FlagAmount) == "" {
viper.Set(cli.FlagAmount, defaultAmount)
}
if viper.GetString(cli.FlagCommissionRate) == "" {
viper.Set(cli.FlagCommissionRate, defaultCommissionRate)
}
if viper.GetString(cli.FlagCommissionMaxRate) == "" {
viper.Set(cli.FlagCommissionMaxRate, defaultCommissionMaxRate)
}
if viper.GetString(cli.FlagCommissionMaxChangeRate) == "" {
viper.Set(cli.FlagCommissionMaxChangeRate, defaultCommissionMaxChangeRate)
}
}
func prepareFlagsForTxSign() {

View File

@ -2,24 +2,19 @@ package init
import (
"encoding/json"
"errors"
"fmt"
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/cmd/gaia/app"
"github.com/cosmos/cosmos-sdk/x/auth"
authtx "github.com/cosmos/cosmos-sdk/x/auth/client/txbuilder"
"github.com/cosmos/cosmos-sdk/x/stake"
"github.com/tendermint/tendermint/crypto"
"github.com/tendermint/tendermint/privval"
"os"
"path/filepath"
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/cmd/gaia/app"
"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/server"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/spf13/cobra"
"github.com/spf13/viper"
cfg "github.com/tendermint/tendermint/config"
"github.com/tendermint/tendermint/crypto"
"github.com/tendermint/tendermint/libs/cli"
"github.com/tendermint/tendermint/libs/common"
"github.com/tendermint/tendermint/p2p"
@ -27,26 +22,11 @@ import (
)
const (
flagWithTxs = "with-txs"
flagOverwrite = "overwrite"
flagClientHome = "home-client"
flagOverwriteKey = "overwrite-key"
flagSkipGenesis = "skip-genesis"
flagMoniker = "moniker"
flagOverwrite = "overwrite"
flagClientHome = "home-client"
flagMoniker = "moniker"
)
type initConfig struct {
ChainID string
GenTxsDir string
Name string
NodeID string
ClientHome string
WithTxs bool
Overwrite bool
OverwriteKey bool
ValPubKey crypto.PubKey
}
type printInfo struct {
Moniker string `json:"moniker"`
ChainID string `json:"chain_id"`
@ -70,22 +50,16 @@ func InitCmd(ctx *server.Context, cdc *codec.Codec, appInit server.AppInit) *cob
cmd := &cobra.Command{
Use: "init",
Short: "Initialize private validator, p2p, genesis, and application configuration files",
Long: `Initialize validators's and node's configuration files.
Note that only node's configuration files will be written if the flag --skip-genesis is
enabled, and the genesis file will not be generated.
`,
Args: cobra.NoArgs,
Long: `Initialize validators's and node's configuration files.`,
Args: cobra.NoArgs,
RunE: func(_ *cobra.Command, _ []string) error {
config := ctx.Config
config.SetRoot(viper.GetString(cli.HomeFlag))
name := viper.GetString(client.FlagName)
chainID := viper.GetString(client.FlagChainID)
if chainID == "" {
chainID = fmt.Sprintf("test-chain-%v", common.RandStr(6))
}
nodeID, valPubKey, err := InitializeNodeValidatorFiles(config)
nodeID, _, err := InitializeNodeValidatorFiles(config)
if err != nil {
return err
}
@ -93,37 +67,26 @@ enabled, and the genesis file will not be generated.
if viper.GetString(flagMoniker) != "" {
config.Moniker = viper.GetString(flagMoniker)
}
if config.Moniker == "" && name != "" {
config.Moniker = name
}
toPrint := printInfo{
ChainID: chainID,
Moniker: config.Moniker,
NodeID: nodeID,
}
if viper.GetBool(flagSkipGenesis) {
cfg.WriteConfigFile(filepath.Join(config.RootDir, "config", "config.toml"), config)
return displayInfo(cdc, toPrint)
}
initCfg := initConfig{
ChainID: chainID,
GenTxsDir: filepath.Join(config.RootDir, "config", "gentx"),
Name: name,
NodeID: nodeID,
ClientHome: viper.GetString(flagClientHome),
WithTxs: viper.GetBool(flagWithTxs),
Overwrite: viper.GetBool(flagOverwrite),
OverwriteKey: viper.GetBool(flagOverwriteKey),
ValPubKey: valPubKey,
var appState json.RawMessage
genFile := config.GenesisFile()
if appState, err = initializeEmptyGenesis(cdc, genFile, chainID,
viper.GetBool(flagOverwrite)); err != nil {
return err
}
appMessage, err := initWithConfig(cdc, config, initCfg)
// print out some key information
if err != nil {
if err = WriteGenesisFile(genFile, chainID, nil, appState); err != nil {
return err
}
toPrint.AppMessage = appMessage
toPrint := printInfo{
ChainID: chainID,
Moniker: config.Moniker,
NodeID: nodeID,
AppMessage: appState,
}
cfg.WriteConfigFile(filepath.Join(config.RootDir, "config", "config.toml"), config)
return displayInfo(cdc, toPrint)
},
}
@ -131,12 +94,7 @@ enabled, and the genesis file will not be generated.
cmd.Flags().String(cli.HomeFlag, app.DefaultNodeHome, "node's home directory")
cmd.Flags().BoolP(flagOverwrite, "o", false, "overwrite the genesis.json file")
cmd.Flags().String(client.FlagChainID, "", "genesis file chain-id, if left blank will be randomly created")
cmd.Flags().Bool(flagWithTxs, false, "apply existing genesis transactions from [--home]/config/gentx/")
cmd.Flags().String(client.FlagName, "", "name of private key with which to sign the gentx")
cmd.Flags().String(flagMoniker, "", "overrides --name flag and set the validator's moniker to a different value; ignored if it runs without the --with-txs flag")
cmd.Flags().String(flagClientHome, app.DefaultCLIHome, "client's home directory")
cmd.Flags().Bool(flagOverwriteKey, false, "overwrite client's key")
cmd.Flags().Bool(flagSkipGenesis, false, "do not create genesis.json")
cmd.Flags().String(flagMoniker, "", "set the validator's moniker")
return cmd
}
@ -151,105 +109,6 @@ func InitializeNodeValidatorFiles(config *cfg.Config) (nodeID string, valPubKey
return
}
func initWithConfig(cdc *codec.Codec, config *cfg.Config, initCfg initConfig) (
appMessage json.RawMessage, err error) {
genFile := config.GenesisFile()
if !initCfg.Overwrite && common.FileExists(genFile) {
err = fmt.Errorf("genesis.json file already exists: %v", genFile)
return
}
// process genesis transactions, else create default genesis.json
var appGenTxs []auth.StdTx
var persistentPeers string
var genTxs []json.RawMessage
var appState json.RawMessage
var jsonRawTx json.RawMessage
chainID := initCfg.ChainID
if initCfg.WithTxs {
_, appGenTxs, persistentPeers, err = app.CollectStdTxs(config.Moniker, initCfg.GenTxsDir, cdc)
if err != nil {
return
}
genTxs = make([]json.RawMessage, len(appGenTxs))
config.P2P.PersistentPeers = persistentPeers
for i, stdTx := range appGenTxs {
jsonRawTx, err = cdc.MarshalJSON(stdTx)
if err != nil {
return
}
genTxs[i] = jsonRawTx
}
} else {
var ip, keyPass, secret string
var addr sdk.AccAddress
var signedTx auth.StdTx
if initCfg.Name == "" {
err = errors.New("must specify validator's moniker (--name)")
return
}
config.Moniker = initCfg.Name
ip, err = server.ExternalIP()
if err != nil {
return
}
memo := fmt.Sprintf("%s@%s:26656", initCfg.NodeID, ip)
buf := client.BufferStdin()
prompt := fmt.Sprintf("Password for account %q (default: %q):", initCfg.Name, app.DefaultKeyPass)
keyPass, err = client.GetPassword(prompt, buf)
if err != nil && keyPass != "" {
// An error was returned that either failed to read the password from
// STDIN or the given password is not empty but failed to meet minimum
// length requirements.
return
}
if keyPass == "" {
keyPass = app.DefaultKeyPass
}
addr, secret, err = server.GenerateSaveCoinKey(initCfg.ClientHome, initCfg.Name, keyPass, initCfg.OverwriteKey)
if err != nil {
return
}
appMessage, err = json.Marshal(map[string]string{"secret": secret})
if err != nil {
return
}
msg := stake.NewMsgCreateValidator(
sdk.ValAddress(addr),
initCfg.ValPubKey,
sdk.NewInt64Coin("steak", 100),
stake.NewDescription(config.Moniker, "", "", ""),
stake.NewCommissionMsg(sdk.ZeroDec(), sdk.ZeroDec(), sdk.ZeroDec()),
)
txBldr := authtx.NewTxBuilderFromCLI().WithCodec(cdc).WithMemo(memo).WithChainID(chainID)
signedTx, err = txBldr.SignStdTx(
initCfg.Name, keyPass, auth.NewStdTx([]sdk.Msg{msg}, auth.StdFee{}, []auth.StdSignature{}, memo), false,
)
if err != nil {
return
}
jsonRawTx, err = cdc.MarshalJSON(signedTx)
if err != nil {
return
}
genTxs = []json.RawMessage{jsonRawTx}
}
cfg.WriteConfigFile(filepath.Join(config.RootDir, "config", "config.toml"), config)
appState, err = app.GaiaAppGenStateJSON(cdc, genTxs)
if err != nil {
return
}
err = WriteGenesisFile(genFile, chainID, nil, appState)
return
}
// WriteGenesisFile creates and writes the genesis configuration to disk. An
// error is returned if building or writing the configuration to file fails.
// nolint: unparam
@ -279,3 +138,13 @@ func ReadOrCreatePrivValidator(privValFile string) crypto.PubKey {
}
return privValidator.GetPubKey()
}
func initializeEmptyGenesis(cdc *codec.Codec, genFile string, chainID string,
overwrite bool) (appState json.RawMessage, err error) {
if !overwrite && common.FileExists(genFile) {
err = fmt.Errorf("genesis.json file already exists: %v", genFile)
return
}
return codec.MarshalJSONIndent(cdc, app.NewDefaultGenesisState())
}

View File

@ -42,7 +42,6 @@ func setupClientHome(t *testing.T) func() {
clientDir, err := ioutil.TempDir("", "mock-sdk-cmd")
require.Nil(t, err)
viper.Set(flagClientHome, clientDir)
viper.Set(flagOverwriteKey, true)
return func() {
if err := os.RemoveAll(clientDir); err != nil {
// TODO: Handle with #870

View File

@ -10,6 +10,7 @@ import (
"github.com/cosmos/cosmos-sdk/x/auth"
authtx "github.com/cosmos/cosmos-sdk/x/auth/client/txbuilder"
"github.com/cosmos/cosmos-sdk/x/stake"
"github.com/tendermint/tendermint/types"
"net"
"os"
"path/filepath"
@ -35,7 +36,9 @@ var (
const nodeDirPerm = 0755
// get cmd to initialize all files for tendermint testnet and application
func TestnetFilesCmd(ctx *server.Context, cdc *codec.Codec, appInit server.AppInit) *cobra.Command {
func TestnetFilesCmd(ctx *server.Context, cdc *codec.Codec,
appInit server.AppInit) *cobra.Command {
cmd := &cobra.Command{
Use: "testnet",
Short: "Initialize files for a Gaiad testnet",
@ -50,7 +53,7 @@ Example:
`,
RunE: func(_ *cobra.Command, _ []string) error {
config := ctx.Config
return testnetWithConfig(config, cdc, appInit)
return testnetWithConfig(config, cdc)
},
}
cmd.Flags().Int(nValidators, 4,
@ -69,7 +72,7 @@ Example:
return cmd
}
func testnetWithConfig(config *cfg.Config, cdc *codec.Codec, appInit server.AppInit) error {
func testnetWithConfig(config *cfg.Config, cdc *codec.Codec) error {
outDir := viper.GetString(outputDir)
numValidators := viper.GetInt(nValidators)
@ -80,6 +83,8 @@ func testnetWithConfig(config *cfg.Config, cdc *codec.Codec, appInit server.AppI
valPubKeys := make([]crypto.PubKey, numValidators)
// Generate private key, node ID, initial transaction
var accs []app.GenesisAccount
var genFiles []string
for i := 0; i < numValidators; i++ {
nodeDirName := fmt.Sprintf("%s%d", viper.GetString(nodeDirPrefix), i)
nodeDaemonHomeName := viper.GetString(nodeDaemonHome)
@ -115,8 +120,12 @@ func testnetWithConfig(config *cfg.Config, cdc *codec.Codec, appInit server.AppI
}
memo := fmt.Sprintf("%s@%s:26656", nodeIDs[i], ip)
// write genesis
genFiles = append(genFiles, config.GenesisFile())
buf := client.BufferStdin()
prompt := fmt.Sprintf("Password for account '%s' (default %s):", nodeDirName, app.DefaultKeyPass)
prompt := fmt.Sprintf(
"Password for account '%s' (default %s):", nodeDirName, app.DefaultKeyPass)
keyPass, err := client.GetPassword(prompt, buf)
if err != nil && keyPass != "" {
// An error was returned that either failed to read the password from
@ -138,12 +147,20 @@ func testnetWithConfig(config *cfg.Config, cdc *codec.Codec, appInit server.AppI
if err != nil {
return err
}
// Save private key seed words
// save private key seed words
err = writeFile(fmt.Sprintf("%v.json", "key_seed"), clientDir, cliPrint)
if err != nil {
return err
}
accs = append(accs, app.GenesisAccount{
Address: addr,
Coins: sdk.Coins{
sdk.NewInt64Coin(fmt.Sprintf("%sToken", nodeDirName), 1000),
sdk.NewInt64Coin("steak", 150),
},
})
msg := stake.NewMsgCreateValidator(
sdk.ValAddress(addr),
valPubKeys[i],
@ -173,8 +190,27 @@ func testnetWithConfig(config *cfg.Config, cdc *codec.Codec, appInit server.AppI
}
}
for i := 0; i < numValidators; i++ {
// Generate empty genesis.json
appGenState := app.NewDefaultGenesisState()
appGenState.Accounts = accs
appGenStateJSON, err := codec.MarshalJSONIndent(cdc, appGenState)
if err != nil {
return err
}
genDoc := types.GenesisDoc{
ChainID: chainID,
AppState: appGenStateJSON,
Validators: nil,
}
// Save all genesis.json files
for i := 0; i < numValidators; i++ {
if err := genDoc.SaveAs(genFiles[i]); err != nil {
return err
}
}
for i := 0; i < numValidators; i++ {
nodeDirName := fmt.Sprintf("%s%d", viper.GetString(nodeDirPrefix), i)
nodeDaemonHomeName := viper.GetString(nodeDaemonHome)
nodeDir := filepath.Join(outDir, nodeDirName, nodeDaemonHomeName)
@ -186,16 +222,17 @@ func testnetWithConfig(config *cfg.Config, cdc *codec.Codec, appInit server.AppI
nodeID, valPubKey := nodeIDs[i], valPubKeys[i]
// Run `init` and generate genesis.json and config.toml
initCfg := initConfig{
ChainID: chainID,
GenTxsDir: gentxsDir,
Name: moniker,
WithTxs: true,
Overwrite: true,
OverwriteKey: false,
NodeID: nodeID,
ValPubKey: valPubKey,
ChainID: chainID,
GenTxsDir: gentxsDir,
Name: moniker,
NodeID: nodeID,
ValPubKey: valPubKey,
}
if _, err := initWithConfig(cdc, config, initCfg); err != nil {
genDoc, err := loadGenesisDoc(cdc, config.GenesisFile())
if err != nil {
return err
}
if _, err := genAppStateFromConfig(cdc, config, initCfg, genDoc); err != nil {
return err
}
}

View File

@ -273,7 +273,7 @@ func (kb dbKeybase) Sign(name, passphrase string, msg []byte) (sig []byte, pub t
if err != nil {
return nil, nil, err
}
cdc.MustUnmarshalBinary([]byte(signed), sig)
cdc.MustUnmarshalBinaryLengthPrefixed([]byte(signed), sig)
return sig, linfo.GetPubKey(), nil
}
sig, err = priv.Sign(msg)

View File

@ -182,11 +182,11 @@ func (i offlineInfo) GetAddress() types.AccAddress {
// encoding info
func writeInfo(i Info) []byte {
return cdc.MustMarshalBinary(i)
return cdc.MustMarshalBinaryLengthPrefixed(i)
}
// decoding info
func readInfo(bz []byte) (info Info, err error) {
err = cdc.UnmarshalBinary(bz, &info)
err = cdc.UnmarshalBinaryLengthPrefixed(bz, &info)
return
}

View File

@ -178,7 +178,7 @@ func (tx app2Tx) GetMsgs() []sdk.Msg {
func tx2Decoder(cdc *codec.Codec) sdk.TxDecoder {
return func(txBytes []byte) (sdk.Tx, sdk.Error) {
var tx app2Tx
err := cdc.UnmarshalBinary(txBytes, &tx)
err := cdc.UnmarshalBinaryLengthPrefixed(txBytes, &tx)
if err != nil {
return nil, sdk.ErrTxDecode(err.Error())
}

View File

@ -201,7 +201,7 @@ func (tx app2Tx) GetSignature() []byte {
func tx2Decoder(cdc *codec.Codec) sdk.TxDecoder {
return func(txBytes []byte) (sdk.Tx, sdk.Error) {
var tx app2Tx
err := cdc.UnmarshalBinary(txBytes, &tx)
err := cdc.UnmarshalBinaryLengthPrefixed(txBytes, &tx)
if err != nil {
return nil, sdk.ErrTxDecode(err.Error())
}

View File

@ -39,7 +39,7 @@ func TestEncoding(t *testing.T) {
cdc := NewCodec()
testTxDecoder := tx2Decoder(cdc)
encodedSendTx, err := cdc.MarshalBinary(sendTxBefore)
encodedSendTx, err := cdc.MarshalBinaryLengthPrefixed(sendTxBefore)
require.Nil(t, err, "Error encoding sendTx")
@ -69,7 +69,7 @@ func TestEncoding(t *testing.T) {
Signature: sig,
}
encodedIssueTx, err2 := cdc.MarshalBinary(issueTxBefore)
encodedIssueTx, err2 := cdc.MarshalBinaryLengthPrefixed(issueTxBefore)
require.Nil(t, err2, "Error encoding issueTx")

View File

@ -41,7 +41,6 @@ func main() {
appInit := server.DefaultAppInit
rootCmd.AddCommand(InitCmd(ctx, cdc, appInit))
rootCmd.AddCommand(gaiaInit.TestnetFilesCmd(ctx, cdc, appInit))
server.AddCommands(ctx, cdc, rootCmd, appInit,
newApp, exportAppStateAndTMValidators)
@ -85,7 +84,8 @@ func InitCmd(ctx *server.Context, cdc *codec.Codec, appInit server.AppInit) *cob
return err
}
appState, err := appInit.AppGenState(cdc, []json.RawMessage{genTx})
appState, err := appInit.AppGenState(
cdc, tmtypes.GenesisDoc{}, []json.RawMessage{genTx})
if err != nil {
return err
}
@ -108,13 +108,15 @@ func InitCmd(ctx *server.Context, cdc *codec.Codec, appInit server.AppInit) *cob
return err
}
fmt.Fprintf(os.Stderr, "%s\n", string(out))
return gaiaInit.WriteGenesisFile(config.GenesisFile(), chainID, []tmtypes.GenesisValidator{validator}, appStateJSON)
return gaiaInit.WriteGenesisFile(config.GenesisFile(), chainID,
[]tmtypes.GenesisValidator{validator}, appStateJSON)
},
}
cmd.Flags().String(cli.HomeFlag, app.DefaultNodeHome, "node's home directory")
cmd.Flags().String(flagClientHome, app.DefaultCLIHome, "client's home directory")
cmd.Flags().String(client.FlagChainID, "", "genesis file chain-id, if left blank will be randomly created")
cmd.Flags().String(client.FlagChainID, "",
"genesis file chain-id, if left blank will be randomly created")
cmd.Flags().String(client.FlagName, "", "validator's moniker")
cmd.MarkFlagRequired(client.FlagName)
return cmd
@ -124,7 +126,8 @@ func newApp(logger log.Logger, db dbm.DB, storeTracer io.Writer) abci.Applicatio
return app.NewBasecoinApp(logger, db, baseapp.SetPruning(viper.GetString("pruning")))
}
func exportAppStateAndTMValidators(logger log.Logger, db dbm.DB, storeTracer io.Writer) (json.RawMessage, []tmtypes.GenesisValidator, error) {
func exportAppStateAndTMValidators(logger log.Logger, db dbm.DB, storeTracer io.Writer) (
json.RawMessage, []tmtypes.GenesisValidator, error) {
bapp := app.NewBasecoinApp(logger, db)
return bapp.ExportAppStateAndValidators()
}

View File

@ -36,8 +36,9 @@ var CoolAppInit = server.AppInit{
}
// coolGenAppParams sets up the app_state and appends the cool app state
func CoolAppGenState(cdc *codec.Codec, appGenTxs []json.RawMessage) (appState json.RawMessage, err error) {
appState, err = server.SimpleAppGenState(cdc, appGenTxs)
func CoolAppGenState(cdc *codec.Codec, genDoc tmtypes.GenesisDoc, appGenTxs []json.RawMessage) (
appState json.RawMessage, err error) {
appState, err = server.SimpleAppGenState(cdc, tmtypes.GenesisDoc{}, appGenTxs)
if err != nil {
return
}
@ -90,7 +91,8 @@ func InitCmd(ctx *server.Context, cdc *codec.Codec, appInit server.AppInit) *cob
return err
}
appState, err := appInit.AppGenState(cdc, []json.RawMessage{genTx})
appState, err := appInit.AppGenState(cdc, tmtypes.GenesisDoc{},
[]json.RawMessage{genTx})
if err != nil {
return err
}
@ -113,13 +115,15 @@ func InitCmd(ctx *server.Context, cdc *codec.Codec, appInit server.AppInit) *cob
return err
}
fmt.Fprintf(os.Stderr, "%s\n", string(out))
return gaiaInit.WriteGenesisFile(config.GenesisFile(), chainID, []tmtypes.GenesisValidator{validator}, appStateJSON)
return gaiaInit.WriteGenesisFile(config.GenesisFile(), chainID,
[]tmtypes.GenesisValidator{validator}, appStateJSON)
},
}
cmd.Flags().String(cli.HomeFlag, app.DefaultNodeHome, "node's home directory")
cmd.Flags().String(flagClientHome, app.DefaultCLIHome, "client's home directory")
cmd.Flags().String(client.FlagChainID, "", "genesis file chain-id, if left blank will be randomly created")
cmd.Flags().String(client.FlagChainID, "",
"genesis file chain-id, if left blank will be randomly created")
cmd.Flags().String(client.FlagName, "", "validator's moniker")
cmd.MarkFlagRequired(client.FlagName)
return cmd
@ -129,7 +133,8 @@ func newApp(logger log.Logger, db dbm.DB, _ io.Writer) abci.Application {
return app.NewDemocoinApp(logger, db)
}
func exportAppStateAndTMValidators(logger log.Logger, db dbm.DB, _ io.Writer) (json.RawMessage, []tmtypes.GenesisValidator, error) {
func exportAppStateAndTMValidators(logger log.Logger, db dbm.DB, _ io.Writer) (
json.RawMessage, []tmtypes.GenesisValidator, error) {
dapp := app.NewDemocoinApp(logger, db)
return dapp.ExportAppStateAndValidators()
}

View File

@ -82,8 +82,13 @@ func (vs *ValidatorSet) IterateValidators(ctx sdk.Context, fn func(index int64,
}
}
// IterateValidatorsBonded implements sdk.ValidatorSet
func (vs *ValidatorSet) IterateValidatorsBonded(ctx sdk.Context, fn func(index int64, Validator sdk.Validator) bool) {
// IterateBondedValidatorsByPower implements sdk.ValidatorSet
func (vs *ValidatorSet) IterateBondedValidatorsByPower(ctx sdk.Context, fn func(index int64, Validator sdk.Validator) bool) {
vs.IterateValidators(ctx, fn)
}
// IterateLastValidators implements sdk.ValidatorSet
func (vs *ValidatorSet) IterateLastValidators(ctx sdk.Context, fn func(index int64, Validator sdk.Validator) bool) {
vs.IterateValidators(ctx, fn)
}

View File

@ -71,7 +71,7 @@ func (keeper Keeper) Info(ctx sdk.Context, p Payload) (res Info) {
if bz == nil {
return EmptyInfo(ctx)
}
keeper.cdc.MustUnmarshalBinary(bz, &res)
keeper.cdc.MustUnmarshalBinaryLengthPrefixed(bz, &res)
return
}
@ -80,7 +80,7 @@ func (keeper Keeper) setInfo(ctx sdk.Context, p Payload, info Info) {
store := ctx.KVStore(keeper.key)
key := GetInfoKey(p, keeper.cdc)
bz := keeper.cdc.MustMarshalBinary(info)
bz := keeper.cdc.MustMarshalBinaryLengthPrefixed(info)
store.Set(key, bz)
}

View File

@ -7,13 +7,13 @@ import (
// GetInfoKey returns the key for OracleInfo
func GetInfoKey(p Payload, cdc *codec.Codec) []byte {
bz := cdc.MustMarshalBinary(p)
bz := cdc.MustMarshalBinaryLengthPrefixed(p)
return append([]byte{0x00}, bz...)
}
// GetSignPrefix returns the prefix for signs
func GetSignPrefix(p Payload, cdc *codec.Codec) []byte {
bz := cdc.MustMarshalBinary(p)
bz := cdc.MustMarshalBinaryLengthPrefixed(p)
return append([]byte{0x01}, bz...)
}

View File

@ -82,7 +82,7 @@ func getSequence(ctx sdk.Context, key sdk.StoreKey) int {
if seqbz == nil {
seq = 0
} else {
codec.New().MustUnmarshalBinary(seqbz, &seq)
codec.New().MustUnmarshalBinaryLengthPrefixed(seqbz, &seq)
}
return seq
@ -96,7 +96,7 @@ func handleSeqOracle(ctx sdk.Context, key sdk.StoreKey, o seqOracle) sdk.Error {
return sdk.NewError(sdk.CodespaceRoot, 1, "")
}
bz := codec.New().MustMarshalBinary(seq + 1)
bz := codec.New().MustMarshalBinaryLengthPrefixed(seq + 1)
store.Set([]byte("seq"), bz)
return nil

View File

@ -39,7 +39,7 @@ func (k Keeper) getBondInfo(ctx sdk.Context, addr sdk.AccAddress) bondInfo {
return bondInfo{}
}
var bi bondInfo
err := k.cdc.UnmarshalBinary(bz, &bi)
err := k.cdc.UnmarshalBinaryLengthPrefixed(bz, &bi)
if err != nil {
panic(err)
}
@ -48,7 +48,7 @@ func (k Keeper) getBondInfo(ctx sdk.Context, addr sdk.AccAddress) bondInfo {
func (k Keeper) setBondInfo(ctx sdk.Context, addr sdk.AccAddress, bi bondInfo) {
store := ctx.KVStore(k.key)
bz, err := k.cdc.MarshalBinary(bi)
bz, err := k.cdc.MarshalBinaryLengthPrefixed(bi)
if err != nil {
panic(err)
}

View File

@ -1,6 +1,7 @@
#!/bin/bash
seeds=(1 2 4 7 9 20 32 123 124 582 1893 2989 3012 4728 37827 981928 87821 891823782 989182 89182391)
seeds=(1 2 4 7 9 20 32 123 124 582 1893 2989 3012 4728 37827 981928 87821 891823782 989182 89182391 \
11 22 44 77 99 2020 3232 123123 124124 582582 18931893 29892989 30123012 47284728 37827)
blocks=$1
echo "Running multi-seed simulation with seeds ${seeds[@]}"

View File

@ -19,7 +19,8 @@ import (
type AppInit struct {
// AppGenState creates the core parameters initialization. It takes in a
// pubkey meant to represent the pubkey of the validator of this machine.
AppGenState func(cdc *codec.Codec, appGenTx []json.RawMessage) (appState json.RawMessage, err error)
AppGenState func(cdc *codec.Codec, genDoc tmtypes.GenesisDoc, appGenTxs []json.RawMessage) (
appState json.RawMessage, err error)
}
// SimpleGenTx is a simple genesis tx
@ -35,7 +36,8 @@ var DefaultAppInit = AppInit{
}
// Generate a genesis transaction
func SimpleAppGenTx(cdc *codec.Codec, pk crypto.PubKey) (appGenTx, cliPrint json.RawMessage, validator types.GenesisValidator, err error) {
func SimpleAppGenTx(cdc *codec.Codec, pk crypto.PubKey) (
appGenTx, cliPrint json.RawMessage, validator types.GenesisValidator, err error) {
var addr sdk.AccAddress
var secret string
addr, secret, err = GenerateCoinKey()
@ -63,7 +65,8 @@ func SimpleAppGenTx(cdc *codec.Codec, pk crypto.PubKey) (appGenTx, cliPrint json
}
// create the genesis app state
func SimpleAppGenState(cdc *codec.Codec, appGenTxs []json.RawMessage) (appState json.RawMessage, err error) {
func SimpleAppGenState(cdc *codec.Codec, genDoc tmtypes.GenesisDoc, appGenTxs []json.RawMessage) (
appState json.RawMessage, err error) {
if len(appGenTxs) != 1 {
err = errors.New("must provide a single genesis transaction")

View File

@ -3,6 +3,7 @@ package mock
import (
"encoding/json"
"fmt"
"github.com/tendermint/tendermint/types"
"path/filepath"
abci "github.com/tendermint/tendermint/abci/types"
@ -102,7 +103,8 @@ func InitChainer(key sdk.StoreKey) func(sdk.Context, abci.RequestInitChain) abci
// AppGenState can be passed into InitCmd, returns a static string of a few
// key-values that can be parsed by InitChainer
func AppGenState(_ *codec.Codec, _ []json.RawMessage) (appState json.RawMessage, err error) {
func AppGenState(_ *codec.Codec, _ types.GenesisDoc, _ []json.RawMessage) (appState json.
RawMessage, err error) {
appState = json.RawMessage(`{
"values": [
{
@ -119,7 +121,8 @@ func AppGenState(_ *codec.Codec, _ []json.RawMessage) (appState json.RawMessage,
}
// AppGenStateEmpty returns an empty transaction state for mocking.
func AppGenStateEmpty(_ *codec.Codec, _ []json.RawMessage) (appState json.RawMessage, err error) {
func AppGenStateEmpty(_ *codec.Codec, _ types.GenesisDoc, _ []json.RawMessage) (
appState json.RawMessage, err error) {
appState = json.RawMessage(``)
return
}

View File

@ -1,6 +1,7 @@
package mock
import (
"github.com/tendermint/tendermint/types"
"testing"
"github.com/stretchr/testify/require"
@ -20,7 +21,7 @@ func TestInitApp(t *testing.T) {
require.NoError(t, err)
// initialize it future-way
appState, err := AppGenState(nil, nil)
appState, err := AppGenState(nil, types.GenesisDoc{}, nil)
require.NoError(t, err)
//TODO test validators in the init chain?

View File

@ -93,7 +93,6 @@ func startStandAlone(ctx *Context, appCreator AppCreator) error {
return nil
}
// nolint: unparam
func startInProcess(ctx *Context, appCreator AppCreator) (*node.Node, error) {
cfg := ctx.Config
home := cfg.RootDir
@ -135,7 +134,12 @@ func startInProcess(ctx *Context, appCreator AppCreator) (*node.Node, error) {
return nil, err
}
// trap signal (run forever)
tmNode.RunForever()
return tmNode, nil
TrapSignal(func() {
if tmNode.IsRunning() {
_ = tmNode.Stop()
}
})
// run forever (the node will not be returned)
select {}
}

View File

@ -5,9 +5,9 @@ import (
"io"
"sync"
"github.com/tendermint/go-amino"
"github.com/tendermint/iavl"
abci "github.com/tendermint/tendermint/abci/types"
"github.com/tendermint/tendermint/crypto/merkle"
cmn "github.com/tendermint/tendermint/libs/common"
dbm "github.com/tendermint/tendermint/libs/db"
@ -210,13 +210,15 @@ func (st *iavlStore) Query(req abci.RequestQuery) (res abci.ResponseQuery) {
res.Height = getHeight(tree, req)
switch req.Path {
case "/store", "/key": // Get by key
key := req.Data // Data holds the key bytes
case "/key": // get by key
key := req.Data // data holds the key bytes
res.Key = key
if !st.VersionExists(res.Height) {
res.Log = cmn.ErrorWrap(iavl.ErrVersionDoesNotExist, "").Error()
break
}
if req.Prove {
value, proof, err := tree.GetVersionedWithProof(key, res.Height)
if err != nil {
@ -224,30 +226,30 @@ func (st *iavlStore) Query(req abci.RequestQuery) (res abci.ResponseQuery) {
break
}
res.Value = value
cdc := amino.NewCodec()
p, err := cdc.MarshalBinary(proof)
if err != nil {
res.Log = err.Error()
break
}
res.Proof = p
res.Proof = &merkle.Proof{Ops: []merkle.ProofOp{iavl.NewIAVLValueOp(key, proof).ProofOp()}}
} else {
_, res.Value = tree.GetVersioned(key, res.Height)
}
case "/subspace":
var KVs []KVPair
subspace := req.Data
res.Key = subspace
var KVs []KVPair
iterator := sdk.KVStorePrefixIterator(st, subspace)
for ; iterator.Valid(); iterator.Next() {
KVs = append(KVs, KVPair{Key: iterator.Key(), Value: iterator.Value()})
}
iterator.Close()
res.Value = cdc.MustMarshalBinary(KVs)
res.Value = cdc.MustMarshalBinaryLengthPrefixed(KVs)
default:
msg := fmt.Sprintf("Unexpected Query path: %v", req.Path)
return sdk.ErrUnknownRequest(msg).QueryResult()
}
return
}

View File

@ -394,9 +394,9 @@ func TestIAVLStoreQuery(t *testing.T) {
{Key: k1, Value: v3},
{Key: k2, Value: v2},
}
valExpSubEmpty := cdc.MustMarshalBinary(KVs0)
valExpSub1 := cdc.MustMarshalBinary(KVs1)
valExpSub2 := cdc.MustMarshalBinary(KVs2)
valExpSubEmpty := cdc.MustMarshalBinaryLengthPrefixed(KVs0)
valExpSub1 := cdc.MustMarshalBinaryLengthPrefixed(KVs1)
valExpSub2 := cdc.MustMarshalBinaryLengthPrefixed(KVs2)
cid := iavlStore.Commit()
ver := cid.Version
@ -459,7 +459,7 @@ func TestIAVLStoreQuery(t *testing.T) {
require.Equal(t, valExpSub2, qres.Value)
// default (height 0) will show latest -1
query0 := abci.RequestQuery{Path: "/store", Data: k1}
query0 := abci.RequestQuery{Path: "/key", Data: k1}
qres = iavlStore.Query(query0)
require.Equal(t, uint32(sdk.CodeOK), qres.Code)
require.Equal(t, v1, qres.Value)

View File

@ -42,21 +42,22 @@ func (m List) Len() (res uint64) {
if bz == nil {
return 0
}
m.cdc.MustUnmarshalBinary(bz, &res)
m.cdc.MustUnmarshalBinaryLengthPrefixed(bz, &res)
return
}
// Get() returns the element by its index
func (m List) Get(index uint64, ptr interface{}) error {
bz := m.store.Get(ElemKey(index))
return m.cdc.UnmarshalBinary(bz, ptr)
return m.cdc.UnmarshalBinaryLengthPrefixed(bz, ptr)
}
// Set() stores the element to the given position
// Setting element out of range will break length counting
// Use Push() instead of Set() to append a new element
func (m List) Set(index uint64, value interface{}) {
bz := m.cdc.MustMarshalBinary(value)
bz := m.cdc.MustMarshalBinaryLengthPrefixed(value)
m.store.Set(ElemKey(index), bz)
}
@ -72,7 +73,7 @@ func (m List) Delete(index uint64) {
func (m List) Push(value interface{}) {
length := m.Len()
m.Set(length, value)
m.store.Set(LengthKey(), m.cdc.MustMarshalBinary(length+1))
m.store.Set(LengthKey(), m.cdc.MustMarshalBinaryLengthPrefixed(length+1))
}
// Iterate() is used to iterate over all existing elements in the list
@ -85,13 +86,16 @@ func (m List) Iterate(ptr interface{}, fn func(uint64) bool) {
iter := sdk.KVStorePrefixIterator(m.store, []byte{0x01})
for ; iter.Valid(); iter.Next() {
v := iter.Value()
m.cdc.MustUnmarshalBinary(v, ptr)
m.cdc.MustUnmarshalBinaryLengthPrefixed(v, ptr)
k := iter.Key()
s := string(k[len(k)-20:])
index, err := strconv.ParseUint(s, 10, 64)
if err != nil {
panic(err)
}
if fn(index) {
break
}

View File

@ -2,90 +2,139 @@ package store
import (
"bytes"
"fmt"
"github.com/pkg/errors"
"github.com/tendermint/iavl"
"github.com/tendermint/tendermint/crypto/merkle"
cmn "github.com/tendermint/tendermint/libs/common"
)
// MultiStoreProof defines a collection of store proofs in a multi-store
type MultiStoreProof struct {
StoreInfos []storeInfo
StoreName string
RangeProof iavl.RangeProof
}
// buildMultiStoreProof build MultiStoreProof based on iavl proof and storeInfos
func buildMultiStoreProof(iavlProof []byte, storeName string, storeInfos []storeInfo) []byte {
var rangeProof iavl.RangeProof
cdc.MustUnmarshalBinary(iavlProof, &rangeProof)
msp := MultiStoreProof{
StoreInfos: storeInfos,
StoreName: storeName,
RangeProof: rangeProof,
}
proof := cdc.MustMarshalBinary(msp)
return proof
func NewMultiStoreProof(storeInfos []storeInfo) *MultiStoreProof {
return &MultiStoreProof{StoreInfos: storeInfos}
}
// VerifyMultiStoreCommitInfo verify multiStoreCommitInfo against appHash
func VerifyMultiStoreCommitInfo(storeName string, storeInfos []storeInfo, appHash []byte) ([]byte, error) {
var substoreCommitHash []byte
var height int64
for _, storeInfo := range storeInfos {
if storeInfo.Name == storeName {
substoreCommitHash = storeInfo.Core.CommitID.Hash
height = storeInfo.Core.CommitID.Version
}
}
if len(substoreCommitHash) == 0 {
return nil, cmn.NewError("failed to get substore root commit hash by store name")
}
// ComputeRootHash returns the root hash for a given multi-store proof.
func (proof *MultiStoreProof) ComputeRootHash() []byte {
ci := commitInfo{
Version: height,
StoreInfos: storeInfos,
Version: -1, // TODO: Not needed; improve code.
StoreInfos: proof.StoreInfos,
}
if !bytes.Equal(appHash, ci.Hash()) {
return nil, cmn.NewError("the merkle root of multiStoreCommitInfo doesn't equal to appHash")
}
return substoreCommitHash, nil
return ci.Hash()
}
// VerifyRangeProof verify iavl RangeProof
func VerifyRangeProof(key, value []byte, substoreCommitHash []byte, rangeProof *iavl.RangeProof) error {
// verify the proof to ensure data integrity.
err := rangeProof.Verify(substoreCommitHash)
if err != nil {
return errors.Wrap(err, "proof root hash doesn't equal to substore commit root hash")
}
if len(value) != 0 {
// verify existence proof
err = rangeProof.VerifyItem(key, value)
if err != nil {
return errors.Wrap(err, "failed in existence verification")
}
} else {
// verify absence proof
err = rangeProof.VerifyAbsence(key)
if err != nil {
return errors.Wrap(err, "failed in absence verification")
}
}
return nil
}
// RequireProof return whether proof is require for the subpath
// RequireProof returns whether proof is required for the subpath.
func RequireProof(subpath string) bool {
// Currently, only when query subpath is "/store" or "/key", will proof be included in response.
// If there are some changes about proof building in iavlstore.go, we must change code here to keep consistency with iavlstore.go:212
if subpath == "/store" || subpath == "/key" {
// XXX: create a better convention.
// Currently, only when query subpath is "/key", will proof be included in
// response. If there are some changes about proof building in iavlstore.go,
// we must change code here to keep consistency with iavlStore#Query.
if subpath == "/key" {
return true
}
return false
}
//-----------------------------------------------------------------------------
var _ merkle.ProofOperator = MultiStoreProofOp{}
// the multi-store proof operation constant value
const ProofOpMultiStore = "multistore"
// TODO: document
type MultiStoreProofOp struct {
// Encoded in ProofOp.Key
key []byte
// To encode in ProofOp.Data.
Proof *MultiStoreProof `json:"proof"`
}
func NewMultiStoreProofOp(key []byte, proof *MultiStoreProof) MultiStoreProofOp {
return MultiStoreProofOp{
key: key,
Proof: proof,
}
}
// MultiStoreProofOpDecoder returns a multi-store merkle proof operator from a
// given proof operation.
func MultiStoreProofOpDecoder(pop merkle.ProofOp) (merkle.ProofOperator, error) {
if pop.Type != ProofOpMultiStore {
return nil, cmn.NewError("unexpected ProofOp.Type; got %v, want %v", pop.Type, ProofOpMultiStore)
}
// XXX: a bit strange as we'll discard this, but it works
var op MultiStoreProofOp
err := cdc.UnmarshalBinaryLengthPrefixed(pop.Data, &op)
if err != nil {
return nil, cmn.ErrorWrap(err, "decoding ProofOp.Data into MultiStoreProofOp")
}
return NewMultiStoreProofOp(pop.Key, op.Proof), nil
}
// ProofOp return a merkle proof operation from a given multi-store proof
// operation.
func (op MultiStoreProofOp) ProofOp() merkle.ProofOp {
bz := cdc.MustMarshalBinaryLengthPrefixed(op)
return merkle.ProofOp{
Type: ProofOpMultiStore,
Key: op.key,
Data: bz,
}
}
// String implements the Stringer interface for a mult-store proof operation.
func (op MultiStoreProofOp) String() string {
return fmt.Sprintf("MultiStoreProofOp{%v}", op.GetKey())
}
// GetKey returns the key for a multi-store proof operation.
func (op MultiStoreProofOp) GetKey() []byte {
return op.key
}
// Run executes a multi-store proof operation for a given value. It returns
// the root hash if the value matches all the store's commitID's hash or an
// error otherwise.
func (op MultiStoreProofOp) Run(args [][]byte) ([][]byte, error) {
if len(args) != 1 {
return nil, cmn.NewError("Value size is not 1")
}
value := args[0]
root := op.Proof.ComputeRootHash()
for _, si := range op.Proof.StoreInfos {
if si.Name == string(op.key) {
if bytes.Equal(value, si.Core.CommitID.Hash) {
return [][]byte{root}, nil
}
return nil, cmn.NewError("hash mismatch for substore %v: %X vs %X", si.Name, si.Core.CommitID.Hash, value)
}
}
return nil, cmn.NewError("key %v not found in multistore proof", op.key)
}
//-----------------------------------------------------------------------------
// XXX: This should be managed by the rootMultiStore which may want to register
// more proof ops?
func DefaultProofRuntime() (prt *merkle.ProofRuntime) {
prt = merkle.NewProofRuntime()
prt.RegisterOpDecoder(merkle.ProofOpSimpleValue, merkle.SimpleValueOpDecoder)
prt.RegisterOpDecoder(iavl.ProofOpIAVLValue, iavl.IAVLValueOpDecoder)
prt.RegisterOpDecoder(iavl.ProofOpIAVLAbsence, iavl.IAVLAbsenceOpDecoder)
prt.RegisterOpDecoder(ProofOpMultiStore, MultiStoreProofOpDecoder)
return
}

View File

@ -1,123 +1,108 @@
package store
import (
"encoding/hex"
"testing"
"github.com/stretchr/testify/assert"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/stretchr/testify/require"
"github.com/tendermint/iavl"
cmn "github.com/tendermint/tendermint/libs/common"
"github.com/tendermint/tendermint/libs/db"
abci "github.com/tendermint/tendermint/abci/types"
dbm "github.com/tendermint/tendermint/libs/db"
)
func TestVerifyMultiStoreCommitInfo(t *testing.T) {
appHash, _ := hex.DecodeString("69959B1B4E68E0F7BD3551A50C8F849B81801AF2")
substoreRootHash, _ := hex.DecodeString("ea5d468431015c2cd6295e9a0bb1fc0e49033828")
storeName := "acc"
var storeInfos []storeInfo
gocRootHash, _ := hex.DecodeString("62c171bb022e47d1f745608ff749e676dbd25f78")
storeInfos = append(storeInfos, storeInfo{
Name: "gov",
Core: storeCore{
CommitID: CommitID{
Version: 689,
Hash: gocRootHash,
},
},
})
storeInfos = append(storeInfos, storeInfo{
Name: "main",
Core: storeCore{
CommitID: CommitID{
Version: 689,
Hash: nil,
},
},
})
accRootHash, _ := hex.DecodeString("ea5d468431015c2cd6295e9a0bb1fc0e49033828")
storeInfos = append(storeInfos, storeInfo{
Name: "acc",
Core: storeCore{
CommitID: CommitID{
Version: 689,
Hash: accRootHash,
},
},
})
storeInfos = append(storeInfos, storeInfo{
Name: "ibc",
Core: storeCore{
CommitID: CommitID{
Version: 689,
Hash: nil,
},
},
})
stakeRootHash, _ := hex.DecodeString("987d1d27b8771d93aa3691262f661d2c85af7ca4")
storeInfos = append(storeInfos, storeInfo{
Name: "stake",
Core: storeCore{
CommitID: CommitID{
Version: 689,
Hash: stakeRootHash,
},
},
})
slashingRootHash, _ := hex.DecodeString("388ee6e5b11f367069beb1eefd553491afe9d73e")
storeInfos = append(storeInfos, storeInfo{
Name: "slashing",
Core: storeCore{
CommitID: CommitID{
Version: 689,
Hash: slashingRootHash,
},
},
})
commitHash, err := VerifyMultiStoreCommitInfo(storeName, storeInfos, appHash)
func TestVerifyIAVLStoreQueryProof(t *testing.T) {
// Create main tree for testing.
db := dbm.NewMemDB()
iStore, err := LoadIAVLStore(db, CommitID{}, sdk.PruneNothing)
store := iStore.(*iavlStore)
require.Nil(t, err)
require.Equal(t, commitHash, substoreRootHash)
store.Set([]byte("MYKEY"), []byte("MYVALUE"))
cid := store.Commit()
appHash, _ = hex.DecodeString("29de216bf5e2531c688de36caaf024cd3bb09ee3")
// Get Proof
res := store.Query(abci.RequestQuery{
Path: "/key", // required path to get key/value+proof
Data: []byte("MYKEY"),
Prove: true,
})
require.NotNil(t, res.Proof)
_, err = VerifyMultiStoreCommitInfo(storeName, storeInfos, appHash)
require.Error(t, err, "appHash doesn't match to the merkle root of multiStoreCommitInfo")
// Verify proof.
prt := DefaultProofRuntime()
err = prt.VerifyValue(res.Proof, cid.Hash, "/MYKEY", []byte("MYVALUE"))
require.Nil(t, err)
// Verify (bad) proof.
err = prt.VerifyValue(res.Proof, cid.Hash, "/MYKEY_NOT", []byte("MYVALUE"))
require.NotNil(t, err)
// Verify (bad) proof.
err = prt.VerifyValue(res.Proof, cid.Hash, "/MYKEY/MYKEY", []byte("MYVALUE"))
require.NotNil(t, err)
// Verify (bad) proof.
err = prt.VerifyValue(res.Proof, cid.Hash, "MYKEY", []byte("MYVALUE"))
require.NotNil(t, err)
// Verify (bad) proof.
err = prt.VerifyValue(res.Proof, cid.Hash, "/MYKEY", []byte("MYVALUE_NOT"))
require.NotNil(t, err)
// Verify (bad) proof.
err = prt.VerifyValue(res.Proof, cid.Hash, "/MYKEY", []byte(nil))
require.NotNil(t, err)
}
func TestVerifyRangeProof(t *testing.T) {
tree := iavl.NewMutableTree(db.NewMemDB(), 0)
func TestVerifyMultiStoreQueryProof(t *testing.T) {
// Create main tree for testing.
db := dbm.NewMemDB()
store := NewCommitMultiStore(db)
iavlStoreKey := sdk.NewKVStoreKey("iavlStoreKey")
rand := cmn.NewRand()
rand.Seed(0) // for determinism
for _, ikey := range []byte{0x11, 0x32, 0x50, 0x72, 0x99} {
key := []byte{ikey}
tree.Set(key, []byte(rand.Str(8)))
}
store.MountStoreWithDB(iavlStoreKey, sdk.StoreTypeIAVL, nil)
store.LoadVersion(0)
root := tree.WorkingHash()
iavlStore := store.GetCommitStore(iavlStoreKey).(*iavlStore)
iavlStore.Set([]byte("MYKEY"), []byte("MYVALUE"))
cid := store.Commit()
key := []byte{0x32}
val, proof, err := tree.GetWithProof(key)
assert.Nil(t, err)
assert.NotEmpty(t, val)
assert.NotEmpty(t, proof)
err = VerifyRangeProof(key, val, root, proof)
assert.Nil(t, err)
// Get Proof
res := store.Query(abci.RequestQuery{
Path: "/iavlStoreKey/key", // required path to get key/value+proof
Data: []byte("MYKEY"),
Prove: true,
})
require.NotNil(t, res.Proof)
key = []byte{0x40}
val, proof, err = tree.GetWithProof(key)
assert.Nil(t, err)
assert.Empty(t, val)
assert.NotEmpty(t, proof)
err = VerifyRangeProof(key, val, root, proof)
assert.Nil(t, err)
// Verify proof.
prt := DefaultProofRuntime()
err := prt.VerifyValue(res.Proof, cid.Hash, "/iavlStoreKey/MYKEY", []byte("MYVALUE"))
require.Nil(t, err)
// Verify proof.
err = prt.VerifyValue(res.Proof, cid.Hash, "/iavlStoreKey/MYKEY", []byte("MYVALUE"))
require.Nil(t, err)
// Verify (bad) proof.
err = prt.VerifyValue(res.Proof, cid.Hash, "/iavlStoreKey/MYKEY_NOT", []byte("MYVALUE"))
require.NotNil(t, err)
// Verify (bad) proof.
err = prt.VerifyValue(res.Proof, cid.Hash, "/iavlStoreKey/MYKEY/MYKEY", []byte("MYVALUE"))
require.NotNil(t, err)
// Verify (bad) proof.
err = prt.VerifyValue(res.Proof, cid.Hash, "iavlStoreKey/MYKEY", []byte("MYVALUE"))
require.NotNil(t, err)
// Verify (bad) proof.
err = prt.VerifyValue(res.Proof, cid.Hash, "/MYKEY", []byte("MYVALUE"))
require.NotNil(t, err)
// Verify (bad) proof.
err = prt.VerifyValue(res.Proof, cid.Hash, "/iavlStoreKey/MYKEY", []byte("MYVALUE_NOT"))
require.NotNil(t, err)
// Verify (bad) proof.
err = prt.VerifyValue(res.Proof, cid.Hash, "/iavlStoreKey/MYKEY", []byte(nil))
require.NotNil(t, err)
}

View File

@ -27,12 +27,12 @@ func (m Queue) getTop() (res uint64) {
return 0
}
m.List.cdc.MustUnmarshalBinary(bz, &res)
m.List.cdc.MustUnmarshalBinaryLengthPrefixed(bz, &res)
return
}
func (m Queue) setTop(top uint64) {
bz := m.List.cdc.MustMarshalBinary(top)
bz := m.List.cdc.MustMarshalBinaryLengthPrefixed(top)
m.List.store.Set(TopKey(), bz)
}

View File

@ -81,7 +81,7 @@ func TestKeys(t *testing.T) {
var actual int
// Checking keys.LengthKey
err := cdc.UnmarshalBinary(store.Get(LengthKey()), &len)
err := cdc.UnmarshalBinaryLengthPrefixed(store.Get(LengthKey()), &len)
require.Nil(t, err)
require.Equal(t, len, queue.List.Len())
@ -89,14 +89,14 @@ func TestKeys(t *testing.T) {
for i := 0; i < 10; i++ {
queue.List.Get(uint64(i), &expected)
bz := store.Get(ElemKey(uint64(i)))
err = cdc.UnmarshalBinary(bz, &actual)
err = cdc.UnmarshalBinaryLengthPrefixed(bz, &actual)
require.Nil(t, err)
require.Equal(t, expected, actual)
}
queue.Pop()
err = cdc.UnmarshalBinary(store.Get(TopKey()), &top)
err = cdc.UnmarshalBinaryLengthPrefixed(store.Get(TopKey()), &top)
require.Nil(t, err)
require.Equal(t, top, queue.getTop())
}

View File

@ -300,8 +300,14 @@ func (rs *rootMultiStore) Query(req abci.RequestQuery) abci.ResponseQuery {
return sdk.ErrInternal(errMsg.Error()).QueryResult()
}
res.Proof = buildMultiStoreProof(res.Proof, storeName, commitInfo.StoreInfos)
// Restore origin path and append proof op.
res.Proof.Ops = append(res.Proof.Ops, NewMultiStoreProofOp(
[]byte(storeName),
NewMultiStoreProof(commitInfo.StoreInfos),
).ProofOp())
// TODO: handle in another TM v0.26 update PR
// res.Proof = buildMultiStoreProof(res.Proof, storeName, commitInfo.StoreInfos)
return res
}
@ -313,11 +319,14 @@ func parsePath(path string) (storeName string, subpath string, err sdk.Error) {
err = sdk.ErrUnknownRequest(fmt.Sprintf("invalid path: %s", path))
return
}
paths := strings.SplitN(path[1:], "/", 2)
storeName = paths[0]
if len(paths) == 2 {
subpath = "/" + paths[1]
}
return
}
@ -386,11 +395,12 @@ type commitInfo struct {
// Hash returns the simple merkle root hash of the stores sorted by name.
func (ci commitInfo) Hash() []byte {
// TODO cache to ci.hash []byte
m := make(map[string]merkle.Hasher, len(ci.StoreInfos))
// TODO: cache to ci.hash []byte
m := make(map[string][]byte, len(ci.StoreInfos))
for _, storeInfo := range ci.StoreInfos {
m[storeInfo.Name] = storeInfo
m[storeInfo.Name] = storeInfo.Hash()
}
return merkle.SimpleHashFromMap(m)
}
@ -422,13 +432,15 @@ type storeCore struct {
func (si storeInfo) Hash() []byte {
// Doesn't write Name, since merkle.SimpleHashFromMap() will
// include them via the keys.
bz, _ := cdc.MarshalBinary(si.Core) // Does not error
bz, _ := cdc.MarshalBinaryLengthPrefixed(si.Core)
hasher := tmhash.New()
_, err := hasher.Write(bz)
if err != nil {
// TODO: Handle with #870
panic(err)
}
return hasher.Sum(nil)
}
@ -441,16 +453,18 @@ func getLatestVersion(db dbm.DB) int64 {
if latestBytes == nil {
return 0
}
err := cdc.UnmarshalBinary(latestBytes, &latest)
err := cdc.UnmarshalBinaryLengthPrefixed(latestBytes, &latest)
if err != nil {
panic(err)
}
return latest
}
// Set the latest version.
func setLatestVersion(batch dbm.Batch, version int64) {
latestBytes, _ := cdc.MarshalBinary(version) // Does not error
latestBytes, _ := cdc.MarshalBinaryLengthPrefixed(version)
batch.Set([]byte(latestVersionKey), latestBytes)
}
@ -491,21 +505,19 @@ func getCommitInfo(db dbm.DB, ver int64) (commitInfo, error) {
return commitInfo{}, fmt.Errorf("failed to get rootMultiStore: no data")
}
// Parse bytes.
var cInfo commitInfo
err := cdc.UnmarshalBinary(cInfoBytes, &cInfo)
err := cdc.UnmarshalBinaryLengthPrefixed(cInfoBytes, &cInfo)
if err != nil {
return commitInfo{}, fmt.Errorf("failed to get rootMultiStore: %v", err)
}
return cInfo, nil
}
// Set a commitInfo for given version.
func setCommitInfo(batch dbm.Batch, version int64, cInfo commitInfo) {
cInfoBytes, err := cdc.MarshalBinary(cInfo)
if err != nil {
panic(err)
}
cInfoBytes := cdc.MustMarshalBinaryLengthPrefixed(cInfo)
cInfoKey := fmt.Sprintf(commitInfoKeyFmt, version)
batch.Set([]byte(cInfoKey), cInfoBytes)
}

View File

@ -215,7 +215,7 @@ func getExpectedCommitID(store *rootMultiStore, ver int64) CommitID {
}
func hashStores(stores map[StoreKey]CommitStore) []byte {
m := make(map[string]merkle.Hasher, len(stores))
m := make(map[string][]byte, len(stores))
for key, store := range stores {
name := key.Name()
m[name] = storeInfo{
@ -224,7 +224,7 @@ func hashStores(stores map[StoreKey]CommitStore) []byte {
CommitID: store.LastCommitID(),
// StoreType: store.GetStoreType(),
},
}
}.Hash()
}
return merkle.SimpleHashFromMap(m)
}

View File

@ -305,11 +305,11 @@ func TestSerializationGocodecJSON(t *testing.T) {
func TestSerializationGocodecBinary(t *testing.T) {
d := mustNewDecFromStr(t, "0.333")
bz, err := cdc.MarshalBinary(d)
bz, err := cdc.MarshalBinaryLengthPrefixed(d)
require.NoError(t, err)
var d2 Dec
err = cdc.UnmarshalBinary(bz, &d2)
err = cdc.UnmarshalBinaryLengthPrefixed(bz, &d2)
require.NoError(t, err)
require.True(t, d.Equal(d2), "original: %v, unmarshalled: %v", d, d2)
}
@ -323,11 +323,11 @@ type testDEmbedStruct struct {
// TODO make work for UnmarshalJSON
func TestEmbeddedStructSerializationGocodec(t *testing.T) {
obj := testDEmbedStruct{"foo", 10, NewDecWithPrec(1, 3)}
bz, err := cdc.MarshalBinary(obj)
bz, err := cdc.MarshalBinaryLengthPrefixed(obj)
require.Nil(t, err)
var obj2 testDEmbedStruct
err = cdc.UnmarshalBinary(bz, &obj2)
err = cdc.UnmarshalBinaryLengthPrefixed(bz, &obj2)
require.Nil(t, err)
require.Equal(t, obj.Field1, obj2.Field1)

View File

@ -64,7 +64,11 @@ type ValidatorSet interface {
func(index int64, validator Validator) (stop bool))
// iterate through bonded validators by operator address, execute func for each validator
IterateValidatorsBonded(Context,
IterateBondedValidatorsByPower(Context,
func(index int64, validator Validator) (stop bool))
// iterate through the consensus validator set of the last block by operator address, execute func for each validator
IterateLastValidators(Context,
func(index int64, validator Validator) (stop bool))
Validator(Context, ValAddress) Validator // get a particular validator by operator address

View File

@ -93,16 +93,16 @@ func TestBaseAccountMarshal(t *testing.T) {
cdc := codec.New()
codec.RegisterCrypto(cdc)
b, err := cdc.MarshalBinary(acc)
b, err := cdc.MarshalBinaryLengthPrefixed(acc)
require.Nil(t, err)
acc2 := BaseAccount{}
err = cdc.UnmarshalBinary(b, &acc2)
err = cdc.UnmarshalBinaryLengthPrefixed(b, &acc2)
require.Nil(t, err)
require.Equal(t, acc, acc2)
// error on bad bytes
acc2 = BaseAccount{}
err = cdc.UnmarshalBinary(b[:len(b)/2], &acc2)
err = cdc.UnmarshalBinaryLengthPrefixed(b[:len(b)/2], &acc2)
require.NotNil(t, err)
}

View File

@ -125,7 +125,8 @@ func (bldr TxBuilder) Sign(name, passphrase string, msg StdSignMsg) ([]byte, err
if err != nil {
return nil, err
}
return bldr.Codec.MarshalBinary(auth.NewStdTx(msg.Msgs, msg.Fee, []auth.StdSignature{sig}, msg.Memo))
return bldr.Codec.MarshalBinaryLengthPrefixed(auth.NewStdTx(msg.Msgs, msg.Fee, []auth.StdSignature{sig}, msg.Memo))
}
// BuildAndSign builds a single message to be signed, and signs a transaction
@ -166,7 +167,7 @@ func (bldr TxBuilder) BuildWithPubKey(name string, msgs []sdk.Msg) ([]byte, erro
PubKey: info.GetPubKey(),
}}
return bldr.Codec.MarshalBinary(auth.NewStdTx(msg.Msgs, msg.Fee, sigs, msg.Memo))
return bldr.Codec.MarshalBinaryLengthPrefixed(auth.NewStdTx(msg.Msgs, msg.Fee, sigs, msg.Memo))
}
// SignStdTx appends a signature to a StdTx and returns a copy of a it. If append

View File

@ -36,12 +36,12 @@ func (fck FeeCollectionKeeper) GetCollectedFees(ctx sdk.Context) sdk.Coins {
}
feePool := &(sdk.Coins{})
fck.cdc.MustUnmarshalBinary(bz, feePool)
fck.cdc.MustUnmarshalBinaryLengthPrefixed(bz, feePool)
return *feePool
}
func (fck FeeCollectionKeeper) setCollectedFees(ctx sdk.Context, coins sdk.Coins) {
bz := fck.cdc.MustMarshalBinary(coins)
bz := fck.cdc.MustMarshalBinaryLengthPrefixed(coins)
store := ctx.KVStore(fck.key)
store.Set(collectedFeesKey, bz)
}

View File

@ -148,13 +148,13 @@ func (am AccountKeeper) GetNextAccountNumber(ctx sdk.Context) int64 {
if bz == nil {
accNumber = 0
} else {
err := am.cdc.UnmarshalBinary(bz, &accNumber)
err := am.cdc.UnmarshalBinaryLengthPrefixed(bz, &accNumber)
if err != nil {
panic(err)
}
}
bz = am.cdc.MustMarshalBinary(accNumber + 1)
bz = am.cdc.MustMarshalBinaryLengthPrefixed(accNumber + 1)
store.Set(globalAccountNumberKey, bz)
return accNumber

View File

@ -151,10 +151,11 @@ func DefaultTxDecoder(cdc *codec.Codec) sdk.TxDecoder {
// StdTx.Msg is an interface. The concrete types
// are registered by MakeTxCodec
err := cdc.UnmarshalBinary(txBytes, &tx)
err := cdc.UnmarshalBinaryLengthPrefixed(txBytes, &tx)
if err != nil {
return nil, sdk.ErrTxDecode("").TraceSDK(err.Error())
}
return tx, nil
}
}

View File

@ -25,7 +25,8 @@ in place of an input filename, the command reads from standard input.`,
if err != nil {
return
}
txBytes, err := cliCtx.Codec.MarshalBinary(stdTx)
txBytes, err := cliCtx.Codec.MarshalBinaryLengthPrefixed(stdTx)
if err != nil {
return
}

View File

@ -22,11 +22,12 @@ func BroadcastTxRequestHandlerFn(cdc *codec.Codec, cliCtx context.CLIContext) ht
return
}
txBytes, err := cliCtx.Codec.MarshalBinary(m.Tx)
txBytes, err := cliCtx.Codec.MarshalBinaryLengthPrefixed(m.Tx)
if err != nil {
utils.WriteErrorResponse(w, http.StatusInternalServerError, err.Error())
return
}
res, err := cliCtx.BroadcastTx(txBytes)
if err != nil {
utils.WriteErrorResponse(w, http.StatusInternalServerError, err.Error())

View File

@ -23,14 +23,14 @@ func (k Keeper) GetDelegationDistInfo(ctx sdk.Context, delAddr sdk.AccAddress,
panic("Stored delegation-distribution info should not have been nil")
}
k.cdc.MustUnmarshalBinary(b, &ddi)
k.cdc.MustUnmarshalBinaryLengthPrefixed(b, &ddi)
return
}
// set the delegator distribution info
func (k Keeper) SetDelegationDistInfo(ctx sdk.Context, ddi types.DelegationDistInfo) {
store := ctx.KVStore(k.storeKey)
b := k.cdc.MustMarshalBinary(ddi)
b := k.cdc.MustMarshalBinaryLengthPrefixed(ddi)
store.Set(GetDelegationDistInfoKey(ddi.DelegatorAddr, ddi.ValOperatorAddr), b)
}

View File

@ -13,7 +13,7 @@ func (k Keeper) GetAllValidatorDistInfos(ctx sdk.Context) (vdis []types.Validato
for ; iterator.Valid(); iterator.Next() {
var vdi types.ValidatorDistInfo
k.cdc.MustUnmarshalBinary(iterator.Value(), &vdi)
k.cdc.MustUnmarshalBinaryLengthPrefixed(iterator.Value(), &vdi)
vdis = append(vdis, vdi)
}
return vdis
@ -27,7 +27,7 @@ func (k Keeper) GetAllDelegationDistInfos(ctx sdk.Context) (ddis []types.Delegat
for ; iterator.Valid(); iterator.Next() {
var ddi types.DelegationDistInfo
k.cdc.MustUnmarshalBinary(iterator.Value(), &ddi)
k.cdc.MustUnmarshalBinaryLengthPrefixed(iterator.Value(), &ddi)
ddis = append(ddis, ddi)
}
return ddis

View File

@ -1,6 +1,8 @@
package keeper
import (
"fmt"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/distribution/types"
)
@ -38,11 +40,12 @@ func (k Keeper) onValidatorBonded(ctx sdk.Context, valAddr sdk.ValAddress) {
k.onValidatorModified(ctx, valAddr)
}
// XXX Consider removing this after debugging.
// Sanity check, very useful!
func (k Keeper) onValidatorPowerDidChange(ctx sdk.Context, valAddr sdk.ValAddress) {
vi := k.GetValidatorDistInfo(ctx, valAddr)
if vi.FeePoolWithdrawalHeight != ctx.BlockHeight() {
panic("expected validator dist info FeePoolWithdrawalHeight to be updated, but was not.")
panic(fmt.Sprintf("expected validator (%v) dist info FeePoolWithdrawalHeight to be updated to %v, but was %v.",
valAddr.String(), ctx.BlockHeight(), vi.FeePoolWithdrawalHeight))
}
}

View File

@ -44,14 +44,14 @@ func (k Keeper) GetFeePool(ctx sdk.Context) (feePool types.FeePool) {
if b == nil {
panic("Stored fee pool should not have been nil")
}
k.cdc.MustUnmarshalBinary(b, &feePool)
k.cdc.MustUnmarshalBinaryLengthPrefixed(b, &feePool)
return
}
// set the global fee pool distribution info
func (k Keeper) SetFeePool(ctx sdk.Context, feePool types.FeePool) {
store := ctx.KVStore(k.storeKey)
b := k.cdc.MustMarshalBinary(feePool)
b := k.cdc.MustMarshalBinaryLengthPrefixed(feePool)
store.Set(FeePoolKey, b)
}
@ -77,14 +77,14 @@ func (k Keeper) GetPreviousProposerConsAddr(ctx sdk.Context) (consAddr sdk.ConsA
panic("Previous proposer not set")
}
k.cdc.MustUnmarshalBinary(b, &consAddr)
k.cdc.MustUnmarshalBinaryLengthPrefixed(b, &consAddr)
return
}
// get the proposer public key for this block
func (k Keeper) SetPreviousProposerConsAddr(ctx sdk.Context, consAddr sdk.ConsAddress) {
store := ctx.KVStore(k.storeKey)
b := k.cdc.MustMarshalBinary(consAddr)
b := k.cdc.MustMarshalBinaryLengthPrefixed(consAddr)
store.Set(ProposerKey, b)
}

View File

@ -130,7 +130,7 @@ func CreateTestInputAdvanced(t *testing.T, isCheckTx bool, initCoins int64,
keeper := NewKeeper(cdc, keyDistr, pk.Subspace(DefaultParamspace), ck, sk, fck, types.DefaultCodespace)
// set the distribution hooks on staking
sk = sk.WithHooks(keeper.Hooks())
sk.SetHooks(keeper.Hooks())
// set genesis items required for distribution
keeper.SetFeePool(ctx, types.InitialFeePool())
@ -172,7 +172,7 @@ func (k Keeper) IterateValidatorDistInfos(ctx sdk.Context,
index := int64(0)
for ; iter.Valid(); iter.Next() {
var vdi types.ValidatorDistInfo
k.cdc.MustUnmarshalBinary(iter.Value(), &vdi)
k.cdc.MustUnmarshalBinaryLengthPrefixed(iter.Value(), &vdi)
if fn(index, vdi) {
return
}

View File

@ -23,14 +23,14 @@ func (k Keeper) GetValidatorDistInfo(ctx sdk.Context,
panic("Stored validator-distribution info should not have been nil")
}
k.cdc.MustUnmarshalBinary(b, &vdi)
k.cdc.MustUnmarshalBinaryLengthPrefixed(b, &vdi)
return
}
// set the validator distribution info
func (k Keeper) SetValidatorDistInfo(ctx sdk.Context, vdi types.ValidatorDistInfo) {
store := ctx.KVStore(k.storeKey)
b := k.cdc.MustMarshalBinary(vdi)
b := k.cdc.MustMarshalBinaryLengthPrefixed(vdi)
store.Set(GetValidatorDistInfoKey(vdi.OperatorAddr), b)
}

View File

@ -292,7 +292,7 @@ func queryDepositHandlerFn(cdc *codec.Codec, cliCtx context.CLIContext) http.Han
var deposit gov.Deposit
cdc.UnmarshalJSON(res, &deposit)
if deposit.Empty() {
res, err := cliCtx.QueryWithData("custom/gov/proposal", cdc.MustMarshalBinary(gov.QueryProposalParams{params.ProposalID}))
res, err := cliCtx.QueryWithData("custom/gov/proposal", cdc.MustMarshalBinaryLengthPrefixed(gov.QueryProposalParams{params.ProposalID}))
if err != nil || len(res) == 0 {
err := errors.Errorf("proposalID [%d] does not exist", proposalID)
utils.WriteErrorResponse(w, http.StatusNotFound, err.Error())

View File

@ -106,7 +106,7 @@ func (keeper Keeper) GetProposal(ctx sdk.Context, proposalID int64) Proposal {
}
var proposal Proposal
keeper.cdc.MustUnmarshalBinary(bz, &proposal)
keeper.cdc.MustUnmarshalBinaryLengthPrefixed(bz, &proposal)
return proposal
}
@ -114,7 +114,7 @@ func (keeper Keeper) GetProposal(ctx sdk.Context, proposalID int64) Proposal {
// Implements sdk.AccountKeeper.
func (keeper Keeper) SetProposal(ctx sdk.Context, proposal Proposal) {
store := ctx.KVStore(keeper.storeKey)
bz := keeper.cdc.MustMarshalBinary(proposal)
bz := keeper.cdc.MustMarshalBinaryLengthPrefixed(proposal)
store.Set(KeyProposal(proposal.GetProposalID()), bz)
}
@ -175,7 +175,7 @@ func (keeper Keeper) setInitialProposalID(ctx sdk.Context, proposalID int64) sdk
if bz != nil {
return ErrInvalidGenesis(keeper.codespace, "Initial ProposalID already set")
}
bz = keeper.cdc.MustMarshalBinary(proposalID)
bz = keeper.cdc.MustMarshalBinaryLengthPrefixed(proposalID)
store.Set(KeyNextProposalID, bz)
return nil
}
@ -197,8 +197,8 @@ func (keeper Keeper) getNewProposalID(ctx sdk.Context) (proposalID int64, err sd
if bz == nil {
return -1, ErrInvalidGenesis(keeper.codespace, "InitialProposalID never set")
}
keeper.cdc.MustUnmarshalBinary(bz, &proposalID)
bz = keeper.cdc.MustMarshalBinary(proposalID + 1)
keeper.cdc.MustUnmarshalBinaryLengthPrefixed(bz, &proposalID)
bz = keeper.cdc.MustMarshalBinaryLengthPrefixed(proposalID + 1)
store.Set(KeyNextProposalID, bz)
return proposalID, nil
}
@ -210,7 +210,7 @@ func (keeper Keeper) peekCurrentProposalID(ctx sdk.Context) (proposalID int64, e
if bz == nil {
return -1, ErrInvalidGenesis(keeper.codespace, "InitialProposalID never set")
}
keeper.cdc.MustUnmarshalBinary(bz, &proposalID)
keeper.cdc.MustUnmarshalBinaryLengthPrefixed(bz, &proposalID)
return proposalID, nil
}
@ -298,13 +298,13 @@ func (keeper Keeper) GetVote(ctx sdk.Context, proposalID int64, voterAddr sdk.Ac
return Vote{}, false
}
var vote Vote
keeper.cdc.MustUnmarshalBinary(bz, &vote)
keeper.cdc.MustUnmarshalBinaryLengthPrefixed(bz, &vote)
return vote, true
}
func (keeper Keeper) setVote(ctx sdk.Context, proposalID int64, voterAddr sdk.AccAddress, vote Vote) {
store := ctx.KVStore(keeper.storeKey)
bz := keeper.cdc.MustMarshalBinary(vote)
bz := keeper.cdc.MustMarshalBinaryLengthPrefixed(vote)
store.Set(KeyVote(proposalID, voterAddr), bz)
}
@ -330,13 +330,13 @@ func (keeper Keeper) GetDeposit(ctx sdk.Context, proposalID int64, depositerAddr
return Deposit{}, false
}
var deposit Deposit
keeper.cdc.MustUnmarshalBinary(bz, &deposit)
keeper.cdc.MustUnmarshalBinaryLengthPrefixed(bz, &deposit)
return deposit, true
}
func (keeper Keeper) setDeposit(ctx sdk.Context, proposalID int64, depositerAddr sdk.AccAddress, deposit Deposit) {
store := ctx.KVStore(keeper.storeKey)
bz := keeper.cdc.MustMarshalBinary(deposit)
bz := keeper.cdc.MustMarshalBinaryLengthPrefixed(deposit)
store.Set(KeyDeposit(proposalID, depositerAddr), bz)
}
@ -398,7 +398,7 @@ func (keeper Keeper) RefundDeposits(ctx sdk.Context, proposalID int64) {
for ; depositsIterator.Valid(); depositsIterator.Next() {
deposit := &Deposit{}
keeper.cdc.MustUnmarshalBinary(depositsIterator.Value(), deposit)
keeper.cdc.MustUnmarshalBinaryLengthPrefixed(depositsIterator.Value(), deposit)
_, _, err := keeper.ck.AddCoins(ctx, deposit.Depositer, deposit.Amount)
if err != nil {
@ -434,14 +434,14 @@ func (keeper Keeper) getActiveProposalQueue(ctx sdk.Context) ProposalQueue {
}
var proposalQueue ProposalQueue
keeper.cdc.MustUnmarshalBinary(bz, &proposalQueue)
keeper.cdc.MustUnmarshalBinaryLengthPrefixed(bz, &proposalQueue)
return proposalQueue
}
func (keeper Keeper) setActiveProposalQueue(ctx sdk.Context, proposalQueue ProposalQueue) {
store := ctx.KVStore(keeper.storeKey)
bz := keeper.cdc.MustMarshalBinary(proposalQueue)
bz := keeper.cdc.MustMarshalBinaryLengthPrefixed(proposalQueue)
store.Set(KeyActiveProposalQueue, bz)
}
@ -480,14 +480,14 @@ func (keeper Keeper) getInactiveProposalQueue(ctx sdk.Context) ProposalQueue {
var proposalQueue ProposalQueue
keeper.cdc.MustUnmarshalBinary(bz, &proposalQueue)
keeper.cdc.MustUnmarshalBinaryLengthPrefixed(bz, &proposalQueue)
return proposalQueue
}
func (keeper Keeper) setInactiveProposalQueue(ctx sdk.Context, proposalQueue ProposalQueue) {
store := ctx.KVStore(keeper.storeKey)
bz := keeper.cdc.MustMarshalBinary(proposalQueue)
bz := keeper.cdc.MustMarshalBinaryLengthPrefixed(proposalQueue)
store.Set(KeyInactiveProposalQueue, bz)
}

View File

@ -122,11 +122,11 @@ func TestDeposits(t *testing.T) {
// Test deposit iterator
depositsIterator := keeper.GetDeposits(ctx, proposalID)
require.True(t, depositsIterator.Valid())
keeper.cdc.MustUnmarshalBinary(depositsIterator.Value(), &deposit)
keeper.cdc.MustUnmarshalBinaryLengthPrefixed(depositsIterator.Value(), &deposit)
require.Equal(t, addrs[0], deposit.Depositer)
require.Equal(t, fourSteak.Plus(fiveSteak), deposit.Amount)
depositsIterator.Next()
keeper.cdc.MustUnmarshalBinary(depositsIterator.Value(), &deposit)
keeper.cdc.MustUnmarshalBinaryLengthPrefixed(depositsIterator.Value(), &deposit)
require.Equal(t, addrs[1], deposit.Depositer)
require.Equal(t, fourSteak, deposit.Amount)
depositsIterator.Next()
@ -184,14 +184,14 @@ func TestVotes(t *testing.T) {
// Test vote iterator
votesIterator := keeper.GetVotes(ctx, proposalID)
require.True(t, votesIterator.Valid())
keeper.cdc.MustUnmarshalBinary(votesIterator.Value(), &vote)
keeper.cdc.MustUnmarshalBinaryLengthPrefixed(votesIterator.Value(), &vote)
require.True(t, votesIterator.Valid())
require.Equal(t, addrs[0], vote.Voter)
require.Equal(t, proposalID, vote.ProposalID)
require.Equal(t, OptionYes, vote.Option)
votesIterator.Next()
require.True(t, votesIterator.Valid())
keeper.cdc.MustUnmarshalBinary(votesIterator.Value(), &vote)
keeper.cdc.MustUnmarshalBinaryLengthPrefixed(votesIterator.Value(), &vote)
require.True(t, votesIterator.Valid())
require.Equal(t, addrs[1], vote.Voter)
require.Equal(t, proposalID, vote.ProposalID)

View File

@ -126,7 +126,7 @@ func queryDeposits(ctx sdk.Context, path []string, req abci.RequestQuery, keeper
depositsIterator := keeper.GetDeposits(ctx, params.ProposalID)
for ; depositsIterator.Valid(); depositsIterator.Next() {
deposit := Deposit{}
keeper.cdc.MustUnmarshalBinary(depositsIterator.Value(), &deposit)
keeper.cdc.MustUnmarshalBinaryLengthPrefixed(depositsIterator.Value(), &deposit)
deposits = append(deposits, deposit)
}
@ -155,7 +155,7 @@ func queryVotes(ctx sdk.Context, path []string, req abci.RequestQuery, keeper Ke
votesIterator := keeper.GetVotes(ctx, params.ProposalID)
for ; votesIterator.Valid(); votesIterator.Next() {
vote := Vote{}
keeper.cdc.MustUnmarshalBinary(votesIterator.Value(), &vote)
keeper.cdc.MustUnmarshalBinaryLengthPrefixed(votesIterator.Value(), &vote)
votes = append(votes, vote)
}

View File

@ -23,7 +23,7 @@ func tally(ctx sdk.Context, keeper Keeper, proposal Proposal) (passes bool, tall
totalVotingPower := sdk.ZeroDec()
currValidators := make(map[string]validatorGovInfo)
keeper.vs.IterateValidatorsBonded(ctx, func(index int64, validator sdk.Validator) (stop bool) {
keeper.vs.IterateBondedValidatorsByPower(ctx, func(index int64, validator sdk.Validator) (stop bool) {
currValidators[validator.GetOperator().String()] = validatorGovInfo{
Address: validator.GetOperator(),
Power: validator.GetPower(),
@ -39,7 +39,7 @@ func tally(ctx sdk.Context, keeper Keeper, proposal Proposal) (passes bool, tall
defer votesIterator.Close()
for ; votesIterator.Valid(); votesIterator.Next() {
vote := &Vote{}
keeper.cdc.MustUnmarshalBinary(votesIterator.Value(), vote)
keeper.cdc.MustUnmarshalBinaryLengthPrefixed(votesIterator.Value(), vote)
// if validator, just record it in the map
// if delegator tally voting power

View File

@ -117,7 +117,7 @@ OUTER:
var processed int64
if processedbz == nil {
processed = 0
} else if err = c.cdc.UnmarshalBinary(processedbz, &processed); err != nil {
} else if err = c.cdc.UnmarshalBinaryLengthPrefixed(processedbz, &processed); err != nil {
panic(err)
}
@ -131,7 +131,7 @@ OUTER:
var egressLength int64
if egressLengthbz == nil {
egressLength = 0
} else if err = c.cdc.UnmarshalBinary(egressLengthbz, &egressLength); err != nil {
} else if err = c.cdc.UnmarshalBinaryLengthPrefixed(egressLengthbz, &egressLength); err != nil {
panic(err)
}
@ -192,7 +192,7 @@ func (c relayCommander) getSequence(node string) int64 {
func (c relayCommander) refine(bz []byte, sequence int64, passphrase string) []byte {
var packet ibc.IBCPacket
if err := c.cdc.UnmarshalBinary(bz, &packet); err != nil {
if err := c.cdc.UnmarshalBinaryLengthPrefixed(bz, &packet); err != nil {
panic(err)
}

View File

@ -33,13 +33,13 @@ func (ibcm Mapper) PostIBCPacket(ctx sdk.Context, packet IBCPacket) sdk.Error {
// write everything into the state
store := ctx.KVStore(ibcm.key)
index := ibcm.getEgressLength(store, packet.DestChain)
bz, err := ibcm.cdc.MarshalBinary(packet)
bz, err := ibcm.cdc.MarshalBinaryLengthPrefixed(packet)
if err != nil {
panic(err)
}
store.Set(EgressKey(packet.DestChain, index), bz)
bz, err = ibcm.cdc.MarshalBinary(index + 1)
bz, err = ibcm.cdc.MarshalBinaryLengthPrefixed(index + 1)
if err != nil {
panic(err)
}
@ -61,7 +61,7 @@ func (ibcm Mapper) ReceiveIBCPacket(ctx sdk.Context, packet IBCPacket) sdk.Error
// Functions for accessing the underlying KVStore.
func marshalBinaryPanic(cdc *codec.Codec, value interface{}) []byte {
res, err := cdc.MarshalBinary(value)
res, err := cdc.MarshalBinaryLengthPrefixed(value)
if err != nil {
panic(err)
}
@ -69,7 +69,7 @@ func marshalBinaryPanic(cdc *codec.Codec, value interface{}) []byte {
}
func unmarshalBinaryPanic(cdc *codec.Codec, bz []byte, ptr interface{}) {
err := cdc.UnmarshalBinary(bz, ptr)
err := cdc.UnmarshalBinaryLengthPrefixed(bz, ptr)
if err != nil {
panic(err)
}

View File

@ -59,14 +59,14 @@ func (k Keeper) GetMinter(ctx sdk.Context) (minter Minter) {
if b == nil {
panic("Stored fee pool should not have been nil")
}
k.cdc.MustUnmarshalBinary(b, &minter)
k.cdc.MustUnmarshalBinaryLengthPrefixed(b, &minter)
return
}
// set the minter
func (k Keeper) SetMinter(ctx sdk.Context, minter Minter) {
store := ctx.KVStore(k.storeKey)
b := k.cdc.MustMarshalBinary(minter)
b := k.cdc.MustMarshalBinaryLengthPrefixed(minter)
store.Set(minterKey, b)
}

View File

@ -1,37 +0,0 @@
package simulation
const (
// Fraction of double-signing evidence from a past height
pastEvidenceFraction float64 = 0.5
// Minimum time per block
minTimePerBlock int64 = 1000 / 2
// Maximum time per block
maxTimePerBlock int64 = 1000
// Number of keys
numKeys int = 250
// Chance that double-signing evidence is found on a given block
evidenceFraction float64 = 0.5
// TODO Remove in favor of binary search for invariant violation
onOperation bool = false
)
var (
// Currently there are 3 different liveness types, fully online, spotty connection, offline.
initialLivenessWeightings = []int{40, 5, 5}
livenessTransitionMatrix, _ = CreateTransitionMatrix([][]int{
{90, 20, 1},
{10, 50, 5},
{0, 10, 1000},
})
// 3 states: rand in range [0, 4*provided blocksize], rand in range [0, 2 * provided blocksize], 0
blockSizeTransitionMatrix, _ = CreateTransitionMatrix([][]int{
{85, 5, 0},
{15, 92, 1},
{0, 3, 99},
})
)

View File

@ -0,0 +1,66 @@
package simulation
import (
"math/rand"
)
const (
// Minimum time per block
minTimePerBlock int64 = 10000 / 2
// Maximum time per block
maxTimePerBlock int64 = 10000
// TODO Remove in favor of binary search for invariant violation
onOperation bool = false
)
var (
// Currently there are 3 different liveness types, fully online, spotty connection, offline.
defaultLivenessTransitionMatrix, _ = CreateTransitionMatrix([][]int{
{90, 20, 1},
{10, 50, 5},
{0, 10, 1000},
})
// 3 states: rand in range [0, 4*provided blocksize], rand in range [0, 2 * provided blocksize], 0
defaultBlockSizeTransitionMatrix, _ = CreateTransitionMatrix([][]int{
{85, 5, 0},
{15, 92, 1},
{0, 3, 99},
})
)
// Simulation parameters
type Params struct {
PastEvidenceFraction float64
NumKeys int
EvidenceFraction float64
InitialLivenessWeightings []int
LivenessTransitionMatrix TransitionMatrix
BlockSizeTransitionMatrix TransitionMatrix
}
// Return default simulation parameters
func DefaultParams() Params {
return Params{
PastEvidenceFraction: 0.5,
NumKeys: 250,
EvidenceFraction: 0.5,
InitialLivenessWeightings: []int{40, 5, 5},
LivenessTransitionMatrix: defaultLivenessTransitionMatrix,
BlockSizeTransitionMatrix: defaultBlockSizeTransitionMatrix,
}
}
// Return random simulation parameters
func RandomParams(r *rand.Rand) Params {
return Params{
PastEvidenceFraction: r.Float64(),
NumKeys: r.Intn(250),
EvidenceFraction: r.Float64(),
InitialLivenessWeightings: []int{r.Intn(80), r.Intn(10), r.Intn(10)},
LivenessTransitionMatrix: defaultLivenessTransitionMatrix,
BlockSizeTransitionMatrix: defaultBlockSizeTransitionMatrix,
}
}

View File

@ -14,7 +14,7 @@ import (
"time"
abci "github.com/tendermint/tendermint/abci/types"
common "github.com/tendermint/tendermint/libs/common"
cmn "github.com/tendermint/tendermint/libs/common"
tmtypes "github.com/tendermint/tendermint/types"
"github.com/cosmos/cosmos-sdk/baseapp"
@ -31,13 +31,13 @@ func Simulate(t *testing.T, app *baseapp.BaseApp,
return SimulateFromSeed(t, app, appStateFn, time, ops, setups, invariants, numBlocks, blockSize, commit)
}
func initChain(r *rand.Rand, accounts []Account, setups []RandSetup, app *baseapp.BaseApp,
func initChain(r *rand.Rand, params Params, accounts []Account, setups []RandSetup, app *baseapp.BaseApp,
appStateFn func(r *rand.Rand, accounts []Account) json.RawMessage) (validators map[string]mockValidator) {
res := app.InitChain(abci.RequestInitChain{AppStateBytes: appStateFn(r, accounts)})
validators = make(map[string]mockValidator)
for _, validator := range res.Validators {
str := fmt.Sprintf("%v", validator.PubKey)
validators[str] = mockValidator{validator, GetMemberOfInitialState(r, initialLivenessWeightings)}
validators[str] = mockValidator{validator, GetMemberOfInitialState(r, params.InitialLivenessWeightings)}
}
for i := 0; i < len(setups); i++ {
@ -65,11 +65,13 @@ func SimulateFromSeed(tb testing.TB, app *baseapp.BaseApp,
testingMode, t, b := getTestingMode(tb)
fmt.Printf("Starting SimulateFromSeed with randomness created with seed %d\n", int(seed))
r := rand.New(rand.NewSource(seed))
params := RandomParams(r) // := DefaultParams()
fmt.Printf("Randomized simulation params: %+v\n", params)
timestamp := randTimestamp(r)
fmt.Printf("Starting the simulation from time %v, unixtime %v\n", timestamp.UTC().Format(time.UnixDate), timestamp.Unix())
timeDiff := maxTimePerBlock - minTimePerBlock
accs := RandomAccounts(r, numKeys)
accs := RandomAccounts(r, params.NumKeys)
// Setup event stats
events := make(map[string]uint)
@ -77,7 +79,7 @@ func SimulateFromSeed(tb testing.TB, app *baseapp.BaseApp,
events[what]++
}
validators := initChain(r, accs, setups, app, appStateFn)
validators := initChain(r, params, accs, setups, app, appStateFn)
// Second variable to keep pending validator set (delayed one block since TM 0.24)
// Initially this is the same as the initial validator set
nextValidators := validators
@ -90,7 +92,7 @@ func SimulateFromSeed(tb testing.TB, app *baseapp.BaseApp,
signal.Notify(c, os.Interrupt, syscall.SIGTERM, syscall.SIGINT)
go func() {
receivedSignal := <-c
fmt.Printf("Exiting early due to %s, on block %d, operation %d\n", receivedSignal, header.Height, opCount)
fmt.Printf("\nExiting early due to %s, on block %d, operation %d\n", receivedSignal, header.Height, opCount)
simError = fmt.Errorf("Exited due to %s", receivedSignal)
stopEarly = true
}()
@ -98,7 +100,7 @@ func SimulateFromSeed(tb testing.TB, app *baseapp.BaseApp,
var pastTimes []time.Time
var pastVoteInfos [][]abci.VoteInfo
request := RandomRequestBeginBlock(r, validators, livenessTransitionMatrix, evidenceFraction, pastTimes, pastVoteInfos, event, header)
request := RandomRequestBeginBlock(r, params, validators, pastTimes, pastVoteInfos, event, header)
// These are operations which have been queued by previous operations
operationQueue := make(map[int][]Operation)
timeOperationQueue := []FutureOperation{}
@ -108,7 +110,7 @@ func SimulateFromSeed(tb testing.TB, app *baseapp.BaseApp,
blockLogBuilders = make([]*strings.Builder, numBlocks)
}
displayLogs := logPrinter(testingMode, blockLogBuilders)
blockSimulator := createBlockSimulator(testingMode, tb, t, event, invariants, ops, operationQueue, timeOperationQueue, numBlocks, blockSize, displayLogs)
blockSimulator := createBlockSimulator(testingMode, tb, t, params, event, invariants, ops, operationQueue, timeOperationQueue, numBlocks, blockSize, displayLogs)
if !testingMode {
b.ResetTimer()
} else {
@ -181,11 +183,11 @@ func SimulateFromSeed(tb testing.TB, app *baseapp.BaseApp,
}
// Generate a random RequestBeginBlock with the current validator set for the next block
request = RandomRequestBeginBlock(r, validators, livenessTransitionMatrix, evidenceFraction, pastTimes, pastVoteInfos, event, header)
request = RandomRequestBeginBlock(r, params, validators, pastTimes, pastVoteInfos, event, header)
// Update the validator set, which will be reflected in the application on the next block
validators = nextValidators
nextValidators = updateValidators(tb, r, validators, res.ValidatorUpdates, event)
nextValidators = updateValidators(tb, r, params, validators, res.ValidatorUpdates, event)
}
if stopEarly {
DisplayEvents(events)
@ -203,7 +205,7 @@ type blockSimFn func(
// Returns a function to simulate blocks. Written like this to avoid constant parameters being passed everytime, to minimize
// memory overhead
func createBlockSimulator(testingMode bool, tb testing.TB, t *testing.T,
func createBlockSimulator(testingMode bool, tb testing.TB, t *testing.T, params Params,
event func(string), invariants []Invariant,
ops []WeightedOperation, operationQueue map[int][]Operation, timeOperationQueue []FutureOperation,
totalNumBlocks int, avgBlockSize int, displayLogs func()) blockSimFn {
@ -231,7 +233,8 @@ func createBlockSimulator(testingMode bool, tb testing.TB, t *testing.T,
return func(r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context,
accounts []Account, header abci.Header, logWriter func(string)) (opCount int) {
lastBlocksizeState, blocksize = getBlockSize(r, lastBlocksizeState, avgBlockSize)
fmt.Printf("\rSimulating... block %d/%d, operation %d/%d. ", header.Height, totalNumBlocks, opCount, blocksize)
lastBlocksizeState, blocksize = getBlockSize(r, params, lastBlocksizeState, avgBlockSize)
for j := 0; j < blocksize; j++ {
logUpdate, futureOps, err := selectOp(r)(r, app, ctx, accounts, event)
logWriter(logUpdate)
@ -272,11 +275,10 @@ func getTestingMode(tb testing.TB) (testingMode bool, t *testing.T, b *testing.B
// "over stuffed" blocks with average size of 2 * avgblocksize,
// normal sized blocks, hitting avgBlocksize on average,
// and empty blocks, with no txs / only txs scheduled from the past.
func getBlockSize(r *rand.Rand, lastBlockSizeState, avgBlockSize int) (state, blocksize int) {
// TODO: Make blockSizeTransitionMatrix non-global
func getBlockSize(r *rand.Rand, params Params, lastBlockSizeState, avgBlockSize int) (state, blocksize int) {
// TODO: Make default blocksize transition matrix actually make the average
// blocksize equal to avgBlockSize.
state = blockSizeTransitionMatrix.NextState(r, lastBlockSizeState)
state = params.BlockSizeTransitionMatrix.NextState(r, lastBlockSizeState)
if state == 0 {
blocksize = r.Intn(avgBlockSize * 4)
} else if state == 1 {
@ -363,7 +365,7 @@ func getKeys(validators map[string]mockValidator) []string {
}
// randomProposer picks a random proposer from the current validator set
func randomProposer(r *rand.Rand, validators map[string]mockValidator) common.HexBytes {
func randomProposer(r *rand.Rand, validators map[string]mockValidator) cmn.HexBytes {
keys := getKeys(validators)
if len(keys) == 0 {
return nil
@ -379,7 +381,7 @@ func randomProposer(r *rand.Rand, validators map[string]mockValidator) common.He
// RandomRequestBeginBlock generates a list of signing validators according to the provided list of validators, signing fraction, and evidence fraction
// nolint: unparam
func RandomRequestBeginBlock(r *rand.Rand, validators map[string]mockValidator, livenessTransitions TransitionMatrix, evidenceFraction float64,
func RandomRequestBeginBlock(r *rand.Rand, params Params, validators map[string]mockValidator,
pastTimes []time.Time, pastVoteInfos [][]abci.VoteInfo, event func(string), header abci.Header) abci.RequestBeginBlock {
if len(validators) == 0 {
return abci.RequestBeginBlock{Header: header}
@ -388,7 +390,7 @@ func RandomRequestBeginBlock(r *rand.Rand, validators map[string]mockValidator,
i := 0
for _, key := range getKeys(validators) {
mVal := validators[key]
mVal.livenessState = livenessTransitions.NextState(r, mVal.livenessState)
mVal.livenessState = params.LivenessTransitionMatrix.NextState(r, mVal.livenessState)
signed := true
if mVal.livenessState == 1 {
@ -422,11 +424,11 @@ func RandomRequestBeginBlock(r *rand.Rand, validators map[string]mockValidator,
evidence := make([]abci.Evidence, 0)
// Anything but the first block
if len(pastTimes) > 0 {
for r.Float64() < evidenceFraction {
for r.Float64() < params.EvidenceFraction {
height := header.Height
time := header.Time
vals := voteInfos
if r.Float64() < pastEvidenceFraction {
if r.Float64() < params.PastEvidenceFraction {
height = int64(r.Intn(int(header.Height) - 1))
time = pastTimes[height]
vals = pastVoteInfos[height]
@ -457,7 +459,7 @@ func RandomRequestBeginBlock(r *rand.Rand, validators map[string]mockValidator,
// updateValidators mimicks Tendermint's update logic
// nolint: unparam
func updateValidators(tb testing.TB, r *rand.Rand, current map[string]mockValidator, updates []abci.ValidatorUpdate, event func(string)) map[string]mockValidator {
func updateValidators(tb testing.TB, r *rand.Rand, params Params, current map[string]mockValidator, updates []abci.ValidatorUpdate, event func(string)) map[string]mockValidator {
for _, update := range updates {
str := fmt.Sprintf("%v", update.PubKey)
@ -476,7 +478,7 @@ func updateValidators(tb testing.TB, r *rand.Rand, current map[string]mockValida
event("endblock/validatorupdates/updated")
} else {
// Set this new validator
current[str] = mockValidator{update, GetMemberOfInitialState(r, initialLivenessWeightings)}
current[str] = mockValidator{update, GetMemberOfInitialState(r, params.InitialLivenessWeightings)}
event("endblock/validatorupdates/added")
}
}

View File

@ -34,7 +34,7 @@ func GetCmdQuerySigningInfo(storeName string, cdc *codec.Codec) *cobra.Command {
}
signingInfo := new(slashing.ValidatorSigningInfo)
cdc.MustUnmarshalBinary(res, signingInfo)
cdc.MustUnmarshalBinaryLengthPrefixed(res, signingInfo)
switch viper.Get(cli.OutputFlag) {

View File

@ -45,7 +45,7 @@ func signingInfoHandlerFn(cliCtx context.CLIContext, storeName string, cdc *code
var signingInfo slashing.ValidatorSigningInfo
err = cdc.UnmarshalBinary(res, &signingInfo)
err = cdc.UnmarshalBinaryLengthPrefixed(res, &signingInfo)
if err != nil {
utils.WriteErrorResponse(w, http.StatusInternalServerError, err.Error())
return

View File

@ -49,6 +49,15 @@ func (k Keeper) handleDoubleSign(ctx sdk.Context, addr crypto.Address, infractio
panic(fmt.Sprintf("Validator consensus-address %v not found", consAddr))
}
// Get validator.
validator := k.validatorSet.ValidatorByConsAddr(ctx, consAddr)
if validator == nil || validator.GetStatus() == sdk.Unbonded {
// Defensive.
// Simulation doesn't take unbonding periods into account, and
// Tendermint might break this assumption at some point.
return
}
// Double sign too old
maxEvidenceAge := k.MaxEvidenceAge(ctx)
if age > maxEvidenceAge {
@ -80,7 +89,6 @@ func (k Keeper) handleDoubleSign(ctx sdk.Context, addr crypto.Address, infractio
k.validatorSet.Slash(ctx, consAddr, distributionHeight, power, revisedFraction)
// Jail validator if not already jailed
validator := k.validatorSet.ValidatorByConsAddr(ctx, consAddr)
if !validator.GetJailed() {
k.validatorSet.Jail(ctx, consAddr)
}
@ -187,7 +195,7 @@ func (k Keeper) addPubkey(ctx sdk.Context, pubkey crypto.PubKey) {
func (k Keeper) getPubkey(ctx sdk.Context, address crypto.Address) (crypto.PubKey, error) {
store := ctx.KVStore(k.storeKey)
var pubkey crypto.PubKey
err := k.cdc.UnmarshalBinary(store.Get(getAddrPubkeyRelationKey(address)), &pubkey)
err := k.cdc.UnmarshalBinaryLengthPrefixed(store.Get(getAddrPubkeyRelationKey(address)), &pubkey)
if err != nil {
return nil, fmt.Errorf("address %v not found", address)
}
@ -196,7 +204,7 @@ func (k Keeper) getPubkey(ctx sdk.Context, address crypto.Address) (crypto.PubKe
func (k Keeper) setAddrPubkeyRelation(ctx sdk.Context, addr crypto.Address, pubkey crypto.PubKey) {
store := ctx.KVStore(k.storeKey)
bz := k.cdc.MustMarshalBinary(pubkey)
bz := k.cdc.MustMarshalBinaryLengthPrefixed(pubkey)
store.Set(getAddrPubkeyRelationKey(addr), bz)
}

View File

@ -15,7 +15,7 @@ func (k Keeper) getValidatorSigningInfo(ctx sdk.Context, address sdk.ConsAddress
found = false
return
}
k.cdc.MustUnmarshalBinary(bz, &info)
k.cdc.MustUnmarshalBinaryLengthPrefixed(bz, &info)
found = true
return
}
@ -23,7 +23,7 @@ func (k Keeper) getValidatorSigningInfo(ctx sdk.Context, address sdk.ConsAddress
// Stored by *validator* address (not operator address)
func (k Keeper) setValidatorSigningInfo(ctx sdk.Context, address sdk.ConsAddress, info ValidatorSigningInfo) {
store := ctx.KVStore(k.storeKey)
bz := k.cdc.MustMarshalBinary(info)
bz := k.cdc.MustMarshalBinaryLengthPrefixed(info)
store.Set(GetValidatorSigningInfoKey(address), bz)
}
@ -36,14 +36,14 @@ func (k Keeper) getValidatorMissedBlockBitArray(ctx sdk.Context, address sdk.Con
missed = false
return
}
k.cdc.MustUnmarshalBinary(bz, &missed)
k.cdc.MustUnmarshalBinaryLengthPrefixed(bz, &missed)
return
}
// Stored by *validator* address (not operator address)
func (k Keeper) setValidatorMissedBlockBitArray(ctx sdk.Context, address sdk.ConsAddress, index int64, missed bool) {
store := ctx.KVStore(k.storeKey)
bz := k.cdc.MustMarshalBinary(missed)
bz := k.cdc.MustMarshalBinaryLengthPrefixed(missed)
store.Set(GetValidatorMissedBlockBitArrayKey(address, index), bz)
}

View File

@ -61,14 +61,14 @@ func (k Keeper) addOrUpdateValidatorSlashingPeriod(ctx sdk.Context, slashingPeri
SlashedSoFar: slashingPeriod.SlashedSoFar,
}
store := ctx.KVStore(k.storeKey)
bz := k.cdc.MustMarshalBinary(slashingPeriodValue)
bz := k.cdc.MustMarshalBinaryLengthPrefixed(slashingPeriodValue)
store.Set(GetValidatorSlashingPeriodKey(slashingPeriod.ValidatorAddr, slashingPeriod.StartHeight), bz)
}
// Unmarshal key/value into a ValidatorSlashingPeriod
func (k Keeper) unmarshalSlashingPeriodKeyValue(key []byte, value []byte) ValidatorSlashingPeriod {
var slashingPeriodValue ValidatorSlashingPeriodValue
k.cdc.MustUnmarshalBinary(value, &slashingPeriodValue)
k.cdc.MustUnmarshalBinaryLengthPrefixed(value, &slashingPeriodValue)
address := sdk.ConsAddress(key[1 : 1+sdk.AddrLen])
startHeight := int64(binary.BigEndian.Uint64(key[1+sdk.AddrLen:1+sdk.AddrLen+8]) - uint64(stake.ValidatorUpdateDelay))
return ValidatorSlashingPeriod{

View File

@ -87,8 +87,8 @@ func createTestInput(t *testing.T, defaults Params) (sdk.Context, bank.Keeper, s
}
require.Nil(t, err)
paramstore := paramsKeeper.Subspace(DefaultParamspace)
keeper := NewKeeper(cdc, keySlashing, sk, paramstore, DefaultCodespace)
sk = sk.WithHooks(keeper.Hooks())
keeper := NewKeeper(cdc, keySlashing, &sk, paramstore, DefaultCodespace)
sk.SetHooks(keeper.Hooks())
require.NotPanics(t, func() {
InitGenesis(ctx, keeper, GenesisState{defaults}, genesis)

View File

@ -35,11 +35,11 @@ const (
// common flagsets to add to various functions
var (
fsPk = flag.NewFlagSet("", flag.ContinueOnError)
fsAmount = flag.NewFlagSet("", flag.ContinueOnError)
FsPk = flag.NewFlagSet("", flag.ContinueOnError)
FsAmount = flag.NewFlagSet("", flag.ContinueOnError)
fsShares = flag.NewFlagSet("", flag.ContinueOnError)
fsDescriptionCreate = flag.NewFlagSet("", flag.ContinueOnError)
fsCommissionCreate = flag.NewFlagSet("", flag.ContinueOnError)
FsCommissionCreate = flag.NewFlagSet("", flag.ContinueOnError)
fsCommissionUpdate = flag.NewFlagSet("", flag.ContinueOnError)
fsDescriptionEdit = flag.NewFlagSet("", flag.ContinueOnError)
fsValidator = flag.NewFlagSet("", flag.ContinueOnError)
@ -48,8 +48,8 @@ var (
)
func init() {
fsPk.String(FlagPubKey, "", "Go-Amino encoded hex PubKey of the validator. For Ed25519 the go-amino prepend hex is 1624de6220")
fsAmount.String(FlagAmount, "", "Amount of coins to bond")
FsPk.String(FlagPubKey, "", "Bech32-encoded PubKey of the validator. ")
FsAmount.String(FlagAmount, "", "Amount of coins to bond")
fsShares.String(FlagSharesAmount, "", "Amount of source-shares to either unbond or redelegate as a positive integer or decimal")
fsShares.String(FlagSharesFraction, "", "Fraction of source-shares to either unbond or redelegate as a positive integer or decimal >0 and <=1")
fsDescriptionCreate.String(FlagMoniker, "", "validator name")
@ -57,9 +57,9 @@ func init() {
fsDescriptionCreate.String(FlagWebsite, "", "optional website")
fsDescriptionCreate.String(FlagDetails, "", "optional details")
fsCommissionUpdate.String(FlagCommissionRate, "", "The new commission rate percentage")
fsCommissionCreate.String(FlagCommissionRate, "", "The initial commission rate percentage")
fsCommissionCreate.String(FlagCommissionMaxRate, "", "The maximum commission rate percentage")
fsCommissionCreate.String(FlagCommissionMaxChangeRate, "", "The maximum commission change rate percentage (per day)")
FsCommissionCreate.String(FlagCommissionRate, "", "The initial commission rate percentage")
FsCommissionCreate.String(FlagCommissionMaxRate, "", "The maximum commission rate percentage")
FsCommissionCreate.String(FlagCommissionMaxChangeRate, "", "The maximum commission change rate percentage (per day)")
fsDescriptionEdit.String(FlagMoniker, types.DoNotModifyDesc, "validator name")
fsDescriptionEdit.String(FlagIdentity, types.DoNotModifyDesc, "optional identity signature (ex. UPort or Keybase)")
fsDescriptionEdit.String(FlagWebsite, types.DoNotModifyDesc, "optional website")

View File

@ -103,10 +103,10 @@ func GetCmdCreateValidator(cdc *codec.Codec) *cobra.Command {
},
}
cmd.Flags().AddFlagSet(fsPk)
cmd.Flags().AddFlagSet(fsAmount)
cmd.Flags().AddFlagSet(FsPk)
cmd.Flags().AddFlagSet(FsAmount)
cmd.Flags().AddFlagSet(fsDescriptionCreate)
cmd.Flags().AddFlagSet(fsCommissionCreate)
cmd.Flags().AddFlagSet(FsCommissionCreate)
cmd.Flags().AddFlagSet(fsDelegator)
cmd.Flags().Bool(FlagGenesisFormat, false, "Export the transaction in gen-tx format; it implies --generate-only")
cmd.Flags().String(FlagIP, "", fmt.Sprintf("Node's public IP. It takes effect only when used in combination with --%s", FlagGenesisFormat))
@ -204,7 +204,7 @@ func GetCmdDelegate(cdc *codec.Codec) *cobra.Command {
},
}
cmd.Flags().AddFlagSet(fsAmount)
cmd.Flags().AddFlagSet(FsAmount)
cmd.Flags().AddFlagSet(fsValidator)
return cmd

View File

@ -72,7 +72,7 @@ func WriteGenesis(ctx sdk.Context, keeper Keeper) types.GenesisState {
// WriteValidators returns a slice of bonded genesis validators.
func WriteValidators(ctx sdk.Context, keeper Keeper) (vals []tmtypes.GenesisValidator) {
keeper.IterateValidatorsBonded(ctx, func(_ int64, validator sdk.Validator) (stop bool) {
keeper.IterateLastValidators(ctx, func(_ int64, validator sdk.Validator) (stop bool) {
vals = append(vals, tmtypes.GenesisValidator{
PubKey: validator.GetConsPubKey(),
Power: validator.GetPower().RoundInt64(),

View File

@ -31,11 +31,27 @@ func NewHandler(k keeper.Keeper) sdk.Handler {
}
// Called every block, update validator set
func EndBlocker(ctx sdk.Context, k keeper.Keeper) (ValidatorUpdates []abci.ValidatorUpdate) {
func EndBlocker(ctx sdk.Context, k keeper.Keeper) (validatorUpdates []abci.ValidatorUpdate) {
endBlockerTags := sdk.EmptyTags()
// Reset the intra-transaction counter.
k.SetIntraTxCounter(ctx, 0)
// Calculate validator set changes.
//
// NOTE: ApplyAndReturnValidatorSetUpdates has to come before
// UnbondAllMatureValidatorQueue.
// This fixes a bug when the unbonding period is instant (is the case in
// some of the tests). The test expected the validator to be completely
// unbonded after the Endblocker (go from Bonded -> Unbonding during
// ApplyAndReturnValidatorSetUpdates and then Unbonding -> Unbonded during
// UnbondAllMatureValidatorQueue).
validatorUpdates = k.ApplyAndReturnValidatorSetUpdates(ctx)
// Unbond all mature validators from the unbonding queue.
k.UnbondAllMatureValidatorQueue(ctx)
// Remove all mature unbonding delegations from the ubd queue.
matureUnbonds := k.DequeueAllMatureUnbondingQueue(ctx, ctx.BlockHeader().Time)
for _, dvPair := range matureUnbonds {
err := k.CompleteUnbonding(ctx, dvPair.DelegatorAddr, dvPair.ValidatorAddr)
@ -49,6 +65,7 @@ func EndBlocker(ctx sdk.Context, k keeper.Keeper) (ValidatorUpdates []abci.Valid
))
}
// Remove all mature redelegations from the red queue.
matureRedelegations := k.DequeueAllMatureRedelegationQueue(ctx, ctx.BlockHeader().Time)
for _, dvvTriplet := range matureRedelegations {
err := k.CompleteRedelegation(ctx, dvvTriplet.DelegatorAddr, dvvTriplet.ValidatorSrcAddr, dvvTriplet.ValidatorDstAddr)
@ -62,12 +79,6 @@ func EndBlocker(ctx sdk.Context, k keeper.Keeper) (ValidatorUpdates []abci.Valid
tags.DstValidator, []byte(dvvTriplet.ValidatorDstAddr.String()),
))
}
// reset the intra-transaction counter
k.SetIntraTxCounter(ctx, 0)
// calculate validator set changes
ValidatorUpdates = k.ApplyAndReturnValidatorSetUpdates(ctx)
return
}
@ -201,7 +212,7 @@ func handleMsgBeginUnbonding(ctx sdk.Context, msg types.MsgBeginUnbonding, k kee
return err.Result()
}
finishTime := types.MsgCdc.MustMarshalBinary(ubd.MinTime)
finishTime := types.MsgCdc.MustMarshalBinaryLengthPrefixed(ubd.MinTime)
tags := sdk.NewTags(
tags.Action, tags.ActionBeginUnbonding,
@ -219,7 +230,7 @@ func handleMsgBeginRedelegate(ctx sdk.Context, msg types.MsgBeginRedelegate, k k
return err.Result()
}
finishTime := types.MsgCdc.MustMarshalBinary(red.MinTime)
finishTime := types.MsgCdc.MustMarshalBinaryLengthPrefixed(red.MinTime)
tags := sdk.NewTags(
tags.Action, tags.ActionBeginRedelegation,

View File

@ -94,7 +94,7 @@ func TestValidatorByPowerIndex(t *testing.T) {
got = handleMsgBeginUnbonding(ctx, msgBeginUnbonding, keeper)
require.True(t, got.IsOK(), "expected msg to be ok, got %v", got)
var finishTime time.Time
types.MsgCdc.MustUnmarshalBinary(got.Data, &finishTime)
types.MsgCdc.MustUnmarshalBinaryLengthPrefixed(got.Data, &finishTime)
ctx = ctx.WithBlockTime(finishTime)
EndBlocker(ctx, keeper)
@ -232,7 +232,7 @@ func TestLegacyValidatorDelegations(t *testing.T) {
require.True(t, got.IsOK(), "expected begin unbonding validator msg to be ok, got %v", got)
var finishTime time.Time
types.MsgCdc.MustUnmarshalBinary(got.Data, &finishTime)
types.MsgCdc.MustUnmarshalBinaryLengthPrefixed(got.Data, &finishTime)
ctx = ctx.WithBlockTime(finishTime)
EndBlocker(ctx, keeper)
@ -400,7 +400,7 @@ func TestIncrementsMsgUnbond(t *testing.T) {
got := handleMsgBeginUnbonding(ctx, msgBeginUnbonding, keeper)
require.True(t, got.IsOK(), "expected msg %d to be ok, got %v", i, got)
var finishTime time.Time
types.MsgCdc.MustUnmarshalBinary(got.Data, &finishTime)
types.MsgCdc.MustUnmarshalBinaryLengthPrefixed(got.Data, &finishTime)
ctx = ctx.WithBlockTime(finishTime)
EndBlocker(ctx, keeper)
@ -494,11 +494,12 @@ func TestMultipleMsgCreateValidator(t *testing.T) {
got := handleMsgBeginUnbonding(ctx, msgBeginUnbonding, keeper)
require.True(t, got.IsOK(), "expected msg %d to be ok, got %v", i, got)
var finishTime time.Time
types.MsgCdc.MustUnmarshalBinary(got.Data, &finishTime)
// Jump to finishTime for unbonding period and remove from unbonding queue
types.MsgCdc.MustUnmarshalBinaryLengthPrefixed(got.Data, &finishTime)
ctx = ctx.WithBlockTime(finishTime)
EndBlocker(ctx, keeper)
//Check that the account is unbonded
// Check that the validator is deleted from state
validators := keeper.GetValidators(ctx, 100)
require.Equal(t, len(validatorAddrs)-(i+1), len(validators),
"expected %d validators got %d", len(validatorAddrs)-(i+1), len(validators))
@ -540,7 +541,7 @@ func TestMultipleMsgDelegate(t *testing.T) {
got := handleMsgBeginUnbonding(ctx, msgBeginUnbonding, keeper)
require.True(t, got.IsOK(), "expected msg %d to be ok, got %v", i, got)
var finishTime time.Time
types.MsgCdc.MustUnmarshalBinary(got.Data, &finishTime)
types.MsgCdc.MustUnmarshalBinaryLengthPrefixed(got.Data, &finishTime)
ctx = ctx.WithBlockTime(finishTime)
EndBlocker(ctx, keeper)
@ -570,7 +571,7 @@ func TestJailValidator(t *testing.T) {
got = handleMsgBeginUnbonding(ctx, msgBeginUnbondingValidator, keeper)
require.True(t, got.IsOK(), "expected no error: %v", got)
var finishTime time.Time
types.MsgCdc.MustUnmarshalBinary(got.Data, &finishTime)
types.MsgCdc.MustUnmarshalBinaryLengthPrefixed(got.Data, &finishTime)
ctx = ctx.WithBlockTime(finishTime)
EndBlocker(ctx, keeper)
@ -586,7 +587,7 @@ func TestJailValidator(t *testing.T) {
msgBeginUnbondingDelegator := NewMsgBeginUnbonding(delegatorAddr, validatorAddr, sdk.NewDec(10))
got = handleMsgBeginUnbonding(ctx, msgBeginUnbondingDelegator, keeper)
require.True(t, got.IsOK(), "expected no error")
types.MsgCdc.MustUnmarshalBinary(got.Data, &finishTime)
types.MsgCdc.MustUnmarshalBinaryLengthPrefixed(got.Data, &finishTime)
ctx = ctx.WithBlockTime(finishTime)
EndBlocker(ctx, keeper)
@ -621,7 +622,7 @@ func TestValidatorQueue(t *testing.T) {
got = handleMsgBeginUnbonding(ctx, msgBeginUnbondingValidator, keeper)
require.True(t, got.IsOK(), "expected no error: %v", got)
var finishTime time.Time
types.MsgCdc.MustUnmarshalBinary(got.Data, &finishTime)
types.MsgCdc.MustUnmarshalBinaryLengthPrefixed(got.Data, &finishTime)
ctx = ctx.WithBlockTime(finishTime)
EndBlocker(ctx, keeper)
origHeader := ctx.BlockHeader()
@ -709,7 +710,7 @@ func TestUnbondingFromUnbondingValidator(t *testing.T) {
// change the ctx to Block Time one second before the validator would have unbonded
var finishTime time.Time
types.MsgCdc.MustUnmarshalBinary(got.Data, &finishTime)
types.MsgCdc.MustUnmarshalBinaryLengthPrefixed(got.Data, &finishTime)
ctx = ctx.WithBlockTime(finishTime.Add(time.Second * -1))
// unbond the delegator from the validator
@ -1013,7 +1014,7 @@ func TestBondUnbondRedelegateSlashTwice(t *testing.T) {
EndBlocker(ctx, keeper)
// validator power should have been reduced to zero
// ergo validator should have been removed from the store
_, found = keeper.GetValidator(ctx, valA)
require.False(t, found)
// validator should be in unbonding state
validator, _ = keeper.GetValidator(ctx, valA)
require.Equal(t, validator.GetStatus(), sdk.Unbonding)
}

View File

@ -163,14 +163,14 @@ func (k Keeper) GetUnbondingQueueTimeSlice(ctx sdk.Context, timestamp time.Time)
if bz == nil {
return []types.DVPair{}
}
k.cdc.MustUnmarshalBinary(bz, &dvPairs)
k.cdc.MustUnmarshalBinaryLengthPrefixed(bz, &dvPairs)
return dvPairs
}
// Sets a specific unbonding queue timeslice.
func (k Keeper) SetUnbondingQueueTimeSlice(ctx sdk.Context, timestamp time.Time, keys []types.DVPair) {
store := ctx.KVStore(k.storeKey)
bz := k.cdc.MustMarshalBinary(keys)
bz := k.cdc.MustMarshalBinaryLengthPrefixed(keys)
store.Set(GetUnbondingDelegationTimeKey(timestamp), bz)
}
@ -199,7 +199,7 @@ func (k Keeper) DequeueAllMatureUnbondingQueue(ctx sdk.Context, currTime time.Ti
unbondingTimesliceIterator := k.UnbondingQueueIterator(ctx, ctx.BlockHeader().Time)
for ; unbondingTimesliceIterator.Valid(); unbondingTimesliceIterator.Next() {
timeslice := []types.DVPair{}
k.cdc.MustUnmarshalBinary(unbondingTimesliceIterator.Value(), &timeslice)
k.cdc.MustUnmarshalBinaryLengthPrefixed(unbondingTimesliceIterator.Value(), &timeslice)
matureUnbonds = append(matureUnbonds, timeslice...)
store.Delete(unbondingTimesliceIterator.Key())
}
@ -300,14 +300,14 @@ func (k Keeper) GetRedelegationQueueTimeSlice(ctx sdk.Context, timestamp time.Ti
if bz == nil {
return []types.DVVTriplet{}
}
k.cdc.MustUnmarshalBinary(bz, &dvvTriplets)
k.cdc.MustUnmarshalBinaryLengthPrefixed(bz, &dvvTriplets)
return dvvTriplets
}
// Sets a specific redelegation queue timeslice.
func (k Keeper) SetRedelegationQueueTimeSlice(ctx sdk.Context, timestamp time.Time, keys []types.DVVTriplet) {
store := ctx.KVStore(k.storeKey)
bz := k.cdc.MustMarshalBinary(keys)
bz := k.cdc.MustMarshalBinaryLengthPrefixed(keys)
store.Set(GetRedelegationTimeKey(timestamp), bz)
}
@ -336,7 +336,7 @@ func (k Keeper) DequeueAllMatureRedelegationQueue(ctx sdk.Context, currTime time
redelegationTimesliceIterator := k.RedelegationQueueIterator(ctx, ctx.BlockHeader().Time)
for ; redelegationTimesliceIterator.Valid(); redelegationTimesliceIterator.Next() {
timeslice := []types.DVVTriplet{}
k.cdc.MustUnmarshalBinary(redelegationTimesliceIterator.Value(), &timeslice)
k.cdc.MustUnmarshalBinaryLengthPrefixed(redelegationTimesliceIterator.Value(), &timeslice)
matureRedelegations = append(matureRedelegations, timeslice...)
store.Delete(redelegationTimesliceIterator.Key())
}
@ -349,6 +349,13 @@ func (k Keeper) DequeueAllMatureRedelegationQueue(ctx sdk.Context, currTime time
func (k Keeper) Delegate(ctx sdk.Context, delAddr sdk.AccAddress, bondAmt sdk.Coin,
validator types.Validator, subtractAccount bool) (newShares sdk.Dec, err sdk.Error) {
// In some situations, the exchange rate becomes invalid, e.g. if
// validator loses all tokens due to slashing. In this case,
// make all future delegations invalid.
if validator.DelegatorShareExRate().IsZero() {
return sdk.ZeroDec(), types.ErrDelegatorShareExRateInvalid(k.Codespace())
}
// Get or create the delegator delegation
delegation, found := k.GetDelegation(ctx, delAddr, validator.OperatorAddr)
if !found {

View File

@ -36,7 +36,7 @@ func NewKeeper(cdc *codec.Codec, key, tkey sdk.StoreKey, ck bank.Keeper, paramst
}
// Set the validator hooks
func (k Keeper) WithHooks(sh sdk.StakingHooks) Keeper {
func (k *Keeper) SetHooks(sh sdk.StakingHooks) *Keeper {
if k.hooks != nil {
panic("cannot set validator hooks twice")
}
@ -60,14 +60,14 @@ func (k Keeper) GetPool(ctx sdk.Context) (pool types.Pool) {
if b == nil {
panic("stored pool should not have been nil")
}
k.cdc.MustUnmarshalBinary(b, &pool)
k.cdc.MustUnmarshalBinaryLengthPrefixed(b, &pool)
return
}
// set the pool
func (k Keeper) SetPool(ctx sdk.Context, pool types.Pool) {
store := ctx.KVStore(k.storeKey)
b := k.cdc.MustMarshalBinary(pool)
b := k.cdc.MustMarshalBinaryLengthPrefixed(pool)
store.Set(PoolKey, b)
}
@ -80,14 +80,14 @@ func (k Keeper) GetLastTotalPower(ctx sdk.Context) (power sdk.Int) {
if b == nil {
return sdk.ZeroInt()
}
k.cdc.MustUnmarshalBinary(b, &power)
k.cdc.MustUnmarshalBinaryLengthPrefixed(b, &power)
return
}
// Set the last total validator power.
func (k Keeper) SetLastTotalPower(ctx sdk.Context, power sdk.Int) {
store := ctx.KVStore(k.storeKey)
b := k.cdc.MustMarshalBinary(power)
b := k.cdc.MustMarshalBinaryLengthPrefixed(power)
store.Set(LastTotalPowerKey, b)
}
@ -101,14 +101,14 @@ func (k Keeper) GetLastValidatorPower(ctx sdk.Context, operator sdk.ValAddress)
if bz == nil {
return sdk.ZeroInt()
}
k.cdc.MustUnmarshalBinary(bz, &power)
k.cdc.MustUnmarshalBinaryLengthPrefixed(bz, &power)
return
}
// Set the last validator power.
func (k Keeper) SetLastValidatorPower(ctx sdk.Context, operator sdk.ValAddress, power sdk.Int) {
store := ctx.KVStore(k.storeKey)
bz := k.cdc.MustMarshalBinary(power)
bz := k.cdc.MustMarshalBinaryLengthPrefixed(power)
store.Set(GetLastValidatorPowerKey(operator), bz)
}
@ -128,13 +128,13 @@ func (k Keeper) GetIntraTxCounter(ctx sdk.Context) int16 {
return 0
}
var counter int16
k.cdc.MustUnmarshalBinary(b, &counter)
k.cdc.MustUnmarshalBinaryLengthPrefixed(b, &counter)
return counter
}
// set the current in-block validator operation counter
func (k Keeper) SetIntraTxCounter(ctx sdk.Context, counter int16) {
store := ctx.KVStore(k.storeKey)
bz := k.cdc.MustMarshalBinary(counter)
bz := k.cdc.MustMarshalBinaryLengthPrefixed(counter)
store.Set(IntraTxCounterKey, bz)
}

View File

@ -28,9 +28,31 @@ func (k Keeper) IterateValidators(ctx sdk.Context, fn func(index int64, validato
}
// iterate through the active validator set and perform the provided function
func (k Keeper) IterateValidatorsBonded(ctx sdk.Context, fn func(index int64, validator sdk.Validator) (stop bool)) {
func (k Keeper) IterateBondedValidatorsByPower(ctx sdk.Context, fn func(index int64, validator sdk.Validator) (stop bool)) {
store := ctx.KVStore(k.storeKey)
iterator := sdk.KVStorePrefixIterator(store, LastValidatorPowerKey)
maxValidators := k.MaxValidators(ctx)
iterator := sdk.KVStoreReversePrefixIterator(store, ValidatorsByPowerIndexKey)
defer iterator.Close()
i := int64(0)
for ; iterator.Valid() && i < int64(maxValidators); iterator.Next() {
address := iterator.Value()
validator := k.mustGetValidator(ctx, address)
if validator.Status == sdk.Bonded {
stop := fn(i, validator) // XXX is this safe will the validator unexposed fields be able to get written to?
if stop {
break
}
i++
}
}
}
// iterate through the active validator set and perform the provided function
func (k Keeper) IterateLastValidators(ctx sdk.Context, fn func(index int64, validator sdk.Validator) (stop bool)) {
iterator := k.LastValidatorsIterator(ctx)
i := int64(0)
for ; iterator.Valid(); iterator.Next() {
address := AddressFromLastValidatorPowerKey(iterator.Key())

View File

@ -108,12 +108,6 @@ func (k Keeper) Slash(ctx sdk.Context, consAddr sdk.ConsAddress, infractionHeigh
pool.LooseTokens = pool.LooseTokens.Sub(tokensToBurn)
k.SetPool(ctx, pool)
// remove validator if it has no more tokens
if validator.DelegatorShares.IsZero() && validator.Status == sdk.Unbonded {
// if not unbonded, we must instead remove validator in EndBlocker once it finishes its unbonding period
k.RemoveValidator(ctx, validator.OperatorAddr)
}
// Log that a slash occurred!
logger.Info(fmt.Sprintf(
"validator %s slashed by slash factor of %s; burned %v tokens",
@ -236,6 +230,7 @@ func (k Keeper) slashRedelegation(ctx sdk.Context, validator types.Validator, re
if sharesToUnbond.GT(delegation.Shares) {
sharesToUnbond = delegation.Shares
}
tokensToBurn, err := k.unbond(ctx, redelegation.DelegatorAddr, redelegation.ValidatorDstAddr, sharesToUnbond)
if err != nil {
panic(fmt.Errorf("error unbonding delegator: %v", err))

View File

@ -348,9 +348,9 @@ func TestSlashWithUnbondingDelegation(t *testing.T) {
keeper.ApplyAndReturnValidatorSetUpdates(ctx)
// read updated validator
// power decreased by 1 again, validator is out of stake
// ergo validator should have been removed from the store
_, found = keeper.GetValidatorByConsAddr(ctx, consAddr)
require.False(t, found)
// validator should be in unbonding period
validator, _ = keeper.GetValidatorByConsAddr(ctx, consAddr)
require.Equal(t, validator.GetStatus(), sdk.Unbonding)
}
// tests Slash at a previous height with a redelegation
@ -450,16 +450,16 @@ func TestSlashWithRedelegation(t *testing.T) {
// apply TM updates
keeper.ApplyAndReturnValidatorSetUpdates(ctx)
// read updated validator
// validator decreased to zero power, should have been removed from the store
_, found = keeper.GetValidatorByConsAddr(ctx, consAddr)
require.False(t, found)
// validator decreased to zero power, should be in unbonding period
validator, _ = keeper.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 no longer in the store
_, found = keeper.GetValidatorByConsAddr(ctx, consAddr)
require.False(t, found)
// validator still in unbonding period
validator, _ = keeper.GetValidatorByConsAddr(ctx, consAddr)
require.Equal(t, validator.GetStatus(), sdk.Unbonding)
keeper.Slash(ctx, consAddr, 10, 10, sdk.OneDec())
// read updating redelegation
@ -472,9 +472,9 @@ func TestSlashWithRedelegation(t *testing.T) {
// no more bonded tokens burned
require.Equal(t, int64(16), oldPool.BondedTokens.Sub(newPool.BondedTokens).RoundInt64())
// read updated validator
// power still zero, still not in the store
_, found = keeper.GetValidatorByConsAddr(ctx, consAddr)
require.False(t, found)
// power still zero, still in unbonding period
validator, _ = keeper.GetValidatorByConsAddr(ctx, consAddr)
require.Equal(t, validator.GetStatus(), sdk.Unbonding)
}
// tests Slash at a previous height with both an unbonding delegation and a redelegation

View File

@ -73,13 +73,13 @@ func (k Keeper) ApplyAndReturnValidatorSetUpdates(ctx sdk.Context) (updates []ab
// calculate the new power bytes
newPower := validator.BondedTokens().RoundInt64()
newPowerBytes := k.cdc.MustMarshalBinary(sdk.NewInt(newPower))
newPowerBytes := k.cdc.MustMarshalBinaryLengthPrefixed(sdk.NewInt(newPower))
// update the validator set if power has changed
if !found || !bytes.Equal(oldPowerBytes, newPowerBytes) {
updates = append(updates, validator.ABCIValidatorUpdate())
// XXX Assert that the validator had updated its ValidatorDistInfo.FeePoolWithdrawalHeight.
// XXX This hook probably shouldn't exist. Maybe rethink the hook system.
// Assert that the validator had updated its ValidatorDistInfo.FeePoolWithdrawalHeight.
// This hook is extremely useful, otherwise lazy accum bugs will be difficult to solve.
if k.hooks != nil {
k.hooks.OnValidatorPowerDidChange(ctx, validator.ConsAddress(), valAddr)
}
@ -108,11 +108,6 @@ func (k Keeper) ApplyAndReturnValidatorSetUpdates(ctx sdk.Context) (updates []ab
// bonded to unbonding
k.bondedToUnbonding(ctx, validator)
// remove validator if it has no more tokens
if validator.Tokens.IsZero() {
k.RemoveValidator(ctx, validator.OperatorAddr)
}
// delete from the bonded validator index
k.DeleteLastValidatorPower(ctx, sdk.ValAddress(valAddrBytes))

View File

@ -155,6 +155,7 @@ func (k Keeper) RemoveValidatorTokensAndShares(ctx sdk.Context, validator types.
// Update the tokens of an existing validator, update the validators power index key
func (k Keeper) RemoveValidatorTokens(ctx sdk.Context, validator types.Validator, tokensToRemove sdk.Dec) types.Validator {
pool := k.GetPool(ctx)
k.DeleteValidatorByPowerIndex(ctx, validator, pool)
validator, pool = validator.RemoveTokens(pool, tokensToRemove)
@ -189,6 +190,9 @@ func (k Keeper) RemoveValidator(ctx sdk.Context, address sdk.ValAddress) {
if !found {
return
}
if validator.Status != sdk.Unbonded {
panic("Cannot call RemoveValidator on bonded or unbonding validators")
}
// delete the old validator record
store := ctx.KVStore(k.storeKey)
@ -261,6 +265,13 @@ func (k Keeper) GetLastValidators(ctx sdk.Context) (validators []types.Validator
return validators[:i] // trim
}
// returns an iterator for the consensus validators in the last block
func (k Keeper) LastValidatorsIterator(ctx sdk.Context) (iterator sdk.Iterator) {
store := ctx.KVStore(k.storeKey)
iterator = sdk.KVStorePrefixIterator(store, LastValidatorPowerKey)
return iterator
}
// get the current group of bonded validators sorted by power-rank
func (k Keeper) GetBondedValidatorsByPower(ctx sdk.Context) []types.Validator {
store := ctx.KVStore(k.storeKey)
@ -283,6 +294,13 @@ func (k Keeper) GetBondedValidatorsByPower(ctx sdk.Context) []types.Validator {
return validators[:i] // trim
}
// returns an iterator for the current validator power store
func (k Keeper) ValidatorsPowerStoreIterator(ctx sdk.Context) (iterator sdk.Iterator) {
store := ctx.KVStore(k.storeKey)
iterator = sdk.KVStoreReversePrefixIterator(store, ValidatorsByPowerIndexKey)
return iterator
}
// gets a specific validator queue timeslice. A timeslice is a slice of ValAddresses corresponding to unbonding validators
// that expire at a certain time.
func (k Keeper) GetValidatorQueueTimeSlice(ctx sdk.Context, timestamp time.Time) (valAddrs []sdk.ValAddress) {
@ -291,14 +309,14 @@ func (k Keeper) GetValidatorQueueTimeSlice(ctx sdk.Context, timestamp time.Time)
if bz == nil {
return []sdk.ValAddress{}
}
k.cdc.MustUnmarshalBinary(bz, &valAddrs)
k.cdc.MustUnmarshalBinaryLengthPrefixed(bz, &valAddrs)
return valAddrs
}
// Sets a specific validator queue timeslice.
func (k Keeper) SetValidatorQueueTimeSlice(ctx sdk.Context, timestamp time.Time, keys []sdk.ValAddress) {
store := ctx.KVStore(k.storeKey)
bz := k.cdc.MustMarshalBinary(keys)
bz := k.cdc.MustMarshalBinaryLengthPrefixed(keys)
store.Set(GetValidatorQueueTimeKey(timestamp), bz)
}
@ -325,7 +343,7 @@ func (k Keeper) GetAllMatureValidatorQueue(ctx sdk.Context, currTime time.Time)
validatorTimesliceIterator := k.ValidatorQueueIterator(ctx, ctx.BlockHeader().Time)
for ; validatorTimesliceIterator.Valid(); validatorTimesliceIterator.Next() {
timeslice := []sdk.ValAddress{}
k.cdc.MustUnmarshalBinary(validatorTimesliceIterator.Value(), &timeslice)
k.cdc.MustUnmarshalBinaryLengthPrefixed(validatorTimesliceIterator.Value(), &timeslice)
matureValsAddrs = append(matureValsAddrs, timeslice...)
}
return matureValsAddrs
@ -337,16 +355,15 @@ func (k Keeper) UnbondAllMatureValidatorQueue(ctx sdk.Context) {
validatorTimesliceIterator := k.ValidatorQueueIterator(ctx, ctx.BlockHeader().Time)
for ; validatorTimesliceIterator.Valid(); validatorTimesliceIterator.Next() {
timeslice := []sdk.ValAddress{}
k.cdc.MustUnmarshalBinary(validatorTimesliceIterator.Value(), &timeslice)
k.cdc.MustUnmarshalBinaryLengthPrefixed(validatorTimesliceIterator.Value(), &timeslice)
for _, valAddr := range timeslice {
val, found := k.GetValidator(ctx, valAddr)
if !found || val.GetStatus() != sdk.Unbonding {
continue
}
k.unbondingToUnbonded(ctx, val)
if val.GetDelegatorShares().IsZero() {
k.RemoveValidator(ctx, val.OperatorAddr)
} else {
k.unbondingToUnbonded(ctx, val)
}
}
store.Delete(validatorTimesliceIterator.Key())

View File

@ -186,9 +186,9 @@ func TestSlashToZeroPowerRemoved(t *testing.T) {
keeper.Slash(ctx, consAddr0, 0, 100, sdk.OneDec())
// apply TM updates
keeper.ApplyAndReturnValidatorSetUpdates(ctx)
// validator should have been deleted
_, found := keeper.GetValidator(ctx, addrVals[0])
require.False(t, found)
// validator should be unbonding
validator, _ = keeper.GetValidator(ctx, addrVals[0])
require.Equal(t, validator.GetStatus(), sdk.Unbonding)
}
// This function tests UpdateValidator, GetValidator, GetLastValidators, RemoveValidator
@ -276,7 +276,9 @@ func TestValidatorBasics(t *testing.T) {
assert.True(ValEq(t, validators[2], resVals[2]))
// remove a record
keeper.RemoveValidator(ctx, validators[1].OperatorAddr)
validators[1].Status = sdk.Unbonded // First must set to Unbonded.
keeper.SetValidator(ctx, validators[1]) // ...
keeper.RemoveValidator(ctx, validators[1].OperatorAddr) // Now it can be removed.
_, found = keeper.GetValidator(ctx, addrVals[1])
require.False(t, found)
}

View File

@ -1,6 +1,7 @@
package simulation
import (
"bytes"
"fmt"
"github.com/cosmos/cosmos-sdk/baseapp"
@ -10,6 +11,7 @@ import (
"github.com/cosmos/cosmos-sdk/x/distribution"
"github.com/cosmos/cosmos-sdk/x/mock/simulation"
"github.com/cosmos/cosmos-sdk/x/stake"
"github.com/cosmos/cosmos-sdk/x/stake/keeper"
abci "github.com/tendermint/tendermint/abci/types"
)
@ -24,10 +26,12 @@ func AllInvariants(ck bank.Keeper, k stake.Keeper,
if err != nil {
return err
}
err = PositivePowerInvariant(k)(app)
if err != nil {
return err
}
err = ValidatorSetInvariant(k)(app)
return err
}
@ -100,19 +104,29 @@ func SupplyInvariants(ck bank.Keeper, k stake.Keeper,
}
}
// PositivePowerInvariant checks that all stored validators have > 0 power
// PositivePowerInvariant checks that all stored validators have > 0 power.
func PositivePowerInvariant(k stake.Keeper) simulation.Invariant {
return func(app *baseapp.BaseApp) error {
ctx := app.NewContext(false, abci.Header{})
var err error
k.IterateValidatorsBonded(ctx, func(_ int64, validator sdk.Validator) bool {
if !validator.GetPower().GT(sdk.ZeroDec()) {
err = fmt.Errorf("validator with non-positive power stored. (pubkey %v)", validator.GetConsPubKey())
return true
iterator := k.ValidatorsPowerStoreIterator(ctx)
pool := k.GetPool(ctx)
for ; iterator.Valid(); iterator.Next() {
validator, found := k.GetValidator(ctx, iterator.Value())
if !found {
panic(fmt.Sprintf("validator record not found for address: %X\n", iterator.Value()))
}
return false
})
return err
powerKey := keeper.GetValidatorsByPowerIndexKey(validator, pool)
if !bytes.Equal(iterator.Key(), powerKey) {
return fmt.Errorf("power store invariance:\n\tvalidator.Power: %v"+
"\n\tkey should be: %v\n\tkey in store: %v", validator.GetPower(), powerKey, iterator.Key())
}
}
iterator.Close()
return nil
}
}

View File

@ -47,7 +47,7 @@ func MustMarshalDelegation(cdc *codec.Codec, delegation Delegation) []byte {
delegation.Shares,
delegation.Height,
}
return cdc.MustMarshalBinary(val)
return cdc.MustMarshalBinaryLengthPrefixed(val)
}
// return the delegation without fields contained within the key for the store
@ -62,7 +62,7 @@ func MustUnmarshalDelegation(cdc *codec.Codec, key, value []byte) Delegation {
// return the delegation without fields contained within the key for the store
func UnmarshalDelegation(cdc *codec.Codec, key, value []byte) (delegation Delegation, err error) {
var storeValue delegationValue
err = cdc.UnmarshalBinary(value, &storeValue)
err = cdc.UnmarshalBinaryLengthPrefixed(value, &storeValue)
if err != nil {
err = fmt.Errorf("%v: %v", ErrNoDelegation(DefaultCodespace).Data(), err)
return
@ -139,7 +139,7 @@ func MustMarshalUBD(cdc *codec.Codec, ubd UnbondingDelegation) []byte {
ubd.InitialBalance,
ubd.Balance,
}
return cdc.MustMarshalBinary(val)
return cdc.MustMarshalBinaryLengthPrefixed(val)
}
// unmarshal a unbonding delegation from a store key and value
@ -154,7 +154,7 @@ func MustUnmarshalUBD(cdc *codec.Codec, key, value []byte) UnbondingDelegation {
// unmarshal a unbonding delegation from a store key and value
func UnmarshalUBD(cdc *codec.Codec, key, value []byte) (ubd UnbondingDelegation, err error) {
var storeValue ubdValue
err = cdc.UnmarshalBinary(value, &storeValue)
err = cdc.UnmarshalBinaryLengthPrefixed(value, &storeValue)
if err != nil {
return
}
@ -179,8 +179,8 @@ func UnmarshalUBD(cdc *codec.Codec, key, value []byte) (ubd UnbondingDelegation,
// nolint
func (d UnbondingDelegation) Equal(d2 UnbondingDelegation) bool {
bz1 := MsgCdc.MustMarshalBinary(&d)
bz2 := MsgCdc.MustMarshalBinary(&d2)
bz1 := MsgCdc.MustMarshalBinaryLengthPrefixed(&d)
bz2 := MsgCdc.MustMarshalBinaryLengthPrefixed(&d2)
return bytes.Equal(bz1, bz2)
}
@ -231,7 +231,7 @@ func MustMarshalRED(cdc *codec.Codec, red Redelegation) []byte {
red.SharesSrc,
red.SharesDst,
}
return cdc.MustMarshalBinary(val)
return cdc.MustMarshalBinaryLengthPrefixed(val)
}
// unmarshal a redelegation from a store key and value
@ -246,7 +246,7 @@ func MustUnmarshalRED(cdc *codec.Codec, key, value []byte) Redelegation {
// unmarshal a redelegation from a store key and value
func UnmarshalRED(cdc *codec.Codec, key, value []byte) (red Redelegation, err error) {
var storeValue redValue
err = cdc.UnmarshalBinary(value, &storeValue)
err = cdc.UnmarshalBinaryLengthPrefixed(value, &storeValue)
if err != nil {
return
}
@ -275,8 +275,8 @@ func UnmarshalRED(cdc *codec.Codec, key, value []byte) (red Redelegation, err er
// nolint
func (d Redelegation) Equal(d2 Redelegation) bool {
bz1 := MsgCdc.MustMarshalBinary(&d)
bz2 := MsgCdc.MustMarshalBinary(&d2)
bz1 := MsgCdc.MustMarshalBinaryLengthPrefixed(&d)
bz2 := MsgCdc.MustMarshalBinaryLengthPrefixed(&d2)
return bytes.Equal(bz1, bz2)
}

View File

@ -173,6 +173,11 @@ func ErrConflictingRedelegation(codespace sdk.CodespaceType) sdk.Error {
"conflicting redelegation from this source validator to this dest validator already exists, you must wait for it to finish")
}
func ErrDelegatorShareExRateInvalid(codespace sdk.CodespaceType) sdk.Error {
return sdk.NewError(codespace, CodeInvalidDelegation,
"cannot delegate to validators with invalid (zero) ex-rate")
}
func ErrBothShareMsgsGiven(codespace sdk.CodespaceType) sdk.Error {
return sdk.NewError(codespace, CodeInvalidInput, "both shares amount and shares percent provided")
}

View File

@ -49,8 +49,8 @@ func (p *Params) KeyValuePairs() params.KeyValuePairs {
// Equal returns a boolean determining if two Param types are identical.
func (p Params) Equal(p2 Params) bool {
bz1 := MsgCdc.MustMarshalBinary(&p)
bz2 := MsgCdc.MustMarshalBinary(&p2)
bz1 := MsgCdc.MustMarshalBinaryLengthPrefixed(&p)
bz2 := MsgCdc.MustMarshalBinaryLengthPrefixed(&p2)
return bytes.Equal(bz1, bz2)
}
@ -85,7 +85,7 @@ func MustUnmarshalParams(cdc *codec.Codec, value []byte) Params {
// unmarshal the current staking params value from store key
func UnmarshalParams(cdc *codec.Codec, value []byte) (params Params, err error) {
err = cdc.UnmarshalBinary(value, &params)
err = cdc.UnmarshalBinaryLengthPrefixed(value, &params)
if err != nil {
return
}

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