Add ValidatorPubkeyTypes as a consensus param (#2636)

* Add ValidatorPubkeyTypes as a consensus param

Ref #2414

* update spec

* address anton's comment

* Switch to Validator and Validator Params

* Correct changelog entry

* Address bucky's comments!

* forgot to update changelog

* fix typo

* fix Params naming
This commit is contained in:
Dev Ojha 2018-10-30 08:36:53 -07:00 committed by Ethan Buchman
parent cdc252b818
commit 56d7160606
16 changed files with 893 additions and 393 deletions

View File

@ -57,6 +57,8 @@ Friendly reminder, we have a [bug bounty program](https://hackerone.com/tendermi
`PrecommitType`. `PrecommitType`.
* Blockchain Protocol * Blockchain Protocol
* [abci] [\#2636](https://github.com/tendermint/tendermint/issues/2636) Add ValidatorParams field to ConsensusParams.
(Used to control which pubkey types validators can use, by abci type)
* [types] Update SignBytes for `Vote`/`Proposal`/`Heartbeat`: * [types] Update SignBytes for `Vote`/`Proposal`/`Heartbeat`:
* [\#2459](https://github.com/tendermint/tendermint/issues/2459) Use amino encoding instead of JSON in `SignBytes`. * [\#2459](https://github.com/tendermint/tendermint/issues/2459) Use amino encoding instead of JSON in `SignBytes`.
* [\#2598](https://github.com/tendermint/tendermint/issues/2598) Reorder fields and use fixed sized encoding. * [\#2598](https://github.com/tendermint/tendermint/issues/2598) Reorder fields and use fixed sized encoding.

File diff suppressed because it is too large Load Diff

View File

@ -74,7 +74,6 @@ message RequestQuery {
bool prove = 4; bool prove = 4;
} }
// NOTE: validators here have empty pubkeys.
message RequestBeginBlock { message RequestBeginBlock {
bytes hash = 1; bytes hash = 1;
Header header = 2 [(gogoproto.nullable)=false]; Header header = 2 [(gogoproto.nullable)=false];
@ -208,12 +207,13 @@ message ResponseCommit {
// ConsensusParams contains all consensus-relevant parameters // ConsensusParams contains all consensus-relevant parameters
// that can be adjusted by the abci app // that can be adjusted by the abci app
message ConsensusParams { message ConsensusParams {
BlockSize block_size = 1; BlockSizeParams block_size = 1;
EvidenceParams evidence_params = 2; EvidenceParams evidence = 2;
ValidatorParams validator = 3;
} }
// BlockSize contains limits on the block size. // BlockSize contains limits on the block size.
message BlockSize { message BlockSizeParams {
// Note: must be greater than 0 // Note: must be greater than 0
int64 max_bytes = 1; int64 max_bytes = 1;
// Note: must be greater or equal to -1 // Note: must be greater or equal to -1
@ -226,6 +226,11 @@ message EvidenceParams {
int64 max_age = 1; int64 max_age = 1;
} }
// ValidatorParams contains limits on validators.
message ValidatorParams {
repeated string pub_key_types = 1;
}
message LastCommitInfo { message LastCommitInfo {
int32 round = 1; int32 round = 1;
repeated VoteInfo votes = 2 [(gogoproto.nullable)=false]; repeated VoteInfo votes = 2 [(gogoproto.nullable)=false];

View File

@ -1479,15 +1479,15 @@ func TestConsensusParamsMarshalTo(t *testing.T) {
} }
} }
func TestBlockSizeProto(t *testing.T) { func TestBlockSizeParamsProto(t *testing.T) {
seed := time.Now().UnixNano() seed := time.Now().UnixNano()
popr := math_rand.New(math_rand.NewSource(seed)) popr := math_rand.New(math_rand.NewSource(seed))
p := NewPopulatedBlockSize(popr, false) p := NewPopulatedBlockSizeParams(popr, false)
dAtA, err := github_com_gogo_protobuf_proto.Marshal(p) dAtA, err := github_com_gogo_protobuf_proto.Marshal(p)
if err != nil { if err != nil {
t.Fatalf("seed = %d, err = %v", seed, err) t.Fatalf("seed = %d, err = %v", seed, err)
} }
msg := &BlockSize{} msg := &BlockSizeParams{}
if err := github_com_gogo_protobuf_proto.Unmarshal(dAtA, msg); err != nil { if err := github_com_gogo_protobuf_proto.Unmarshal(dAtA, msg); err != nil {
t.Fatalf("seed = %d, err = %v", seed, err) t.Fatalf("seed = %d, err = %v", seed, err)
} }
@ -1510,10 +1510,10 @@ func TestBlockSizeProto(t *testing.T) {
} }
} }
func TestBlockSizeMarshalTo(t *testing.T) { func TestBlockSizeParamsMarshalTo(t *testing.T) {
seed := time.Now().UnixNano() seed := time.Now().UnixNano()
popr := math_rand.New(math_rand.NewSource(seed)) popr := math_rand.New(math_rand.NewSource(seed))
p := NewPopulatedBlockSize(popr, false) p := NewPopulatedBlockSizeParams(popr, false)
size := p.Size() size := p.Size()
dAtA := make([]byte, size) dAtA := make([]byte, size)
for i := range dAtA { for i := range dAtA {
@ -1523,7 +1523,7 @@ func TestBlockSizeMarshalTo(t *testing.T) {
if err != nil { if err != nil {
t.Fatalf("seed = %d, err = %v", seed, err) t.Fatalf("seed = %d, err = %v", seed, err)
} }
msg := &BlockSize{} msg := &BlockSizeParams{}
if err := github_com_gogo_protobuf_proto.Unmarshal(dAtA, msg); err != nil { if err := github_com_gogo_protobuf_proto.Unmarshal(dAtA, msg); err != nil {
t.Fatalf("seed = %d, err = %v", seed, err) t.Fatalf("seed = %d, err = %v", seed, err)
} }
@ -1591,6 +1591,62 @@ func TestEvidenceParamsMarshalTo(t *testing.T) {
} }
} }
func TestValidatorParamsProto(t *testing.T) {
seed := time.Now().UnixNano()
popr := math_rand.New(math_rand.NewSource(seed))
p := NewPopulatedValidatorParams(popr, false)
dAtA, err := github_com_gogo_protobuf_proto.Marshal(p)
if err != nil {
t.Fatalf("seed = %d, err = %v", seed, err)
}
msg := &ValidatorParams{}
if err := github_com_gogo_protobuf_proto.Unmarshal(dAtA, msg); err != nil {
t.Fatalf("seed = %d, err = %v", seed, err)
}
littlefuzz := make([]byte, len(dAtA))
copy(littlefuzz, dAtA)
for i := range dAtA {
dAtA[i] = byte(popr.Intn(256))
}
if !p.Equal(msg) {
t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p)
}
if len(littlefuzz) > 0 {
fuzzamount := 100
for i := 0; i < fuzzamount; i++ {
littlefuzz[popr.Intn(len(littlefuzz))] = byte(popr.Intn(256))
littlefuzz = append(littlefuzz, byte(popr.Intn(256)))
}
// shouldn't panic
_ = github_com_gogo_protobuf_proto.Unmarshal(littlefuzz, msg)
}
}
func TestValidatorParamsMarshalTo(t *testing.T) {
seed := time.Now().UnixNano()
popr := math_rand.New(math_rand.NewSource(seed))
p := NewPopulatedValidatorParams(popr, false)
size := p.Size()
dAtA := make([]byte, size)
for i := range dAtA {
dAtA[i] = byte(popr.Intn(256))
}
_, err := p.MarshalTo(dAtA)
if err != nil {
t.Fatalf("seed = %d, err = %v", seed, err)
}
msg := &ValidatorParams{}
if err := github_com_gogo_protobuf_proto.Unmarshal(dAtA, msg); err != nil {
t.Fatalf("seed = %d, err = %v", seed, err)
}
for i := range dAtA {
dAtA[i] = byte(popr.Intn(256))
}
if !p.Equal(msg) {
t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p)
}
}
func TestLastCommitInfoProto(t *testing.T) { func TestLastCommitInfoProto(t *testing.T) {
seed := time.Now().UnixNano() seed := time.Now().UnixNano()
popr := math_rand.New(math_rand.NewSource(seed)) popr := math_rand.New(math_rand.NewSource(seed))
@ -2619,16 +2675,16 @@ func TestConsensusParamsJSON(t *testing.T) {
t.Fatalf("seed = %d, %#v !Json Equal %#v", seed, msg, p) t.Fatalf("seed = %d, %#v !Json Equal %#v", seed, msg, p)
} }
} }
func TestBlockSizeJSON(t *testing.T) { func TestBlockSizeParamsJSON(t *testing.T) {
seed := time.Now().UnixNano() seed := time.Now().UnixNano()
popr := math_rand.New(math_rand.NewSource(seed)) popr := math_rand.New(math_rand.NewSource(seed))
p := NewPopulatedBlockSize(popr, true) p := NewPopulatedBlockSizeParams(popr, true)
marshaler := github_com_gogo_protobuf_jsonpb.Marshaler{} marshaler := github_com_gogo_protobuf_jsonpb.Marshaler{}
jsondata, err := marshaler.MarshalToString(p) jsondata, err := marshaler.MarshalToString(p)
if err != nil { if err != nil {
t.Fatalf("seed = %d, err = %v", seed, err) t.Fatalf("seed = %d, err = %v", seed, err)
} }
msg := &BlockSize{} msg := &BlockSizeParams{}
err = github_com_gogo_protobuf_jsonpb.UnmarshalString(jsondata, msg) err = github_com_gogo_protobuf_jsonpb.UnmarshalString(jsondata, msg)
if err != nil { if err != nil {
t.Fatalf("seed = %d, err = %v", seed, err) t.Fatalf("seed = %d, err = %v", seed, err)
@ -2655,6 +2711,24 @@ func TestEvidenceParamsJSON(t *testing.T) {
t.Fatalf("seed = %d, %#v !Json Equal %#v", seed, msg, p) t.Fatalf("seed = %d, %#v !Json Equal %#v", seed, msg, p)
} }
} }
func TestValidatorParamsJSON(t *testing.T) {
seed := time.Now().UnixNano()
popr := math_rand.New(math_rand.NewSource(seed))
p := NewPopulatedValidatorParams(popr, true)
marshaler := github_com_gogo_protobuf_jsonpb.Marshaler{}
jsondata, err := marshaler.MarshalToString(p)
if err != nil {
t.Fatalf("seed = %d, err = %v", seed, err)
}
msg := &ValidatorParams{}
err = github_com_gogo_protobuf_jsonpb.UnmarshalString(jsondata, msg)
if err != nil {
t.Fatalf("seed = %d, err = %v", seed, err)
}
if !p.Equal(msg) {
t.Fatalf("seed = %d, %#v !Json Equal %#v", seed, msg, p)
}
}
func TestLastCommitInfoJSON(t *testing.T) { func TestLastCommitInfoJSON(t *testing.T) {
seed := time.Now().UnixNano() seed := time.Now().UnixNano()
popr := math_rand.New(math_rand.NewSource(seed)) popr := math_rand.New(math_rand.NewSource(seed))
@ -3563,12 +3637,12 @@ func TestConsensusParamsProtoCompactText(t *testing.T) {
} }
} }
func TestBlockSizeProtoText(t *testing.T) { func TestBlockSizeParamsProtoText(t *testing.T) {
seed := time.Now().UnixNano() seed := time.Now().UnixNano()
popr := math_rand.New(math_rand.NewSource(seed)) popr := math_rand.New(math_rand.NewSource(seed))
p := NewPopulatedBlockSize(popr, true) p := NewPopulatedBlockSizeParams(popr, true)
dAtA := github_com_gogo_protobuf_proto.MarshalTextString(p) dAtA := github_com_gogo_protobuf_proto.MarshalTextString(p)
msg := &BlockSize{} msg := &BlockSizeParams{}
if err := github_com_gogo_protobuf_proto.UnmarshalText(dAtA, msg); err != nil { if err := github_com_gogo_protobuf_proto.UnmarshalText(dAtA, msg); err != nil {
t.Fatalf("seed = %d, err = %v", seed, err) t.Fatalf("seed = %d, err = %v", seed, err)
} }
@ -3577,12 +3651,12 @@ func TestBlockSizeProtoText(t *testing.T) {
} }
} }
func TestBlockSizeProtoCompactText(t *testing.T) { func TestBlockSizeParamsProtoCompactText(t *testing.T) {
seed := time.Now().UnixNano() seed := time.Now().UnixNano()
popr := math_rand.New(math_rand.NewSource(seed)) popr := math_rand.New(math_rand.NewSource(seed))
p := NewPopulatedBlockSize(popr, true) p := NewPopulatedBlockSizeParams(popr, true)
dAtA := github_com_gogo_protobuf_proto.CompactTextString(p) dAtA := github_com_gogo_protobuf_proto.CompactTextString(p)
msg := &BlockSize{} msg := &BlockSizeParams{}
if err := github_com_gogo_protobuf_proto.UnmarshalText(dAtA, msg); err != nil { if err := github_com_gogo_protobuf_proto.UnmarshalText(dAtA, msg); err != nil {
t.Fatalf("seed = %d, err = %v", seed, err) t.Fatalf("seed = %d, err = %v", seed, err)
} }
@ -3619,6 +3693,34 @@ func TestEvidenceParamsProtoCompactText(t *testing.T) {
} }
} }
func TestValidatorParamsProtoText(t *testing.T) {
seed := time.Now().UnixNano()
popr := math_rand.New(math_rand.NewSource(seed))
p := NewPopulatedValidatorParams(popr, true)
dAtA := github_com_gogo_protobuf_proto.MarshalTextString(p)
msg := &ValidatorParams{}
if err := github_com_gogo_protobuf_proto.UnmarshalText(dAtA, msg); err != nil {
t.Fatalf("seed = %d, err = %v", seed, err)
}
if !p.Equal(msg) {
t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p)
}
}
func TestValidatorParamsProtoCompactText(t *testing.T) {
seed := time.Now().UnixNano()
popr := math_rand.New(math_rand.NewSource(seed))
p := NewPopulatedValidatorParams(popr, true)
dAtA := github_com_gogo_protobuf_proto.CompactTextString(p)
msg := &ValidatorParams{}
if err := github_com_gogo_protobuf_proto.UnmarshalText(dAtA, msg); err != nil {
t.Fatalf("seed = %d, err = %v", seed, err)
}
if !p.Equal(msg) {
t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p)
}
}
func TestLastCommitInfoProtoText(t *testing.T) { func TestLastCommitInfoProtoText(t *testing.T) {
seed := time.Now().UnixNano() seed := time.Now().UnixNano()
popr := math_rand.New(math_rand.NewSource(seed)) popr := math_rand.New(math_rand.NewSource(seed))
@ -4471,10 +4573,10 @@ func TestConsensusParamsSize(t *testing.T) {
} }
} }
func TestBlockSizeSize(t *testing.T) { func TestBlockSizeParamsSize(t *testing.T) {
seed := time.Now().UnixNano() seed := time.Now().UnixNano()
popr := math_rand.New(math_rand.NewSource(seed)) popr := math_rand.New(math_rand.NewSource(seed))
p := NewPopulatedBlockSize(popr, true) p := NewPopulatedBlockSizeParams(popr, true)
size2 := github_com_gogo_protobuf_proto.Size(p) size2 := github_com_gogo_protobuf_proto.Size(p)
dAtA, err := github_com_gogo_protobuf_proto.Marshal(p) dAtA, err := github_com_gogo_protobuf_proto.Marshal(p)
if err != nil { if err != nil {
@ -4515,6 +4617,28 @@ func TestEvidenceParamsSize(t *testing.T) {
} }
} }
func TestValidatorParamsSize(t *testing.T) {
seed := time.Now().UnixNano()
popr := math_rand.New(math_rand.NewSource(seed))
p := NewPopulatedValidatorParams(popr, true)
size2 := github_com_gogo_protobuf_proto.Size(p)
dAtA, err := github_com_gogo_protobuf_proto.Marshal(p)
if err != nil {
t.Fatalf("seed = %d, err = %v", seed, err)
}
size := p.Size()
if len(dAtA) != size {
t.Errorf("seed = %d, size %v != marshalled size %v", seed, size, len(dAtA))
}
if size2 != size {
t.Errorf("seed = %d, size %v != before marshal proto.Size %v", seed, size, size2)
}
size3 := github_com_gogo_protobuf_proto.Size(p)
if size3 != size {
t.Errorf("seed = %d, size %v != after marshal proto.Size %v", seed, size, size3)
}
}
func TestLastCommitInfoSize(t *testing.T) { func TestLastCommitInfoSize(t *testing.T) {
seed := time.Now().UnixNano() seed := time.Now().UnixNano()
popr := math_rand.New(math_rand.NewSource(seed)) popr := math_rand.New(math_rand.NewSource(seed))

View File

@ -441,11 +441,12 @@ Commit are included in the header of the next block.
### ConsensusParams ### ConsensusParams
- **Fields**: - **Fields**:
- `BlockSize (BlockSize)`: Parameters limiting the size of a block. - `BlockSize (BlockSizeParams)`: Parameters limiting the size of a block.
- `EvidenceParams (EvidenceParams)`: Parameters limiting the validity of - `Evidence (EvidenceParams)`: Parameters limiting the validity of
evidence of byzantine behaviour. evidence of byzantine behaviour.
- `Validator (ValidatorParams)`: Parameters limitng the types of pubkeys validators can use.
### BlockSize ### BlockSizeParams
- **Fields**: - **Fields**:
- `MaxBytes (int64)`: Max size of a block, in bytes. - `MaxBytes (int64)`: Max size of a block, in bytes.
@ -463,6 +464,12 @@ Commit are included in the header of the next block.
similar mechanism for handling Nothing-At-Stake attacks. similar mechanism for handling Nothing-At-Stake attacks.
- NOTE: this should change to time (instead of blocks)! - NOTE: this should change to time (instead of blocks)!
### ValidatorParams
- **Fields**:
- `PubKeyTypes ([]string)`: List of accepted pubkey types. Uses same
naming as `PubKey.Type`.
### Proof ### Proof
- **Fields**: - **Fields**:

View File

@ -127,7 +127,7 @@ func (evpool *EvidencePool) MarkEvidenceAsCommitted(height int64, evidence []typ
} }
// remove committed evidence from the clist // remove committed evidence from the clist
maxAge := evpool.State().ConsensusParams.EvidenceParams.MaxAge maxAge := evpool.State().ConsensusParams.Evidence.MaxAge
evpool.removeEvidence(height, maxAge, blockEvidenceMap) evpool.removeEvidence(height, maxAge, blockEvidenceMap)
} }

