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