Browse Source

abci: VoteInfo, ValidatorUpdate. See ADR-018

pull/2159/head
Ethan Buchman 6 years ago
parent
commit
e3f54ece2f
18 changed files with 665 additions and 411 deletions
  1. +4
    -6
      abci/example/kvstore/helpers.go
  2. +9
    -9
      abci/example/kvstore/kvstore_test.go
  3. +6
    -6
      abci/example/kvstore/persistent_kvstore.go
  4. +2
    -2
      abci/tests/server/client.go
  5. +2
    -2
      abci/types/pubkey.go
  6. +402
    -245
      abci/types/types.pb.go
  7. +13
    -8
      abci/types/types.proto
  8. +143
    -18
      abci/types/typespb_test.go
  9. +8
    -33
      abci/types/util.go
  10. +2
    -2
      consensus/common_test.go
  11. +1
    -1
      consensus/reactor_test.go
  12. +2
    -2
      consensus/replay.go
  13. +5
    -5
      consensus/replay_test.go
  14. +19
    -15
      state/execution.go
  15. +9
    -9
      state/execution_test.go
  16. +7
    -7
      state/state_test.go
  17. +17
    -24
      types/protobuf.go
  18. +14
    -17
      types/protobuf_test.go

+ 4
- 6
abci/example/kvstore/helpers.go View File

@ -7,12 +7,10 @@ import (
// RandVal creates one random validator, with a key derived // RandVal creates one random validator, with a key derived
// from the input value // from the input value
func RandVal(i int) types.Validator {
addr := cmn.RandBytes(20)
func RandVal(i int) types.ValidatorUpdate {
pubkey := cmn.RandBytes(32) pubkey := cmn.RandBytes(32)
power := cmn.RandUint16() + 1 power := cmn.RandUint16() + 1
v := types.Ed25519Validator(pubkey, int64(power))
v.Address = addr
v := types.Ed25519ValidatorUpdate(pubkey, int64(power))
return v return v
} }
@ -20,8 +18,8 @@ func RandVal(i int) types.Validator {
// the application. Note that the keys are deterministically // the application. Note that the keys are deterministically
// derived from the index in the array, while the power is // derived from the index in the array, while the power is
// random (Change this if not desired) // random (Change this if not desired)
func RandVals(cnt int) []types.Validator {
res := make([]types.Validator, cnt)
func RandVals(cnt int) []types.ValidatorUpdate {
res := make([]types.ValidatorUpdate, cnt)
for i := 0; i < cnt; i++ { for i := 0; i < cnt; i++ {
res[i] = RandVal(i) res[i] = RandVal(i)
} }


+ 9
- 9
abci/example/kvstore/kvstore_test.go View File

@ -122,11 +122,11 @@ func TestValUpdates(t *testing.T) {
vals1, vals2 := vals[:nInit], kvstore.Validators() vals1, vals2 := vals[:nInit], kvstore.Validators()
valsEqual(t, vals1, vals2) valsEqual(t, vals1, vals2)
var v1, v2, v3 types.Validator
var v1, v2, v3 types.ValidatorUpdate
// add some validators // add some validators
v1, v2 = vals[nInit], vals[nInit+1] v1, v2 = vals[nInit], vals[nInit+1]
diff := []types.Validator{v1, v2}
diff := []types.ValidatorUpdate{v1, v2}
tx1 := MakeValSetChangeTx(v1.PubKey, v1.Power) tx1 := MakeValSetChangeTx(v1.PubKey, v1.Power)
tx2 := MakeValSetChangeTx(v2.PubKey, v2.Power) tx2 := MakeValSetChangeTx(v2.PubKey, v2.Power)
@ -140,7 +140,7 @@ func TestValUpdates(t *testing.T) {
v1.Power = 0 v1.Power = 0
v2.Power = 0 v2.Power = 0
v3.Power = 0 v3.Power = 0
diff = []types.Validator{v1, v2, v3}
diff = []types.ValidatorUpdate{v1, v2, v3}
tx1 = MakeValSetChangeTx(v1.PubKey, v1.Power) tx1 = MakeValSetChangeTx(v1.PubKey, v1.Power)
tx2 = MakeValSetChangeTx(v2.PubKey, v2.Power) tx2 = MakeValSetChangeTx(v2.PubKey, v2.Power)
tx3 := MakeValSetChangeTx(v3.PubKey, v3.Power) tx3 := MakeValSetChangeTx(v3.PubKey, v3.Power)
@ -158,18 +158,18 @@ func TestValUpdates(t *testing.T) {
} else { } else {
v1.Power = 5 v1.Power = 5
} }
diff = []types.Validator{v1}
diff = []types.ValidatorUpdate{v1}
tx1 = MakeValSetChangeTx(v1.PubKey, v1.Power) tx1 = MakeValSetChangeTx(v1.PubKey, v1.Power)
makeApplyBlock(t, kvstore, 3, diff, tx1) makeApplyBlock(t, kvstore, 3, diff, tx1)
vals1 = append([]types.Validator{v1}, vals1[1:]...)
vals1 = append([]types.ValidatorUpdate{v1}, vals1[1:]...)
vals2 = kvstore.Validators() vals2 = kvstore.Validators()
valsEqual(t, vals1, vals2) valsEqual(t, vals1, vals2)
} }
func makeApplyBlock(t *testing.T, kvstore types.Application, heightInt int, diff []types.Validator, txs ...[]byte) {
func makeApplyBlock(t *testing.T, kvstore types.Application, heightInt int, diff []types.ValidatorUpdate, txs ...[]byte) {
// make and apply block // make and apply block
height := int64(heightInt) height := int64(heightInt)
hash := []byte("foo") hash := []byte("foo")
@ -191,12 +191,12 @@ func makeApplyBlock(t *testing.T, kvstore types.Application, heightInt int, diff
} }
// order doesn't matter // order doesn't matter
func valsEqual(t *testing.T, vals1, vals2 []types.Validator) {
func valsEqual(t *testing.T, vals1, vals2 []types.ValidatorUpdate) {
if len(vals1) != len(vals2) { if len(vals1) != len(vals2) {
t.Fatalf("vals dont match in len. got %d, expected %d", len(vals2), len(vals1)) t.Fatalf("vals dont match in len. got %d, expected %d", len(vals2), len(vals1))
} }
sort.Sort(types.Validators(vals1))
sort.Sort(types.Validators(vals2))
sort.Sort(types.ValidatorUpdates(vals1))
sort.Sort(types.ValidatorUpdates(vals2))
for i, v1 := range vals1 { for i, v1 := range vals1 {
v2 := vals2[i] v2 := vals2[i]
if !bytes.Equal(v1.PubKey.Data, v2.PubKey.Data) || if !bytes.Equal(v1.PubKey.Data, v2.PubKey.Data) ||


+ 6
- 6
abci/example/kvstore/persistent_kvstore.go View File

@ -25,7 +25,7 @@ type PersistentKVStoreApplication struct {
app *KVStoreApplication app *KVStoreApplication
// validator set // validator set
ValUpdates []types.Validator
ValUpdates []types.ValidatorUpdate
logger log.Logger logger log.Logger
} }
@ -101,7 +101,7 @@ func (app *PersistentKVStoreApplication) InitChain(req types.RequestInitChain) t
// Track the block hash and header information // Track the block hash and header information
func (app *PersistentKVStoreApplication) BeginBlock(req types.RequestBeginBlock) types.ResponseBeginBlock { func (app *PersistentKVStoreApplication) BeginBlock(req types.RequestBeginBlock) types.ResponseBeginBlock {
// reset valset changes // reset valset changes
app.ValUpdates = make([]types.Validator, 0)
app.ValUpdates = make([]types.ValidatorUpdate, 0)
return types.ResponseBeginBlock{} return types.ResponseBeginBlock{}
} }
@ -113,11 +113,11 @@ func (app *PersistentKVStoreApplication) EndBlock(req types.RequestEndBlock) typ
//--------------------------------------------- //---------------------------------------------
// update validators // update validators
func (app *PersistentKVStoreApplication) Validators() (validators []types.Validator) {
func (app *PersistentKVStoreApplication) Validators() (validators []types.ValidatorUpdate) {
itr := app.app.state.db.Iterator(nil, nil) itr := app.app.state.db.Iterator(nil, nil)
for ; itr.Valid(); itr.Next() { for ; itr.Valid(); itr.Next() {
if isValidatorTx(itr.Key()) { if isValidatorTx(itr.Key()) {
validator := new(types.Validator)
validator := new(types.ValidatorUpdate)
err := types.ReadMessage(bytes.NewBuffer(itr.Value()), validator) err := types.ReadMessage(bytes.NewBuffer(itr.Value()), validator)
if err != nil { if err != nil {
panic(err) panic(err)
@ -167,11 +167,11 @@ func (app *PersistentKVStoreApplication) execValidatorTx(tx []byte) types.Respon
} }
// update // update
return app.updateValidator(types.Ed25519Validator(pubkey, int64(power)))
return app.updateValidator(types.Ed25519ValidatorUpdate(pubkey, int64(power)))
} }
// add, update, or remove a validator // add, update, or remove a validator
func (app *PersistentKVStoreApplication) updateValidator(v types.Validator) types.ResponseDeliverTx {
func (app *PersistentKVStoreApplication) updateValidator(v types.ValidatorUpdate) types.ResponseDeliverTx {
key := []byte("val:" + string(v.PubKey.Data)) key := []byte("val:" + string(v.PubKey.Data))
if v.Power == 0 { if v.Power == 0 {
// remove validator // remove validator


+ 2
- 2
abci/tests/server/client.go View File

@ -12,11 +12,11 @@ import (
func InitChain(client abcicli.Client) error { func InitChain(client abcicli.Client) error {
total := 10 total := 10
vals := make([]types.Validator, total)
vals := make([]types.ValidatorUpdate, total)
for i := 0; i < total; i++ { for i := 0; i < total; i++ {
pubkey := cmn.RandBytes(33) pubkey := cmn.RandBytes(33)
power := cmn.RandInt() power := cmn.RandInt()
vals[i] = types.Ed25519Validator(pubkey, int64(power))
vals[i] = types.Ed25519ValidatorUpdate(pubkey, int64(power))
} }
_, err := client.InitChainSync(types.RequestInitChain{ _, err := client.InitChainSync(types.RequestInitChain{
Validators: vals, Validators: vals,


+ 2
- 2
abci/types/pubkey.go View File

@ -4,8 +4,8 @@ const (
PubKeyEd25519 = "ed25519" PubKeyEd25519 = "ed25519"
) )
func Ed25519Validator(pubkey []byte, power int64) Validator {
return Validator{
func Ed25519ValidatorUpdate(pubkey []byte, power int64) ValidatorUpdate {
return ValidatorUpdate{
// Address: // Address:
PubKey: PubKey{ PubKey: PubKey{
Type: PubKeyEd25519, Type: PubKeyEd25519,


+ 402
- 245
abci/types/types.pb.go View File

@ -42,7 +42,8 @@
BlockID BlockID
PartSetHeader PartSetHeader
Validator Validator
SigningValidator
ValidatorUpdate
VoteInfo
PubKey PubKey
Evidence Evidence
*/ */
@ -551,11 +552,11 @@ func (m *RequestSetOption) GetValue() string {
} }
type RequestInitChain struct { type RequestInitChain struct {
Time time.Time `protobuf:"bytes,1,opt,name=time,stdtime" json:"time"`
ChainId string `protobuf:"bytes,2,opt,name=chain_id,json=chainId,proto3" json:"chain_id,omitempty"`
ConsensusParams *ConsensusParams `protobuf:"bytes,3,opt,name=consensus_params,json=consensusParams" json:"consensus_params,omitempty"`
Validators []Validator `protobuf:"bytes,4,rep,name=validators" json:"validators"`
AppStateBytes []byte `protobuf:"bytes,5,opt,name=app_state_bytes,json=appStateBytes,proto3" json:"app_state_bytes,omitempty"`
Time time.Time `protobuf:"bytes,1,opt,name=time,stdtime" json:"time"`
ChainId string `protobuf:"bytes,2,opt,name=chain_id,json=chainId,proto3" json:"chain_id,omitempty"`
ConsensusParams *ConsensusParams `protobuf:"bytes,3,opt,name=consensus_params,json=consensusParams" json:"consensus_params,omitempty"`
Validators []ValidatorUpdate `protobuf:"bytes,4,rep,name=validators" json:"validators"`
AppStateBytes []byte `protobuf:"bytes,5,opt,name=app_state_bytes,json=appStateBytes,proto3" json:"app_state_bytes,omitempty"`
} }
func (m *RequestInitChain) Reset() { *m = RequestInitChain{} } func (m *RequestInitChain) Reset() { *m = RequestInitChain{} }
@ -584,7 +585,7 @@ func (m *RequestInitChain) GetConsensusParams() *ConsensusParams {
return nil return nil
} }
func (m *RequestInitChain) GetValidators() []Validator {
func (m *RequestInitChain) GetValidators() []ValidatorUpdate {
if m != nil { if m != nil {
return m.Validators return m.Validators
} }
@ -1285,8 +1286,8 @@ func (m *ResponseSetOption) GetInfo() string {
} }
type ResponseInitChain struct { type ResponseInitChain struct {
ConsensusParams *ConsensusParams `protobuf:"bytes,1,opt,name=consensus_params,json=consensusParams" json:"consensus_params,omitempty"`
Validators []Validator `protobuf:"bytes,2,rep,name=validators" json:"validators"`
ConsensusParams *ConsensusParams `protobuf:"bytes,1,opt,name=consensus_params,json=consensusParams" json:"consensus_params,omitempty"`
Validators []ValidatorUpdate `protobuf:"bytes,2,rep,name=validators" json:"validators"`
} }
func (m *ResponseInitChain) Reset() { *m = ResponseInitChain{} } func (m *ResponseInitChain) Reset() { *m = ResponseInitChain{} }
@ -1301,7 +1302,7 @@ func (m *ResponseInitChain) GetConsensusParams() *ConsensusParams {
return nil return nil
} }
func (m *ResponseInitChain) GetValidators() []Validator {
func (m *ResponseInitChain) GetValidators() []ValidatorUpdate {
if m != nil { if m != nil {
return m.Validators return m.Validators
} }
@ -1526,9 +1527,9 @@ func (m *ResponseDeliverTx) GetTags() []common.KVPair {
} }
type ResponseEndBlock struct { type ResponseEndBlock struct {
ValidatorUpdates []Validator `protobuf:"bytes,1,rep,name=validator_updates,json=validatorUpdates" json:"validator_updates"`
ConsensusParamUpdates *ConsensusParams `protobuf:"bytes,2,opt,name=consensus_param_updates,json=consensusParamUpdates" json:"consensus_param_updates,omitempty"`
Tags []common.KVPair `protobuf:"bytes,3,rep,name=tags" json:"tags,omitempty"`
ValidatorUpdates []ValidatorUpdate `protobuf:"bytes,1,rep,name=validator_updates,json=validatorUpdates" json:"validator_updates"`
ConsensusParamUpdates *ConsensusParams `protobuf:"bytes,2,opt,name=consensus_param_updates,json=consensusParamUpdates" json:"consensus_param_updates,omitempty"`
Tags []common.KVPair `protobuf:"bytes,3,rep,name=tags" json:"tags,omitempty"`
} }
func (m *ResponseEndBlock) Reset() { *m = ResponseEndBlock{} } func (m *ResponseEndBlock) Reset() { *m = ResponseEndBlock{} }
@ -1536,7 +1537,7 @@ func (m *ResponseEndBlock) String() string { return proto.CompactText
func (*ResponseEndBlock) ProtoMessage() {} func (*ResponseEndBlock) ProtoMessage() {}
func (*ResponseEndBlock) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{23} } func (*ResponseEndBlock) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{23} }
func (m *ResponseEndBlock) GetValidatorUpdates() []Validator {
func (m *ResponseEndBlock) GetValidatorUpdates() []ValidatorUpdate {
if m != nil { if m != nil {
return m.ValidatorUpdates return m.ValidatorUpdates
} }
@ -1686,8 +1687,7 @@ func (m *BlockGossip) GetBlockPartSizeBytes() int32 {
} }
type LastCommitInfo struct { type LastCommitInfo struct {
CommitRound int32 `protobuf:"varint,1,opt,name=commit_round,json=commitRound,proto3" json:"commit_round,omitempty"`
Validators []SigningValidator `protobuf:"bytes,2,rep,name=validators" json:"validators"`
CommitVotes []VoteInfo `protobuf:"bytes,1,rep,name=commit_votes,json=commitVotes" json:"commit_votes"`
} }
func (m *LastCommitInfo) Reset() { *m = LastCommitInfo{} } func (m *LastCommitInfo) Reset() { *m = LastCommitInfo{} }
@ -1695,16 +1695,9 @@ func (m *LastCommitInfo) String() string { return proto.CompactTextSt
func (*LastCommitInfo) ProtoMessage() {} func (*LastCommitInfo) ProtoMessage() {}
func (*LastCommitInfo) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{29} } func (*LastCommitInfo) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{29} }
func (m *LastCommitInfo) GetCommitRound() int32 {
func (m *LastCommitInfo) GetCommitVotes() []VoteInfo {
if m != nil { if m != nil {
return m.CommitRound
}
return 0
}
func (m *LastCommitInfo) GetValidators() []SigningValidator {
if m != nil {
return m.Validators
return m.CommitVotes
} }
return nil return nil
} }
@ -1893,7 +1886,6 @@ func (m *PartSetHeader) GetHash() []byte {
// Validator // Validator
type Validator struct { type Validator struct {
Address []byte `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"` Address []byte `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"`
PubKey PubKey `protobuf:"bytes,2,opt,name=pub_key,json=pubKey" json:"pub_key"`
Power int64 `protobuf:"varint,3,opt,name=power,proto3" json:"power,omitempty"` Power int64 `protobuf:"varint,3,opt,name=power,proto3" json:"power,omitempty"`
} }
@ -1909,45 +1901,71 @@ func (m *Validator) GetAddress() []byte {
return nil return nil
} }
func (m *Validator) GetPubKey() PubKey {
func (m *Validator) GetPower() int64 {
if m != nil {
return m.Power
}
return 0
}
// ValidatorUpdate
type ValidatorUpdate struct {
PubKey PubKey `protobuf:"bytes,1,opt,name=pub_key,json=pubKey" json:"pub_key"`
Power int64 `protobuf:"varint,2,opt,name=power,proto3" json:"power,omitempty"`
}
func (m *ValidatorUpdate) Reset() { *m = ValidatorUpdate{} }
func (m *ValidatorUpdate) String() string { return proto.CompactTextString(m) }
func (*ValidatorUpdate) ProtoMessage() {}
func (*ValidatorUpdate) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{34} }
func (m *ValidatorUpdate) GetPubKey() PubKey {
if m != nil { if m != nil {
return m.PubKey return m.PubKey
} }
return PubKey{} return PubKey{}
} }
func (m *Validator) GetPower() int64 {
func (m *ValidatorUpdate) GetPower() int64 {
if m != nil { if m != nil {
return m.Power return m.Power
} }
return 0 return 0
} }
// Validator with an extra bool
type SigningValidator struct {
// VoteInfo
type VoteInfo struct {
Validator Validator `protobuf:"bytes,1,opt,name=validator" json:"validator"` Validator Validator `protobuf:"bytes,1,opt,name=validator" json:"validator"`
SignedLastBlock bool `protobuf:"varint,2,opt,name=signed_last_block,json=signedLastBlock,proto3" json:"signed_last_block,omitempty"` SignedLastBlock bool `protobuf:"varint,2,opt,name=signed_last_block,json=signedLastBlock,proto3" json:"signed_last_block,omitempty"`
CommitRound int64 `protobuf:"varint,3,opt,name=commit_round,json=commitRound,proto3" json:"commit_round,omitempty"`
} }
func (m *SigningValidator) Reset() { *m = SigningValidator{} }
func (m *SigningValidator) String() string { return proto.CompactTextString(m) }
func (*SigningValidator) ProtoMessage() {}
func (*SigningValidator) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{34} }
func (m *VoteInfo) Reset() { *m = VoteInfo{} }
func (m *VoteInfo) String() string { return proto.CompactTextString(m) }
func (*VoteInfo) ProtoMessage() {}
func (*VoteInfo) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{35} }
func (m *SigningValidator) GetValidator() Validator {
func (m *VoteInfo) GetValidator() Validator {
if m != nil { if m != nil {
return m.Validator return m.Validator
} }
return Validator{} return Validator{}
} }
func (m *SigningValidator) GetSignedLastBlock() bool {
func (m *VoteInfo) GetSignedLastBlock() bool {
if m != nil { if m != nil {
return m.SignedLastBlock return m.SignedLastBlock
} }
return false return false
} }
func (m *VoteInfo) GetCommitRound() int64 {
if m != nil {
return m.CommitRound
}
return 0
}
type PubKey struct { type PubKey struct {
Type string `protobuf:"bytes,1,opt,name=type,proto3" json:"type,omitempty"` Type string `protobuf:"bytes,1,opt,name=type,proto3" json:"type,omitempty"`
Data []byte `protobuf:"bytes,2,opt,name=data,proto3" json:"data,omitempty"` Data []byte `protobuf:"bytes,2,opt,name=data,proto3" json:"data,omitempty"`
@ -1956,7 +1974,7 @@ type PubKey struct {
func (m *PubKey) Reset() { *m = PubKey{} } func (m *PubKey) Reset() { *m = PubKey{} }
func (m *PubKey) String() string { return proto.CompactTextString(m) } func (m *PubKey) String() string { return proto.CompactTextString(m) }
func (*PubKey) ProtoMessage() {} func (*PubKey) ProtoMessage() {}
func (*PubKey) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{35} }
func (*PubKey) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{36} }
func (m *PubKey) GetType() string { func (m *PubKey) GetType() string {
if m != nil { if m != nil {
@ -1983,7 +2001,7 @@ type Evidence struct {
func (m *Evidence) Reset() { *m = Evidence{} } func (m *Evidence) Reset() { *m = Evidence{} }
func (m *Evidence) String() string { return proto.CompactTextString(m) } func (m *Evidence) String() string { return proto.CompactTextString(m) }
func (*Evidence) ProtoMessage() {} func (*Evidence) ProtoMessage() {}
func (*Evidence) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{36} }
func (*Evidence) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{37} }
func (m *Evidence) GetType() string { func (m *Evidence) GetType() string {
if m != nil { if m != nil {
@ -2089,8 +2107,10 @@ func init() {
golang_proto.RegisterType((*PartSetHeader)(nil), "types.PartSetHeader") golang_proto.RegisterType((*PartSetHeader)(nil), "types.PartSetHeader")
proto.RegisterType((*Validator)(nil), "types.Validator") proto.RegisterType((*Validator)(nil), "types.Validator")
golang_proto.RegisterType((*Validator)(nil), "types.Validator") golang_proto.RegisterType((*Validator)(nil), "types.Validator")
proto.RegisterType((*SigningValidator)(nil), "types.SigningValidator")
golang_proto.RegisterType((*SigningValidator)(nil), "types.SigningValidator")
proto.RegisterType((*ValidatorUpdate)(nil), "types.ValidatorUpdate")
golang_proto.RegisterType((*ValidatorUpdate)(nil), "types.ValidatorUpdate")
proto.RegisterType((*VoteInfo)(nil), "types.VoteInfo")
golang_proto.RegisterType((*VoteInfo)(nil), "types.VoteInfo")
proto.RegisterType((*PubKey)(nil), "types.PubKey") proto.RegisterType((*PubKey)(nil), "types.PubKey")
golang_proto.RegisterType((*PubKey)(nil), "types.PubKey") golang_proto.RegisterType((*PubKey)(nil), "types.PubKey")
proto.RegisterType((*Evidence)(nil), "types.Evidence") proto.RegisterType((*Evidence)(nil), "types.Evidence")
@ -3535,14 +3555,11 @@ func (this *LastCommitInfo) Equal(that interface{}) bool {
} else if this == nil { } else if this == nil {
return false return false
} }
if this.CommitRound != that1.CommitRound {
if len(this.CommitVotes) != len(that1.CommitVotes) {
return false return false
} }
if len(this.Validators) != len(that1.Validators) {
return false
}
for i := range this.Validators {
if !this.Validators[i].Equal(&that1.Validators[i]) {
for i := range this.CommitVotes {
if !this.CommitVotes[i].Equal(&that1.CommitVotes[i]) {
return false return false
} }
} }
@ -3690,6 +3707,30 @@ func (this *Validator) Equal(that interface{}) bool {
if !bytes.Equal(this.Address, that1.Address) { if !bytes.Equal(this.Address, that1.Address) {
return false return false
} }
if this.Power != that1.Power {
return false
}
return true
}
func (this *ValidatorUpdate) Equal(that interface{}) bool {
if that == nil {
return this == nil
}
that1, ok := that.(*ValidatorUpdate)
if !ok {
that2, ok := that.(ValidatorUpdate)
if ok {
that1 = &that2
} else {
return false
}
}
if that1 == nil {
return this == nil
} else if this == nil {
return false
}
if !this.PubKey.Equal(&that1.PubKey) { if !this.PubKey.Equal(&that1.PubKey) {
return false return false
} }
@ -3698,14 +3739,14 @@ func (this *Validator) Equal(that interface{}) bool {
} }
return true return true
} }
func (this *SigningValidator) Equal(that interface{}) bool {
func (this *VoteInfo) Equal(that interface{}) bool {
if that == nil { if that == nil {
return this == nil return this == nil
} }
that1, ok := that.(*SigningValidator)
that1, ok := that.(*VoteInfo)
if !ok { if !ok {
that2, ok := that.(SigningValidator)
that2, ok := that.(VoteInfo)
if ok { if ok {
that1 = &that2 that1 = &that2
} else { } else {
@ -3723,6 +3764,9 @@ func (this *SigningValidator) Equal(that interface{}) bool {
if this.SignedLastBlock != that1.SignedLastBlock { if this.SignedLastBlock != that1.SignedLastBlock {
return false return false
} }
if this.CommitRound != that1.CommitRound {
return false
}
return true return true
} }
func (this *PubKey) Equal(that interface{}) bool { func (this *PubKey) Equal(that interface{}) bool {
@ -5532,14 +5576,9 @@ func (m *LastCommitInfo) MarshalTo(dAtA []byte) (int, error) {
_ = i _ = i
var l int var l int
_ = l _ = l
if m.CommitRound != 0 {
dAtA[i] = 0x8
i++
i = encodeVarintTypes(dAtA, i, uint64(m.CommitRound))
}
if len(m.Validators) > 0 {
for _, msg := range m.Validators {
dAtA[i] = 0x12
if len(m.CommitVotes) > 0 {
for _, msg := range m.CommitVotes {
dAtA[i] = 0xa
i++ i++
i = encodeVarintTypes(dAtA, i, uint64(msg.Size())) i = encodeVarintTypes(dAtA, i, uint64(msg.Size()))
n, err := msg.MarshalTo(dAtA[i:]) n, err := msg.MarshalTo(dAtA[i:])
@ -5743,7 +5782,30 @@ func (m *Validator) MarshalTo(dAtA []byte) (int, error) {
i = encodeVarintTypes(dAtA, i, uint64(len(m.Address))) i = encodeVarintTypes(dAtA, i, uint64(len(m.Address)))
i += copy(dAtA[i:], m.Address) i += copy(dAtA[i:], m.Address)
} }
dAtA[i] = 0x12
if m.Power != 0 {
dAtA[i] = 0x18
i++
i = encodeVarintTypes(dAtA, i, uint64(m.Power))
}
return i, nil
}
func (m *ValidatorUpdate) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalTo(dAtA)
if err != nil {
return nil, err
}
return dAtA[:n], nil
}
func (m *ValidatorUpdate) MarshalTo(dAtA []byte) (int, error) {
var i int
_ = i
var l int
_ = l
dAtA[i] = 0xa
i++ i++
i = encodeVarintTypes(dAtA, i, uint64(m.PubKey.Size())) i = encodeVarintTypes(dAtA, i, uint64(m.PubKey.Size()))
n38, err := m.PubKey.MarshalTo(dAtA[i:]) n38, err := m.PubKey.MarshalTo(dAtA[i:])
@ -5752,14 +5814,14 @@ func (m *Validator) MarshalTo(dAtA []byte) (int, error) {
} }
i += n38 i += n38
if m.Power != 0 { if m.Power != 0 {
dAtA[i] = 0x18
dAtA[i] = 0x10
i++ i++
i = encodeVarintTypes(dAtA, i, uint64(m.Power)) i = encodeVarintTypes(dAtA, i, uint64(m.Power))
} }
return i, nil return i, nil
} }
func (m *SigningValidator) Marshal() (dAtA []byte, err error) {
func (m *VoteInfo) Marshal() (dAtA []byte, err error) {
size := m.Size() size := m.Size()
dAtA = make([]byte, size) dAtA = make([]byte, size)
n, err := m.MarshalTo(dAtA) n, err := m.MarshalTo(dAtA)
@ -5769,7 +5831,7 @@ func (m *SigningValidator) Marshal() (dAtA []byte, err error) {
return dAtA[:n], nil return dAtA[:n], nil
} }
func (m *SigningValidator) MarshalTo(dAtA []byte) (int, error) {
func (m *VoteInfo) MarshalTo(dAtA []byte) (int, error) {
var i int var i int
_ = i _ = i
var l int var l int
@ -5792,6 +5854,11 @@ func (m *SigningValidator) MarshalTo(dAtA []byte) (int, error) {
} }
i++ i++
} }
if m.CommitRound != 0 {
dAtA[i] = 0x18
i++
i = encodeVarintTypes(dAtA, i, uint64(m.CommitRound))
}
return i, nil return i, nil
} }
@ -6013,9 +6080,9 @@ func NewPopulatedRequestInitChain(r randyTypes, easy bool) *RequestInitChain {
} }
if r.Intn(10) != 0 { if r.Intn(10) != 0 {
v2 := r.Intn(5) v2 := r.Intn(5)
this.Validators = make([]Validator, v2)
this.Validators = make([]ValidatorUpdate, v2)
for i := 0; i < v2; i++ { for i := 0; i < v2; i++ {
v3 := NewPopulatedValidator(r, easy)
v3 := NewPopulatedValidatorUpdate(r, easy)
this.Validators[i] = *v3 this.Validators[i] = *v3
} }
} }
@ -6265,9 +6332,9 @@ func NewPopulatedResponseInitChain(r randyTypes, easy bool) *ResponseInitChain {
} }
if r.Intn(10) != 0 { if r.Intn(10) != 0 {
v14 := r.Intn(5) v14 := r.Intn(5)
this.Validators = make([]Validator, v14)
this.Validators = make([]ValidatorUpdate, v14)
for i := 0; i < v14; i++ { for i := 0; i < v14; i++ {
v15 := NewPopulatedValidator(r, easy)
v15 := NewPopulatedValidatorUpdate(r, easy)
this.Validators[i] = *v15 this.Validators[i] = *v15
} }
} }
@ -6390,9 +6457,9 @@ func NewPopulatedResponseEndBlock(r randyTypes, easy bool) *ResponseEndBlock {
this := &ResponseEndBlock{} this := &ResponseEndBlock{}
if r.Intn(10) != 0 { if r.Intn(10) != 0 {
v27 := r.Intn(5) v27 := r.Intn(5)
this.ValidatorUpdates = make([]Validator, v27)
this.ValidatorUpdates = make([]ValidatorUpdate, v27)
for i := 0; i < v27; i++ { for i := 0; i < v27; i++ {
v28 := NewPopulatedValidator(r, easy)
v28 := NewPopulatedValidatorUpdate(r, easy)
this.ValidatorUpdates[i] = *v28 this.ValidatorUpdates[i] = *v28
} }
} }
@ -6487,16 +6554,12 @@ func NewPopulatedBlockGossip(r randyTypes, easy bool) *BlockGossip {
func NewPopulatedLastCommitInfo(r randyTypes, easy bool) *LastCommitInfo { func NewPopulatedLastCommitInfo(r randyTypes, easy bool) *LastCommitInfo {
this := &LastCommitInfo{} this := &LastCommitInfo{}
this.CommitRound = int32(r.Int31())
if r.Intn(2) == 0 {
this.CommitRound *= -1
}
if r.Intn(10) != 0 { if r.Intn(10) != 0 {
v32 := r.Intn(5) v32 := r.Intn(5)
this.Validators = make([]SigningValidator, v32)
this.CommitVotes = make([]VoteInfo, v32)
for i := 0; i < v32; i++ { for i := 0; i < v32; i++ {
v33 := NewPopulatedSigningValidator(r, easy)
this.Validators[i] = *v33
v33 := NewPopulatedVoteInfo(r, easy)
this.CommitVotes[i] = *v33
} }
} }
if !easy && r.Intn(10) != 0 { if !easy && r.Intn(10) != 0 {
@ -6610,6 +6673,17 @@ func NewPopulatedValidator(r randyTypes, easy bool) *Validator {
for i := 0; i < v48; i++ { for i := 0; i < v48; i++ {
this.Address[i] = byte(r.Intn(256)) this.Address[i] = byte(r.Intn(256))
} }
this.Power = int64(r.Int63())
if r.Intn(2) == 0 {
this.Power *= -1
}
if !easy && r.Intn(10) != 0 {
}
return this
}
func NewPopulatedValidatorUpdate(r randyTypes, easy bool) *ValidatorUpdate {
this := &ValidatorUpdate{}
v49 := NewPopulatedPubKey(r, easy) v49 := NewPopulatedPubKey(r, easy)
this.PubKey = *v49 this.PubKey = *v49
this.Power = int64(r.Int63()) this.Power = int64(r.Int63())
@ -6621,11 +6695,15 @@ func NewPopulatedValidator(r randyTypes, easy bool) *Validator {
return this return this
} }
func NewPopulatedSigningValidator(r randyTypes, easy bool) *SigningValidator {
this := &SigningValidator{}
func NewPopulatedVoteInfo(r randyTypes, easy bool) *VoteInfo {
this := &VoteInfo{}
v50 := NewPopulatedValidator(r, easy) v50 := NewPopulatedValidator(r, easy)
this.Validator = *v50 this.Validator = *v50
this.SignedLastBlock = bool(bool(r.Intn(2) == 0)) this.SignedLastBlock = bool(bool(r.Intn(2) == 0))
this.CommitRound = int64(r.Int63())
if r.Intn(2) == 0 {
this.CommitRound *= -1
}
if !easy && r.Intn(10) != 0 { if !easy && r.Intn(10) != 0 {
} }
return this return this
@ -7384,11 +7462,8 @@ func (m *BlockGossip) Size() (n int) {
func (m *LastCommitInfo) Size() (n int) { func (m *LastCommitInfo) Size() (n int) {
var l int var l int
_ = l _ = l
if m.CommitRound != 0 {
n += 1 + sovTypes(uint64(m.CommitRound))
}
if len(m.Validators) > 0 {
for _, e := range m.Validators {
if len(m.CommitVotes) > 0 {
for _, e := range m.CommitVotes {
l = e.Size() l = e.Size()
n += 1 + l + sovTypes(uint64(l)) n += 1 + l + sovTypes(uint64(l))
} }
@ -7487,6 +7562,15 @@ func (m *Validator) Size() (n int) {
if l > 0 { if l > 0 {
n += 1 + l + sovTypes(uint64(l)) n += 1 + l + sovTypes(uint64(l))
} }
if m.Power != 0 {
n += 1 + sovTypes(uint64(m.Power))
}
return n
}
func (m *ValidatorUpdate) Size() (n int) {
var l int
_ = l
l = m.PubKey.Size() l = m.PubKey.Size()
n += 1 + l + sovTypes(uint64(l)) n += 1 + l + sovTypes(uint64(l))
if m.Power != 0 { if m.Power != 0 {
@ -7495,7 +7579,7 @@ func (m *Validator) Size() (n int) {
return n return n
} }
func (m *SigningValidator) Size() (n int) {
func (m *VoteInfo) Size() (n int) {
var l int var l int
_ = l _ = l
l = m.Validator.Size() l = m.Validator.Size()
@ -7503,6 +7587,9 @@ func (m *SigningValidator) Size() (n int) {
if m.SignedLastBlock { if m.SignedLastBlock {
n += 2 n += 2
} }
if m.CommitRound != 0 {
n += 1 + sovTypes(uint64(m.CommitRound))
}
return n return n
} }
@ -8418,7 +8505,7 @@ func (m *RequestInitChain) Unmarshal(dAtA []byte) error {
if postIndex > l { if postIndex > l {
return io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
} }
m.Validators = append(m.Validators, Validator{})
m.Validators = append(m.Validators, ValidatorUpdate{})
if err := m.Validators[len(m.Validators)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { if err := m.Validators[len(m.Validators)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err return err
} }
@ -10092,7 +10179,7 @@ func (m *ResponseInitChain) Unmarshal(dAtA []byte) error {
if postIndex > l { if postIndex > l {
return io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
} }
m.Validators = append(m.Validators, Validator{})
m.Validators = append(m.Validators, ValidatorUpdate{})
if err := m.Validators[len(m.Validators)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { if err := m.Validators[len(m.Validators)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err return err
} }
@ -10966,7 +11053,7 @@ func (m *ResponseEndBlock) Unmarshal(dAtA []byte) error {
if postIndex > l { if postIndex > l {
return io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
} }
m.ValidatorUpdates = append(m.ValidatorUpdates, Validator{})
m.ValidatorUpdates = append(m.ValidatorUpdates, ValidatorUpdate{})
if err := m.ValidatorUpdates[len(m.ValidatorUpdates)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { if err := m.ValidatorUpdates[len(m.ValidatorUpdates)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err return err
} }
@ -11580,27 +11667,8 @@ func (m *LastCommitInfo) Unmarshal(dAtA []byte) error {
} }
switch fieldNum { switch fieldNum {
case 1: case 1:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field CommitRound", wireType)
}
m.CommitRound = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowTypes
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.CommitRound |= (int32(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
case 2:
if wireType != 2 { if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Validators", wireType)
return fmt.Errorf("proto: wrong wireType = %d for field CommitVotes", wireType)
} }
var msglen int var msglen int
for shift := uint(0); ; shift += 7 { for shift := uint(0); ; shift += 7 {
@ -11624,8 +11692,8 @@ func (m *LastCommitInfo) Unmarshal(dAtA []byte) error {
if postIndex > l { if postIndex > l {
return io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
} }
m.Validators = append(m.Validators, SigningValidator{})
if err := m.Validators[len(m.Validators)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
m.CommitVotes = append(m.CommitVotes, VoteInfo{})
if err := m.CommitVotes[len(m.CommitVotes)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err return err
} }
iNdEx = postIndex iNdEx = postIndex
@ -12396,7 +12464,76 @@ func (m *Validator) Unmarshal(dAtA []byte) error {
m.Address = []byte{} m.Address = []byte{}
} }
iNdEx = postIndex iNdEx = postIndex
case 2:
case 3:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field Power", wireType)
}
m.Power = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowTypes
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.Power |= (int64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
default:
iNdEx = preIndex
skippy, err := skipTypes(dAtA[iNdEx:])
if err != nil {
return err
}
if skippy < 0 {
return ErrInvalidLengthTypes
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func (m *ValidatorUpdate) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
preIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowTypes
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: ValidatorUpdate: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: ValidatorUpdate: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 2 { if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field PubKey", wireType) return fmt.Errorf("proto: wrong wireType = %d for field PubKey", wireType)
} }
@ -12426,7 +12563,7 @@ func (m *Validator) Unmarshal(dAtA []byte) error {
return err return err
} }
iNdEx = postIndex iNdEx = postIndex
case 3:
case 2:
if wireType != 0 { if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field Power", wireType) return fmt.Errorf("proto: wrong wireType = %d for field Power", wireType)
} }
@ -12466,7 +12603,7 @@ func (m *Validator) Unmarshal(dAtA []byte) error {
} }
return nil return nil
} }
func (m *SigningValidator) Unmarshal(dAtA []byte) error {
func (m *VoteInfo) Unmarshal(dAtA []byte) error {
l := len(dAtA) l := len(dAtA)
iNdEx := 0 iNdEx := 0
for iNdEx < l { for iNdEx < l {
@ -12489,10 +12626,10 @@ func (m *SigningValidator) Unmarshal(dAtA []byte) error {
fieldNum := int32(wire >> 3) fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7) wireType := int(wire & 0x7)
if wireType == 4 { if wireType == 4 {
return fmt.Errorf("proto: SigningValidator: wiretype end group for non-group")
return fmt.Errorf("proto: VoteInfo: wiretype end group for non-group")
} }
if fieldNum <= 0 { if fieldNum <= 0 {
return fmt.Errorf("proto: SigningValidator: illegal tag %d (wire type %d)", fieldNum, wire)
return fmt.Errorf("proto: VoteInfo: illegal tag %d (wire type %d)", fieldNum, wire)
} }
switch fieldNum { switch fieldNum {
case 1: case 1:
@ -12545,6 +12682,25 @@ func (m *SigningValidator) Unmarshal(dAtA []byte) error {
} }
} }
m.SignedLastBlock = bool(v != 0) m.SignedLastBlock = bool(v != 0)
case 3:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field CommitRound", wireType)
}
m.CommitRound = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowTypes
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.CommitRound |= (int64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
default: default:
iNdEx = preIndex iNdEx = preIndex
skippy, err := skipTypes(dAtA[iNdEx:]) skippy, err := skipTypes(dAtA[iNdEx:])
@ -12962,137 +13118,138 @@ func init() { proto.RegisterFile("abci/types/types.proto", fileDescriptorTypes)
func init() { golang_proto.RegisterFile("abci/types/types.proto", fileDescriptorTypes) } func init() { golang_proto.RegisterFile("abci/types/types.proto", fileDescriptorTypes) }
var fileDescriptorTypes = []byte{ var fileDescriptorTypes = []byte{
// 2109 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xdc, 0x58, 0xdf, 0x6f, 0x23, 0x49,
0xf1, 0xcf, 0x38, 0x8e, 0xed, 0x29, 0x3b, 0xb6, 0xb7, 0x37, 0x9b, 0x78, 0x7d, 0xdf, 0x6f, 0xb2,
0x0c, 0xb0, 0x97, 0x70, 0xb9, 0xe4, 0xc8, 0xb1, 0xa7, 0xec, 0x1d, 0x77, 0x22, 0xce, 0x2e, 0x97,
0xe8, 0x0e, 0x08, 0xb3, 0x7b, 0x8b, 0x84, 0x90, 0x46, 0x6d, 0x4f, 0x67, 0x3c, 0x5a, 0x7b, 0x66,
0x6e, 0xa6, 0x9d, 0x73, 0xf6, 0x4f, 0x40, 0x27, 0xc4, 0x1b, 0xcf, 0xbc, 0xf1, 0x0f, 0x20, 0xf1,
0xc8, 0x13, 0xba, 0x47, 0x84, 0x40, 0xbc, 0x2d, 0x90, 0x13, 0x2f, 0xfc, 0x05, 0x3c, 0xa2, 0xae,
0xee, 0xf9, 0x99, 0xf1, 0x6a, 0x6f, 0x79, 0xe3, 0xc5, 0x9e, 0xee, 0xaa, 0xea, 0xee, 0xaa, 0xae,
0xaa, 0x4f, 0x55, 0xc3, 0x3a, 0x1d, 0x8e, 0xdc, 0x7d, 0x7e, 0x19, 0xb0, 0x48, 0xfe, 0xee, 0x05,
0xa1, 0xcf, 0x7d, 0xb2, 0x82, 0x83, 0xfe, 0x9b, 0x8e, 0xcb, 0xc7, 0xb3, 0xe1, 0xde, 0xc8, 0x9f,
0xee, 0x3b, 0xbe, 0xe3, 0xef, 0x23, 0x75, 0x38, 0x3b, 0xc7, 0x11, 0x0e, 0xf0, 0x4b, 0x4a, 0xf5,
0xb7, 0x1c, 0xdf, 0x77, 0x26, 0x2c, 0xe5, 0xe2, 0xee, 0x94, 0x45, 0x9c, 0x4e, 0x03, 0xc5, 0x70,
0x98, 0x59, 0x8f, 0x33, 0xcf, 0x66, 0xe1, 0xd4, 0xf5, 0x78, 0xf6, 0x73, 0xe2, 0x0e, 0xa3, 0xfd,
0x91, 0x3f, 0x9d, 0xfa, 0x5e, 0xf6, 0x40, 0xc6, 0x1f, 0xaa, 0x50, 0x37, 0xd9, 0xa7, 0x33, 0x16,
0x71, 0xb2, 0x0d, 0x55, 0x36, 0x1a, 0xfb, 0xbd, 0xca, 0x1d, 0x6d, 0xbb, 0x79, 0x40, 0xf6, 0x24,
0x9f, 0xa2, 0x3e, 0x1c, 0x8d, 0xfd, 0x93, 0x25, 0x13, 0x39, 0xc8, 0x1b, 0xb0, 0x72, 0x3e, 0x99,
0x45, 0xe3, 0xde, 0x32, 0xb2, 0xde, 0xcc, 0xb3, 0x7e, 0x5f, 0x90, 0x4e, 0x96, 0x4c, 0xc9, 0x23,
0x96, 0x75, 0xbd, 0x73, 0xbf, 0x57, 0x2d, 0x5b, 0xf6, 0xd4, 0x3b, 0xc7, 0x65, 0x05, 0x07, 0x39,
0x04, 0x88, 0x18, 0xb7, 0xfc, 0x80, 0xbb, 0xbe, 0xd7, 0x5b, 0x41, 0xfe, 0x8d, 0x3c, 0xff, 0x23,
0xc6, 0x7f, 0x84, 0xe4, 0x93, 0x25, 0x53, 0x8f, 0xe2, 0x81, 0x90, 0x74, 0x3d, 0x97, 0x5b, 0xa3,
0x31, 0x75, 0xbd, 0x5e, 0xad, 0x4c, 0xf2, 0xd4, 0x73, 0xf9, 0xb1, 0x20, 0x0b, 0x49, 0x37, 0x1e,
0x08, 0x55, 0x3e, 0x9d, 0xb1, 0xf0, 0xb2, 0x57, 0x2f, 0x53, 0xe5, 0xc7, 0x82, 0x24, 0x54, 0x41,
0x1e, 0xf2, 0x1e, 0x34, 0x87, 0xcc, 0x71, 0x3d, 0x6b, 0x38, 0xf1, 0x47, 0x4f, 0x7b, 0x0d, 0x14,
0xe9, 0xe5, 0x45, 0x06, 0x82, 0x61, 0x20, 0xe8, 0x27, 0x4b, 0x26, 0x0c, 0x93, 0x11, 0x39, 0x80,
0xc6, 0x68, 0xcc, 0x46, 0x4f, 0x2d, 0x3e, 0xef, 0xe9, 0x28, 0x79, 0x2b, 0x2f, 0x79, 0x2c, 0xa8,
0x8f, 0xe7, 0x27, 0x4b, 0x66, 0x7d, 0x24, 0x3f, 0xc9, 0x3d, 0xd0, 0x99, 0x67, 0xab, 0xed, 0x9a,
0x28, 0xb4, 0x5e, 0xb8, 0x17, 0xcf, 0x8e, 0x37, 0x6b, 0x30, 0xf5, 0x4d, 0xf6, 0xa0, 0x26, 0xee,
0xda, 0xe5, 0xbd, 0x16, 0xca, 0xac, 0x15, 0x36, 0x42, 0xda, 0xc9, 0x92, 0xa9, 0xb8, 0x84, 0xf9,
0x6c, 0x36, 0x71, 0x2f, 0x58, 0x28, 0x0e, 0x77, 0xb3, 0xcc, 0x7c, 0x0f, 0x24, 0x1d, 0x8f, 0xa7,
0xdb, 0xf1, 0x60, 0x50, 0x87, 0x95, 0x0b, 0x3a, 0x99, 0x31, 0xe3, 0x75, 0x68, 0x66, 0x3c, 0x85,
0xf4, 0xa0, 0x3e, 0x65, 0x51, 0x44, 0x1d, 0xd6, 0xd3, 0xee, 0x68, 0xdb, 0xba, 0x19, 0x0f, 0x8d,
0x36, 0xb4, 0xb2, 0x7e, 0x92, 0x11, 0x14, 0xbe, 0x20, 0x04, 0x2f, 0x58, 0x18, 0x09, 0x07, 0x50,
0x82, 0x6a, 0x68, 0xbc, 0x0b, 0xdd, 0xa2, 0x13, 0x90, 0x2e, 0x2c, 0x3f, 0x65, 0x97, 0x8a, 0x53,
0x7c, 0x92, 0x35, 0x75, 0x20, 0xf4, 0x62, 0xdd, 0x54, 0xa7, 0xfb, 0x79, 0x25, 0x11, 0x4e, 0xfc,
0x80, 0x1c, 0x42, 0x55, 0x04, 0x12, 0x4a, 0x37, 0x0f, 0xfa, 0x7b, 0x32, 0xca, 0xf6, 0xe2, 0x28,
0xdb, 0x7b, 0x1c, 0x47, 0xd9, 0xa0, 0xf1, 0xc5, 0xf3, 0xad, 0xa5, 0x5f, 0xfe, 0x6d, 0x4b, 0x33,
0x51, 0x82, 0xdc, 0x16, 0x57, 0x49, 0x5d, 0xcf, 0x72, 0x6d, 0xb5, 0x4f, 0x1d, 0xc7, 0xa7, 0x36,
0x39, 0x82, 0xee, 0xc8, 0xf7, 0x22, 0xe6, 0x45, 0xb3, 0xc8, 0x0a, 0x68, 0x48, 0xa7, 0x91, 0x8a,
0x92, 0xf8, 0xe2, 0x8e, 0x63, 0xf2, 0x19, 0x52, 0xcd, 0xce, 0x28, 0x3f, 0x41, 0xde, 0x01, 0xb8,
0xa0, 0x13, 0xd7, 0xa6, 0xdc, 0x0f, 0xa3, 0x5e, 0xf5, 0xce, 0xf2, 0x76, 0xf3, 0xa0, 0xab, 0x84,
0x9f, 0xc4, 0x84, 0x41, 0x55, 0x9c, 0xc9, 0xcc, 0x70, 0x92, 0xbb, 0xd0, 0xa1, 0x41, 0x60, 0x45,
0x9c, 0x72, 0x66, 0x0d, 0x2f, 0x39, 0x8b, 0x30, 0x86, 0x5a, 0xe6, 0x2a, 0x0d, 0x82, 0x47, 0x62,
0x76, 0x20, 0x26, 0x0d, 0x3b, 0xb9, 0x01, 0x74, 0x6f, 0x42, 0xa0, 0x6a, 0x53, 0x4e, 0xd1, 0x0e,
0x2d, 0x13, 0xbf, 0xc5, 0x5c, 0x40, 0xf9, 0x58, 0x69, 0x87, 0xdf, 0x64, 0x1d, 0x6a, 0x63, 0xe6,
0x3a, 0x63, 0x8e, 0x0a, 0x2d, 0x9b, 0x6a, 0x24, 0x4c, 0x1e, 0x84, 0xfe, 0x05, 0xc3, 0x08, 0x6f,
0x98, 0x72, 0x60, 0xfc, 0x53, 0x83, 0x1b, 0xd7, 0x42, 0x42, 0xac, 0x3b, 0xa6, 0xd1, 0x38, 0xde,
0x4b, 0x7c, 0x93, 0x37, 0xc4, 0xba, 0xd4, 0x66, 0xa1, 0xca, 0x3c, 0xab, 0x4a, 0xd7, 0x13, 0x9c,
0x54, 0x8a, 0x2a, 0x16, 0xf2, 0x10, 0xba, 0x13, 0x1a, 0x71, 0x4b, 0x7a, 0xae, 0x85, 0x99, 0x65,
0x39, 0x17, 0x4d, 0x1f, 0xd3, 0xd8, 0xc3, 0x85, 0x43, 0x29, 0xf1, 0xf6, 0x24, 0x37, 0x4b, 0x4e,
0x60, 0x6d, 0x78, 0xf9, 0x8c, 0x7a, 0xdc, 0xf5, 0x98, 0x75, 0xcd, 0xda, 0x1d, 0xb5, 0xd4, 0xc3,
0x0b, 0xd7, 0x66, 0xde, 0x88, 0xa9, 0x45, 0x6e, 0x26, 0x22, 0xc9, 0x35, 0x44, 0xc6, 0x1d, 0x68,
0xe7, 0xe3, 0x97, 0xb4, 0xa1, 0xc2, 0xe7, 0x4a, 0xc3, 0x0a, 0x9f, 0x1b, 0x46, 0xe2, 0x7b, 0x49,
0x10, 0x5d, 0xe3, 0xd9, 0x81, 0x4e, 0x21, 0xa0, 0x33, 0xe6, 0xd6, 0xb2, 0xe6, 0x36, 0x3a, 0xb0,
0x9a, 0x8b, 0x63, 0xe3, 0xf3, 0x15, 0x68, 0x98, 0x2c, 0x0a, 0x84, 0x1b, 0x91, 0x43, 0xd0, 0xd9,
0x7c, 0xc4, 0x64, 0x0a, 0xd5, 0x0a, 0x09, 0x4a, 0xf2, 0x3c, 0x8c, 0xe9, 0x22, 0x94, 0x13, 0x66,
0xb2, 0x93, 0x4b, 0xff, 0x37, 0x8b, 0x42, 0xd9, 0xfc, 0xbf, 0x9b, 0xcf, 0xff, 0x6b, 0x05, 0xde,
0x02, 0x00, 0xec, 0xe4, 0x00, 0xa0, 0xb8, 0x70, 0x0e, 0x01, 0xee, 0x97, 0x20, 0x40, 0xf1, 0xf8,
0x0b, 0x20, 0xe0, 0x7e, 0x09, 0x04, 0xf4, 0xae, 0xed, 0x55, 0x8a, 0x01, 0xbb, 0x79, 0x0c, 0x28,
0xaa, 0x53, 0x00, 0x81, 0xef, 0x96, 0x81, 0xc0, 0xed, 0x82, 0xcc, 0x42, 0x14, 0x78, 0xfb, 0x1a,
0x0a, 0xac, 0x17, 0x44, 0x4b, 0x60, 0xe0, 0x7e, 0x2e, 0x3f, 0x43, 0xa9, 0x6e, 0xe5, 0x09, 0x9a,
0xbc, 0x73, 0x1d, 0x41, 0x36, 0x8a, 0x57, 0x5b, 0x06, 0x21, 0xfb, 0x05, 0x08, 0xb9, 0x55, 0x3c,
0x65, 0x01, 0x43, 0x52, 0x24, 0xd8, 0x11, 0x71, 0x5f, 0xf0, 0x34, 0x91, 0x23, 0x58, 0x18, 0xfa,
0xa1, 0x4a, 0xd5, 0x72, 0x60, 0x6c, 0x8b, 0x4c, 0x94, 0xfa, 0xd7, 0x0b, 0x50, 0x03, 0x9d, 0x3e,
0xe3, 0x5d, 0xc6, 0xaf, 0xb4, 0x54, 0x16, 0x23, 0x3a, 0x9b, 0xc5, 0x74, 0x95, 0xc5, 0x32, 0x60,
0x52, 0xc9, 0x81, 0x09, 0xf9, 0x16, 0xdc, 0xc0, 0x34, 0x82, 0x76, 0xb1, 0x72, 0x69, 0xad, 0x23,
0x08, 0xd2, 0x20, 0x32, 0xbf, 0xbd, 0x09, 0x37, 0x33, 0xbc, 0x22, 0xc5, 0x62, 0x0a, 0xab, 0x62,
0xf0, 0x76, 0x13, 0xee, 0xa3, 0x20, 0x38, 0xa1, 0xd1, 0xd8, 0xf8, 0x41, 0xaa, 0x7f, 0x0a, 0x54,
0x04, 0xaa, 0x23, 0xdf, 0x96, 0x6a, 0xad, 0x9a, 0xf8, 0x2d, 0xc0, 0x6b, 0xe2, 0x3b, 0xb8, 0xab,
0x6e, 0x8a, 0x4f, 0xc1, 0x95, 0x44, 0x8a, 0x2e, 0x43, 0xc2, 0xf8, 0x85, 0x96, 0xae, 0x97, 0x62,
0x57, 0x19, 0xcc, 0x68, 0xff, 0x0d, 0xcc, 0x54, 0x5e, 0x16, 0x66, 0x8c, 0xdf, 0x6a, 0xe9, 0x5d,
0x24, 0x00, 0xf2, 0x6a, 0xca, 0x09, 0xb7, 0x70, 0x3d, 0x9b, 0xcd, 0x31, 0xd4, 0x97, 0x4d, 0x39,
0x88, 0x51, 0xbd, 0x86, 0x06, 0xce, 0xa3, 0x7a, 0x1d, 0xe7, 0xe4, 0x40, 0x01, 0x8f, 0x7f, 0x8e,
0x31, 0xd8, 0x32, 0xe5, 0x20, 0x93, 0x37, 0xf5, 0x5c, 0xde, 0x3c, 0x03, 0x72, 0x3d, 0x3a, 0xc9,
0xbb, 0x50, 0xe5, 0xd4, 0x11, 0xc6, 0x13, 0xfa, 0xb7, 0xf7, 0x64, 0x8d, 0xbc, 0xf7, 0xd1, 0x93,
0x33, 0xea, 0x86, 0x83, 0x75, 0xa1, 0xfd, 0xbf, 0x9e, 0x6f, 0xb5, 0x05, 0xcf, 0xae, 0x3f, 0x75,
0x39, 0x9b, 0x06, 0xfc, 0xd2, 0x44, 0x19, 0xe3, 0x2f, 0x9a, 0xc8, 0xda, 0xb9, 0xa8, 0x2d, 0xb5,
0x45, 0xec, 0x9a, 0x95, 0x0c, 0xc0, 0xbe, 0x9c, 0x7d, 0xfe, 0x1f, 0xc0, 0xa1, 0x91, 0xf5, 0x19,
0xf5, 0x38, 0xb3, 0x95, 0x91, 0x74, 0x87, 0x46, 0x3f, 0xc1, 0x09, 0x51, 0x87, 0x08, 0xf2, 0x2c,
0x62, 0x36, 0x5a, 0x6b, 0xd9, 0xac, 0x3b, 0x34, 0xfa, 0x24, 0x62, 0x76, 0xa2, 0x57, 0xfd, 0x15,
0xf4, 0xfa, 0x6b, 0xc6, 0xe5, 0x52, 0xc8, 0xfa, 0x5f, 0xd0, 0xec, 0x4b, 0x4d, 0x60, 0x71, 0x3e,
0xed, 0x91, 0x63, 0xb8, 0x91, 0xb8, 0xb7, 0x35, 0x0b, 0x6c, 0x2a, 0x2a, 0x27, 0xed, 0x85, 0xf1,
0xd0, 0x4d, 0x04, 0x3e, 0x91, 0xfc, 0xe4, 0x87, 0xb0, 0x51, 0x08, 0xc8, 0x64, 0xa9, 0xca, 0x0b,
0xe3, 0xf2, 0x56, 0x3e, 0x2e, 0xe3, 0xf5, 0x62, 0x2d, 0x97, 0x5f, 0x41, 0xcb, 0x6f, 0x88, 0x92,
0x24, 0x9b, 0xa6, 0xcb, 0xee, 0xc9, 0xf8, 0xb5, 0x06, 0x9d, 0xc2, 0x61, 0xc8, 0x3e, 0x80, 0xcc,
0x72, 0x91, 0xfb, 0x2c, 0x2e, 0x8c, 0x63, 0x1b, 0xa0, 0xb1, 0x1e, 0xb9, 0xcf, 0x98, 0xa9, 0x0f,
0xe3, 0x4f, 0x72, 0x17, 0xea, 0x7c, 0x2e, 0xb9, 0xf3, 0xc5, 0xdb, 0xe3, 0x39, 0xb2, 0xd6, 0x38,
0xfe, 0x93, 0x7b, 0xd0, 0x92, 0x0b, 0x3b, 0x7e, 0x14, 0xb9, 0x81, 0x2a, 0x1c, 0x48, 0x76, 0xe9,
0x0f, 0x91, 0x62, 0x36, 0x87, 0xe9, 0xc0, 0xf8, 0x29, 0xe8, 0xc9, 0xb6, 0xe4, 0x35, 0xd0, 0xa7,
0x74, 0xae, 0x2a, 0x5b, 0x71, 0xb6, 0x15, 0xb3, 0x31, 0xa5, 0x73, 0x2c, 0x6a, 0xc9, 0x06, 0xd4,
0x05, 0x91, 0xcf, 0xa5, 0xbd, 0x57, 0xcc, 0xda, 0x94, 0xce, 0x1f, 0xcf, 0x13, 0x82, 0x43, 0xa3,
0xb8, 0x6c, 0x9d, 0xd2, 0xf9, 0x87, 0x34, 0x32, 0x3e, 0x80, 0x9a, 0x3c, 0xe4, 0x4b, 0x2d, 0x2c,
0xe4, 0x2b, 0x39, 0xf9, 0xef, 0x41, 0x33, 0x73, 0x6e, 0xf2, 0x6d, 0xb8, 0x25, 0x35, 0x0c, 0x68,
0xc8, 0xd1, 0x22, 0xb9, 0x05, 0x09, 0x12, 0xcf, 0x68, 0xc8, 0xc5, 0x96, 0xb2, 0x10, 0x0f, 0xa1,
0x9d, 0x2f, 0x56, 0xc9, 0xd7, 0xa0, 0xa5, 0x0a, 0xdb, 0xd0, 0x9f, 0x79, 0xb6, 0x92, 0x6d, 0xca,
0x39, 0x53, 0x4c, 0x91, 0xf7, 0x4b, 0xd2, 0x76, 0x8c, 0xe8, 0x8f, 0x5c, 0xc7, 0x73, 0x3d, 0xe7,
0x45, 0xd9, 0xfb, 0x4f, 0x55, 0xa8, 0xc9, 0xc2, 0x9a, 0xdc, 0xcd, 0x74, 0x31, 0x88, 0x9a, 0x83,
0xe6, 0xd5, 0xf3, 0xad, 0x3a, 0x02, 0xcc, 0xe9, 0x83, 0xb4, 0xa5, 0x49, 0x13, 0x6a, 0x25, 0x57,
0xf7, 0xc7, 0xfd, 0xd3, 0xf2, 0x57, 0xee, 0x9f, 0x36, 0xa0, 0xee, 0xcd, 0xa6, 0x78, 0x59, 0x55,
0xb9, 0xa4, 0x37, 0x9b, 0x8a, 0xcb, 0x7a, 0x0d, 0x74, 0xee, 0x73, 0x3a, 0x41, 0x92, 0x4c, 0x0a,
0x0d, 0x9c, 0x10, 0xc4, 0x43, 0x58, 0xcd, 0xe0, 0xb0, 0x6b, 0xab, 0x22, 0xaf, 0x9d, 0x75, 0xa2,
0xd3, 0x07, 0x4a, 0xe7, 0x66, 0x82, 0xcb, 0xa7, 0x36, 0xd9, 0xce, 0x37, 0x0d, 0x08, 0xdf, 0x12,
0x49, 0x32, 0x7d, 0x81, 0x00, 0x6f, 0x71, 0x00, 0x11, 0x1c, 0x92, 0x45, 0xc2, 0x4a, 0x43, 0x4c,
0x20, 0xf1, 0x75, 0xe8, 0xa4, 0x96, 0x94, 0x2c, 0xba, 0x5c, 0x25, 0x9d, 0x46, 0xc6, 0xb7, 0x60,
0xcd, 0x63, 0x73, 0x6e, 0x15, 0xb9, 0x01, 0xb9, 0x89, 0xa0, 0x3d, 0xc9, 0x4b, 0x7c, 0x13, 0xda,
0x69, 0xfa, 0x40, 0xde, 0xa6, 0x6c, 0xdd, 0x92, 0x59, 0x64, 0xbb, 0x0d, 0x8d, 0xa4, 0xfe, 0x68,
0x21, 0x43, 0x9d, 0xca, 0xb2, 0x23, 0xa9, 0x68, 0x42, 0x16, 0xcd, 0x26, 0x5c, 0x2d, 0xb2, 0x8a,
0x3c, 0x58, 0xd1, 0x98, 0x72, 0x1e, 0x79, 0xbf, 0x0e, 0xab, 0x4c, 0xb5, 0x36, 0x92, 0xaf, 0x8d,
0x7c, 0xad, 0x78, 0x12, 0x99, 0x76, 0xa0, 0x1b, 0x84, 0x7e, 0xe0, 0x47, 0x2c, 0xb4, 0xa8, 0x6d,
0x87, 0x2c, 0x8a, 0x7a, 0x1d, 0xb9, 0x5e, 0x3c, 0x7f, 0x24, 0xa7, 0x8d, 0x9f, 0x41, 0x5d, 0x59,
0xbf, 0xb4, 0xc1, 0x7b, 0x1f, 0x5a, 0x22, 0x28, 0x22, 0x2b, 0xd7, 0xe6, 0xc5, 0x65, 0x36, 0xc6,
0x04, 0xe3, 0xb9, 0x6e, 0xaf, 0x89, 0xfc, 0x72, 0xca, 0xb8, 0x0f, 0xab, 0x39, 0x1e, 0x81, 0xfb,
0xe8, 0x14, 0x2a, 0x3c, 0xe4, 0x20, 0xd9, 0xb9, 0x92, 0xee, 0x6c, 0xb8, 0xa0, 0x27, 0x86, 0x16,
0xd5, 0x60, 0xac, 0x87, 0xa6, 0x6c, 0x27, 0x87, 0x64, 0x17, 0xea, 0xc1, 0x6c, 0x68, 0x89, 0xa2,
0x23, 0x9f, 0xc5, 0xce, 0x66, 0xc3, 0x8f, 0xd8, 0x65, 0xdc, 0x82, 0x06, 0x38, 0xc2, 0xb2, 0xc3,
0xff, 0x8c, 0x85, 0x2a, 0x9f, 0xc8, 0x81, 0xc1, 0xa1, 0x5b, 0x0c, 0x3f, 0xf2, 0x1d, 0xd0, 0x13,
0x17, 0x28, 0x64, 0xd3, 0x62, 0x8c, 0xa6, 0x8c, 0xe2, 0x26, 0x23, 0xd7, 0xf1, 0x98, 0x6d, 0xa5,
0xee, 0x8e, 0xe7, 0x6a, 0x98, 0x1d, 0x49, 0xf8, 0x38, 0xf6, 0x6d, 0xe3, 0x2d, 0xa8, 0xc9, 0x33,
0x0a, 0xf5, 0xc5, 0xca, 0x71, 0xfd, 0x2b, 0xbe, 0x4b, 0xd3, 0xfe, 0x9f, 0x35, 0x68, 0xc4, 0x7d,
0x6d, 0xa9, 0x50, 0xee, 0xd0, 0x95, 0x97, 0x3d, 0xf4, 0xa2, 0xc7, 0x81, 0x38, 0x49, 0x54, 0xbf,
0x72, 0x92, 0xd8, 0x05, 0x22, 0x73, 0xc1, 0x85, 0xcf, 0x5d, 0xcf, 0xb1, 0xa4, 0xcd, 0x65, 0x52,
0xe8, 0x22, 0xe5, 0x09, 0x12, 0xce, 0xc4, 0xfc, 0xc1, 0xe7, 0x2b, 0xd0, 0x39, 0x1a, 0x1c, 0x9f,
0x1e, 0x05, 0xc1, 0xc4, 0x1d, 0x51, 0x2c, 0xba, 0xf7, 0xa1, 0x8a, 0x6d, 0x45, 0xc9, 0x53, 0x66,
0xbf, 0xac, 0xbf, 0x25, 0x07, 0xb0, 0x82, 0xdd, 0x05, 0x29, 0x7b, 0xd1, 0xec, 0x97, 0xb6, 0xb9,
0x62, 0x13, 0xd9, 0x7f, 0x5c, 0x7f, 0xd8, 0xec, 0x97, 0xf5, 0xba, 0xe4, 0x03, 0xd0, 0xd3, 0xbe,
0x60, 0xd1, 0xf3, 0x66, 0x7f, 0x61, 0xd7, 0x2b, 0xe4, 0xd3, 0xa2, 0x6c, 0xd1, 0x2b, 0x5d, 0x7f,
0x61, 0x7b, 0x48, 0x0e, 0xa1, 0x1e, 0x17, 0xab, 0xe5, 0x0f, 0x90, 0xfd, 0x05, 0x1d, 0xa9, 0x30,
0x8f, 0x2c, 0xf8, 0xcb, 0x5e, 0x49, 0xfb, 0xa5, 0x6d, 0x33, 0xb9, 0x07, 0x35, 0x55, 0x83, 0x94,
0x3e, 0x42, 0xf6, 0xcb, 0xfb, 0x4a, 0xa1, 0x64, 0xda, 0xec, 0x2c, 0x7a, 0xc9, 0xed, 0x2f, 0xec,
0xef, 0xc9, 0x11, 0x40, 0xa6, 0xc8, 0x5f, 0xf8, 0x44, 0xdb, 0x5f, 0xdc, 0xb7, 0x93, 0xf7, 0xa0,
0x91, 0xbe, 0xc5, 0x94, 0x3f, 0xba, 0xf6, 0x17, 0xb5, 0xd2, 0x83, 0xff, 0xfb, 0xf7, 0x3f, 0x36,
0xb5, 0xdf, 0x5c, 0x6d, 0x6a, 0xbf, 0xbb, 0xda, 0xd4, 0xbe, 0xb8, 0xda, 0xd4, 0xfe, 0x78, 0xb5,
0xa9, 0xfd, 0xfd, 0x6a, 0x53, 0xfb, 0xfd, 0x97, 0x9b, 0xda, 0xb0, 0x86, 0xee, 0xff, 0xf6, 0x7f,
0x02, 0x00, 0x00, 0xff, 0xff, 0x91, 0x83, 0x9b, 0x1e, 0x27, 0x18, 0x00, 0x00,
// 2126 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xdc, 0x58, 0x5f, 0x73, 0x1b, 0x49,
0x11, 0xf7, 0xca, 0xb2, 0xa4, 0x6d, 0xc9, 0x92, 0x33, 0xf9, 0xa7, 0xe8, 0xc0, 0x09, 0x0b, 0xe4,
0x6c, 0xce, 0x67, 0x1f, 0x3e, 0x42, 0x39, 0x97, 0xe3, 0x0a, 0x2b, 0x09, 0x67, 0x73, 0x07, 0x98,
0x4d, 0x62, 0xaa, 0x28, 0xaa, 0xb6, 0x46, 0xda, 0xb1, 0xb4, 0x15, 0x69, 0x77, 0x6f, 0x67, 0xe4,
0x93, 0xf3, 0x19, 0xae, 0x8a, 0x7b, 0xa0, 0x8a, 0x67, 0xde, 0xf8, 0x02, 0x54, 0xf1, 0xc8, 0x13,
0x75, 0x8f, 0x14, 0x05, 0xc5, 0x5b, 0x00, 0x53, 0x3c, 0xc0, 0x27, 0xe0, 0x91, 0x9a, 0x9e, 0xd9,
0xbf, 0x5e, 0xa5, 0x92, 0xf0, 0xc6, 0x8b, 0xb4, 0x33, 0xdd, 0x3d, 0x33, 0xdd, 0xd3, 0xdd, 0xbf,
0xee, 0x81, 0x6b, 0x74, 0x30, 0xf4, 0x76, 0xc4, 0x59, 0xc8, 0xb8, 0xfa, 0xdd, 0x0e, 0xa3, 0x40,
0x04, 0x64, 0x05, 0x07, 0xbd, 0xb7, 0x47, 0x9e, 0x18, 0xcf, 0x06, 0xdb, 0xc3, 0x60, 0xba, 0x33,
0x0a, 0x46, 0xc1, 0x0e, 0x52, 0x07, 0xb3, 0x13, 0x1c, 0xe1, 0x00, 0xbf, 0x94, 0x54, 0xef, 0xe6,
0x28, 0x08, 0x46, 0x13, 0x96, 0x72, 0x09, 0x6f, 0xca, 0xb8, 0xa0, 0xd3, 0x50, 0x33, 0xec, 0x65,
0xd6, 0x13, 0xcc, 0x77, 0x59, 0x34, 0xf5, 0x7c, 0x91, 0xfd, 0x9c, 0x78, 0x03, 0xbe, 0x33, 0x0c,
0xa6, 0xd3, 0xc0, 0xcf, 0x1e, 0xc8, 0xfa, 0x7d, 0x15, 0xea, 0x36, 0xfb, 0x64, 0xc6, 0xb8, 0x20,
0x1b, 0x50, 0x65, 0xc3, 0x71, 0xd0, 0xad, 0xdc, 0x32, 0x36, 0x9a, 0xbb, 0x64, 0x5b, 0xf1, 0x69,
0xea, 0xc3, 0xe1, 0x38, 0x38, 0x58, 0xb2, 0x91, 0x83, 0xbc, 0x05, 0x2b, 0x27, 0x93, 0x19, 0x1f,
0x77, 0x97, 0x91, 0xf5, 0x72, 0x9e, 0xf5, 0x7b, 0x92, 0x74, 0xb0, 0x64, 0x2b, 0x1e, 0xb9, 0xac,
0xe7, 0x9f, 0x04, 0xdd, 0x6a, 0xd9, 0xb2, 0x87, 0xfe, 0x09, 0x2e, 0x2b, 0x39, 0xc8, 0x1e, 0x00,
0x67, 0xc2, 0x09, 0x42, 0xe1, 0x05, 0x7e, 0x77, 0x05, 0xf9, 0xaf, 0xe7, 0xf9, 0x1f, 0x31, 0xf1,
0x23, 0x24, 0x1f, 0x2c, 0xd9, 0x26, 0x8f, 0x07, 0x52, 0xd2, 0xf3, 0x3d, 0xe1, 0x0c, 0xc7, 0xd4,
0xf3, 0xbb, 0xb5, 0x32, 0xc9, 0x43, 0xdf, 0x13, 0xf7, 0x25, 0x59, 0x4a, 0x7a, 0xf1, 0x40, 0xaa,
0xf2, 0xc9, 0x8c, 0x45, 0x67, 0xdd, 0x7a, 0x99, 0x2a, 0x3f, 0x96, 0x24, 0xa9, 0x0a, 0xf2, 0x90,
0x7b, 0xd0, 0x1c, 0xb0, 0x91, 0xe7, 0x3b, 0x83, 0x49, 0x30, 0x7c, 0xda, 0x6d, 0xa0, 0x48, 0x37,
0x2f, 0xd2, 0x97, 0x0c, 0x7d, 0x49, 0x3f, 0x58, 0xb2, 0x61, 0x90, 0x8c, 0xc8, 0x2e, 0x34, 0x86,
0x63, 0x36, 0x7c, 0xea, 0x88, 0x79, 0xd7, 0x44, 0xc9, 0xab, 0x79, 0xc9, 0xfb, 0x92, 0xfa, 0x78,
0x7e, 0xb0, 0x64, 0xd7, 0x87, 0xea, 0x93, 0xdc, 0x01, 0x93, 0xf9, 0xae, 0xde, 0xae, 0x89, 0x42,
0xd7, 0x0a, 0xf7, 0xe2, 0xbb, 0xf1, 0x66, 0x0d, 0xa6, 0xbf, 0xc9, 0x36, 0xd4, 0xe4, 0x5d, 0x7b,
0xa2, 0xdb, 0x42, 0x99, 0x2b, 0x85, 0x8d, 0x90, 0x76, 0xb0, 0x64, 0x6b, 0x2e, 0x69, 0x3e, 0x97,
0x4d, 0xbc, 0x53, 0x16, 0xc9, 0xc3, 0x5d, 0x2e, 0x33, 0xdf, 0x03, 0x45, 0xc7, 0xe3, 0x99, 0x6e,
0x3c, 0xe8, 0xd7, 0x61, 0xe5, 0x94, 0x4e, 0x66, 0xcc, 0x7a, 0x13, 0x9a, 0x19, 0x4f, 0x21, 0x5d,
0xa8, 0x4f, 0x19, 0xe7, 0x74, 0xc4, 0xba, 0xc6, 0x2d, 0x63, 0xc3, 0xb4, 0xe3, 0xa1, 0xd5, 0x86,
0x56, 0xd6, 0x4f, 0x32, 0x82, 0xd2, 0x17, 0xa4, 0xe0, 0x29, 0x8b, 0xb8, 0x74, 0x00, 0x2d, 0xa8,
0x87, 0xd6, 0x7b, 0xb0, 0x56, 0x74, 0x02, 0xb2, 0x06, 0xcb, 0x4f, 0xd9, 0x99, 0xe6, 0x94, 0x9f,
0xe4, 0x8a, 0x3e, 0x10, 0x7a, 0xb1, 0x69, 0xeb, 0xd3, 0x7d, 0x5e, 0x49, 0x84, 0x13, 0x3f, 0x20,
0x7b, 0x50, 0x95, 0x81, 0x84, 0xd2, 0xcd, 0xdd, 0xde, 0xb6, 0x8a, 0xb2, 0xed, 0x38, 0xca, 0xb6,
0x1f, 0xc7, 0x51, 0xd6, 0x6f, 0x7c, 0xf1, 0xfc, 0xe6, 0xd2, 0xe7, 0x7f, 0xbd, 0x69, 0xd8, 0x28,
0x41, 0x6e, 0xc8, 0xab, 0xa4, 0x9e, 0xef, 0x78, 0xae, 0xde, 0xa7, 0x8e, 0xe3, 0x43, 0x97, 0xec,
0xc3, 0xda, 0x30, 0xf0, 0x39, 0xf3, 0xf9, 0x8c, 0x3b, 0x21, 0x8d, 0xe8, 0x94, 0xeb, 0x28, 0x89,
0x2f, 0xee, 0x7e, 0x4c, 0x3e, 0x42, 0xaa, 0xdd, 0x19, 0xe6, 0x27, 0xc8, 0xfb, 0x00, 0xa7, 0x74,
0xe2, 0xb9, 0x54, 0x04, 0x11, 0xef, 0x56, 0x6f, 0x2d, 0x67, 0x84, 0x8f, 0x63, 0xc2, 0x93, 0xd0,
0xa5, 0x82, 0xf5, 0xab, 0xf2, 0x64, 0x76, 0x86, 0x9f, 0xdc, 0x86, 0x0e, 0x0d, 0x43, 0x87, 0x0b,
0x2a, 0x98, 0x33, 0x38, 0x13, 0x8c, 0x63, 0x24, 0xb5, 0xec, 0x55, 0x1a, 0x86, 0x8f, 0xe4, 0x6c,
0x5f, 0x4e, 0x5a, 0x6e, 0x72, 0x0f, 0xe8, 0xe4, 0x84, 0x40, 0xd5, 0xa5, 0x82, 0xa2, 0x35, 0x5a,
0x36, 0x7e, 0xcb, 0xb9, 0x90, 0x8a, 0xb1, 0xd6, 0x11, 0xbf, 0xc9, 0x35, 0xa8, 0x8d, 0x99, 0x37,
0x1a, 0x0b, 0x54, 0x6b, 0xd9, 0xd6, 0x23, 0x69, 0xf8, 0x30, 0x0a, 0x4e, 0x19, 0xc6, 0x79, 0xc3,
0x56, 0x03, 0xeb, 0x9f, 0x06, 0x5c, 0xba, 0x10, 0x18, 0x72, 0xdd, 0x31, 0xe5, 0xe3, 0x78, 0x2f,
0xf9, 0x4d, 0xde, 0x92, 0xeb, 0x52, 0x97, 0x45, 0x3a, 0xff, 0xac, 0x6a, 0x8d, 0x0f, 0x70, 0x52,
0x2b, 0xaa, 0x59, 0xc8, 0x43, 0x58, 0x9b, 0x50, 0x2e, 0x1c, 0xe5, 0xbf, 0x0e, 0xe6, 0x97, 0xe5,
0x5c, 0x4c, 0x7d, 0x4c, 0x63, 0x3f, 0x97, 0x6e, 0xa5, 0xc5, 0xdb, 0x93, 0xdc, 0x2c, 0x39, 0x80,
0x2b, 0x83, 0xb3, 0x67, 0xd4, 0x17, 0x9e, 0xcf, 0x9c, 0x0b, 0x36, 0xef, 0xe8, 0xa5, 0x1e, 0x9e,
0x7a, 0x2e, 0xf3, 0x87, 0xb1, 0xb1, 0x2f, 0x27, 0x22, 0xc9, 0x65, 0x70, 0xeb, 0x16, 0xb4, 0xf3,
0x51, 0x4c, 0xda, 0x50, 0x11, 0x73, 0xad, 0x61, 0x45, 0xcc, 0x2d, 0x2b, 0xf1, 0xc0, 0x24, 0x94,
0x2e, 0xf0, 0x6c, 0x42, 0xa7, 0x10, 0xd6, 0x19, 0x73, 0x1b, 0x59, 0x73, 0x5b, 0x1d, 0x58, 0xcd,
0x45, 0xb3, 0xf5, 0xd9, 0x0a, 0x34, 0x6c, 0xc6, 0x43, 0xe9, 0x4c, 0x64, 0x0f, 0x4c, 0x36, 0x1f,
0x32, 0x95, 0x48, 0x8d, 0x42, 0x9a, 0x52, 0x3c, 0x0f, 0x63, 0xba, 0x0c, 0xe8, 0x84, 0x99, 0x6c,
0xe6, 0x40, 0xe0, 0x72, 0x51, 0x28, 0x8b, 0x02, 0x5b, 0x79, 0x14, 0xb8, 0x52, 0xe0, 0x2d, 0xc0,
0xc0, 0x66, 0x0e, 0x06, 0x8a, 0x0b, 0xe7, 0x70, 0xe0, 0x6e, 0x09, 0x0e, 0x14, 0x8f, 0xbf, 0x00,
0x08, 0xee, 0x96, 0x00, 0x41, 0xf7, 0xc2, 0x5e, 0xa5, 0x48, 0xb0, 0x95, 0x47, 0x82, 0xa2, 0x3a,
0x05, 0x28, 0x78, 0xbf, 0x0c, 0x0a, 0x6e, 0x14, 0x64, 0x16, 0x62, 0xc1, 0xbb, 0x17, 0xb0, 0xe0,
0x5a, 0x41, 0xb4, 0x04, 0x0c, 0xee, 0xe6, 0xb2, 0x34, 0x94, 0xea, 0x56, 0x9e, 0xa6, 0xc9, 0xb7,
0x2f, 0xe2, 0xc8, 0xf5, 0xe2, 0xd5, 0x96, 0x01, 0xc9, 0x4e, 0x01, 0x48, 0xae, 0x16, 0x4f, 0x59,
0x40, 0x92, 0x14, 0x0f, 0x36, 0x65, 0xdc, 0x17, 0x3c, 0x4d, 0xe6, 0x08, 0x16, 0x45, 0x41, 0xa4,
0x13, 0xb6, 0x1a, 0x58, 0x1b, 0x32, 0x13, 0xa5, 0xfe, 0xf5, 0x02, 0xec, 0x40, 0xa7, 0xcf, 0x78,
0x97, 0xf5, 0x4b, 0x23, 0x95, 0xc5, 0x88, 0xce, 0x66, 0x31, 0x53, 0x67, 0xb1, 0x0c, 0xa4, 0x54,
0x72, 0x90, 0x42, 0xbe, 0x01, 0x97, 0x30, 0x8d, 0xa0, 0x5d, 0x9c, 0x5c, 0x5a, 0xeb, 0x48, 0x82,
0x32, 0x88, 0xca, 0x6f, 0x6f, 0xc3, 0xe5, 0x0c, 0xaf, 0x4c, 0xb1, 0x98, 0xc2, 0xaa, 0x18, 0xbc,
0x6b, 0x09, 0xf7, 0x7e, 0x18, 0x1e, 0x50, 0x3e, 0xb6, 0x7e, 0x90, 0xea, 0x9f, 0xc2, 0x15, 0x81,
0xea, 0x30, 0x70, 0x95, 0x5a, 0xab, 0x36, 0x7e, 0x4b, 0x08, 0x9b, 0x04, 0x23, 0xdc, 0xd5, 0xb4,
0xe5, 0xa7, 0xe4, 0x4a, 0x22, 0xc5, 0x54, 0x21, 0x61, 0xfd, 0xc2, 0x48, 0xd7, 0x4b, 0x11, 0xac,
0x0c, 0x6c, 0x8c, 0xff, 0x05, 0x6c, 0x2a, 0xaf, 0x06, 0x36, 0xd6, 0x6f, 0x8c, 0xf4, 0x46, 0x12,
0x18, 0x79, 0x3d, 0x15, 0xa5, 0x73, 0x78, 0xbe, 0xcb, 0xe6, 0x18, 0xf0, 0xcb, 0xb6, 0x1a, 0xc4,
0x08, 0x5f, 0x43, 0x33, 0xe7, 0x11, 0xbe, 0x8e, 0x73, 0x6a, 0xa0, 0xe1, 0x27, 0x38, 0xc1, 0x48,
0x6c, 0xd9, 0x6a, 0x90, 0xc9, 0x9e, 0x66, 0x2e, 0x7b, 0x1e, 0x01, 0xb9, 0x18, 0xa3, 0xe4, 0x3d,
0xa8, 0x0a, 0x3a, 0x92, 0x26, 0x94, 0x56, 0x68, 0x6f, 0xab, 0x7a, 0x79, 0xfb, 0xa3, 0xe3, 0x23,
0xea, 0x45, 0xfd, 0x6b, 0x52, 0xfb, 0x7f, 0x3f, 0xbf, 0xd9, 0x96, 0x3c, 0x5b, 0xc1, 0xd4, 0x13,
0x6c, 0x1a, 0x8a, 0x33, 0x1b, 0x65, 0xac, 0x3f, 0x1b, 0x32, 0x77, 0xe7, 0x62, 0xb7, 0xd4, 0x16,
0xb1, 0x83, 0x56, 0x32, 0x30, 0xfb, 0x72, 0xf6, 0xf9, 0x32, 0xc0, 0x88, 0x72, 0xe7, 0x53, 0xea,
0x0b, 0xe6, 0x6a, 0x23, 0x99, 0x23, 0xca, 0x7f, 0x82, 0x13, 0xb2, 0x26, 0x91, 0xe4, 0x19, 0x67,
0x2e, 0x5a, 0x6b, 0xd9, 0xae, 0x8f, 0x28, 0x7f, 0xc2, 0x99, 0x9b, 0xe8, 0x55, 0x7f, 0x0d, 0xbd,
0xfe, 0x92, 0x71, 0xbc, 0x14, 0xb8, 0xfe, 0x1f, 0x34, 0xfb, 0x97, 0x21, 0x11, 0x39, 0x9f, 0xfc,
0xc8, 0x21, 0x5c, 0x4a, 0xdc, 0xdb, 0x99, 0xa1, 0xdb, 0xc7, 0xfe, 0xf0, 0xe2, 0xa8, 0x58, 0x3b,
0xcd, 0x4f, 0x73, 0xf2, 0x43, 0xb8, 0x5e, 0x08, 0xce, 0x64, 0xc1, 0xca, 0x0b, 0x63, 0xf4, 0x6a,
0x3e, 0x46, 0xe3, 0xf5, 0x62, 0x5d, 0x97, 0x5f, 0x43, 0xd7, 0xaf, 0xc9, 0xf2, 0x24, 0x9b, 0xb2,
0xcb, 0x6e, 0xcb, 0xfa, 0x95, 0x01, 0x9d, 0xc2, 0x61, 0xc8, 0x0e, 0x80, 0xca, 0x78, 0xdc, 0x7b,
0x16, 0x97, 0xca, 0x6b, 0xfa, 0xe0, 0x68, 0xb2, 0x47, 0xde, 0x33, 0x66, 0x9b, 0x83, 0xf8, 0x93,
0xdc, 0x86, 0xba, 0x98, 0x2b, 0xee, 0x7c, 0x21, 0xf7, 0x78, 0x8e, 0xac, 0x35, 0x81, 0xff, 0xe4,
0x0e, 0xb4, 0xd4, 0xc2, 0xa3, 0x80, 0x73, 0x2f, 0xd4, 0x45, 0x04, 0xc9, 0x2e, 0xfd, 0x21, 0x52,
0xec, 0xe6, 0x20, 0x1d, 0x58, 0x3f, 0x05, 0x33, 0xd9, 0x96, 0xbc, 0x01, 0xe6, 0x94, 0xce, 0x75,
0x95, 0x2b, 0xcf, 0xb6, 0x62, 0x37, 0xa6, 0x74, 0x8e, 0x05, 0x2e, 0xb9, 0x0e, 0x75, 0x49, 0x14,
0x73, 0x65, 0xef, 0x15, 0xbb, 0x36, 0xa5, 0xf3, 0xc7, 0xf3, 0x84, 0x30, 0xa2, 0x3c, 0x2e, 0x61,
0xa7, 0x74, 0xfe, 0x21, 0xe5, 0xd6, 0x07, 0x50, 0x53, 0x87, 0x7c, 0xa9, 0x85, 0xa5, 0x7c, 0x25,
0x27, 0xff, 0x5d, 0x68, 0x66, 0xce, 0x4d, 0xbe, 0x09, 0x57, 0x95, 0x86, 0x21, 0x8d, 0x04, 0x5a,
0x24, 0xb7, 0x20, 0x41, 0xe2, 0x11, 0x8d, 0x84, 0xdc, 0x52, 0x15, 0xe5, 0xdf, 0x87, 0x76, 0xbe,
0x70, 0x25, 0x7b, 0xd0, 0xd2, 0x45, 0xee, 0x69, 0x90, 0xfa, 0x62, 0x5c, 0x9a, 0x1e, 0x07, 0x82,
0x65, 0xea, 0xdb, 0xa6, 0x62, 0x95, 0xb3, 0xdc, 0xfa, 0x63, 0x15, 0x6a, 0xaa, 0x78, 0x26, 0xb7,
0x33, 0xfd, 0x0a, 0x22, 0x63, 0xbf, 0x79, 0xfe, 0xfc, 0x66, 0x1d, 0x41, 0xe4, 0xf0, 0x41, 0xda,
0xbc, 0xa4, 0xe9, 0xb2, 0x92, 0xab, 0xed, 0xe3, 0x4e, 0x69, 0xf9, 0x95, 0x3b, 0xa5, 0xeb, 0x50,
0xf7, 0x67, 0x53, 0xbc, 0x84, 0xaa, 0x5a, 0xd2, 0x9f, 0x4d, 0xe5, 0x25, 0xbc, 0x01, 0xa6, 0x08,
0x04, 0x9d, 0x20, 0x49, 0x85, 0x7c, 0x03, 0x27, 0x24, 0x71, 0x0f, 0x56, 0x33, 0x58, 0xeb, 0xb9,
0xba, 0x90, 0x6b, 0x67, 0x9d, 0xe3, 0xf0, 0x41, 0xac, 0x74, 0x82, 0xbd, 0x87, 0x2e, 0xd9, 0xc8,
0x37, 0x06, 0x08, 0xd1, 0x0a, 0x27, 0x32, 0xb5, 0xbf, 0x04, 0x68, 0x79, 0x00, 0xe9, 0xf4, 0x8a,
0x45, 0x81, 0x46, 0x43, 0x4e, 0x20, 0xf1, 0x4d, 0xe8, 0xa4, 0x28, 0xa7, 0x58, 0x4c, 0xb5, 0x4a,
0x3a, 0x8d, 0x8c, 0xef, 0xc0, 0x15, 0x9f, 0xcd, 0x85, 0x53, 0xe4, 0x06, 0xe4, 0x26, 0x92, 0x76,
0x9c, 0x97, 0xf8, 0x3a, 0xb4, 0xd3, 0xb4, 0x80, 0xbc, 0x4d, 0xd5, 0x9e, 0x25, 0xb3, 0xc8, 0x76,
0x03, 0x1a, 0x49, 0x8d, 0xd1, 0x42, 0x86, 0x3a, 0x55, 0xa5, 0x45, 0x52, 0xb5, 0x44, 0x8c, 0xcf,
0x26, 0x42, 0x2f, 0xb2, 0x8a, 0x3c, 0x58, 0xb5, 0xd8, 0x6a, 0x1e, 0x79, 0xbf, 0x0a, 0xab, 0x4c,
0xb7, 0x2f, 0x8a, 0xaf, 0x8d, 0x7c, 0xad, 0x78, 0x12, 0x99, 0x36, 0x61, 0x2d, 0x8c, 0x82, 0x30,
0xe0, 0x2c, 0x72, 0xa8, 0xeb, 0x46, 0x8c, 0xf3, 0x6e, 0x47, 0xad, 0x17, 0xcf, 0xef, 0xab, 0x69,
0xeb, 0x67, 0x50, 0xd7, 0xd6, 0x2f, 0x6d, 0xe2, 0xbe, 0x03, 0x2d, 0xe9, 0xec, 0xdc, 0xc9, 0xb5,
0x72, 0x71, 0x29, 0x8d, 0xbe, 0xce, 0x44, 0xae, 0xa3, 0x6b, 0x22, 0xbf, 0x9a, 0xb2, 0xee, 0xc2,
0x6a, 0x8e, 0x47, 0xa2, 0x3a, 0x3a, 0x85, 0x0e, 0x19, 0x35, 0x48, 0x76, 0xae, 0xa4, 0x3b, 0x5b,
0xf7, 0xc0, 0x4c, 0x0c, 0x2d, 0x2b, 0xbe, 0x58, 0x0f, 0x43, 0xdb, 0x4e, 0x0d, 0xb1, 0x4c, 0x08,
0x3e, 0x65, 0x91, 0x8e, 0x7c, 0x35, 0xb0, 0x9e, 0x40, 0xa7, 0x90, 0xd5, 0xc9, 0x16, 0xd4, 0xc3,
0xd9, 0xc0, 0x89, 0x5f, 0x17, 0xd2, 0x34, 0x76, 0x34, 0x1b, 0x7c, 0xc4, 0xce, 0xe2, 0x7e, 0x34,
0xc4, 0x51, 0xba, 0x6c, 0x25, 0xbb, 0xec, 0xcf, 0x0d, 0x68, 0xc4, 0x11, 0x4a, 0xbe, 0x05, 0x66,
0xe2, 0x24, 0x85, 0x3c, 0x9a, 0xec, 0xad, 0x57, 0x4d, 0x19, 0xe5, 0x5d, 0x73, 0x6f, 0xe4, 0x33,
0xd7, 0x49, 0x03, 0x02, 0x37, 0x69, 0xd8, 0x1d, 0x45, 0xf8, 0x38, 0xf6, 0x7e, 0xf2, 0x95, 0x24,
0x55, 0x44, 0xc1, 0xcc, 0x77, 0xb5, 0x8a, 0x3a, 0x27, 0xd8, 0x72, 0xca, 0x7a, 0x07, 0x6a, 0xea,
0xfc, 0xd2, 0x86, 0x72, 0xf3, 0xb8, 0x50, 0x96, 0xdf, 0xa5, 0x98, 0xf0, 0x27, 0x03, 0x1a, 0x71,
0x03, 0x5c, 0x2a, 0x94, 0xd3, 0xab, 0xf2, 0xb2, 0x7a, 0x2d, 0x7a, 0x45, 0x88, 0x33, 0x4d, 0xf5,
0x95, 0x33, 0xcd, 0x16, 0x10, 0x95, 0x50, 0x4e, 0x03, 0xe1, 0xf9, 0x23, 0x47, 0xdd, 0x87, 0xca,
0x2c, 0x6b, 0x48, 0x39, 0x46, 0xc2, 0x91, 0x9c, 0xdf, 0xfd, 0x6c, 0x05, 0x3a, 0xfb, 0xfd, 0xfb,
0x87, 0xfb, 0x61, 0x38, 0xf1, 0x86, 0x14, 0xab, 0xf3, 0x1d, 0xa8, 0x62, 0xff, 0x51, 0xf2, 0xf2,
0xd9, 0x2b, 0x6b, 0x84, 0xc9, 0x2e, 0xac, 0x60, 0x1b, 0x42, 0xca, 0x1e, 0x40, 0x7b, 0xa5, 0xfd,
0xb0, 0xdc, 0x44, 0x35, 0x2a, 0x17, 0xdf, 0x41, 0x7b, 0x65, 0x4d, 0x31, 0xf9, 0x00, 0xcc, 0xb4,
0x81, 0x58, 0xf4, 0x1a, 0xda, 0x5b, 0xd8, 0x1e, 0x4b, 0xf9, 0xb4, 0x6e, 0x5b, 0xf4, 0xa8, 0xd7,
0x5b, 0xd8, 0x47, 0x92, 0x3d, 0xa8, 0xc7, 0xf5, 0x6c, 0xf9, 0x7b, 0x65, 0x6f, 0x41, 0xeb, 0x2a,
0xcd, 0xa3, 0x7a, 0x82, 0xb2, 0x47, 0xd5, 0x5e, 0x69, 0x7f, 0x4d, 0xee, 0x40, 0x4d, 0x17, 0x28,
0xa5, 0x6f, 0x96, 0xbd, 0xf2, 0x06, 0x54, 0x2a, 0x99, 0x76, 0x45, 0x8b, 0x1e, 0x7e, 0x7b, 0x0b,
0x1f, 0x02, 0xc8, 0x3e, 0x40, 0xa6, 0x0f, 0x58, 0xf8, 0xa2, 0xdb, 0x5b, 0xdc, 0xe0, 0x93, 0x7b,
0xd0, 0x48, 0x1f, 0x6d, 0xca, 0xdf, 0x68, 0x7b, 0x8b, 0x7a, 0xee, 0xfe, 0x97, 0xfe, 0xf3, 0xf7,
0x75, 0xe3, 0xd7, 0xe7, 0xeb, 0xc6, 0x6f, 0xcf, 0xd7, 0x8d, 0x2f, 0xce, 0xd7, 0x8d, 0x3f, 0x9c,
0xaf, 0x1b, 0x7f, 0x3b, 0x5f, 0x37, 0x7e, 0xf7, 0x8f, 0x75, 0x63, 0x50, 0x43, 0xf7, 0x7f, 0xf7,
0xbf, 0x01, 0x00, 0x00, 0xff, 0xff, 0x30, 0x52, 0xb5, 0x7b, 0x56, 0x18, 0x00, 0x00,
} }

+ 13
- 8
abci/types/types.proto View File

@ -60,7 +60,7 @@ message RequestInitChain {
google.protobuf.Timestamp time = 1 [(gogoproto.nullable)=false, (gogoproto.stdtime)=true]; google.protobuf.Timestamp time = 1 [(gogoproto.nullable)=false, (gogoproto.stdtime)=true];
string chain_id = 2; string chain_id = 2;
ConsensusParams consensus_params = 3; ConsensusParams consensus_params = 3;
repeated Validator validators = 4 [(gogoproto.nullable)=false];
repeated ValidatorUpdate validators = 4 [(gogoproto.nullable)=false];
bytes app_state_bytes = 5; bytes app_state_bytes = 5;
} }
@ -143,7 +143,7 @@ message ResponseSetOption {
message ResponseInitChain { message ResponseInitChain {
ConsensusParams consensus_params = 1; ConsensusParams consensus_params = 1;
repeated Validator validators = 2 [(gogoproto.nullable)=false];
repeated ValidatorUpdate validators = 2 [(gogoproto.nullable)=false];
} }
message ResponseQuery { message ResponseQuery {
@ -183,7 +183,7 @@ message ResponseDeliverTx {
} }
message ResponseEndBlock { message ResponseEndBlock {
repeated Validator validator_updates = 1 [(gogoproto.nullable)=false];
repeated ValidatorUpdate validator_updates = 1 [(gogoproto.nullable)=false];
ConsensusParams consensus_param_updates = 2; ConsensusParams consensus_param_updates = 2;
repeated common.KVPair tags = 3 [(gogoproto.nullable)=false, (gogoproto.jsontag)="tags,omitempty"]; repeated common.KVPair tags = 3 [(gogoproto.nullable)=false, (gogoproto.jsontag)="tags,omitempty"];
} }
@ -225,8 +225,7 @@ message BlockGossip {
} }
message LastCommitInfo { message LastCommitInfo {
int32 commit_round = 1;
repeated SigningValidator validators = 2 [(gogoproto.nullable)=false];
repeated VoteInfo commit_votes = 1 [(gogoproto.nullable)=false];
} }
//---------------------------------------- //----------------------------------------
@ -272,14 +271,20 @@ message PartSetHeader {
// Validator // Validator
message Validator { message Validator {
bytes address = 1; bytes address = 1;
PubKey pub_key = 2 [(gogoproto.nullable)=false];
int64 power = 3; int64 power = 3;
} }
// Validator with an extra bool
message SigningValidator {
// ValidatorUpdate
message ValidatorUpdate {
PubKey pub_key = 1 [(gogoproto.nullable)=false];
int64 power = 2;
}
// VoteInfo
message VoteInfo {
Validator validator = 1 [(gogoproto.nullable)=false]; Validator validator = 1 [(gogoproto.nullable)=false];
bool signed_last_block = 2; bool signed_last_block = 2;
int64 commit_round = 3;
} }
message PubKey { message PubKey {


+ 143
- 18
abci/types/typespb_test.go View File

@ -42,7 +42,8 @@ It has these top-level messages:
BlockID BlockID
PartSetHeader PartSetHeader
Validator Validator
SigningValidator
ValidatorUpdate
VoteInfo
PubKey PubKey
Evidence Evidence
*/ */
@ -1970,15 +1971,15 @@ func TestValidatorMarshalTo(t *testing.T) {
} }
} }
func TestSigningValidatorProto(t *testing.T) {
func TestValidatorUpdateProto(t *testing.T) {
seed := time.Now().UnixNano() seed := time.Now().UnixNano()
popr := rand.New(rand.NewSource(seed)) popr := rand.New(rand.NewSource(seed))
p := NewPopulatedSigningValidator(popr, false)
p := NewPopulatedValidatorUpdate(popr, false)
dAtA, err := proto.Marshal(p) dAtA, err := 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 := &SigningValidator{}
msg := &ValidatorUpdate{}
if err := proto.Unmarshal(dAtA, msg); err != nil { if err := proto.Unmarshal(dAtA, msg); err != nil {
t.Fatalf("seed = %d, err = %v", seed, err) t.Fatalf("seed = %d, err = %v", seed, err)
} }
@ -2001,10 +2002,10 @@ func TestSigningValidatorProto(t *testing.T) {
} }
} }
func TestSigningValidatorMarshalTo(t *testing.T) {
func TestValidatorUpdateMarshalTo(t *testing.T) {
seed := time.Now().UnixNano() seed := time.Now().UnixNano()
popr := rand.New(rand.NewSource(seed)) popr := rand.New(rand.NewSource(seed))
p := NewPopulatedSigningValidator(popr, false)
p := NewPopulatedValidatorUpdate(popr, false)
size := p.Size() size := p.Size()
dAtA := make([]byte, size) dAtA := make([]byte, size)
for i := range dAtA { for i := range dAtA {
@ -2014,7 +2015,63 @@ func TestSigningValidatorMarshalTo(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 := &SigningValidator{}
msg := &ValidatorUpdate{}
if err := 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 TestVoteInfoProto(t *testing.T) {
seed := time.Now().UnixNano()
popr := rand.New(rand.NewSource(seed))
p := NewPopulatedVoteInfo(popr, false)
dAtA, err := proto.Marshal(p)
if err != nil {
t.Fatalf("seed = %d, err = %v", seed, err)
}
msg := &VoteInfo{}
if err := 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
_ = proto.Unmarshal(littlefuzz, msg)
}
}
func TestVoteInfoMarshalTo(t *testing.T) {
seed := time.Now().UnixNano()
popr := rand.New(rand.NewSource(seed))
p := NewPopulatedVoteInfo(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 := &VoteInfo{}
if err := proto.Unmarshal(dAtA, msg); err != nil { if err := proto.Unmarshal(dAtA, msg); err != nil {
t.Fatalf("seed = %d, err = %v", seed, err) t.Fatalf("seed = %d, err = %v", seed, err)
} }
@ -2750,16 +2807,34 @@ func TestValidatorJSON(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 TestSigningValidatorJSON(t *testing.T) {
func TestValidatorUpdateJSON(t *testing.T) {
seed := time.Now().UnixNano() seed := time.Now().UnixNano()
popr := rand.New(rand.NewSource(seed)) popr := rand.New(rand.NewSource(seed))
p := NewPopulatedSigningValidator(popr, true)
p := NewPopulatedValidatorUpdate(popr, true)
marshaler := jsonpb.Marshaler{} marshaler := 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 := &SigningValidator{}
msg := &ValidatorUpdate{}
err = 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 TestVoteInfoJSON(t *testing.T) {
seed := time.Now().UnixNano()
popr := rand.New(rand.NewSource(seed))
p := NewPopulatedVoteInfo(popr, true)
marshaler := jsonpb.Marshaler{}
jsondata, err := marshaler.MarshalToString(p)
if err != nil {
t.Fatalf("seed = %d, err = %v", seed, err)
}
msg := &VoteInfo{}
err = jsonpb.UnmarshalString(jsondata, msg) err = 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)
@ -3756,12 +3831,12 @@ func TestValidatorProtoCompactText(t *testing.T) {
} }
} }
func TestSigningValidatorProtoText(t *testing.T) {
func TestValidatorUpdateProtoText(t *testing.T) {
seed := time.Now().UnixNano() seed := time.Now().UnixNano()
popr := rand.New(rand.NewSource(seed)) popr := rand.New(rand.NewSource(seed))
p := NewPopulatedSigningValidator(popr, true)
p := NewPopulatedValidatorUpdate(popr, true)
dAtA := proto.MarshalTextString(p) dAtA := proto.MarshalTextString(p)
msg := &SigningValidator{}
msg := &ValidatorUpdate{}
if err := proto.UnmarshalText(dAtA, msg); err != nil { if err := proto.UnmarshalText(dAtA, msg); err != nil {
t.Fatalf("seed = %d, err = %v", seed, err) t.Fatalf("seed = %d, err = %v", seed, err)
} }
@ -3770,12 +3845,40 @@ func TestSigningValidatorProtoText(t *testing.T) {
} }
} }
func TestSigningValidatorProtoCompactText(t *testing.T) {
func TestValidatorUpdateProtoCompactText(t *testing.T) {
seed := time.Now().UnixNano() seed := time.Now().UnixNano()
popr := rand.New(rand.NewSource(seed)) popr := rand.New(rand.NewSource(seed))
p := NewPopulatedSigningValidator(popr, true)
p := NewPopulatedValidatorUpdate(popr, true)
dAtA := proto.CompactTextString(p) dAtA := proto.CompactTextString(p)
msg := &SigningValidator{}
msg := &ValidatorUpdate{}
if err := 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 TestVoteInfoProtoText(t *testing.T) {
seed := time.Now().UnixNano()
popr := rand.New(rand.NewSource(seed))
p := NewPopulatedVoteInfo(popr, true)
dAtA := proto.MarshalTextString(p)
msg := &VoteInfo{}
if err := 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 TestVoteInfoProtoCompactText(t *testing.T) {
seed := time.Now().UnixNano()
popr := rand.New(rand.NewSource(seed))
p := NewPopulatedVoteInfo(popr, true)
dAtA := proto.CompactTextString(p)
msg := &VoteInfo{}
if err := proto.UnmarshalText(dAtA, msg); err != nil { if err := proto.UnmarshalText(dAtA, msg); err != nil {
t.Fatalf("seed = %d, err = %v", seed, err) t.Fatalf("seed = %d, err = %v", seed, err)
} }
@ -4588,10 +4691,32 @@ func TestValidatorSize(t *testing.T) {
} }
} }
func TestSigningValidatorSize(t *testing.T) {
func TestValidatorUpdateSize(t *testing.T) {
seed := time.Now().UnixNano()
popr := rand.New(rand.NewSource(seed))
p := NewPopulatedValidatorUpdate(popr, true)
size2 := proto.Size(p)
dAtA, err := 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 := proto.Size(p)
if size3 != size {
t.Errorf("seed = %d, size %v != after marshal proto.Size %v", seed, size, size3)
}
}
func TestVoteInfoSize(t *testing.T) {
seed := time.Now().UnixNano() seed := time.Now().UnixNano()
popr := rand.New(rand.NewSource(seed)) popr := rand.New(rand.NewSource(seed))
p := NewPopulatedSigningValidator(popr, true)
p := NewPopulatedVoteInfo(popr, true)
size2 := proto.Size(p) size2 := proto.Size(p)
dAtA, err := proto.Marshal(p) dAtA, err := proto.Marshal(p)
if err != nil { if err != nil {


+ 8
- 33
abci/types/util.go View File

@ -2,58 +2,33 @@ package types
import ( import (
"bytes" "bytes"
"encoding/json"
"sort" "sort"
cmn "github.com/tendermint/tendermint/libs/common"
) )
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// Validators is a list of validators that implements the Sort interface
type Validators []Validator
// ValidatorUpdates is a list of validators that implements the Sort interface
type ValidatorUpdates []ValidatorUpdate
var _ sort.Interface = (Validators)(nil)
var _ sort.Interface = (ValidatorUpdates)(nil)
// All these methods for Validators:
// All these methods for ValidatorUpdates:
// Len, Less and Swap // Len, Less and Swap
// are for Validators to implement sort.Interface
// are for ValidatorUpdates to implement sort.Interface
// which will be used by the sort package. // which will be used by the sort package.
// See Issue https://github.com/tendermint/abci/issues/212 // See Issue https://github.com/tendermint/abci/issues/212
func (v Validators) Len() int {
func (v ValidatorUpdates) Len() int {
return len(v) return len(v)
} }
// XXX: doesn't distinguish same validator with different power // XXX: doesn't distinguish same validator with different power
func (v Validators) Less(i, j int) bool {
func (v ValidatorUpdates) Less(i, j int) bool {
return bytes.Compare(v[i].PubKey.Data, v[j].PubKey.Data) <= 0 return bytes.Compare(v[i].PubKey.Data, v[j].PubKey.Data) <= 0
} }
func (v Validators) Swap(i, j int) {
func (v ValidatorUpdates) Swap(i, j int) {
v1 := v[i] v1 := v[i]
v[i] = v[j] v[i] = v[j]
v[j] = v1 v[j] = v1
} }
func ValidatorsString(vs Validators) string {
s := make([]validatorPretty, len(vs))
for i, v := range vs {
s[i] = validatorPretty{
Address: v.Address,
PubKey: v.PubKey.Data,
Power: v.Power,
}
}
b, err := json.Marshal(s)
if err != nil {
panic(err.Error())
}
return string(b)
}
type validatorPretty struct {
Address cmn.HexBytes `json:"address"`
PubKey []byte `json:"pub_key"`
Power int64 `json:"power"`
}

+ 2
- 2
consensus/common_test.go View File

@ -354,7 +354,7 @@ func randConsensusNet(nValidators int, testName string, tickerFunc func() Timeou
} }
ensureDir(path.Dir(thisConfig.Consensus.WalFile()), 0700) // dir for wal ensureDir(path.Dir(thisConfig.Consensus.WalFile()), 0700) // dir for wal
app := appFunc() app := appFunc()
vals := types.TM2PB.Validators(state.Validators)
vals := types.TM2PB.ValidatorUpdates(state.Validators)
app.InitChain(abci.RequestInitChain{Validators: vals}) app.InitChain(abci.RequestInitChain{Validators: vals})
css[i] = newConsensusStateWithConfig(thisConfig, state, privVals[i], app) css[i] = newConsensusStateWithConfig(thisConfig, state, privVals[i], app)
@ -386,7 +386,7 @@ func randConsensusNetWithPeers(nValidators, nPeers int, testName string, tickerF
} }
app := appFunc() app := appFunc()
vals := types.TM2PB.Validators(state.Validators)
vals := types.TM2PB.ValidatorUpdates(state.Validators)
app.InitChain(abci.RequestInitChain{Validators: vals}) app.InitChain(abci.RequestInitChain{Validators: vals})
css[i] = newConsensusStateWithConfig(thisConfig, state, privVal, app) css[i] = newConsensusStateWithConfig(thisConfig, state, privVal, app)


+ 1
- 1
consensus/reactor_test.go View File

@ -118,7 +118,7 @@ func TestReactorWithEvidence(t *testing.T) {
thisConfig := ResetConfig(fmt.Sprintf("%s_%d", testName, i)) thisConfig := ResetConfig(fmt.Sprintf("%s_%d", testName, i))
ensureDir(path.Dir(thisConfig.Consensus.WalFile()), 0700) // dir for wal ensureDir(path.Dir(thisConfig.Consensus.WalFile()), 0700) // dir for wal
app := appFunc() app := appFunc()
vals := types.TM2PB.Validators(state.Validators)
vals := types.TM2PB.ValidatorUpdates(state.Validators)
app.InitChain(abci.RequestInitChain{Validators: vals}) app.InitChain(abci.RequestInitChain{Validators: vals})
pv := privVals[i] pv := privVals[i]


+ 2
- 2
consensus/replay.go View File

@ -266,7 +266,7 @@ func (h *Handshaker) ReplayBlocks(state sm.State, appHash []byte, appBlockHeight
// If appBlockHeight == 0 it means that we are at genesis and hence should send InitChain. // If appBlockHeight == 0 it means that we are at genesis and hence should send InitChain.
if appBlockHeight == 0 { if appBlockHeight == 0 {
nextVals := types.TM2PB.Validators(state.NextValidators) // state.Validators would work too.
nextVals := types.TM2PB.ValidatorUpdates(state.NextValidators) // state.Validators would work too.
csParams := types.TM2PB.ConsensusParams(h.genDoc.ConsensusParams) csParams := types.TM2PB.ConsensusParams(h.genDoc.ConsensusParams)
req := abci.RequestInitChain{ req := abci.RequestInitChain{
Time: h.genDoc.GenesisTime, Time: h.genDoc.GenesisTime,
@ -282,7 +282,7 @@ func (h *Handshaker) ReplayBlocks(state sm.State, appHash []byte, appBlockHeight
// If the app returned validators or consensus params, update the state. // If the app returned validators or consensus params, update the state.
if len(res.Validators) > 0 { if len(res.Validators) > 0 {
vals, err := types.PB2TM.Validators(res.Validators)
vals, err := types.PB2TM.ValidatorUpdates(res.Validators)
if err != nil { if err != nil {
return nil, err return nil, err
} }


+ 5
- 5
consensus/replay_test.go View File

@ -416,7 +416,7 @@ func buildAppStateFromChain(proxyApp proxy.AppConns, stateDB dbm.DB,
} }
defer proxyApp.Stop() defer proxyApp.Stop()
validators := types.TM2PB.Validators(state.Validators)
validators := types.TM2PB.ValidatorUpdates(state.Validators)
if _, err := proxyApp.Consensus().InitChainSync(abci.RequestInitChain{ if _, err := proxyApp.Consensus().InitChainSync(abci.RequestInitChain{
Validators: validators, Validators: validators,
}); err != nil { }); err != nil {
@ -453,7 +453,7 @@ func buildTMStateFromChain(config *cfg.Config, stateDB dbm.DB, state sm.State, c
} }
defer proxyApp.Stop() defer proxyApp.Stop()
validators := types.TM2PB.Validators(state.Validators)
validators := types.TM2PB.ValidatorUpdates(state.Validators)
if _, err := proxyApp.Consensus().InitChainSync(abci.RequestInitChain{ if _, err := proxyApp.Consensus().InitChainSync(abci.RequestInitChain{
Validators: validators, Validators: validators,
}); err != nil { }); err != nil {
@ -639,7 +639,7 @@ func (bs *mockBlockStore) LoadSeenCommit(height int64) *types.Commit {
func TestInitChainUpdateValidators(t *testing.T) { func TestInitChainUpdateValidators(t *testing.T) {
val, _ := types.RandValidator(true, 10) val, _ := types.RandValidator(true, 10)
vals := types.NewValidatorSet([]*types.Validator{val}) vals := types.NewValidatorSet([]*types.Validator{val})
app := &initChainApp{vals: types.TM2PB.Validators(vals)}
app := &initChainApp{vals: types.TM2PB.ValidatorUpdates(vals)}
clientCreator := proxy.NewLocalClientCreator(app) clientCreator := proxy.NewLocalClientCreator(app)
config := ResetConfig("proxy_test_") config := ResetConfig("proxy_test_")
@ -666,7 +666,7 @@ func TestInitChainUpdateValidators(t *testing.T) {
assert.Equal(t, newValAddr, expectValAddr) assert.Equal(t, newValAddr, expectValAddr)
} }
func newInitChainApp(vals []abci.Validator) *initChainApp {
func newInitChainApp(vals []abci.ValidatorUpdate) *initChainApp {
return &initChainApp{ return &initChainApp{
vals: vals, vals: vals,
} }
@ -675,7 +675,7 @@ func newInitChainApp(vals []abci.Validator) *initChainApp {
// returns the vals on InitChain // returns the vals on InitChain
type initChainApp struct { type initChainApp struct {
abci.BaseApplication abci.BaseApplication
vals []abci.Validator
vals []abci.ValidatorUpdate
} }
func (ica *initChainApp) InitChain(req abci.RequestInitChain) abci.ResponseInitChain { func (ica *initChainApp) InitChain(req abci.RequestInitChain) abci.ResponseInitChain {


+ 19
- 15
state/execution.go View File

@ -184,15 +184,14 @@ func execBlockOnProxyApp(logger log.Logger, proxyAppConn proxy.AppConnConsensus,
} }
proxyAppConn.SetResponseCallback(proxyCb) proxyAppConn.SetResponseCallback(proxyCb)
signVals, byzVals := getBeginBlockValidatorInfo(block, lastValSet, stateDB)
voteInfos, byzVals := getBeginBlockValidatorInfo(block, lastValSet, stateDB)
// Begin block. // Begin block.
_, err := proxyAppConn.BeginBlockSync(abci.RequestBeginBlock{ _, err := proxyAppConn.BeginBlockSync(abci.RequestBeginBlock{
Hash: block.Hash(), Hash: block.Hash(),
Header: types.TM2PB.Header(&block.Header), Header: types.TM2PB.Header(&block.Header),
LastCommitInfo: abci.LastCommitInfo{ LastCommitInfo: abci.LastCommitInfo{
CommitRound: int32(block.LastCommit.Round()),
Validators: signVals,
CommitVotes: voteInfos,
}, },
ByzantineValidators: byzVals, ByzantineValidators: byzVals,
}) })
@ -218,15 +217,15 @@ func execBlockOnProxyApp(logger log.Logger, proxyAppConn proxy.AppConnConsensus,
logger.Info("Executed block", "height", block.Height, "validTxs", validTxs, "invalidTxs", invalidTxs) logger.Info("Executed block", "height", block.Height, "validTxs", validTxs, "invalidTxs", invalidTxs)
valUpdates := abciResponses.EndBlock.ValidatorUpdates
if len(valUpdates) > 0 {
logger.Info("Updates to validators", "updates", abci.ValidatorsString(valUpdates))
if len(abciResponses.EndBlock.ValidatorUpdates) > 0 {
// TODO: cleanup the formatting
logger.Info("Updates to validators", "updates", abciResponses.EndBlock.ValidatorUpdates)
} }
return abciResponses, nil return abciResponses, nil
} }
func getBeginBlockValidatorInfo(block *types.Block, lastValSet *types.ValidatorSet, stateDB dbm.DB) ([]abci.SigningValidator, []abci.Evidence) {
func getBeginBlockValidatorInfo(block *types.Block, lastValSet *types.ValidatorSet, stateDB dbm.DB) ([]abci.VoteInfo, []abci.Evidence) {
// Sanity check that commit length matches validator set size - // Sanity check that commit length matches validator set size -
// only applies after first block // only applies after first block
@ -241,17 +240,22 @@ func getBeginBlockValidatorInfo(block *types.Block, lastValSet *types.ValidatorS
} }
// determine which validators did not sign last block. // determine which validators did not sign last block.
signVals := make([]abci.SigningValidator, len(lastValSet.Validators))
voteInfos := make([]abci.VoteInfo, len(lastValSet.Validators))
for i, val := range lastValSet.Validators { for i, val := range lastValSet.Validators {
var vote *types.Vote var vote *types.Vote
var commitRound = -1
if i < len(block.LastCommit.Precommits) { if i < len(block.LastCommit.Precommits) {
vote = block.LastCommit.Precommits[i] vote = block.LastCommit.Precommits[i]
if vote != nil {
commitRound = vote.Round
}
} }
val := abci.SigningValidator{
Validator: types.TM2PB.ValidatorWithoutPubKey(val),
SignedLastBlock: vote != nil,
voteInfo := abci.VoteInfo{
Validator: types.TM2PB.Validator(val),
SignedLastBlock: vote != nil, // XXX: should we replace with commitRound == -1 ?
CommitRound: int64(commitRound), //XXX: why is round an int?
} }
signVals[i] = val
voteInfos[i] = voteInfo
} }
byzVals := make([]abci.Evidence, len(block.Evidence.Evidence)) byzVals := make([]abci.Evidence, len(block.Evidence.Evidence))
@ -266,15 +270,15 @@ func getBeginBlockValidatorInfo(block *types.Block, lastValSet *types.ValidatorS
byzVals[i] = types.TM2PB.Evidence(ev, valset, block.Time) byzVals[i] = types.TM2PB.Evidence(ev, valset, block.Time)
} }
return signVals, byzVals
return voteInfos, byzVals
} }
// If more or equal than 1/3 of total voting power changed in one block, then // If more or equal than 1/3 of total voting power changed in one block, then
// a light client could never prove the transition externally. See // a light client could never prove the transition externally. See
// ./lite/doc.go for details on how a light client tracks validators. // ./lite/doc.go for details on how a light client tracks validators.
func updateValidators(currentSet *types.ValidatorSet, abciUpdates []abci.Validator) error {
updates, err := types.PB2TM.Validators(abciUpdates)
func updateValidators(currentSet *types.ValidatorSet, abciUpdates []abci.ValidatorUpdate) error {
updates, err := types.PB2TM.ValidatorUpdates(abciUpdates)
if err != nil { if err != nil {
return err return err
} }


+ 9
- 9
state/execution_test.go View File

@ -86,7 +86,7 @@ func TestBeginBlockValidators(t *testing.T) {
// -> app receives a list of validators with a bool indicating if they signed // -> app receives a list of validators with a bool indicating if they signed
ctr := 0 ctr := 0
for i, v := range app.Validators {
for i, v := range app.CommitVotes {
if ctr < len(tc.expectedAbsentValidators) && if ctr < len(tc.expectedAbsentValidators) &&
tc.expectedAbsentValidators[ctr] == i { tc.expectedAbsentValidators[ctr] == i {
@ -160,7 +160,7 @@ func TestUpdateValidators(t *testing.T) {
name string name string
currentSet *types.ValidatorSet currentSet *types.ValidatorSet
abciUpdates []abci.Validator
abciUpdates []abci.ValidatorUpdate
resultingSet *types.ValidatorSet resultingSet *types.ValidatorSet
shouldErr bool shouldErr bool
@ -169,7 +169,7 @@ func TestUpdateValidators(t *testing.T) {
"adding a validator is OK", "adding a validator is OK",
types.NewValidatorSet([]*types.Validator{val1}), types.NewValidatorSet([]*types.Validator{val1}),
[]abci.Validator{{Address: []byte{}, PubKey: types.TM2PB.PubKey(pubkey2), Power: 20}},
[]abci.ValidatorUpdate{{PubKey: types.TM2PB.PubKey(pubkey2), Power: 20}},
types.NewValidatorSet([]*types.Validator{val1, val2}), types.NewValidatorSet([]*types.Validator{val1, val2}),
false, false,
@ -178,7 +178,7 @@ func TestUpdateValidators(t *testing.T) {
"updating a validator is OK", "updating a validator is OK",
types.NewValidatorSet([]*types.Validator{val1}), types.NewValidatorSet([]*types.Validator{val1}),
[]abci.Validator{{Address: []byte{}, PubKey: types.TM2PB.PubKey(pubkey1), Power: 20}},
[]abci.ValidatorUpdate{{PubKey: types.TM2PB.PubKey(pubkey1), Power: 20}},
types.NewValidatorSet([]*types.Validator{types.NewValidator(pubkey1, 20)}), types.NewValidatorSet([]*types.Validator{types.NewValidator(pubkey1, 20)}),
false, false,
@ -187,7 +187,7 @@ func TestUpdateValidators(t *testing.T) {
"removing a validator is OK", "removing a validator is OK",
types.NewValidatorSet([]*types.Validator{val1, val2}), types.NewValidatorSet([]*types.Validator{val1, val2}),
[]abci.Validator{{Address: []byte{}, PubKey: types.TM2PB.PubKey(pubkey2), Power: 0}},
[]abci.ValidatorUpdate{{PubKey: types.TM2PB.PubKey(pubkey2), Power: 0}},
types.NewValidatorSet([]*types.Validator{val1}), types.NewValidatorSet([]*types.Validator{val1}),
false, false,
@ -197,7 +197,7 @@ func TestUpdateValidators(t *testing.T) {
"removing a non-existing validator results in error", "removing a non-existing validator results in error",
types.NewValidatorSet([]*types.Validator{val1}), types.NewValidatorSet([]*types.Validator{val1}),
[]abci.Validator{{Address: []byte{}, PubKey: types.TM2PB.PubKey(pubkey2), Power: 0}},
[]abci.ValidatorUpdate{{PubKey: types.TM2PB.PubKey(pubkey2), Power: 0}},
types.NewValidatorSet([]*types.Validator{val1}), types.NewValidatorSet([]*types.Validator{val1}),
true, true,
@ -207,7 +207,7 @@ func TestUpdateValidators(t *testing.T) {
"adding a validator with negative power results in error", "adding a validator with negative power results in error",
types.NewValidatorSet([]*types.Validator{val1}), types.NewValidatorSet([]*types.Validator{val1}),
[]abci.Validator{{Address: []byte{}, PubKey: types.TM2PB.PubKey(pubkey2), Power: -100}},
[]abci.ValidatorUpdate{{PubKey: types.TM2PB.PubKey(pubkey2), Power: -100}},
types.NewValidatorSet([]*types.Validator{val1}), types.NewValidatorSet([]*types.Validator{val1}),
true, true,
@ -335,7 +335,7 @@ func makeBlock(state State, height int64) *types.Block {
type testApp struct { type testApp struct {
abci.BaseApplication abci.BaseApplication
Validators []abci.SigningValidator
CommitVotes []abci.VoteInfo
ByzantineValidators []abci.Evidence ByzantineValidators []abci.Evidence
ValidatorUpdates []abci.Validator ValidatorUpdates []abci.Validator
} }
@ -347,7 +347,7 @@ func (app *testApp) Info(req abci.RequestInfo) (resInfo abci.ResponseInfo) {
} }
func (app *testApp) BeginBlock(req abci.RequestBeginBlock) abci.ResponseBeginBlock { func (app *testApp) BeginBlock(req abci.RequestBeginBlock) abci.ResponseBeginBlock {
app.Validators = req.LastCommitInfo.Validators
app.CommitVotes = req.LastCommitInfo.CommitVotes
app.ByzantineValidators = req.ByzantineValidators app.ByzantineValidators = req.ByzantineValidators
return abci.ResponseBeginBlock{} return abci.ResponseBeginBlock{}
} }


+ 7
- 7
state/state_test.go View File

@ -78,8 +78,8 @@ func TestABCIResponsesSaveLoad1(t *testing.T) {
abciResponses := NewABCIResponses(block) abciResponses := NewABCIResponses(block)
abciResponses.DeliverTx[0] = &abci.ResponseDeliverTx{Data: []byte("foo"), Tags: nil} abciResponses.DeliverTx[0] = &abci.ResponseDeliverTx{Data: []byte("foo"), Tags: nil}
abciResponses.DeliverTx[1] = &abci.ResponseDeliverTx{Data: []byte("bar"), Log: "ok", Tags: nil} abciResponses.DeliverTx[1] = &abci.ResponseDeliverTx{Data: []byte("bar"), Log: "ok", Tags: nil}
abciResponses.EndBlock = &abci.ResponseEndBlock{ValidatorUpdates: []abci.Validator{
types.TM2PB.ValidatorFromPubKeyAndPower(ed25519.GenPrivKey().PubKey(), 10),
abciResponses.EndBlock = &abci.ResponseEndBlock{ValidatorUpdates: []abci.ValidatorUpdate{
types.TM2PB.NewValidatorUpdate(ed25519.GenPrivKey().PubKey(), 10),
}} }}
saveABCIResponses(stateDB, block.Height, abciResponses) saveABCIResponses(stateDB, block.Height, abciResponses)
@ -454,9 +454,9 @@ func makeHeaderPartsResponsesValPubKeyChange(state State, height int64,
_, val := state.NextValidators.GetByIndex(0) _, val := state.NextValidators.GetByIndex(0)
if !bytes.Equal(pubkey.Bytes(), val.PubKey.Bytes()) { if !bytes.Equal(pubkey.Bytes(), val.PubKey.Bytes()) {
abciResponses.EndBlock = &abci.ResponseEndBlock{ abciResponses.EndBlock = &abci.ResponseEndBlock{
ValidatorUpdates: []abci.Validator{
types.TM2PB.ValidatorFromPubKeyAndPower(val.PubKey, 0),
types.TM2PB.ValidatorFromPubKeyAndPower(pubkey, 10),
ValidatorUpdates: []abci.ValidatorUpdate{
types.TM2PB.NewValidatorUpdate(val.PubKey, 0),
types.TM2PB.NewValidatorUpdate(pubkey, 10),
}, },
} }
} }
@ -476,8 +476,8 @@ func makeHeaderPartsResponsesValPowerChange(state State, height int64,
_, val := state.NextValidators.GetByIndex(0) _, val := state.NextValidators.GetByIndex(0)
if val.VotingPower != power { if val.VotingPower != power {
abciResponses.EndBlock = &abci.ResponseEndBlock{ abciResponses.EndBlock = &abci.ResponseEndBlock{
ValidatorUpdates: []abci.Validator{
types.TM2PB.ValidatorFromPubKeyAndPower(val.PubKey, power),
ValidatorUpdates: []abci.ValidatorUpdate{
types.TM2PB.NewValidatorUpdate(val.PubKey, power),
}, },
} }
} }


+ 17
- 24
types/protobuf.go View File

@ -1,7 +1,6 @@
package types package types
import ( import (
"bytes"
"fmt" "fmt"
"reflect" "reflect"
"time" "time"
@ -56,7 +55,7 @@ func (tm2pb) Header(header *Header) abci.Header {
} }
} }
func (tm2pb) ValidatorWithoutPubKey(val *Validator) abci.Validator {
func (tm2pb) Validator(val *Validator) abci.Validator {
return abci.Validator{ return abci.Validator{
Address: val.PubKey.Address(), Address: val.PubKey.Address(),
Power: val.VotingPower, Power: val.VotingPower,
@ -78,11 +77,10 @@ func (tm2pb) PartSetHeader(header PartSetHeader) abci.PartSetHeader {
} }
// XXX: panics on unknown pubkey type // XXX: panics on unknown pubkey type
func (tm2pb) Validator(val *Validator) abci.Validator {
return abci.Validator{
Address: val.PubKey.Address(),
PubKey: TM2PB.PubKey(val.PubKey),
Power: val.VotingPower,
func (tm2pb) ValidatorUpdate(val *Validator) abci.ValidatorUpdate {
return abci.ValidatorUpdate{
PubKey: TM2PB.PubKey(val.PubKey),
Power: val.VotingPower,
} }
} }
@ -106,10 +104,10 @@ func (tm2pb) PubKey(pubKey crypto.PubKey) abci.PubKey {
} }
// XXX: panics on nil or unknown pubkey type // XXX: panics on nil or unknown pubkey type
func (tm2pb) Validators(vals *ValidatorSet) []abci.Validator {
validators := make([]abci.Validator, vals.Size())
func (tm2pb) ValidatorUpdates(vals *ValidatorSet) []abci.ValidatorUpdate {
validators := make([]abci.ValidatorUpdate, vals.Size())
for i, val := range vals.Validators { for i, val := range vals.Validators {
validators[i] = TM2PB.Validator(val)
validators[i] = TM2PB.ValidatorUpdate(val)
} }
return validators return validators
} }
@ -156,7 +154,7 @@ func (tm2pb) Evidence(ev Evidence, valSet *ValidatorSet, evTime time.Time) abci.
return abci.Evidence{ return abci.Evidence{
Type: evType, Type: evType,
Validator: TM2PB.ValidatorWithoutPubKey(val),
Validator: TM2PB.Validator(val),
Height: ev.Height(), Height: ev.Height(),
Time: evTime, Time: evTime,
TotalVotingPower: valSet.TotalVotingPower(), TotalVotingPower: valSet.TotalVotingPower(),
@ -164,12 +162,11 @@ func (tm2pb) Evidence(ev Evidence, valSet *ValidatorSet, evTime time.Time) abci.
} }
// XXX: panics on nil or unknown pubkey type // XXX: panics on nil or unknown pubkey type
func (tm2pb) ValidatorFromPubKeyAndPower(pubkey crypto.PubKey, power int64) abci.Validator {
func (tm2pb) NewValidatorUpdate(pubkey crypto.PubKey, power int64) abci.ValidatorUpdate {
pubkeyABCI := TM2PB.PubKey(pubkey) pubkeyABCI := TM2PB.PubKey(pubkey)
return abci.Validator{
Address: pubkey.Address(),
PubKey: pubkeyABCI,
Power: power,
return abci.ValidatorUpdate{
PubKey: pubkeyABCI,
Power: power,
} }
} }
@ -205,7 +202,7 @@ func (pb2tm) PubKey(pubKey abci.PubKey) (crypto.PubKey, error) {
} }
} }
func (pb2tm) Validators(vals []abci.Validator) ([]*Validator, error) {
func (pb2tm) ValidatorUpdates(vals []abci.ValidatorUpdate) ([]*Validator, error) {
tmVals := make([]*Validator, len(vals)) tmVals := make([]*Validator, len(vals))
for i, v := range vals { for i, v := range vals {
pub, err := PB2TM.PubKey(v.PubKey) pub, err := PB2TM.PubKey(v.PubKey)
@ -214,17 +211,13 @@ func (pb2tm) Validators(vals []abci.Validator) ([]*Validator, error) {
} }
// If the app provided an address too, it must match. // If the app provided an address too, it must match.
// This is just a sanity check. // This is just a sanity check.
if len(v.Address) > 0 {
/*if len(v.Address) > 0 {
if !bytes.Equal(pub.Address(), v.Address) { if !bytes.Equal(pub.Address(), v.Address) {
return nil, fmt.Errorf("Validator.Address (%X) does not match PubKey.Address (%X)", return nil, fmt.Errorf("Validator.Address (%X) does not match PubKey.Address (%X)",
v.Address, pub.Address()) v.Address, pub.Address())
} }
}
tmVals[i] = &Validator{
Address: pub.Address(),
PubKey: pub,
VotingPower: v.Power,
}
}*/
tmVals[i] = NewValidator(pub, v.Power)
} }
return tmVals, nil return tmVals, nil
} }


+ 14
- 17
types/protobuf_test.go View File

@ -41,26 +41,26 @@ func TestABCIValidators(t *testing.T) {
VotingPower: 10, VotingPower: 10,
} }
abciVal := TM2PB.Validator(tmVal)
tmVals, err := PB2TM.Validators([]abci.Validator{abciVal})
abciVal := TM2PB.ValidatorUpdate(tmVal)
tmVals, err := PB2TM.ValidatorUpdates([]abci.ValidatorUpdate{abciVal})
assert.Nil(t, err) assert.Nil(t, err)
assert.Equal(t, tmValExpected, tmVals[0]) assert.Equal(t, tmValExpected, tmVals[0])
abciVals := TM2PB.Validators(NewValidatorSet(tmVals))
assert.Equal(t, []abci.Validator{abciVal}, abciVals)
abciVals := TM2PB.ValidatorUpdates(NewValidatorSet(tmVals))
assert.Equal(t, []abci.ValidatorUpdate{abciVal}, abciVals)
// val with address // val with address
tmVal.Address = pkEd.Address() tmVal.Address = pkEd.Address()
abciVal = TM2PB.Validator(tmVal)
tmVals, err = PB2TM.Validators([]abci.Validator{abciVal})
abciVal = TM2PB.ValidatorUpdate(tmVal)
tmVals, err = PB2TM.ValidatorUpdates([]abci.ValidatorUpdate{abciVal})
assert.Nil(t, err) assert.Nil(t, err)
assert.Equal(t, tmValExpected, tmVals[0]) assert.Equal(t, tmValExpected, tmVals[0])
// val with incorrect address
abciVal = TM2PB.Validator(tmVal)
abciVal.Address = []byte("incorrect!")
tmVals, err = PB2TM.Validators([]abci.Validator{abciVal})
// val with incorrect pubkey daya
abciVal = TM2PB.ValidatorUpdate(tmVal)
abciVal.PubKey.Data = []byte("incorrect!")
tmVals, err = PB2TM.ValidatorUpdates([]abci.ValidatorUpdate{abciVal})
assert.NotNil(t, err) assert.NotNil(t, err)
assert.Nil(t, tmVals) assert.Nil(t, tmVals)
} }
@ -104,9 +104,6 @@ func TestABCIEvidence(t *testing.T) {
) )
assert.Equal(t, "duplicate/vote", abciEv.Type) assert.Equal(t, "duplicate/vote", abciEv.Type)
// test we do not send pubkeys
assert.Empty(t, abciEv.Validator.PubKey)
} }
type pubKeyEddie struct{} type pubKeyEddie struct{}
@ -119,17 +116,17 @@ func (pubKeyEddie) Equals(crypto.PubKey) bool { return false }
func TestABCIValidatorFromPubKeyAndPower(t *testing.T) { func TestABCIValidatorFromPubKeyAndPower(t *testing.T) {
pubkey := ed25519.GenPrivKey().PubKey() pubkey := ed25519.GenPrivKey().PubKey()
abciVal := TM2PB.ValidatorFromPubKeyAndPower(pubkey, 10)
abciVal := TM2PB.NewValidatorUpdate(pubkey, 10)
assert.Equal(t, int64(10), abciVal.Power) assert.Equal(t, int64(10), abciVal.Power)
assert.Panics(t, func() { TM2PB.ValidatorFromPubKeyAndPower(nil, 10) })
assert.Panics(t, func() { TM2PB.ValidatorFromPubKeyAndPower(pubKeyEddie{}, 10) })
assert.Panics(t, func() { TM2PB.NewValidatorUpdate(nil, 10) })
assert.Panics(t, func() { TM2PB.NewValidatorUpdate(pubKeyEddie{}, 10) })
} }
func TestABCIValidatorWithoutPubKey(t *testing.T) { func TestABCIValidatorWithoutPubKey(t *testing.T) {
pkEd := ed25519.GenPrivKey().PubKey() pkEd := ed25519.GenPrivKey().PubKey()
abciVal := TM2PB.ValidatorWithoutPubKey(&Validator{
abciVal := TM2PB.Validator(&Validator{
Address: pkEd.Address(), Address: pkEd.Address(),
PubKey: pkEd, PubKey: pkEd,
VotingPower: 10, VotingPower: 10,


Loading…
Cancel
Save