diff --git a/CHANGELOG_PENDING.md b/CHANGELOG_PENDING.md index 2d77ed90..ad745fb8 100644 --- a/CHANGELOG_PENDING.md +++ b/CHANGELOG_PENDING.md @@ -20,5 +20,6 @@ FEATURES: * \#2310 Mempool is now aware of the MaxGas requirement IMPROVEMENTS: +- [types] add Address to GenesisValidator [\#1714](https://github.com/tendermint/tendermint/issues/1714) BUG FIXES: diff --git a/cmd/tendermint/commands/init.go b/cmd/tendermint/commands/init.go index dac4cd9a..5136ded3 100644 --- a/cmd/tendermint/commands/init.go +++ b/cmd/tendermint/commands/init.go @@ -58,6 +58,7 @@ func initFilesWithConfig(config *cfg.Config) error { ConsensusParams: types.DefaultConsensusParams(), } genDoc.Validators = []types.GenesisValidator{{ + Address: pv.GetPubKey().Address(), PubKey: pv.GetPubKey(), Power: 10, }} diff --git a/cmd/tendermint/commands/testnet.go b/cmd/tendermint/commands/testnet.go index d29c29eb..19f137e4 100644 --- a/cmd/tendermint/commands/testnet.go +++ b/cmd/tendermint/commands/testnet.go @@ -91,6 +91,7 @@ func testnetFiles(cmd *cobra.Command, args []string) error { pvFile := filepath.Join(nodeDir, config.BaseConfig.PrivValidator) pv := privval.LoadFilePV(pvFile) genVals[i] = types.GenesisValidator{ + Address: pv.GetPubKey().Address(), PubKey: pv.GetPubKey(), Power: 1, Name: nodeDirName, diff --git a/state/execution_test.go b/state/execution_test.go index 6a200849..02beeb9b 100644 --- a/state/execution_test.go +++ b/state/execution_test.go @@ -307,7 +307,10 @@ func state(nVals, height int) (State, dbm.DB) { secret := []byte(fmt.Sprintf("test%d", i)) pk := ed25519.GenPrivKeyFromSecret(secret) vals[i] = types.GenesisValidator{ - pk.PubKey(), 1000, fmt.Sprintf("test%d", i), + pk.PubKey().Address(), + pk.PubKey(), + 1000, + fmt.Sprintf("test%d", i), } } s, _ := MakeGenesisState(&types.GenesisDoc{ diff --git a/types/genesis.go b/types/genesis.go index 4cf3b730..8684eb33 100644 --- a/types/genesis.go +++ b/types/genesis.go @@ -1,6 +1,7 @@ package types import ( + "bytes" "encoding/json" "fmt" "io/ioutil" @@ -21,9 +22,10 @@ const ( // GenesisValidator is an initial validator. type GenesisValidator struct { - PubKey crypto.PubKey `json:"pub_key"` - Power int64 `json:"power"` - Name string `json:"name"` + Address Address `json:"address"` + PubKey crypto.PubKey `json:"pub_key"` + Power int64 `json:"power"` + Name string `json:"name"` } // GenesisDoc defines the initial conditions for a tendermint blockchain, in particular its validator set. @@ -62,7 +64,7 @@ func (genDoc *GenesisDoc) ValidateAndComplete() error { return cmn.NewError("Genesis doc must include non-empty chain_id") } if len(genDoc.ChainID) > MaxChainIDLen { - return cmn.NewError(fmt.Sprintf("chain_id in genesis doc is too long (max: %d)", MaxChainIDLen)) + return cmn.NewError("chain_id in genesis doc is too long (max: %d)", MaxChainIDLen) } if genDoc.ConsensusParams == nil { @@ -73,10 +75,16 @@ func (genDoc *GenesisDoc) ValidateAndComplete() error { } } - for _, v := range genDoc.Validators { + for i, v := range genDoc.Validators { if v.Power == 0 { return cmn.NewError("The genesis file cannot contain validators with no voting power: %v", v) } + if len(v.Address) > 0 && !bytes.Equal(v.PubKey.Address(), v.Address) { + return cmn.NewError("Incorrect address for validator %v in the genesis file, should be %v", v, v.PubKey.Address()) + } + if len(v.Address) == 0 { + genDoc.Validators[i].Address = v.PubKey.Address() + } } if genDoc.GenesisTime.IsZero() { diff --git a/types/genesis_test.go b/types/genesis_test.go index c0cfcdea..a0686ce0 100644 --- a/types/genesis_test.go +++ b/types/genesis_test.go @@ -22,6 +22,10 @@ func TestGenesisBad(t *testing.T) { []byte(`{"validators":[{"pub_key":{"value":"AT/+aaL1eB0477Mud9JMm8Sh8BIvOYlPGC9KkIUmFaE="},"power":"10","name":""}]}`), // missing chain_id []byte(`{"validators":[{"pub_key":{"type":"tendermint/PubKeyEd25519","value":"AT/+aaL1eB0477Mud9JMm8Sh8BIvOYlPGC9KkIUmFaE="},"power":"10","name":""}]}`), + // too big chain_id + []byte(`{"chain_id": "Lorem ipsum dolor sit amet, consectetuer adipiscing", "validators": [{"pub_key":{"type":"tendermint/PubKeyEd25519","value":"AT/+aaL1eB0477Mud9JMm8Sh8BIvOYlPGC9KkIUmFaE="},"power":"10","name":""}]}`), + // wrong address + []byte(`{"chain_id":"mychain", "validators":[{"address": "A", "pub_key":{"type":"tendermint/PubKeyEd25519","value":"AT/+aaL1eB0477Mud9JMm8Sh8BIvOYlPGC9KkIUmFaE="},"power":"10","name":""}]}`), } for _, testCase := range testCases { @@ -36,10 +40,11 @@ func TestGenesisGood(t *testing.T) { _, err := GenesisDocFromJSON(genDocBytes) assert.NoError(t, err, "expected no error for good genDoc json") + pubkey := ed25519.GenPrivKey().PubKey() // create a base gendoc from struct baseGenDoc := &GenesisDoc{ ChainID: "abc", - Validators: []GenesisValidator{{ed25519.GenPrivKey().PubKey(), 10, "myval"}}, + Validators: []GenesisValidator{{pubkey.Address(), pubkey, 10, "myval"}}, } genDocBytes, err = cdc.MarshalJSON(baseGenDoc) assert.NoError(t, err, "error marshalling genDoc") @@ -49,6 +54,9 @@ func TestGenesisGood(t *testing.T) { assert.NoError(t, err, "expected no error for valid genDoc json") assert.NotNil(t, genDoc.ConsensusParams, "expected consensus params to be filled in") + // check validator's address is filled + assert.NotNil(t, genDoc.Validators[0].Address, "expected validator's address to be filled in") + // create json with consensus params filled genDocBytes, err = cdc.MarshalJSON(genDoc) assert.NoError(t, err, "error marshalling genDoc") @@ -109,10 +117,11 @@ func TestGenesisValidatorHash(t *testing.T) { } func randomGenesisDoc() *GenesisDoc { + pubkey := ed25519.GenPrivKey().PubKey() return &GenesisDoc{ GenesisTime: tmtime.Now(), ChainID: "abc", - Validators: []GenesisValidator{{ed25519.GenPrivKey().PubKey(), 10, "myval"}}, + Validators: []GenesisValidator{{pubkey.Address(), pubkey, 10, "myval"}}, ConsensusParams: DefaultConsensusParams(), } }