|
15 | 15 | package leiosnotify |
16 | 16 |
|
17 | 17 | import ( |
| 18 | + "bytes" |
18 | 19 | "reflect" |
19 | 20 | "testing" |
20 | 21 |
|
21 | 22 | "github.com/blinklabs-io/gouroboros/cbor" |
| 23 | + lcommon "github.com/blinklabs-io/gouroboros/ledger/common" |
22 | 24 | "github.com/blinklabs-io/gouroboros/protocol" |
23 | 25 | pcommon "github.com/blinklabs-io/gouroboros/protocol/common" |
24 | 26 | "github.com/stretchr/testify/assert" |
@@ -198,13 +200,11 @@ func TestMsgDone(t *testing.T) { |
198 | 200 | } |
199 | 201 |
|
200 | 202 | func TestNewMsgFromCborUnknownType(t *testing.T) { |
201 | | - // Test with unknown message type - the NewMsgFromCbor function tries to decode |
202 | | - // into a nil pointer, which results in an error |
203 | 203 | data := []byte{0x80} // empty array |
204 | 204 | msg, err := NewMsgFromCbor(999, data) |
205 | | - // When the message type is unknown, ret is nil, and cbor.Decode(data, nil) returns an error |
206 | | - assert.Error(t, err) |
207 | | - assert.Nil(t, msg) |
| 205 | + require.Error(t, err) |
| 206 | + assert.Contains(t, err.Error(), "unknown message type 999") |
| 207 | + require.Nil(t, msg) |
208 | 208 | } |
209 | 209 |
|
210 | 210 | func TestMsgVotesOfferEmpty(t *testing.T) { |
@@ -235,3 +235,57 @@ func TestMsgBlockAnnouncementEmpty(t *testing.T) { |
235 | 235 | // so we just check it's not nil |
236 | 236 | assert.NotNil(t, decodedMsg) |
237 | 237 | } |
| 238 | + |
| 239 | +// TestMsgVotesOfferThreeElementVote verifies decoding the prototype-2026w27 |
| 240 | +// deployed vote shape: a 3-element array [endorser_block_hash (hash32), |
| 241 | +// voter_id (uint), signature (bytes .size 48)] — the full LeiosVote with the |
| 242 | +// leading slot dropped. Shape confirmed from live musashi captures. |
| 243 | +func TestMsgVotesOfferThreeElementVote(t *testing.T) { |
| 244 | + ebHash := bytes.Repeat([]byte{0xAB}, lcommon.Blake2b256Size) |
| 245 | + sig := bytes.Repeat([]byte{0xCD}, lcommon.LeiosBlsSignatureSize) |
| 246 | + voteCbor, err := cbor.Encode([]any{ebHash, uint64(7), sig}) |
| 247 | + require.NoError(t, err) |
| 248 | + msgCbor, err := cbor.Encode([]any{ |
| 249 | + uint(MessageTypeVotesOffer), |
| 250 | + []cbor.RawMessage{cbor.RawMessage(voteCbor)}, |
| 251 | + }) |
| 252 | + require.NoError(t, err) |
| 253 | + |
| 254 | + var m MsgVotesOffer |
| 255 | + require.NoError(t, m.UnmarshalCBOR(msgCbor)) |
| 256 | + require.Len(t, m.FullVotes, 1) |
| 257 | + require.Empty(t, m.Votes) |
| 258 | + v := m.FullVotes[0] |
| 259 | + assert.Equal(t, uint64(0), v.SlotNo, "3-element vote omits slot") |
| 260 | + assert.Equal(t, ebHash, v.EndorserBlockHash.Bytes()) |
| 261 | + assert.Equal(t, uint64(7), v.VoterId) |
| 262 | + assert.Equal(t, sig, v.VoteSignature) |
| 263 | + |
| 264 | + // A 3-element vote with a wrong-length signature is rejected. |
| 265 | + badCbor, err := cbor.Encode([]any{ebHash, uint64(7), []byte{0x01, 0x02}}) |
| 266 | + require.NoError(t, err) |
| 267 | + badMsg, err := cbor.Encode([]any{ |
| 268 | + uint(MessageTypeVotesOffer), |
| 269 | + []cbor.RawMessage{cbor.RawMessage(badCbor)}, |
| 270 | + }) |
| 271 | + require.NoError(t, err) |
| 272 | + var m2 MsgVotesOffer |
| 273 | + require.ErrorContains(t, m2.UnmarshalCBOR(badMsg), "signature is 2 bytes") |
| 274 | +} |
| 275 | + |
| 276 | +func TestMsgVotesOfferUnknownVoteShape(t *testing.T) { |
| 277 | + voteCbor, err := cbor.Encode([]any{uint64(100)}) |
| 278 | + require.NoError(t, err) |
| 279 | + msgCbor, err := cbor.Encode([]any{ |
| 280 | + uint(MessageTypeVotesOffer), |
| 281 | + []cbor.RawMessage{cbor.RawMessage(voteCbor)}, |
| 282 | + }) |
| 283 | + require.NoError(t, err) |
| 284 | + |
| 285 | + var m MsgVotesOffer |
| 286 | + require.ErrorContains( |
| 287 | + t, |
| 288 | + m.UnmarshalCBOR(msgCbor), |
| 289 | + "votes offer: vote 0 unexpected element count 1", |
| 290 | + ) |
| 291 | +} |
0 commit comments