View File

@ -38,7 +38,7 @@ func initializeValidatorState(valAddr []byte, height int64) dbm.DB {
NextValidators: valSet.CopyIncrementAccum(1), NextValidators: valSet.CopyIncrementAccum(1),
LastHeightValidatorsChanged: 1, LastHeightValidatorsChanged: 1,
ConsensusParams: types.ConsensusParams{ ConsensusParams: types.ConsensusParams{
EvidenceParams: types.EvidenceParams{ Evidence: types.EvidenceParams{
MaxAge: 1000000, MaxAge: 1000000,
}, },
}, },

View File

@ -164,7 +164,7 @@ func (evR EvidenceReactor) checkSendEvidenceMessage(peer p2p.Peer, ev types.Evid
// NOTE: We only send evidence to peers where // NOTE: We only send evidence to peers where
// peerHeight - maxAge < evidenceHeight < peerHeight // peerHeight - maxAge < evidenceHeight < peerHeight
maxAge := evR.evpool.State().ConsensusParams.EvidenceParams.MaxAge maxAge := evR.evpool.State().ConsensusParams.Evidence.MaxAge
peerHeight := peerState.GetHeight() peerHeight := peerState.GetHeight()
if peerHeight < evHeight { if peerHeight < evHeight {
// peer is behind. sleep while he catches up // peer is behind. sleep while he catches up

View File

@ -186,7 +186,7 @@ func (blockExec *BlockExecutor) Commit(
state.Validators.Size(), state.Validators.Size(),
), ),
), ),
mempool.PostCheckMaxGas(state.ConsensusParams.MaxGas), mempool.PostCheckMaxGas(state.ConsensusParams.BlockSize.MaxGas),
) )
return res.Data, err return res.Data, err

