Merge branch 'develop' into sunny/get_all_delegations_validator_querier
This commit is contained in:
commit
dfddac394d
|
@ -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
|
||||
|
|
|
@ -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",
|
||||
|
|
28
Gopkg.toml
28
Gopkg.toml
|
@ -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"
|
||||
|
|
20
PENDING.md
20
PENDING.md
|
@ -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,12 +43,16 @@ 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
|
||||
- \#2027 [x/stake] Add `Querier` for getting all delegations to a specific validator.
|
||||
- \#2027 [x/stake] Add `Querier` for getting all delegations to a specific validator.
|
||||
- \#2610 [x/stake] Block redelegation to and from the same validator
|
||||
- \#2652 [x/auth] Add benchmark for get and set account
|
||||
|
||||
* Tendermint
|
||||
|
||||
|
@ -59,9 +64,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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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())
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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))
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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))
|
||||
|
@ -548,7 +550,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)
|
||||
|
@ -598,12 +600,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
|
||||
}
|
||||
|
@ -622,6 +639,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
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
|
@ -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() {
|
||||
|
|
|
@ -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())
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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())
|
||||
}
|
||||
|
|
|
@ -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())
|
||||
}
|
||||
|
|
|
@ -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")
|
||||
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
||||
|
|
|
@ -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...)
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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[@]}"
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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?
|
||||
|
|
|
@ -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 {}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
||||
|
|
|
@ -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())
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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())
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
||||
|
|
|
@ -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())
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
||||
|
|
|
@ -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},
|
||||
})
|
||||
)
|
|
@ -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,
|
||||
}
|
||||
}
|
|
@ -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")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
||||
|
|
|
@ -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{
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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(),
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -178,14 +178,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)
|
||||
}
|
||||
|
||||
|
@ -214,7 +214,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(), ×lice)
|
||||
k.cdc.MustUnmarshalBinaryLengthPrefixed(unbondingTimesliceIterator.Value(), ×lice)
|
||||
matureUnbonds = append(matureUnbonds, timeslice...)
|
||||
store.Delete(unbondingTimesliceIterator.Key())
|
||||
}
|
||||
|
@ -315,14 +315,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)
|
||||
}
|
||||
|
||||
|
@ -351,7 +351,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(), ×lice)
|
||||
k.cdc.MustUnmarshalBinaryLengthPrefixed(redelegationTimesliceIterator.Value(), ×lice)
|
||||
matureRedelegations = append(matureRedelegations, timeslice...)
|
||||
store.Delete(redelegationTimesliceIterator.Key())
|
||||
}
|
||||
|
@ -364,6 +364,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 {
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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())
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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))
|
||||
|
||||
|
|
|
@ -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(), ×lice)
|
||||
k.cdc.MustUnmarshalBinaryLengthPrefixed(validatorTimesliceIterator.Value(), ×lice)
|
||||
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(), ×lice)
|
||||
k.cdc.MustUnmarshalBinaryLengthPrefixed(validatorTimesliceIterator.Value(), ×lice)
|
||||
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())
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
||||
|
|
|
@ -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")
|
||||
}
|
||||
|
|
|
@ -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, ¶ms)
|
||||
err = cdc.UnmarshalBinaryLengthPrefixed(value, ¶ms)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue