Merge branch 'develop' into cwgoes/a-random-walk-down-proof-of-stake

This commit is contained in:
Christopher Goes 2018-07-19 08:49:20 +02:00 committed by GitHub
commit 7e88a50b2a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 109 additions and 45 deletions

View File

@ -10,6 +10,7 @@ FEATURES
* Modules specify invariants and operations, preferably in an x/[module]/simulation package * Modules specify invariants and operations, preferably in an x/[module]/simulation package
* Modules can test random combinations of their own operations * Modules can test random combinations of their own operations
* Applications can integrate operations and invariants from modules together for an integrated simulation * Applications can integrate operations and invariants from modules together for an integrated simulation
* [baseapp] Initialize validator set on ResponseInitChain
* Added support for cosmos-sdk-cli tool under cosmos-sdk/cmd * Added support for cosmos-sdk-cli tool under cosmos-sdk/cmd
* This allows SDK users to init a new project repository with a single command. * This allows SDK users to init a new project repository with a single command.

View File

@ -290,7 +290,7 @@ func (app *BaseApp) InitChain(req abci.RequestInitChain) (res abci.ResponseInitC
if app.initChainer == nil { if app.initChainer == nil {
return return
} }
app.initChainer(app.deliverState.ctx, req) // no error res = app.initChainer(app.deliverState.ctx, req)
// NOTE: we don't commit, but BeginBlock for block 1 // NOTE: we don't commit, but BeginBlock for block 1
// starts from this deliverState // starts from this deliverState

View File

@ -358,25 +358,20 @@ func TestTxs(t *testing.T) {
} }
func TestValidatorsQuery(t *testing.T) { func TestValidatorsQuery(t *testing.T) {
cleanup, pks, port := InitializeTestLCD(t, 2, []sdk.AccAddress{}) cleanup, pks, port := InitializeTestLCD(t, 1, []sdk.AccAddress{})
defer cleanup() defer cleanup()
require.Equal(t, 2, len(pks)) require.Equal(t, 1, len(pks))
validators := getValidators(t, port) validators := getValidators(t, port)
require.Equal(t, len(validators), 2) require.Equal(t, len(validators), 1)
// make sure all the validators were found (order unknown because sorted by owner addr) // make sure all the validators were found (order unknown because sorted by owner addr)
foundVal1, foundVal2 := false, false foundVal := false
pk1Bech := sdk.MustBech32ifyValPub(pks[0]) pkBech := sdk.MustBech32ifyValPub(pks[0])
pk2Bech := sdk.MustBech32ifyValPub(pks[1]) if validators[0].PubKey == pkBech {
if validators[0].PubKey == pk1Bech || validators[1].PubKey == pk1Bech { foundVal = true
foundVal1 = true
} }
if validators[0].PubKey == pk2Bech || validators[1].PubKey == pk2Bech { require.True(t, foundVal, "pkBech %v, owner %v", pkBech, validators[0].Owner)
foundVal2 = true
}
require.True(t, foundVal1, "pk1Bech %v, owner1 %v, owner2 %v", pk1Bech, validators[0].Owner, validators[1].Owner)
require.True(t, foundVal2, "pk2Bech %v, owner1 %v, owner2 %v", pk2Bech, validators[0].Owner, validators[1].Owner)
} }
func TestBonding(t *testing.T) { func TestBonding(t *testing.T) {

View File

@ -173,7 +173,7 @@ func (app *GaiaApp) initChainer(ctx sdk.Context, req abci.RequestInitChain) abci
} }
// load the initial stake information // load the initial stake information
err = stake.InitGenesis(ctx, app.stakeKeeper, genesisState.StakeData) validators, err := stake.InitGenesis(ctx, app.stakeKeeper, genesisState.StakeData)
if err != nil { if err != nil {
panic(err) // TODO https://github.com/cosmos/cosmos-sdk/issues/468 panic(err) // TODO https://github.com/cosmos/cosmos-sdk/issues/468
// return sdk.ErrGenesisParse("").TraceCause(err, "") // return sdk.ErrGenesisParse("").TraceCause(err, "")
@ -181,7 +181,9 @@ func (app *GaiaApp) initChainer(ctx sdk.Context, req abci.RequestInitChain) abci
gov.InitGenesis(ctx, app.govKeeper, gov.DefaultGenesisState()) gov.InitGenesis(ctx, app.govKeeper, gov.DefaultGenesisState())
return abci.ResponseInitChain{} return abci.ResponseInitChain{
Validators: validators,
}
} }
// export the state of gaia for a genesis file // export the state of gaia for a genesis file

View File

@ -249,10 +249,12 @@ func (app *GaiaApp) initChainer(ctx sdk.Context, req abci.RequestInitChain) abci
} }
// load the initial stake information // load the initial stake information
err = stake.InitGenesis(ctx, app.stakeKeeper, genesisState.StakeData) validators, err := stake.InitGenesis(ctx, app.stakeKeeper, genesisState.StakeData)
if err != nil { if err != nil {
panic(err) // TODO https://github.com/cosmos/cosmos-sdk/issues/468 // return sdk.ErrGenesisParse("").TraceCause(err, "") panic(err) // TODO https://github.com/cosmos/cosmos-sdk/issues/468 // return sdk.ErrGenesisParse("").TraceCause(err, "")
} }
return abci.ResponseInitChain{} return abci.ResponseInitChain{
Validators: validators,
}
} }

View File

@ -48,10 +48,9 @@ var (
// genesis piece structure for creating combined genesis // genesis piece structure for creating combined genesis
type GenesisTx struct { type GenesisTx struct {
NodeID string `json:"node_id"` NodeID string `json:"node_id"`
IP string `json:"ip"` IP string `json:"ip"`
Validator tmtypes.GenesisValidator `json:"validator"` AppGenTx json.RawMessage `json:"app_gen_tx"`
AppGenTx json.RawMessage `json:"app_gen_tx"`
} }
// Storage for init command input parameters // Storage for init command input parameters
@ -121,16 +120,15 @@ func gentxWithConfig(cdc *wire.Codec, appInit AppInit, config *cfg.Config, genTx
nodeID := string(nodeKey.ID()) nodeID := string(nodeKey.ID())
pubKey := readOrCreatePrivValidator(config) pubKey := readOrCreatePrivValidator(config)
appGenTx, cliPrint, validator, err := appInit.AppGenTx(cdc, pubKey, genTxConfig) appGenTx, cliPrint, _, err := appInit.AppGenTx(cdc, pubKey, genTxConfig)
if err != nil { if err != nil {
return return
} }
tx := GenesisTx{ tx := GenesisTx{
NodeID: nodeID, NodeID: nodeID,
IP: genTxConfig.IP, IP: genTxConfig.IP,
Validator: validator, AppGenTx: appGenTx,
AppGenTx: appGenTx,
} }
bz, err := wire.MarshalJSONIndent(cdc, tx) bz, err := wire.MarshalJSONIndent(cdc, tx)
if err != nil { if err != nil {
@ -312,7 +310,6 @@ func processGenTxs(genTxsDir string, cdc *wire.Codec) (
genTx := genTxs[nodeID] genTx := genTxs[nodeID]
// combine some stuff // combine some stuff
validators = append(validators, genTx.Validator)
appGenTxs = append(appGenTxs, genTx.AppGenTx) appGenTxs = append(appGenTxs, genTx.AppGenTx)
// Add a persistent peer // Add a persistent peer

View File

@ -61,12 +61,14 @@ func getInitChainer(mapp *mock.App, keeper Keeper, stakeKeeper stake.Keeper) sdk
stakeGenesis := stake.DefaultGenesisState() stakeGenesis := stake.DefaultGenesisState()
stakeGenesis.Pool.LooseTokens = sdk.NewRat(100000) stakeGenesis.Pool.LooseTokens = sdk.NewRat(100000)
err := stake.InitGenesis(ctx, stakeKeeper, stakeGenesis) validators, err := stake.InitGenesis(ctx, stakeKeeper, stakeGenesis)
if err != nil { if err != nil {
panic(err) panic(err)
} }
InitGenesis(ctx, keeper, DefaultGenesisState()) InitGenesis(ctx, keeper, DefaultGenesisState())
return abci.ResponseInitChain{} return abci.ResponseInitChain{
Validators: validators,
}
} }
} }

View File

@ -59,11 +59,14 @@ func getInitChainer(mapp *mock.App, keeper stake.Keeper) sdk.InitChainer {
mapp.InitChainer(ctx, req) mapp.InitChainer(ctx, req)
stakeGenesis := stake.DefaultGenesisState() stakeGenesis := stake.DefaultGenesisState()
stakeGenesis.Pool.LooseTokens = sdk.NewRat(100000) stakeGenesis.Pool.LooseTokens = sdk.NewRat(100000)
err := stake.InitGenesis(ctx, keeper, stakeGenesis) validators, err := stake.InitGenesis(ctx, keeper, stakeGenesis)
if err != nil { if err != nil {
panic(err) panic(err)
} }
return abci.ResponseInitChain{}
return abci.ResponseInitChain{
Validators: validators,
}
} }
} }

View File

@ -70,7 +70,7 @@ func createTestInput(t *testing.T) (sdk.Context, bank.Keeper, stake.Keeper, para
genesis.Pool.LooseTokens = sdk.NewRat(initCoins.MulRaw(int64(len(addrs))).Int64()) genesis.Pool.LooseTokens = sdk.NewRat(initCoins.MulRaw(int64(len(addrs))).Int64())
err = stake.InitGenesis(ctx, sk, genesis) _, err = stake.InitGenesis(ctx, sk, genesis)
require.Nil(t, err) require.Nil(t, err)
for _, addr := range addrs { for _, addr := range addrs {

View File

@ -65,12 +65,14 @@ func getInitChainer(mapp *mock.App, keeper Keeper) sdk.InitChainer {
stakeGenesis := DefaultGenesisState() stakeGenesis := DefaultGenesisState()
stakeGenesis.Pool.LooseTokens = sdk.NewRat(100000) stakeGenesis.Pool.LooseTokens = sdk.NewRat(100000)
err := InitGenesis(ctx, keeper, stakeGenesis) validators, err := InitGenesis(ctx, keeper, stakeGenesis)
if err != nil { if err != nil {
panic(err) panic(err)
} }
return abci.ResponseInitChain{} return abci.ResponseInitChain{
Validators: validators,
}
} }
} }

View File

@ -1,10 +1,12 @@
package stake package stake
import ( import (
abci "github.com/tendermint/tendermint/abci/types"
tmtypes "github.com/tendermint/tendermint/types"
sdk "github.com/cosmos/cosmos-sdk/types" sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/stake/types" "github.com/cosmos/cosmos-sdk/x/stake/types"
"github.com/pkg/errors" "github.com/pkg/errors"
tmtypes "github.com/tendermint/tendermint/types"
) )
// InitGenesis sets the pool and parameters for the provided keeper and // InitGenesis sets the pool and parameters for the provided keeper and
@ -12,7 +14,8 @@ import (
// validator in the keeper along with manually setting the indexes. In // validator in the keeper along with manually setting the indexes. In
// addition, it also sets any delegations found in data. Finally, it updates // addition, it also sets any delegations found in data. Finally, it updates
// the bonded validators. // the bonded validators.
func InitGenesis(ctx sdk.Context, keeper Keeper, data types.GenesisState) error { // Returns final validator set after applying all declaration and delegations
func InitGenesis(ctx sdk.Context, keeper Keeper, data types.GenesisState) (res []abci.Validator, err error) {
keeper.SetPool(ctx, data.Pool) keeper.SetPool(ctx, data.Pool)
keeper.SetNewParams(ctx, data.Params) keeper.SetNewParams(ctx, data.Params)
keeper.InitIntraTxCounter(ctx) keeper.InitIntraTxCounter(ctx)
@ -21,10 +24,10 @@ func InitGenesis(ctx sdk.Context, keeper Keeper, data types.GenesisState) error
keeper.SetValidator(ctx, validator) keeper.SetValidator(ctx, validator)
if validator.Tokens.IsZero() { if validator.Tokens.IsZero() {
return errors.Errorf("genesis validator cannot have zero pool shares, validator: %v", validator) return res, errors.Errorf("genesis validator cannot have zero pool shares, validator: %v", validator)
} }
if validator.DelegatorShares.IsZero() { if validator.DelegatorShares.IsZero() {
return errors.Errorf("genesis validator cannot have zero delegator shares, validator: %v", validator) return res, errors.Errorf("genesis validator cannot have zero delegator shares, validator: %v", validator)
} }
// Manually set indexes for the first time // Manually set indexes for the first time
@ -43,7 +46,13 @@ func InitGenesis(ctx sdk.Context, keeper Keeper, data types.GenesisState) error
} }
keeper.UpdateBondedValidatorsFull(ctx) keeper.UpdateBondedValidatorsFull(ctx)
return nil
vals := keeper.GetValidatorsBonded(ctx)
res = make([]abci.Validator, len(vals))
for i, val := range vals {
res[i] = sdk.ABCIValidator(val)
}
return
} }
// WriteGenesis returns a GenesisState for a given context and keeper. The // WriteGenesis returns a GenesisState for a given context and keeper. The

View File

@ -1,10 +1,13 @@
package stake package stake
import ( import (
"fmt"
"testing" "testing"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
abci "github.com/tendermint/tendermint/abci/types"
sdk "github.com/cosmos/cosmos-sdk/types" sdk "github.com/cosmos/cosmos-sdk/types"
keep "github.com/cosmos/cosmos-sdk/x/stake/keeper" keep "github.com/cosmos/cosmos-sdk/x/stake/keeper"
"github.com/cosmos/cosmos-sdk/x/stake/types" "github.com/cosmos/cosmos-sdk/x/stake/types"
@ -14,7 +17,7 @@ func TestInitGenesis(t *testing.T) {
ctx, _, keeper := keep.CreateTestInput(t, false, 1000) ctx, _, keeper := keep.CreateTestInput(t, false, 1000)
pool := keeper.GetPool(ctx) pool := keeper.GetPool(ctx)
pool.LooseTokens = sdk.NewRat(2) pool.BondedTokens = sdk.NewRat(2)
params := keeper.GetParams(ctx) params := keeper.GetParams(ctx)
var delegations []Delegation var delegations []Delegation
@ -24,17 +27,19 @@ func TestInitGenesis(t *testing.T) {
NewValidator(keep.Addrs[1], keep.PKs[1], Description{Moniker: "bloop"}), NewValidator(keep.Addrs[1], keep.PKs[1], Description{Moniker: "bloop"}),
} }
genesisState := types.NewGenesisState(pool, params, validators, delegations) genesisState := types.NewGenesisState(pool, params, validators, delegations)
err := InitGenesis(ctx, keeper, genesisState) _, err := InitGenesis(ctx, keeper, genesisState)
require.Error(t, err) require.Error(t, err)
// initialize the validators // initialize the validators
validators[0].Status = sdk.Bonded
validators[0].Tokens = sdk.OneRat() validators[0].Tokens = sdk.OneRat()
validators[0].DelegatorShares = sdk.OneRat() validators[0].DelegatorShares = sdk.OneRat()
validators[1].Status = sdk.Bonded
validators[1].Tokens = sdk.OneRat() validators[1].Tokens = sdk.OneRat()
validators[1].DelegatorShares = sdk.OneRat() validators[1].DelegatorShares = sdk.OneRat()
genesisState = types.NewGenesisState(pool, params, validators, delegations) genesisState = types.NewGenesisState(pool, params, validators, delegations)
err = InitGenesis(ctx, keeper, genesisState) vals, err := InitGenesis(ctx, keeper, genesisState)
require.NoError(t, err) require.NoError(t, err)
// now make sure the validators are bonded // now make sure the validators are bonded
@ -45,4 +50,50 @@ func TestInitGenesis(t *testing.T) {
resVal, found = keeper.GetValidator(ctx, keep.Addrs[1]) resVal, found = keeper.GetValidator(ctx, keep.Addrs[1])
require.True(t, found) require.True(t, found)
require.Equal(t, sdk.Bonded, resVal.Status) require.Equal(t, sdk.Bonded, resVal.Status)
abcivals := make([]abci.Validator, len(vals))
for i, val := range validators {
abcivals[i] = sdk.ABCIValidator(val)
}
require.Equal(t, abcivals, vals)
}
func TestInitGenesisLargeValidatorSet(t *testing.T) {
size := 200
require.True(t, size > 100)
ctx, _, keeper := keep.CreateTestInput(t, false, 1000)
// Assigning 2 to the first 100 vals, 1 to the rest
pool := keeper.GetPool(ctx)
pool.BondedTokens = sdk.NewRat(int64(200 + (size - 100)))
params := keeper.GetParams(ctx)
delegations := []Delegation{}
validators := make([]Validator, size)
for i := range validators {
validators[i] = NewValidator(keep.Addrs[i], keep.PKs[i], Description{Moniker: fmt.Sprintf("#%d", i)})
validators[i].Status = sdk.Bonded
if i < 100 {
validators[i].Tokens = sdk.NewRat(2)
validators[i].DelegatorShares = sdk.NewRat(2)
} else {
validators[i].Tokens = sdk.OneRat()
validators[i].DelegatorShares = sdk.OneRat()
}
}
genesisState := types.NewGenesisState(pool, params, validators, delegations)
vals, err := InitGenesis(ctx, keeper, genesisState)
require.NoError(t, err)
abcivals := make([]abci.Validator, 100)
for i, val := range validators[:100] {
abcivals[i] = sdk.ABCIValidator(val)
}
require.Equal(t, abcivals, vals)
} }

View File

@ -23,8 +23,8 @@ import (
// dummy addresses used for testing // dummy addresses used for testing
var ( var (
Addrs = createTestAddrs(100) Addrs = createTestAddrs(500)
PKs = createTestPubKeys(100) PKs = createTestPubKeys(500)
emptyAddr sdk.AccAddress emptyAddr sdk.AccAddress
emptyPubkey crypto.PubKey emptyPubkey crypto.PubKey