View File

@ -390,11 +390,11 @@ func TestConsensusParamsChangesSaveLoad(t *testing.T) {
func makeParams(blockBytes, blockGas, evidenceAge int64) types.ConsensusParams { func makeParams(blockBytes, blockGas, evidenceAge int64) types.ConsensusParams {
return types.ConsensusParams{ return types.ConsensusParams{
BlockSize: types.BlockSize{ BlockSize: types.BlockSizeParams{
MaxBytes: blockBytes, MaxBytes: blockBytes,
MaxGas: blockGas, MaxGas: blockGas,
}, },
EvidenceParams: types.EvidenceParams{ Evidence: types.EvidenceParams{
MaxAge: evidenceAge, MaxAge: evidenceAge,
}, },
} }
@ -416,7 +416,7 @@ func TestApplyUpdates(t *testing.T) {
1: {initParams, abci.ConsensusParams{}, initParams}, 1: {initParams, abci.ConsensusParams{}, initParams},
2: {initParams, 2: {initParams,
abci.ConsensusParams{ abci.ConsensusParams{
BlockSize: &abci.BlockSize{ BlockSize: &abci.BlockSizeParams{
MaxBytes: 44, MaxBytes: 44,
MaxGas: 55, MaxGas: 55,
}, },
@ -424,7 +424,7 @@ func TestApplyUpdates(t *testing.T) {
makeParams(44, 55, 3)}, makeParams(44, 55, 3)},
3: {initParams, 3: {initParams,
abci.ConsensusParams{ abci.ConsensusParams{
EvidenceParams: &abci.EvidenceParams{ Evidence: &abci.EvidenceParams{
MaxAge: 66, MaxAge: 66,
}, },
}, },

View File

@ -251,7 +251,7 @@ func LoadConsensusParams(db dbm.DB, height int64) (types.ConsensusParams, error)
return empty, ErrNoConsensusParamsForHeight{height} return empty, ErrNoConsensusParamsForHeight{height}
} }
if paramsInfo.ConsensusParams == empty { if paramsInfo.ConsensusParams.Equals(&empty) {
paramsInfo2 := loadConsensusParamsInfo(db, paramsInfo.LastHeightChanged) paramsInfo2 := loadConsensusParamsInfo(db, paramsInfo.LastHeightChanged)
if paramsInfo2 == nil { if paramsInfo2 == nil {
panic( panic(

View File

@ -178,7 +178,7 @@ func VerifyEvidence(stateDB dbm.DB, state State, evidence types.Evidence) error
height := state.LastBlockHeight height := state.LastBlockHeight
evidenceAge := height - evidence.Height() evidenceAge := height - evidence.Height()
maxAge := state.ConsensusParams.EvidenceParams.MaxAge maxAge := state.ConsensusParams.Evidence.MaxAge
if evidenceAge > maxAge { if evidenceAge > maxAge {
return fmt.Errorf("Evidence from height %d is too old. Min height is %d", return fmt.Errorf("Evidence from height %d is too old. Min height is %d",
evidence.Height(), height-maxAge) evidence.Height(), height-maxAge)

View File

@ -17,12 +17,13 @@ const (
// ConsensusParams contains consensus critical parameters that determine the // ConsensusParams contains consensus critical parameters that determine the
// validity of blocks. // validity of blocks.
type ConsensusParams struct { type ConsensusParams struct {
BlockSize `json:"block_size_params"` BlockSize BlockSizeParams `json:"block_size"`
EvidenceParams `json:"evidence_params"` Evidence EvidenceParams `json:"evidence"`
Validator ValidatorParams `json:"validator"`
} }
// BlockSize contain limits on the block size. // BlockSizeParams define limits on the block size.
type BlockSize struct { type BlockSizeParams struct {
MaxBytes int64 `json:"max_bytes"` MaxBytes int64 `json:"max_bytes"`
MaxGas int64 `json:"max_gas"` MaxGas int64 `json:"max_gas"`
} }
@ -32,17 +33,24 @@ type EvidenceParams struct {
MaxAge int64 `json:"max_age"` // only accept new evidence more recent than this MaxAge int64 `json:"max_age"` // only accept new evidence more recent than this
} }
// ValidatorParams restrict the public key types validators can use.
// NOTE: uses ABCI pubkey naming, not Amino routes.
type ValidatorParams struct {
PubKeyTypes []string `json:"pub_key_types"`
}
// DefaultConsensusParams returns a default ConsensusParams. // DefaultConsensusParams returns a default ConsensusParams.
func DefaultConsensusParams() *ConsensusParams { func DefaultConsensusParams() *ConsensusParams {
return &ConsensusParams{ return &ConsensusParams{
DefaultBlockSize(), DefaultBlockSizeParams(),
DefaultEvidenceParams(), DefaultEvidenceParams(),
DefaultValidatorParams(),
} }
} }
// DefaultBlockSize returns a default BlockSize. // DefaultBlockSizeParams returns a default BlockSizeParams.
func DefaultBlockSize() BlockSize { func DefaultBlockSizeParams() BlockSizeParams {
return BlockSize{ return BlockSizeParams{
MaxBytes: 22020096, // 21MB MaxBytes: 22020096, // 21MB
MaxGas: -1, MaxGas: -1,
} }
@ -55,6 +63,12 @@ func DefaultEvidenceParams() EvidenceParams {
} }
} }
// DefaultValidatorParams returns a default ValidatorParams, which allows
// only ed25519 pubkeys.
func DefaultValidatorParams() ValidatorParams {
return ValidatorParams{[]string{ABCIPubKeyTypeEd25519}}
}
// Validate validates the ConsensusParams to ensure all values are within their // Validate validates the ConsensusParams to ensure all values are within their
// allowed limits, and returns an error if they are not. // allowed limits, and returns an error if they are not.
func (params *ConsensusParams) Validate() error { func (params *ConsensusParams) Validate() error {
@ -72,9 +86,22 @@ func (params *ConsensusParams) Validate() error {
params.BlockSize.MaxGas) params.BlockSize.MaxGas)
} }
if params.EvidenceParams.MaxAge <= 0 { if params.Evidence.MaxAge <= 0 {
return cmn.NewError("EvidenceParams.MaxAge must be greater than 0. Got %d", return cmn.NewError("EvidenceParams.MaxAge must be greater than 0. Got %d",
params.EvidenceParams.MaxAge) params.Evidence.MaxAge)
}
if len(params.Validator.PubKeyTypes) == 0 {
return cmn.NewError("len(Validator.PubKeyTypes) must be greater than 0")
}
// Check if keyType is a known ABCIPubKeyType
for i := 0; i < len(params.Validator.PubKeyTypes); i++ {
keyType := params.Validator.PubKeyTypes[i]
if _, ok := ABCIPubKeyTypesToAminoRoutes[keyType]; !ok {
return cmn.NewError("params.Validator.PubKeyTypes[%d], %s, is an unknown pubkey type",
i, keyType)
}
} }
return nil return nil
@ -94,6 +121,24 @@ func (params *ConsensusParams) Hash() []byte {
return hasher.Sum(nil) return hasher.Sum(nil)
} }
func (params *ConsensusParams) Equals(params2 *ConsensusParams) bool {
return params.BlockSize == params2.BlockSize &&
params.Evidence == params2.Evidence &&
stringSliceEqual(params.Validator.PubKeyTypes, params2.Validator.PubKeyTypes)
}
func stringSliceEqual(a, b []string) bool {
if len(a) != len(b) {
return false
}
for i := 0; i < len(a); i++ {
if a[i] != b[i] {
return false
}
}
return true
}
// Update returns a copy of the params with updates from the non-zero fields of p2. // Update returns a copy of the params with updates from the non-zero fields of p2.
// NOTE: note: must not modify the original // NOTE: note: must not modify the original
func (params ConsensusParams) Update(params2 *abci.ConsensusParams) ConsensusParams { func (params ConsensusParams) Update(params2 *abci.ConsensusParams) ConsensusParams {
@ -108,8 +153,11 @@ func (params ConsensusParams) Update(params2 *abci.ConsensusParams) ConsensusPar
res.BlockSize.MaxBytes = params2.BlockSize.MaxBytes res.BlockSize.MaxBytes = params2.BlockSize.MaxBytes
res.BlockSize.MaxGas = params2.BlockSize.MaxGas res.BlockSize.MaxGas = params2.BlockSize.MaxGas
} }
if params2.EvidenceParams != nil { if params2.Evidence != nil {
res.EvidenceParams.MaxAge = params2.EvidenceParams.MaxAge res.Evidence.MaxAge = params2.Evidence.MaxAge
}
if params2.Validator != nil {
res.Validator.PubKeyTypes = params2.Validator.PubKeyTypes
} }
return res return res
} }

View File

@ -9,23 +9,32 @@ import (
abci "github.com/tendermint/tendermint/abci/types" abci "github.com/tendermint/tendermint/abci/types"
) )
var (
valEd25519 = []string{ABCIPubKeyTypeEd25519}
valSecp256k1 = []string{ABCIPubKeyTypeSecp256k1}
)
func TestConsensusParamsValidation(t *testing.T) { func TestConsensusParamsValidation(t *testing.T) {
testCases := []struct { testCases := []struct {
params ConsensusParams params ConsensusParams
valid bool valid bool
}{ }{
// test block size // test block size
0: {makeParams(1, 0, 1), true}, 0: {makeParams(1, 0, 1, valEd25519), true},
1: {makeParams(0, 0, 1), false}, 1: {makeParams(0, 0, 1, valEd25519), false},
2: {makeParams(47*1024*1024, 0, 1), true}, 2: {makeParams(47*1024*1024, 0, 1, valEd25519), true},
3: {makeParams(10, 0, 1), true}, 3: {makeParams(10, 0, 1, valEd25519), true},
4: {makeParams(100*1024*1024, 0, 1), true}, 4: {makeParams(100*1024*1024, 0, 1, valEd25519), true},
5: {makeParams(101*1024*1024, 0, 1), false}, 5: {makeParams(101*1024*1024, 0, 1, valEd25519), false},
6: {makeParams(1024*1024*1024, 0, 1), false}, 6: {makeParams(1024*1024*1024, 0, 1, valEd25519), false},
7: {makeParams(1024*1024*1024, 0, -1), false}, 7: {makeParams(1024*1024*1024, 0, -1, valEd25519), false},
// test evidence age // test evidence age
8: {makeParams(1, 0, 0), false}, 8: {makeParams(1, 0, 0, valEd25519), false},
9: {makeParams(1, 0, -1), false}, 9: {makeParams(1, 0, -1, valEd25519), false},
// test no pubkey type provided
10: {makeParams(1, 0, 1, []string{}), false},
// test invalid pubkey type provided
11: {makeParams(1, 0, 1, []string{"potatoes make good pubkeys"}), false},
} }
for i, tc := range testCases { for i, tc := range testCases {
if tc.valid { if tc.valid {
@ -36,28 +45,31 @@ func TestConsensusParamsValidation(t *testing.T) {
} }
} }
func makeParams(blockBytes, blockGas, evidenceAge int64) ConsensusParams { func makeParams(blockBytes, blockGas, evidenceAge int64, pubkeyTypes []string) ConsensusParams {
return ConsensusParams{ return ConsensusParams{
BlockSize: BlockSize{ BlockSize: BlockSizeParams{
MaxBytes: blockBytes, MaxBytes: blockBytes,
MaxGas: blockGas, MaxGas: blockGas,
}, },
EvidenceParams: EvidenceParams{ Evidence: EvidenceParams{
MaxAge: evidenceAge, MaxAge: evidenceAge,
}, },
Validator: ValidatorParams{
PubKeyTypes: pubkeyTypes,
},
} }
} }
func TestConsensusParamsHash(t *testing.T) { func TestConsensusParamsHash(t *testing.T) {
params := []ConsensusParams{ params := []ConsensusParams{
makeParams(4, 2, 3), makeParams(4, 2, 3, valEd25519),
makeParams(1, 4, 3), makeParams(1, 4, 3, valEd25519),
makeParams(1, 2, 4), makeParams(1, 2, 4, valEd25519),
makeParams(2, 5, 7), makeParams(2, 5, 7, valEd25519),
makeParams(1, 7, 6), makeParams(1, 7, 6, valEd25519),
makeParams(9, 5, 4), makeParams(9, 5, 4, valEd25519),
makeParams(7, 8, 9), makeParams(7, 8, 9, valEd25519),
makeParams(4, 6, 5), makeParams(4, 6, 5, valEd25519),
} }
hashes := make([][]byte, len(params)) hashes := make([][]byte, len(params))
@ -83,23 +95,26 @@ func TestConsensusParamsUpdate(t *testing.T) {
}{ }{
// empty updates // empty updates
{ {
makeParams(1, 2, 3), makeParams(1, 2, 3, valEd25519),
&abci.ConsensusParams{}, &abci.ConsensusParams{},
makeParams(1, 2, 3), makeParams(1, 2, 3, valEd25519),
}, },
// fine updates // fine updates
{ {
makeParams(1, 2, 3), makeParams(1, 2, 3, valEd25519),
&abci.ConsensusParams{ &abci.ConsensusParams{
BlockSize: &abci.BlockSize{ BlockSize: &abci.BlockSizeParams{
MaxBytes: 100, MaxBytes: 100,
MaxGas: 200, MaxGas: 200,
}, },
EvidenceParams: &abci.EvidenceParams{ Evidence: &abci.EvidenceParams{
MaxAge: 300, MaxAge: 300,
}, },
Validator: &abci.ValidatorParams{
PubKeyTypes: valSecp256k1,
}, },
makeParams(100, 200, 300), },
makeParams(100, 200, 300, valSecp256k1),
}, },
} }
for _, tc := range testCases { for _, tc := range testCases {

View File

@ -24,6 +24,12 @@ const (
ABCIPubKeyTypeSecp256k1 = "secp256k1" ABCIPubKeyTypeSecp256k1 = "secp256k1"
) )
// TODO: Make non-global by allowing for registration of more pubkey types
var ABCIPubKeyTypesToAminoRoutes = map[string]string{
ABCIPubKeyTypeEd25519: ed25519.PubKeyAminoRoute,
ABCIPubKeyTypeSecp256k1: secp256k1.PubKeyAminoRoute,
}
//------------------------------------------------------- //-------------------------------------------------------
// TM2PB is used for converting Tendermint ABCI to protobuf ABCI. // TM2PB is used for converting Tendermint ABCI to protobuf ABCI.
@ -119,12 +125,15 @@ func (tm2pb) ValidatorUpdates(vals *ValidatorSet) []abci.ValidatorUpdate {
func (tm2pb) ConsensusParams(params *ConsensusParams) *abci.ConsensusParams { func (tm2pb) ConsensusParams(params *ConsensusParams) *abci.ConsensusParams {
return &abci.ConsensusParams{ return &abci.ConsensusParams{
BlockSize: &abci.BlockSize{ BlockSize: &abci.BlockSizeParams{
MaxBytes: params.BlockSize.MaxBytes, MaxBytes: params.BlockSize.MaxBytes,
MaxGas: params.BlockSize.MaxGas, MaxGas: params.BlockSize.MaxGas,
}, },
EvidenceParams: &abci.EvidenceParams{ Evidence: &abci.EvidenceParams{
MaxAge: params.EvidenceParams.MaxAge, MaxAge: params.Evidence.MaxAge,
},
Validator: &abci.ValidatorParams{
PubKeyTypes: params.Validator.PubKeyTypes,
}, },
} }
} }
@ -215,12 +224,15 @@ func (pb2tm) ValidatorUpdates(vals []abci.ValidatorUpdate) ([]*Validator, error)
func (pb2tm) ConsensusParams(csp *abci.ConsensusParams) ConsensusParams { func (pb2tm) ConsensusParams(csp *abci.ConsensusParams) ConsensusParams {
return ConsensusParams{ return ConsensusParams{
BlockSize: BlockSize{ BlockSize: BlockSizeParams{
MaxBytes: csp.BlockSize.MaxBytes, MaxBytes: csp.BlockSize.MaxBytes,
MaxGas: csp.BlockSize.MaxGas, MaxGas: csp.BlockSize.MaxGas,
}, },
EvidenceParams: EvidenceParams{ Evidence: EvidenceParams{
MaxAge: csp.EvidenceParams.MaxAge, MaxAge: csp.Evidence.MaxAge,
},
Validator: ValidatorParams{
PubKeyTypes: csp.Validator.PubKeyTypes,
}, },
} }
} }

View File

@ -64,7 +64,6 @@ func TestABCIValidators(t *testing.T) {
func TestABCIConsensusParams(t *testing.T) { func TestABCIConsensusParams(t *testing.T) {
cp := DefaultConsensusParams() cp := DefaultConsensusParams()
cp.EvidenceParams.MaxAge = 0 // TODO add this to ABCI
abciCP := TM2PB.ConsensusParams(cp) abciCP := TM2PB.ConsensusParams(cp)
cp2 := PB2TM.ConsensusParams(abciCP) cp2 := PB2TM.ConsensusParams(abciCP)