1 // Copyright (c) 2013-2016 The btcsuite developers
2 // Use of this source code is governed by an ISC
3 // license that can be found in the LICENSE file.
13 "github.com/davecgh/go-spew/spew"
16 // TestMsgAlert tests the MsgAlert API.
17 func TestMsgAlert(t *testing.T) {
18 pver := ProtocolVersion
19 encoding := BaseEncoding
20 serializedpayload := []byte("some message")
21 signature := []byte("some sig")
23 // Ensure we get the same payload and signature back out.
24 msg := NewMsgAlert(serializedpayload, signature)
25 if !reflect.DeepEqual(msg.SerializedPayload, serializedpayload) {
26 t.Errorf("NewMsgAlert: wrong serializedpayload - got %v, want %v",
27 msg.SerializedPayload, serializedpayload)
29 if !reflect.DeepEqual(msg.Signature, signature) {
30 t.Errorf("NewMsgAlert: wrong signature - got %v, want %v",
31 msg.Signature, signature)
34 // Ensure the command is expected value.
36 if cmd := msg.Command(); cmd != wantCmd {
37 t.Errorf("NewMsgAlert: wrong command - got %v want %v",
41 // Ensure max payload is expected value.
42 wantPayload := uint32(1024 * 1024 * 32)
43 maxPayload := msg.MaxPayloadLength(pver)
44 if maxPayload != wantPayload {
45 t.Errorf("MaxPayloadLength: wrong max payload length for "+
46 "protocol version %d - got %v, want %v", pver,
47 maxPayload, wantPayload)
50 // Test BtcEncode with Payload == nil
52 err := msg.BtcEncode(&buf, pver, encoding)
56 // expected = 0x0c + serializedpayload + 0x08 + signature
57 expectedBuf := append([]byte{0x0c}, serializedpayload...)
58 expectedBuf = append(expectedBuf, []byte{0x08}...)
59 expectedBuf = append(expectedBuf, signature...)
60 if !bytes.Equal(buf.Bytes(), expectedBuf) {
61 t.Errorf("BtcEncode got: %s want: %s",
62 spew.Sdump(buf.Bytes()), spew.Sdump(expectedBuf))
65 // Test BtcEncode with Payload != nil
66 // note: Payload is an empty Alert but not nil
67 msg.Payload = new(Alert)
68 buf = *new(bytes.Buffer)
69 err = msg.BtcEncode(&buf, pver, encoding)
73 // empty Alert is 45 null bytes, see Alert comments
75 // expected = 0x2d + 45*0x00 + 0x08 + signature
76 expectedBuf = append([]byte{0x2d}, bytes.Repeat([]byte{0x00}, 45)...)
77 expectedBuf = append(expectedBuf, []byte{0x08}...)
78 expectedBuf = append(expectedBuf, signature...)
79 if !bytes.Equal(buf.Bytes(), expectedBuf) {
80 t.Errorf("BtcEncode got: %s want: %s",
81 spew.Sdump(buf.Bytes()), spew.Sdump(expectedBuf))
85 // TestMsgAlertWire tests the MsgAlert wire encode and decode for various protocol
87 func TestMsgAlertWire(t *testing.T) {
88 baseMsgAlert := NewMsgAlert([]byte("some payload"), []byte("somesig"))
89 baseMsgAlertEncoded := []byte{
90 0x0c, // Varint for payload length
91 0x73, 0x6f, 0x6d, 0x65, 0x20, 0x70, 0x61, 0x79,
92 0x6c, 0x6f, 0x61, 0x64, // "some payload"
93 0x07, // Varint for signature length
94 0x73, 0x6f, 0x6d, 0x65, 0x73, 0x69, 0x67, // "somesig"
98 in *MsgAlert // Message to encode
99 out *MsgAlert // Expected decoded message
100 buf []byte // Wire encoding
101 pver uint32 // Protocol version for wire encoding
102 enc MessageEncoding // Message encoding format
104 // Latest protocol version.
113 // Protocol version BIP0035Version.
122 // Protocol version BIP0031Version.
131 // Protocol version NetAddressTimeVersion.
136 NetAddressTimeVersion,
140 // Protocol version MultipleAddressVersion.
145 MultipleAddressVersion,
150 t.Logf("Running %d tests", len(tests))
151 for i, test := range tests {
152 // Encode the message to wire format.
154 err := test.in.BtcEncode(&buf, test.pver, test.enc)
156 t.Errorf("BtcEncode #%d error %v", i, err)
159 if !bytes.Equal(buf.Bytes(), test.buf) {
160 t.Errorf("BtcEncode #%d\n got: %s want: %s", i,
161 spew.Sdump(buf.Bytes()), spew.Sdump(test.buf))
165 // Decode the message from wire format.
167 rbuf := bytes.NewReader(test.buf)
168 err = msg.BtcDecode(rbuf, test.pver, test.enc)
170 t.Errorf("BtcDecode #%d error %v", i, err)
173 if !reflect.DeepEqual(&msg, test.out) {
174 t.Errorf("BtcDecode #%d\n got: %s want: %s", i,
175 spew.Sdump(msg), spew.Sdump(test.out))
181 // TestMsgAlertWireErrors performs negative tests against wire encode and decode
182 // of MsgAlert to confirm error paths work correctly.
183 func TestMsgAlertWireErrors(t *testing.T) {
184 pver := ProtocolVersion
185 encoding := BaseEncoding
187 baseMsgAlert := NewMsgAlert([]byte("some payload"), []byte("somesig"))
188 baseMsgAlertEncoded := []byte{
189 0x0c, // Varint for payload length
190 0x73, 0x6f, 0x6d, 0x65, 0x20, 0x70, 0x61, 0x79,
191 0x6c, 0x6f, 0x61, 0x64, // "some payload"
192 0x07, // Varint for signature length
193 0x73, 0x6f, 0x6d, 0x65, 0x73, 0x69, 0x67, // "somesig"
197 in *MsgAlert // Value to encode
198 buf []byte // Wire encoding
199 pver uint32 // Protocol version for wire encoding
200 enc MessageEncoding // Message encoding format
201 max int // Max size of fixed buffer to induce errors
202 writeErr error // Expected write error
203 readErr error // Expected read error
205 // Force error in payload length.
206 {baseMsgAlert, baseMsgAlertEncoded, pver, BaseEncoding, 0, io.ErrShortWrite, io.EOF},
207 // Force error in payload.
208 {baseMsgAlert, baseMsgAlertEncoded, pver, BaseEncoding, 1, io.ErrShortWrite, io.EOF},
209 // Force error in signature length.
210 {baseMsgAlert, baseMsgAlertEncoded, pver, BaseEncoding, 13, io.ErrShortWrite, io.EOF},
211 // Force error in signature.
212 {baseMsgAlert, baseMsgAlertEncoded, pver, BaseEncoding, 14, io.ErrShortWrite, io.EOF},
215 t.Logf("Running %d tests", len(tests))
216 for i, test := range tests {
217 // Encode to wire format.
218 w := newFixedWriter(test.max)
219 err := test.in.BtcEncode(w, test.pver, test.enc)
220 if reflect.TypeOf(err) != reflect.TypeOf(test.writeErr) {
221 t.Errorf("BtcEncode #%d wrong error got: %v, want: %v",
222 i, err, test.writeErr)
226 // For errors which are not of type MessageError, check them for
228 if _, ok := err.(*MessageError); !ok {
229 if err != test.writeErr {
230 t.Errorf("BtcEncode #%d wrong error got: %v, "+
231 "want: %v", i, err, test.writeErr)
236 // Decode from wire format.
238 r := newFixedReader(test.max, test.buf)
239 err = msg.BtcDecode(r, test.pver, test.enc)
240 if reflect.TypeOf(err) != reflect.TypeOf(test.readErr) {
241 t.Errorf("BtcDecode #%d wrong error got: %v, want: %v",
242 i, err, test.readErr)
246 // For errors which are not of type MessageError, check them for
248 if _, ok := err.(*MessageError); !ok {
249 if err != test.readErr {
250 t.Errorf("BtcDecode #%d wrong error got: %v, "+
251 "want: %v", i, err, test.readErr)
257 // Test Error on empty Payload
258 baseMsgAlert.SerializedPayload = []byte{}
259 w := new(bytes.Buffer)
260 err := baseMsgAlert.BtcEncode(w, pver, encoding)
261 if _, ok := err.(*MessageError); !ok {
262 t.Errorf("MsgAlert.BtcEncode wrong error got: %T, want: %T",
266 // Test Payload Serialize error
267 // overflow the max number of elements in SetCancel
268 baseMsgAlert.Payload = new(Alert)
269 baseMsgAlert.Payload.SetCancel = make([]int32, maxCountSetCancel+1)
270 buf := *new(bytes.Buffer)
271 err = baseMsgAlert.BtcEncode(&buf, pver, encoding)
272 if _, ok := err.(*MessageError); !ok {
273 t.Errorf("MsgAlert.BtcEncode wrong error got: %T, want: %T",
277 // overflow the max number of elements in SetSubVer
278 baseMsgAlert.Payload = new(Alert)
279 baseMsgAlert.Payload.SetSubVer = make([]string, maxCountSetSubVer+1)
280 buf = *new(bytes.Buffer)
281 err = baseMsgAlert.BtcEncode(&buf, pver, encoding)
282 if _, ok := err.(*MessageError); !ok {
283 t.Errorf("MsgAlert.BtcEncode wrong error got: %T, want: %T",
288 // TestAlert tests serialization and deserialization
289 // of the payload to Alert
290 func TestAlert(t *testing.T) {
291 pver := ProtocolVersion
293 1, 1337093712, 1368628812, 1015,
294 1013, []int32{1014}, 0, 40599, []string{"/Satoshi:0.7.2/"}, 5000, "",
295 "URGENT: upgrade required, see http://bitcoin.org/dos for details",
297 w := new(bytes.Buffer)
298 err := alert.Serialize(w, pver)
302 serializedpayload := w.Bytes()
303 newAlert, err := NewAlertFromPayload(serializedpayload, pver)
308 if alert.Version != newAlert.Version {
309 t.Errorf("NewAlertFromPayload: wrong Version - got %v, want %v ",
310 alert.Version, newAlert.Version)
312 if alert.RelayUntil != newAlert.RelayUntil {
313 t.Errorf("NewAlertFromPayload: wrong RelayUntil - got %v, want %v ",
314 alert.RelayUntil, newAlert.RelayUntil)
316 if alert.Expiration != newAlert.Expiration {
317 t.Errorf("NewAlertFromPayload: wrong Expiration - got %v, want %v ",
318 alert.Expiration, newAlert.Expiration)
320 if alert.ID != newAlert.ID {
321 t.Errorf("NewAlertFromPayload: wrong ID - got %v, want %v ",
322 alert.ID, newAlert.ID)
324 if alert.Cancel != newAlert.Cancel {
325 t.Errorf("NewAlertFromPayload: wrong Cancel - got %v, want %v ",
326 alert.Cancel, newAlert.Cancel)
328 if len(alert.SetCancel) != len(newAlert.SetCancel) {
329 t.Errorf("NewAlertFromPayload: wrong number of SetCancel - got %v, want %v ",
330 len(alert.SetCancel), len(newAlert.SetCancel))
332 for i := 0; i < len(alert.SetCancel); i++ {
333 if alert.SetCancel[i] != newAlert.SetCancel[i] {
334 t.Errorf("NewAlertFromPayload: wrong SetCancel[%v] - got %v, want %v ",
335 len(alert.SetCancel), alert.SetCancel[i], newAlert.SetCancel[i])
338 if alert.MinVer != newAlert.MinVer {
339 t.Errorf("NewAlertFromPayload: wrong MinVer - got %v, want %v ",
340 alert.MinVer, newAlert.MinVer)
342 if alert.MaxVer != newAlert.MaxVer {
343 t.Errorf("NewAlertFromPayload: wrong MaxVer - got %v, want %v ",
344 alert.MaxVer, newAlert.MaxVer)
346 if len(alert.SetSubVer) != len(newAlert.SetSubVer) {
347 t.Errorf("NewAlertFromPayload: wrong number of SetSubVer - got %v, want %v ",
348 len(alert.SetSubVer), len(newAlert.SetSubVer))
350 for i := 0; i < len(alert.SetSubVer); i++ {
351 if alert.SetSubVer[i] != newAlert.SetSubVer[i] {
352 t.Errorf("NewAlertFromPayload: wrong SetSubVer[%v] - got %v, want %v ",
353 len(alert.SetSubVer), alert.SetSubVer[i], newAlert.SetSubVer[i])
356 if alert.Priority != newAlert.Priority {
357 t.Errorf("NewAlertFromPayload: wrong Priority - got %v, want %v ",
358 alert.Priority, newAlert.Priority)
360 if alert.Comment != newAlert.Comment {
361 t.Errorf("NewAlertFromPayload: wrong Comment - got %v, want %v ",
362 alert.Comment, newAlert.Comment)
364 if alert.StatusBar != newAlert.StatusBar {
365 t.Errorf("NewAlertFromPayload: wrong StatusBar - got %v, want %v ",
366 alert.StatusBar, newAlert.StatusBar)
368 if alert.Reserved != newAlert.Reserved {
369 t.Errorf("NewAlertFromPayload: wrong Reserved - got %v, want %v ",
370 alert.Reserved, newAlert.Reserved)
374 // TestAlertErrors performs negative tests against payload serialization,
375 // deserialization of Alert to confirm error paths work correctly.
376 func TestAlertErrors(t *testing.T) {
377 pver := ProtocolVersion
379 baseAlert := NewAlert(
380 1, 1337093712, 1368628812, 1015,
381 1013, []int32{1014}, 0, 40599, []string{"/Satoshi:0.7.2/"}, 5000, "",
384 baseAlertEncoded := []byte{
385 0x01, 0x00, 0x00, 0x00, 0x50, 0x6e, 0xb2, 0x4f, 0x00, 0x00, 0x00, 0x00, 0x4c, 0x9e, 0x93, 0x51, //|....Pn.O....L..Q|
386 0x00, 0x00, 0x00, 0x00, 0xf7, 0x03, 0x00, 0x00, 0xf5, 0x03, 0x00, 0x00, 0x01, 0xf6, 0x03, 0x00, //|................|
387 0x00, 0x00, 0x00, 0x00, 0x00, 0x97, 0x9e, 0x00, 0x00, 0x01, 0x0f, 0x2f, 0x53, 0x61, 0x74, 0x6f, //|.........../Sato|
388 0x73, 0x68, 0x69, 0x3a, 0x30, 0x2e, 0x37, 0x2e, 0x32, 0x2f, 0x88, 0x13, 0x00, 0x00, 0x00, 0x06, //|shi:0.7.2/......|
389 0x55, 0x52, 0x47, 0x45, 0x4e, 0x54, 0x00, //|URGENT.|
392 in *Alert // Value to encode
393 buf []byte // Wire encoding
394 pver uint32 // Protocol version for wire encoding
395 max int // Max size of fixed buffer to induce errors
396 writeErr error // Expected write error
397 readErr error // Expected read error
399 // Force error in Version
400 {baseAlert, baseAlertEncoded, pver, 0, io.ErrShortWrite, io.EOF},
401 // Force error in SetCancel VarInt.
402 {baseAlert, baseAlertEncoded, pver, 28, io.ErrShortWrite, io.EOF},
403 // Force error in SetCancel ints.
404 {baseAlert, baseAlertEncoded, pver, 29, io.ErrShortWrite, io.EOF},
405 // Force error in MinVer
406 {baseAlert, baseAlertEncoded, pver, 40, io.ErrShortWrite, io.EOF},
407 // Force error in SetSubVer string VarInt.
408 {baseAlert, baseAlertEncoded, pver, 41, io.ErrShortWrite, io.EOF},
409 // Force error in SetSubVer strings.
410 {baseAlert, baseAlertEncoded, pver, 48, io.ErrShortWrite, io.EOF},
411 // Force error in Priority
412 {baseAlert, baseAlertEncoded, pver, 60, io.ErrShortWrite, io.EOF},
413 // Force error in Comment string.
414 {baseAlert, baseAlertEncoded, pver, 62, io.ErrShortWrite, io.EOF},
415 // Force error in StatusBar string.
416 {baseAlert, baseAlertEncoded, pver, 64, io.ErrShortWrite, io.EOF},
417 // Force error in Reserved string.
418 {baseAlert, baseAlertEncoded, pver, 70, io.ErrShortWrite, io.EOF},
421 t.Logf("Running %d tests", len(tests))
422 for i, test := range tests {
423 w := newFixedWriter(test.max)
424 err := test.in.Serialize(w, test.pver)
425 if reflect.TypeOf(err) != reflect.TypeOf(test.writeErr) {
426 t.Errorf("Alert.Serialize #%d wrong error got: %v, want: %v",
427 i, err, test.writeErr)
432 r := newFixedReader(test.max, test.buf)
433 err = alert.Deserialize(r, test.pver)
434 if reflect.TypeOf(err) != reflect.TypeOf(test.readErr) {
435 t.Errorf("Alert.Deserialize #%d wrong error got: %v, want: %v",
436 i, err, test.readErr)
441 // overflow the max number of elements in SetCancel
442 // maxCountSetCancel + 1 == 8388575 == \xdf\xff\x7f\x00
443 // replace bytes 29-33
444 badAlertEncoded := []byte{
445 0x01, 0x00, 0x00, 0x00, 0x50, 0x6e, 0xb2, 0x4f, 0x00, 0x00, 0x00, 0x00, 0x4c, 0x9e, 0x93, 0x51, //|....Pn.O....L..Q|
446 0x00, 0x00, 0x00, 0x00, 0xf7, 0x03, 0x00, 0x00, 0xf5, 0x03, 0x00, 0x00, 0xfe, 0xdf, 0xff, 0x7f, //|................|
447 0x00, 0x00, 0x00, 0x00, 0x00, 0x97, 0x9e, 0x00, 0x00, 0x01, 0x0f, 0x2f, 0x53, 0x61, 0x74, 0x6f, //|.........../Sato|
448 0x73, 0x68, 0x69, 0x3a, 0x30, 0x2e, 0x37, 0x2e, 0x32, 0x2f, 0x88, 0x13, 0x00, 0x00, 0x00, 0x06, //|shi:0.7.2/......|
449 0x55, 0x52, 0x47, 0x45, 0x4e, 0x54, 0x00, //|URGENT.|
452 r := bytes.NewReader(badAlertEncoded)
453 err := alert.Deserialize(r, pver)
454 if _, ok := err.(*MessageError); !ok {
455 t.Errorf("Alert.Deserialize wrong error got: %T, want: %T",
459 // overflow the max number of elements in SetSubVer
460 // maxCountSetSubVer + 1 == 131071 + 1 == \x00\x00\x02\x00
461 // replace bytes 42-46
462 badAlertEncoded = []byte{
463 0x01, 0x00, 0x00, 0x00, 0x50, 0x6e, 0xb2, 0x4f, 0x00, 0x00, 0x00, 0x00, 0x4c, 0x9e, 0x93, 0x51, //|....Pn.O....L..Q|
464 0x00, 0x00, 0x00, 0x00, 0xf7, 0x03, 0x00, 0x00, 0xf5, 0x03, 0x00, 0x00, 0x01, 0xf6, 0x03, 0x00, //|................|
465 0x00, 0x00, 0x00, 0x00, 0x00, 0x97, 0x9e, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x02, 0x00, 0x74, 0x6f, //|.........../Sato|
466 0x73, 0x68, 0x69, 0x3a, 0x30, 0x2e, 0x37, 0x2e, 0x32, 0x2f, 0x88, 0x13, 0x00, 0x00, 0x00, 0x06, //|shi:0.7.2/......|
467 0x55, 0x52, 0x47, 0x45, 0x4e, 0x54, 0x00, //|URGENT.|
469 r = bytes.NewReader(badAlertEncoded)
470 err = alert.Deserialize(r, pver)
471 if _, ok := err.(*MessageError); !ok {
472 t.Errorf("Alert.Deserialize wrong error got: %T, want: %T",