Merge PR #2275: genesis: Ensure there are no duplicate accounts in genesis file
This also contains a light refactor of genesis state parsing, so that the tests file didn't duplicate a lot of this code.
This commit is contained in:
parent
4448d175ad
commit
1a700206b8
|
@ -95,6 +95,7 @@ IMPROVEMENTS
|
||||||
* [x/auth] Signature verification's gas cost now accounts for pubkey type. [#2046](https://github.com/tendermint/tendermint/pull/2046)
|
* [x/auth] Signature verification's gas cost now accounts for pubkey type. [#2046](https://github.com/tendermint/tendermint/pull/2046)
|
||||||
* [x/stake] [x/slashing] Ensure delegation invariants to jailed validators [#1883](https://github.com/cosmos/cosmos-sdk/issues/1883).
|
* [x/stake] [x/slashing] Ensure delegation invariants to jailed validators [#1883](https://github.com/cosmos/cosmos-sdk/issues/1883).
|
||||||
* [x/stake] Improve speed of GetValidator, which was shown to be a performance bottleneck. [#2046](https://github.com/tendermint/tendermint/pull/2200)
|
* [x/stake] Improve speed of GetValidator, which was shown to be a performance bottleneck. [#2046](https://github.com/tendermint/tendermint/pull/2200)
|
||||||
|
* [genesis] \#2229 Ensure that there are no duplicate accounts in the genesis state.
|
||||||
* SDK
|
* SDK
|
||||||
* [tools] Make get_vendor_deps deletes `.vendor-new` directories, in case scratch files are present.
|
* [tools] Make get_vendor_deps deletes `.vendor-new` directories, in case scratch files are present.
|
||||||
* [spec] Added simple piggy bank distribution spec
|
* [spec] Added simple piggy bank distribution spec
|
||||||
|
|
|
@ -190,6 +190,11 @@ func (app *GaiaApp) initChainer(ctx sdk.Context, req abci.RequestInitChain) abci
|
||||||
slashing.InitGenesis(ctx, app.slashingKeeper, genesisState.StakeData)
|
slashing.InitGenesis(ctx, app.slashingKeeper, genesisState.StakeData)
|
||||||
|
|
||||||
gov.InitGenesis(ctx, app.govKeeper, genesisState.GovData)
|
gov.InitGenesis(ctx, app.govKeeper, genesisState.GovData)
|
||||||
|
err = GaiaValidateGenesisState(genesisState)
|
||||||
|
if err != nil {
|
||||||
|
// TODO find a way to do this w/o panics
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
return abci.ResponseInitChain{
|
return abci.ResponseInitChain{
|
||||||
Validators: validators,
|
Validators: validators,
|
||||||
|
|
|
@ -180,17 +180,25 @@ func GaiaAppGenState(cdc *wire.Codec, appGenTxs []json.RawMessage) (genesisState
|
||||||
}
|
}
|
||||||
|
|
||||||
// create the genesis account, give'm few steaks and a buncha token with there name
|
// create the genesis account, give'm few steaks and a buncha token with there name
|
||||||
accAuth := auth.NewBaseAccountWithAddress(genTx.Address)
|
genaccs[i] = genesisAccountFromGenTx(genTx)
|
||||||
accAuth.Coins = sdk.Coins{
|
|
||||||
{genTx.Name + "Token", sdk.NewInt(1000)},
|
|
||||||
{"steak", freeFermionsAcc},
|
|
||||||
}
|
|
||||||
acc := NewGenesisAccount(&accAuth)
|
|
||||||
genaccs[i] = acc
|
|
||||||
stakeData.Pool.LooseTokens = stakeData.Pool.LooseTokens.Add(sdk.NewDecFromInt(freeFermionsAcc)) // increase the supply
|
stakeData.Pool.LooseTokens = stakeData.Pool.LooseTokens.Add(sdk.NewDecFromInt(freeFermionsAcc)) // increase the supply
|
||||||
|
|
||||||
// add the validator
|
// add the validator
|
||||||
if len(genTx.Name) > 0 {
|
if len(genTx.Name) > 0 {
|
||||||
|
stakeData = addValidatorToStakeData(genTx, stakeData)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// create the final app state
|
||||||
|
genesisState = GenesisState{
|
||||||
|
Accounts: genaccs,
|
||||||
|
StakeData: stakeData,
|
||||||
|
GovData: gov.DefaultGenesisState(),
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func addValidatorToStakeData(genTx GaiaGenTx, stakeData stake.GenesisState) stake.GenesisState {
|
||||||
desc := stake.NewDescription(genTx.Name, "", "", "")
|
desc := stake.NewDescription(genTx.Name, "", "", "")
|
||||||
validator := stake.NewValidator(
|
validator := stake.NewValidator(
|
||||||
sdk.ValAddress(genTx.Address), sdk.MustGetConsPubKeyBech32(genTx.PubKey), desc,
|
sdk.ValAddress(genTx.Address), sdk.MustGetConsPubKeyBech32(genTx.PubKey), desc,
|
||||||
|
@ -212,14 +220,40 @@ func GaiaAppGenState(cdc *wire.Codec, appGenTxs []json.RawMessage) (genesisState
|
||||||
}
|
}
|
||||||
|
|
||||||
stakeData.Bonds = append(stakeData.Bonds, delegation)
|
stakeData.Bonds = append(stakeData.Bonds, delegation)
|
||||||
}
|
return stakeData
|
||||||
}
|
}
|
||||||
|
|
||||||
// create the final app state
|
func genesisAccountFromGenTx(genTx GaiaGenTx) GenesisAccount {
|
||||||
genesisState = GenesisState{
|
accAuth := auth.NewBaseAccountWithAddress(genTx.Address)
|
||||||
Accounts: genaccs,
|
accAuth.Coins = sdk.Coins{
|
||||||
StakeData: stakeData,
|
{genTx.Name + "Token", sdk.NewInt(1000)},
|
||||||
GovData: gov.DefaultGenesisState(),
|
{"steak", freeFermionsAcc},
|
||||||
|
}
|
||||||
|
return NewGenesisAccount(&accAuth)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GaiaValidateGenesisState ensures that the genesis state obeys the expected invariants
|
||||||
|
// TODO: No validators are both bonded and revoked (#2088)
|
||||||
|
// TODO: Error if there is a duplicate validator (#1708)
|
||||||
|
// TODO: Ensure all state machine parameters are in genesis (#1704)
|
||||||
|
func GaiaValidateGenesisState(genesisState GenesisState) (err error) {
|
||||||
|
err = validateGenesisStateAccounts(genesisState.Accounts)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensures that there are no duplicate accounts in the genesis state,
|
||||||
|
func validateGenesisStateAccounts(accs []GenesisAccount) (err error) {
|
||||||
|
addrMap := make(map[string]bool, len(accs))
|
||||||
|
for i := 0; i < len(accs); i++ {
|
||||||
|
acc := accs[i]
|
||||||
|
strAddr := string(acc.Address)
|
||||||
|
if _, ok := addrMap[strAddr]; ok {
|
||||||
|
return fmt.Errorf("Duplicate account in genesis state: Address %v", acc.Address)
|
||||||
|
}
|
||||||
|
addrMap[strAddr] = true
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,10 +5,36 @@ import (
|
||||||
|
|
||||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
"github.com/cosmos/cosmos-sdk/x/auth"
|
"github.com/cosmos/cosmos-sdk/x/auth"
|
||||||
|
"github.com/cosmos/cosmos-sdk/x/gov"
|
||||||
|
stake "github.com/cosmos/cosmos-sdk/x/stake"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
"github.com/tendermint/tendermint/crypto/ed25519"
|
"github.com/tendermint/tendermint/crypto/ed25519"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func makeGenesisState(genTxs []GaiaGenTx) GenesisState {
|
||||||
|
// start with the default staking genesis state
|
||||||
|
stakeData := stake.DefaultGenesisState()
|
||||||
|
|
||||||
|
// get genesis flag account information
|
||||||
|
genaccs := make([]GenesisAccount, len(genTxs))
|
||||||
|
for i, genTx := range genTxs {
|
||||||
|
genaccs[i] = genesisAccountFromGenTx(genTx)
|
||||||
|
stakeData.Pool.LooseTokens = stakeData.Pool.LooseTokens.Add(sdk.NewDecFromInt(freeFermionsAcc)) // increase the supply
|
||||||
|
|
||||||
|
// add the validator
|
||||||
|
if len(genTx.Name) > 0 {
|
||||||
|
stakeData = addValidatorToStakeData(genTx, stakeData)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// create the final app state
|
||||||
|
return GenesisState{
|
||||||
|
Accounts: genaccs,
|
||||||
|
StakeData: stakeData,
|
||||||
|
GovData: gov.DefaultGenesisState(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestToAccount(t *testing.T) {
|
func TestToAccount(t *testing.T) {
|
||||||
priv := ed25519.GenPrivKey()
|
priv := ed25519.GenPrivKey()
|
||||||
addr := sdk.AccAddress(priv.PubKey().Address())
|
addr := sdk.AccAddress(priv.PubKey().Address())
|
||||||
|
@ -34,3 +60,16 @@ func TestGaiaAppGenState(t *testing.T) {
|
||||||
// TODO test with both one and two genesis transactions:
|
// TODO test with both one and two genesis transactions:
|
||||||
// TODO correct: genesis account created, canididates created, pool token variance
|
// TODO correct: genesis account created, canididates created, pool token variance
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestGaiaGenesisValidation(t *testing.T) {
|
||||||
|
genTxs := make([]GaiaGenTx, 2)
|
||||||
|
privKey := ed25519.GenPrivKey()
|
||||||
|
pubKey := privKey.PubKey()
|
||||||
|
addr := pubKey.Address()
|
||||||
|
// Test duplicate accounts fails
|
||||||
|
genTxs[0] = GaiaGenTx{"", sdk.AccAddress(addr), ""}
|
||||||
|
genTxs[1] = GaiaGenTx{"", sdk.AccAddress(addr), ""}
|
||||||
|
genesisState := makeGenesisState(genTxs)
|
||||||
|
err := GaiaValidateGenesisState(genesisState)
|
||||||
|
require.NotNil(t, err)
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue