Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions sei-tendermint/types/light.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,9 @@ func (lb *LightBlock) ToProto() (*tmproto.LightBlock, error) {
if err != nil {
return nil, err
}
if lbp.ValidatorSet == nil {
return nil, ErrValidatorSetEmpty
}
}

return lbp, nil
Expand Down
4 changes: 2 additions & 2 deletions sei-tendermint/types/light_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,8 @@ func TestLightBlockProtobuf(t *testing.T) {
}{
{"valid light block", sh, vals, false, false},
{"empty signed header", &SignedHeader{}, vals, false, false},
{"empty validator set", sh, &ValidatorSet{}, false, true},
{"empty light block", &SignedHeader{}, &ValidatorSet{}, false, true},
{"empty validator set", sh, &ValidatorSet{}, true, true},
{"empty light block", &SignedHeader{}, &ValidatorSet{}, true, true},
}

for _, tc := range testCases {
Expand Down
15 changes: 9 additions & 6 deletions sei-tendermint/types/validator_set.go
Original file line number Diff line number Diff line change
Expand Up @@ -811,7 +811,7 @@ func (valz ValidatorsByAddress) Swap(i, j int) {
// ToProto converts ValidatorSet to protobuf
func (vals *ValidatorSet) ToProto() (*tmproto.ValidatorSet, error) {
if vals.IsNilOrEmpty() {
return &tmproto.ValidatorSet{}, nil // validator set should never be nil
return nil, nil
}

vp := new(tmproto.ValidatorSet)
Expand Down Expand Up @@ -857,13 +857,16 @@ func ValidatorSetFromProto(vp *tmproto.ValidatorSet) (*ValidatorSet, error) {
}
vals.Validators = valsProto

p, err := ValidatorFromProto(vp.GetProposer())
if err != nil {
return nil, fmt.Errorf("fromProto: validatorSet proposer error: %w", err)
if vp.GetProposer() != nil {
p, err := ValidatorFromProto(vp.GetProposer())
if err != nil {
return nil, fmt.Errorf("fromProto: validatorSet proposer error: %w", err)
}
vals.Proposer = p
} else if len(vals.Validators) > 0 {
vals.Proposer = vals.findProposer()
}

vals.Proposer = p

// NOTE: We can't trust the total voting power given to us by other peers. If someone were to
// inject a non-zeo value that wasn't the correct voting power we could assume a wrong total
// power hence we need to recompute it.
Expand Down
50 changes: 50 additions & 0 deletions sei-tendermint/types/validator_set_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1459,6 +1459,56 @@ func TestValidatorSetProtoBuf(t *testing.T) {
}
}

func TestValidatorSetFromProto_NilProposerWithValidators(t *testing.T) {
pk1 := ed25519.GenerateSecretKey().Public()
pk2 := ed25519.GenerateSecretKey().Public()

protoValSet := &tmproto.ValidatorSet{
Validators: []*tmproto.Validator{
{
Address: pk1.Address(),
PubKey: crypto.PubKeyToProto(pk1),
VotingPower: 50,
ProposerPriority: 10,
},
{
Address: pk2.Address(),
PubKey: crypto.PubKeyToProto(pk2),
VotingPower: 50,
ProposerPriority: -10,
},
},
Proposer: nil,
}

valSet, err := ValidatorSetFromProto(protoValSet)
require.NoError(t, err)
require.NotNil(t, valSet.Proposer, "proposer should be derived when nil in proto")
require.Len(t, valSet.Validators, 2)

found := false
for _, v := range valSet.Validators {
if bytes.Equal(v.Address, valSet.Proposer.Address) {
found = true
break
}
}
require.True(t, found, "derived proposer must be a member of the validator set")

require.Equal(t, valSet.Proposer.Address, pk1.Address(),
"proposer should be the validator with highest ProposerPriority")
}

func TestValidatorSetFromProto_EmptyProtoRoundtrip(t *testing.T) {
empty := &ValidatorSet{}
proto, err := empty.ToProto()
require.NoError(t, err)
require.Nil(t, proto, "ToProto on empty set should return nil")

_, err = ValidatorSetFromProto(proto)
require.Error(t, err, "FromProto(nil) should return error")
}

// ---------------------
// Sort validators by priority and address
type validatorsByPriority []*Validator
Expand Down
Loading