msgalert_test.go raw
1 package wire
2
3 import (
4 "bytes"
5 "io"
6 "reflect"
7 "testing"
8
9 "github.com/davecgh/go-spew/spew"
10 )
11
12 // TestMsgAlert tests the MsgAlert API.
13 func TestMsgAlert(t *testing.T) {
14 pver := ProtocolVersion
15 encoding := BaseEncoding
16 serializedpayload := []byte("some message")
17 signature := []byte("some sig")
18 // Ensure we get the same payload and signature back out.
19 msg := NewMsgAlert(serializedpayload, signature)
20 if !reflect.DeepEqual(msg.SerializedPayload, serializedpayload) {
21 t.Errorf("NewMsgAlert: wrong serializedpayload - got %v, want %v",
22 msg.SerializedPayload, serializedpayload,
23 )
24 }
25 if !reflect.DeepEqual(msg.Signature, signature) {
26 t.Errorf("NewMsgAlert: wrong signature - got %v, want %v",
27 msg.Signature, signature,
28 )
29 }
30 // Ensure the command is expected value.
31 wantCmd := "alert"
32 if cmd := msg.Command(); cmd != wantCmd {
33 t.Errorf("NewMsgAlert: wrong command - got %v want %v",
34 cmd, wantCmd,
35 )
36 }
37 // Ensure max payload is expected value.
38 wantPayload := uint32(1024 * 1024 * 32)
39 maxPayload := msg.MaxPayloadLength(pver)
40 if maxPayload != wantPayload {
41 t.Errorf("MaxPayloadLength: wrong max payload length for "+
42 "protocol version %d - got %v, want %v", pver,
43 maxPayload, wantPayload,
44 )
45 }
46 // Test BtcEncode with Payload == nil
47 var buf bytes.Buffer
48 e := msg.BtcEncode(&buf, pver, encoding)
49 if e != nil {
50 t.Error(e.Error())
51 }
52 // expected = 0x0c + serializedpayload + 0x08 + signature
53 expectedBuf := append([]byte{0x0c}, serializedpayload...)
54 expectedBuf = append(expectedBuf, []byte{0x08}...)
55 expectedBuf = append(expectedBuf, signature...)
56 if !bytes.Equal(buf.Bytes(), expectedBuf) {
57 t.Errorf("BtcEncode got: %s want: %s",
58 spew.Sdump(buf.Bytes()), spew.Sdump(expectedBuf),
59 )
60 }
61 // Test BtcEncode with Payload != nil note: Payload is an empty Alert but not nil
62 msg.Payload = new(Alert)
63 buf = *new(bytes.Buffer)
64 e = msg.BtcEncode(&buf, pver, encoding)
65 if e != nil {
66 t.Error(e.Error())
67 }
68 // empty Alert is 45 null bytes, see Alert comments for details expected = 0x2d + 45*0x00 + 0x08 + signature
69 expectedBuf = append([]byte{0x2d}, bytes.Repeat([]byte{0x00}, 45)...)
70 expectedBuf = append(expectedBuf, []byte{0x08}...)
71 expectedBuf = append(expectedBuf, signature...)
72 if !bytes.Equal(buf.Bytes(), expectedBuf) {
73 t.Errorf("BtcEncode got: %s want: %s",
74 spew.Sdump(buf.Bytes()), spew.Sdump(expectedBuf),
75 )
76 }
77 }
78
79 // TestMsgAlertWire tests the MsgAlert wire encode and decode for various protocol versions.
80 func TestMsgAlertWire(t *testing.T) {
81 baseMsgAlert := NewMsgAlert([]byte("some payload"), []byte("somesig"))
82 baseMsgAlertEncoded := []byte{
83 0x0c, // Varint for payload length
84 0x73, 0x6f, 0x6d, 0x65, 0x20, 0x70, 0x61, 0x79,
85 0x6c, 0x6f, 0x61, 0x64, // "some payload"
86 0x07, // Varint for signature length
87 0x73, 0x6f, 0x6d, 0x65, 0x73, 0x69, 0x67, // "somesig"
88 }
89 tests := []struct {
90 in *MsgAlert // Message to encode
91 out *MsgAlert // Expected decoded message
92 buf []byte // Wire encoding
93 pver uint32 // Protocol version for wire encoding
94 enc MessageEncoding // Message encoding format
95 }{
96 // Latest protocol version.
97 {
98 baseMsgAlert,
99 baseMsgAlert,
100 baseMsgAlertEncoded,
101 ProtocolVersion,
102 BaseEncoding,
103 },
104 // Protocol version BIP0035Version.
105 {
106 baseMsgAlert,
107 baseMsgAlert,
108 baseMsgAlertEncoded,
109 BIP0035Version,
110 BaseEncoding,
111 },
112 // Protocol version BIP0031Version.
113 {
114 baseMsgAlert,
115 baseMsgAlert,
116 baseMsgAlertEncoded,
117 BIP0031Version,
118 BaseEncoding,
119 },
120 // Protocol version NetAddressTimeVersion.
121 {
122 baseMsgAlert,
123 baseMsgAlert,
124 baseMsgAlertEncoded,
125 NetAddressTimeVersion,
126 BaseEncoding,
127 },
128 // Protocol version MultipleAddressVersion.
129 {
130 baseMsgAlert,
131 baseMsgAlert,
132 baseMsgAlertEncoded,
133 MultipleAddressVersion,
134 BaseEncoding,
135 },
136 }
137 t.Logf("Running %d tests", len(tests))
138 for i, test := range tests {
139 // Encode the message to wire format.
140 var buf bytes.Buffer
141 e := test.in.BtcEncode(&buf, test.pver, test.enc)
142 if e != nil {
143 t.Errorf("BtcEncode #%d error %v", i, e)
144 continue
145 }
146 if !bytes.Equal(buf.Bytes(), test.buf) {
147 t.Errorf("BtcEncode #%d\n got: %s want: %s", i,
148 spew.Sdump(buf.Bytes()), spew.Sdump(test.buf),
149 )
150 continue
151 }
152 // Decode the message from wire format.
153 var msg MsgAlert
154 rbuf := bytes.NewReader(test.buf)
155 e = msg.BtcDecode(rbuf, test.pver, test.enc)
156 if e != nil {
157 t.Errorf("BtcDecode #%d error %v", i, e)
158 continue
159 }
160 if !reflect.DeepEqual(&msg, test.out) {
161 t.Errorf("BtcDecode #%d\n got: %s want: %s", i,
162 spew.Sdump(msg), spew.Sdump(test.out),
163 )
164 continue
165 }
166 }
167 }
168
169 // TestMsgAlertWireErrors performs negative tests against wire encode and decode of MsgAlert to confirm error paths work
170 // correctly.
171 func TestMsgAlertWireErrors(t *testing.T) {
172 pver := ProtocolVersion
173 encoding := BaseEncoding
174 baseMsgAlert := NewMsgAlert([]byte("some payload"), []byte("somesig"))
175 baseMsgAlertEncoded := []byte{
176 0x0c, // Varint for payload length
177 0x73, 0x6f, 0x6d, 0x65, 0x20, 0x70, 0x61, 0x79,
178 0x6c, 0x6f, 0x61, 0x64, // "some payload"
179 0x07, // Varint for signature length
180 0x73, 0x6f, 0x6d, 0x65, 0x73, 0x69, 0x67, // "somesig"
181 }
182 tests := []struct {
183 in *MsgAlert // value to encode
184 buf []byte // Wire encoding
185 pver uint32 // Protocol version for wire encoding
186 enc MessageEncoding // Message encoding format
187 max int // Max size of fixed buffer to induce errors
188 writeErr error // Expected write error
189 readErr error // Expected read error
190 }{
191 // Force error in payload length.
192 {baseMsgAlert, baseMsgAlertEncoded, pver, BaseEncoding, 0, io.ErrShortWrite, io.EOF},
193 // Force error in payload.
194 {baseMsgAlert, baseMsgAlertEncoded, pver, BaseEncoding, 1, io.ErrShortWrite, io.EOF},
195 // Force error in signature length.
196 {baseMsgAlert, baseMsgAlertEncoded, pver, BaseEncoding, 13, io.ErrShortWrite, io.EOF},
197 // Force error in signature.
198 {baseMsgAlert, baseMsgAlertEncoded, pver, BaseEncoding, 14, io.ErrShortWrite, io.EOF},
199 }
200 t.Logf("Running %d tests", len(tests))
201 for i, test := range tests {
202 // Encode to wire format.
203 w := newFixedWriter(test.max)
204 e := test.in.BtcEncode(w, test.pver, test.enc)
205 if reflect.TypeOf(e) != reflect.TypeOf(test.writeErr) {
206 t.Errorf("BtcEncode #%d wrong error got: %v, want: %v",
207 i, e, test.writeErr,
208 )
209 continue
210 }
211 // For errors which are not of type MessageError, check them for equality.
212 if _, ok := e.(*MessageError); !ok {
213 if e != test.writeErr {
214 t.Errorf("BtcEncode #%d wrong error got: %v, "+
215 "want: %v", i, e, test.writeErr,
216 )
217 continue
218 }
219 }
220 // Decode from wire format.
221 var msg MsgAlert
222 r := newFixedReader(test.max, test.buf)
223 e = msg.BtcDecode(r, test.pver, test.enc)
224 if reflect.TypeOf(e) != reflect.TypeOf(test.readErr) {
225 t.Errorf("BtcDecode #%d wrong error got: %v, want: %v",
226 i, e, test.readErr,
227 )
228 continue
229 }
230 // For errors which are not of type MessageError, check them for equality.
231 if _, ok := e.(*MessageError); !ok {
232 if e != test.readErr {
233 t.Errorf("BtcDecode #%d wrong error got: %v, "+
234 "want: %v", i, e, test.readErr,
235 )
236 continue
237 }
238 }
239 }
240 // Test Error on empty Payload
241 baseMsgAlert.SerializedPayload = []byte{}
242 w := new(bytes.Buffer)
243 e := baseMsgAlert.BtcEncode(w, pver, encoding)
244 if _, ok := e.(*MessageError); !ok {
245 t.Errorf("MsgAlert.BtcEncode wrong error got: %T, want: %T",
246 e, MessageError{},
247 )
248 }
249 // Test Payload Serialize error overflow the max number of elements in SetCancel
250 baseMsgAlert.Payload = new(Alert)
251 baseMsgAlert.Payload.SetCancel = make([]int32, maxCountSetCancel+1)
252 buf := *new(bytes.Buffer)
253 e = baseMsgAlert.BtcEncode(&buf, pver, encoding)
254 if _, ok := e.(*MessageError); !ok {
255 t.Errorf("MsgAlert.BtcEncode wrong error got: %T, want: %T",
256 e, MessageError{},
257 )
258 }
259 // overflow the max number of elements in SetSubVer
260 baseMsgAlert.Payload = new(Alert)
261 baseMsgAlert.Payload.SetSubVer = make([]string, maxCountSetSubVer+1)
262 buf = *new(bytes.Buffer)
263 e = baseMsgAlert.BtcEncode(&buf, pver, encoding)
264 if _, ok := e.(*MessageError); !ok {
265 t.Errorf("MsgAlert.BtcEncode wrong error got: %T, want: %T",
266 e, MessageError{},
267 )
268 }
269 }
270
271 // TestAlert tests serialization and deserialization of the payload to Alert
272 func TestAlert(t *testing.T) {
273 pver := ProtocolVersion
274 alert := NewAlert(
275 1, 1337093712, 1368628812, 1015,
276 1013, []int32{1014}, 0, 40599, []string{"/Satoshi:0.7.2/"}, 5000, "",
277 "URGENT: upgrade required, see http://bitcoin.org/dos for details",
278 )
279 w := new(bytes.Buffer)
280 e := alert.Serialize(w, pver)
281 if e != nil {
282 t.Error(e.Error())
283 }
284 serializedpayload := w.Bytes()
285 newAlert, e := NewAlertFromPayload(serializedpayload, pver)
286 if e != nil {
287 t.Fatal(e.Error())
288 }
289 if alert.Version != newAlert.Version {
290 t.Errorf("NewAlertFromPayload: wrong Version - got %v, want %v ",
291 alert.Version, newAlert.Version,
292 )
293 }
294 if alert.RelayUntil != newAlert.RelayUntil {
295 t.Errorf("NewAlertFromPayload: wrong RelayUntil - got %v, want %v ",
296 alert.RelayUntil, newAlert.RelayUntil,
297 )
298 }
299 if alert.Expiration != newAlert.Expiration {
300 t.Errorf("NewAlertFromPayload: wrong Expiration - got %v, want %v ",
301 alert.Expiration, newAlert.Expiration,
302 )
303 }
304 if alert.ID != newAlert.ID {
305 t.Errorf("NewAlertFromPayload: wrong ID - got %v, want %v ",
306 alert.ID, newAlert.ID,
307 )
308 }
309 if alert.Cancel != newAlert.Cancel {
310 t.Errorf("NewAlertFromPayload: wrong Cancel - got %v, want %v ",
311 alert.Cancel, newAlert.Cancel,
312 )
313 }
314 if len(alert.SetCancel) != len(newAlert.SetCancel) {
315 t.Errorf("NewAlertFromPayload: wrong number of SetCancel - got %v, want %v ",
316 len(alert.SetCancel), len(newAlert.SetCancel),
317 )
318 }
319 for i := 0; i < len(alert.SetCancel); i++ {
320 if alert.SetCancel[i] != newAlert.SetCancel[i] {
321 t.Errorf("NewAlertFromPayload: wrong SetCancel[%v] - got %v, want %v ",
322 len(alert.SetCancel), alert.SetCancel[i], newAlert.SetCancel[i],
323 )
324 }
325 }
326 if alert.MinVer != newAlert.MinVer {
327 t.Errorf("NewAlertFromPayload: wrong MinVer - got %v, want %v ",
328 alert.MinVer, newAlert.MinVer,
329 )
330 }
331 if alert.MaxVer != newAlert.MaxVer {
332 t.Errorf("NewAlertFromPayload: wrong MaxVer - got %v, want %v ",
333 alert.MaxVer, newAlert.MaxVer,
334 )
335 }
336 if len(alert.SetSubVer) != len(newAlert.SetSubVer) {
337 t.Errorf("NewAlertFromPayload: wrong number of SetSubVer - got %v, want %v ",
338 len(alert.SetSubVer), len(newAlert.SetSubVer),
339 )
340 }
341 for i := 0; i < len(alert.SetSubVer); i++ {
342 if alert.SetSubVer[i] != newAlert.SetSubVer[i] {
343 t.Errorf("NewAlertFromPayload: wrong SetSubVer[%v] - got %v, want %v ",
344 len(alert.SetSubVer), alert.SetSubVer[i], newAlert.SetSubVer[i],
345 )
346 }
347 }
348 if alert.Priority != newAlert.Priority {
349 t.Errorf("NewAlertFromPayload: wrong Priority - got %v, want %v ",
350 alert.Priority, newAlert.Priority,
351 )
352 }
353 if alert.Comment != newAlert.Comment {
354 t.Errorf("NewAlertFromPayload: wrong Comment - got %v, want %v ",
355 alert.Comment, newAlert.Comment,
356 )
357 }
358 if alert.StatusBar != newAlert.StatusBar {
359 t.Errorf("NewAlertFromPayload: wrong StatusBar - got %v, want %v ",
360 alert.StatusBar, newAlert.StatusBar,
361 )
362 }
363 if alert.Reserved != newAlert.Reserved {
364 t.Errorf("NewAlertFromPayload: wrong Reserved - got %v, want %v ",
365 alert.Reserved, newAlert.Reserved,
366 )
367 }
368 }
369
370 // TestAlertErrors performs negative tests against payload serialization, deserialization of Alert to confirm error
371 // paths work correctly.
372 func TestAlertErrors(t *testing.T) {
373 pver := ProtocolVersion
374 baseAlert := NewAlert(
375 1, 1337093712, 1368628812, 1015,
376 1013, []int32{1014}, 0, 40599, []string{"/Satoshi:0.7.2/"}, 5000, "",
377 "URGENT",
378 )
379 baseAlertEncoded := []byte{
380 0x01, 0x00, 0x00, 0x00, 0x50, 0x6e, 0xb2, 0x4f, 0x00, 0x00, 0x00, 0x00, 0x4c, 0x9e, 0x93,
381 0x51, // |....Pn.O....L..Q|
382 0x00, 0x00, 0x00, 0x00, 0xf7, 0x03, 0x00, 0x00, 0xf5, 0x03, 0x00, 0x00, 0x01, 0xf6, 0x03,
383 0x00, // |................|
384 0x00, 0x00, 0x00, 0x00, 0x00, 0x97, 0x9e, 0x00, 0x00, 0x01, 0x0f, 0x2f, 0x53, 0x61, 0x74,
385 0x6f, // |.........../Sato|
386 0x73, 0x68, 0x69, 0x3a, 0x30, 0x2e, 0x37, 0x2e, 0x32, 0x2f, 0x88, 0x13, 0x00, 0x00, 0x00,
387 0x06, // |shi:0.7.2/......|
388 0x55, 0x52, 0x47, 0x45, 0x4e, 0x54, 0x00, // |URGENT.|
389 }
390 tests := []struct {
391 in *Alert // value to encode
392 buf []byte // Wire encoding
393 pver uint32 // Protocol version for wire encoding
394 max int // Max size of fixed buffer to induce errors
395 writeErr error // Expected write error
396 readErr error // Expected read error
397 }{
398 // Force error in Version
399 {baseAlert, baseAlertEncoded, pver, 0, io.ErrShortWrite, io.EOF},
400 // Force error in SetCancel VarInt.
401 {baseAlert, baseAlertEncoded, pver, 28, io.ErrShortWrite, io.EOF},
402 // Force error in SetCancel ints.
403 {baseAlert, baseAlertEncoded, pver, 29, io.ErrShortWrite, io.EOF},
404 // Force error in MinVer
405 {baseAlert, baseAlertEncoded, pver, 40, io.ErrShortWrite, io.EOF},
406 // Force error in SetSubVer string VarInt.
407 {baseAlert, baseAlertEncoded, pver, 41, io.ErrShortWrite, io.EOF},
408 // Force error in SetSubVer strings.
409 {baseAlert, baseAlertEncoded, pver, 48, io.ErrShortWrite, io.EOF},
410 // Force error in Priority
411 {baseAlert, baseAlertEncoded, pver, 60, io.ErrShortWrite, io.EOF},
412 // Force error in Comment string.
413 {baseAlert, baseAlertEncoded, pver, 62, io.ErrShortWrite, io.EOF},
414 // Force error in StatusBar string.
415 {baseAlert, baseAlertEncoded, pver, 64, io.ErrShortWrite, io.EOF},
416 // Force error in Reserved string.
417 {baseAlert, baseAlertEncoded, pver, 70, io.ErrShortWrite, io.EOF},
418 }
419 t.Logf("Running %d tests", len(tests))
420 for i, test := range tests {
421 w := newFixedWriter(test.max)
422 e := test.in.Serialize(w, test.pver)
423 if reflect.TypeOf(e) != reflect.TypeOf(test.writeErr) {
424 t.Errorf("Alert.Serialize #%d wrong error got: %v, want: %v",
425 i, e, test.writeErr,
426 )
427 continue
428 }
429 var alert Alert
430 r := newFixedReader(test.max, test.buf)
431 e = alert.Deserialize(r, test.pver)
432 if reflect.TypeOf(e) != reflect.TypeOf(test.readErr) {
433 t.Errorf("Alert.Deserialize #%d wrong error got: %v, want: %v",
434 i, e, test.readErr,
435 )
436 continue
437 }
438 }
439 // overflow the max number of elements in SetCancel
440 // maxCountSetCancel + 1 == 8388575 == \xdf\xff\x7f\x00
441 // replace bytes 29-33
442 badAlertEncoded := []byte{
443 0x01, 0x00, 0x00, 0x00, 0x50, 0x6e, 0xb2, 0x4f, 0x00, 0x00, 0x00, 0x00, 0x4c, 0x9e, 0x93,
444 0x51, // |....Pn.O....L..Q|
445 0x00, 0x00, 0x00, 0x00, 0xf7, 0x03, 0x00, 0x00, 0xf5, 0x03, 0x00, 0x00, 0xfe, 0xdf, 0xff,
446 0x7f, // |................|
447 0x00, 0x00, 0x00, 0x00, 0x00, 0x97, 0x9e, 0x00, 0x00, 0x01, 0x0f, 0x2f, 0x53, 0x61, 0x74,
448 0x6f, // |.........../Sato|
449 0x73, 0x68, 0x69, 0x3a, 0x30, 0x2e, 0x37, 0x2e, 0x32, 0x2f, 0x88, 0x13, 0x00, 0x00, 0x00,
450 0x06, // |shi:0.7.2/......|
451 0x55, 0x52, 0x47, 0x45, 0x4e, 0x54, 0x00, // |URGENT.|
452 }
453 var alert Alert
454 r := bytes.NewReader(badAlertEncoded)
455 e := alert.Deserialize(r, pver)
456 if _, ok := e.(*MessageError); !ok {
457 t.Errorf("Alert.Deserialize wrong error got: %T, want: %T",
458 e, MessageError{},
459 )
460 }
461 // overflow the max number of elements in SetSubVer maxCountSetSubVer + 1 == 131071 + 1 == \x00\x00\x02\x00
462 // replace bytes 42-46
463 badAlertEncoded = []byte{
464 0x01, 0x00, 0x00, 0x00, 0x50, 0x6e, 0xb2, 0x4f, 0x00, 0x00, 0x00, 0x00, 0x4c, 0x9e, 0x93,
465 0x51, // |....Pn.O....L..Q|
466 0x00, 0x00, 0x00, 0x00, 0xf7, 0x03, 0x00, 0x00, 0xf5, 0x03, 0x00, 0x00, 0x01, 0xf6, 0x03,
467 0x00, // |................|
468 0x00, 0x00, 0x00, 0x00, 0x00, 0x97, 0x9e, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x02, 0x00, 0x74,
469 0x6f, // |.........../Sato|
470 0x73, 0x68, 0x69, 0x3a, 0x30, 0x2e, 0x37, 0x2e, 0x32, 0x2f, 0x88, 0x13, 0x00, 0x00, 0x00,
471 0x06, // |shi:0.7.2/......|
472 0x55, 0x52, 0x47, 0x45, 0x4e, 0x54, 0x00, // |URGENT.|
473 }
474 r = bytes.NewReader(badAlertEncoded)
475 e = alert.Deserialize(r, pver)
476 if _, ok := e.(*MessageError); !ok {
477 t.Errorf("Alert.Deserialize wrong error got: %T, want: %T",
478 e, MessageError{},
479 )
480 }
481 }
482