Skip to content

Commit e810cf7

Browse files
committed
chore(types): harden DoubleSignEvidence (de)serialization
1 parent efcd4d9 commit e810cf7

3 files changed

Lines changed: 27 additions & 1 deletion

File tree

block/internal/syncing/doublesign_branches_test.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,24 @@ func TestDoubleSignEvidence_FromProtoInnerHeaderError(t *testing.T) {
230230
require.Error(t, dst.FromProto(p))
231231
}
232232

233+
// FromProto must reject partial-nil sub-messages (one set, one nil) to keep
234+
// the (FirstHeader, AlternateHeader) pair invariant after deserialization.
235+
func TestDoubleSignEvidence_FromProtoPartialNilHeader(t *testing.T) {
236+
env := newDSTestEnv(t)
237+
hdr := env.signHeaderAtHeight(5, 0x01)
238+
hdrPB, err := hdr.ToProto()
239+
require.NoError(t, err)
240+
241+
t.Run("alternate nil", func(t *testing.T) {
242+
dst := new(types.DoubleSignEvidence)
243+
require.Error(t, dst.FromProto(&pb.DoubleSignEvidence{Height: 5, FirstHeader: hdrPB}))
244+
})
245+
t.Run("first nil", func(t *testing.T) {
246+
dst := new(types.DoubleSignEvidence)
247+
require.Error(t, dst.FromProto(&pb.DoubleSignEvidence{Height: 5, AlternateHeader: hdrPB}))
248+
})
249+
}
250+
233251
func TestDoubleSignEvidence_UnmarshalBinaryGarbage(t *testing.T) {
234252
dst := new(types.DoubleSignEvidence)
235253
require.Error(t, dst.UnmarshalBinary([]byte{0xff, 0xff, 0xff, 0xff}))

block/internal/syncing/doublesign_test.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -465,6 +465,11 @@ func TestDoubleSignEvidence_ValidateBasic(t *testing.T) {
465465
e := &types.DoubleSignEvidence{Height: 5, FirstHeader: first, AlternateHeader: first}
466466
require.Error(t, e.ValidateBasic())
467467
})
468+
t.Run("proposer mismatch", func(t *testing.T) {
469+
other := env.signHeaderWithOtherProposer(5, 0x02)
470+
e := &types.DoubleSignEvidence{Height: 5, FirstHeader: first, AlternateHeader: other}
471+
require.ErrorContains(t, e.ValidateBasic(), "different proposers")
472+
})
468473
t.Run("happy path", func(t *testing.T) {
469474
e := &types.DoubleSignEvidence{Height: 5, FirstHeader: first, AlternateHeader: alt}
470475
require.NoError(t, e.ValidateBasic())

types/double_sign_evidence.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,9 @@ func (e *DoubleSignEvidence) ToProto() (*pb.DoubleSignEvidence, error) {
5555
if e == nil {
5656
return nil, errors.New("evidence is nil")
5757
}
58+
if e.FirstHeader == nil || e.AlternateHeader == nil {
59+
return nil, errors.New("evidence requires both first and alternate headers")
60+
}
5861
first, err := e.FirstHeader.ToProto()
5962
if err != nil {
6063
return nil, fmt.Errorf("marshal first header: %w", err)
@@ -111,7 +114,7 @@ func (e *DoubleSignEvidence) MarshalBinary() ([]byte, error) {
111114
func (e *DoubleSignEvidence) UnmarshalBinary(data []byte) error {
112115
p := new(pb.DoubleSignEvidence)
113116
if err := proto.Unmarshal(data, p); err != nil {
114-
return err
117+
return fmt.Errorf("proto unmarshal double sign evidence: %w", err)
115118
}
116119
return e.FromProto(p)
117120
}

0 commit comments

Comments
 (0)