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.
16 "github.com/davecgh/go-spew/spew"
19 // TestVersion tests the MsgVersion API.
20 func TestVersion(t *testing.T) {
21 pver := ProtocolVersion
23 // Create version message data.
24 lastBlock := int32(234234)
25 tcpAddrMe := &net.TCPAddr{IP: net.ParseIP("127.0.0.1"), Port: 8333}
26 me := NewNetAddress(tcpAddrMe, SFNodeNetwork)
27 tcpAddrYou := &net.TCPAddr{IP: net.ParseIP("192.168.0.1"), Port: 8333}
28 you := NewNetAddress(tcpAddrYou, SFNodeNetwork)
29 nonce, err := RandomUint64()
31 t.Errorf("RandomUint64: error generating nonce: %v", err)
34 // Ensure we get the correct data back out.
35 msg := NewMsgVersion(me, you, nonce, lastBlock)
36 if msg.ProtocolVersion != int32(pver) {
37 t.Errorf("NewMsgVersion: wrong protocol version - got %v, want %v",
38 msg.ProtocolVersion, pver)
40 if !reflect.DeepEqual(&msg.AddrMe, me) {
41 t.Errorf("NewMsgVersion: wrong me address - got %v, want %v",
42 spew.Sdump(&msg.AddrMe), spew.Sdump(me))
44 if !reflect.DeepEqual(&msg.AddrYou, you) {
45 t.Errorf("NewMsgVersion: wrong you address - got %v, want %v",
46 spew.Sdump(&msg.AddrYou), spew.Sdump(you))
48 if msg.Nonce != nonce {
49 t.Errorf("NewMsgVersion: wrong nonce - got %v, want %v",
52 if msg.UserAgent != DefaultUserAgent {
53 t.Errorf("NewMsgVersion: wrong user agent - got %v, want %v",
54 msg.UserAgent, DefaultUserAgent)
56 if msg.LastBlock != lastBlock {
57 t.Errorf("NewMsgVersion: wrong last block - got %v, want %v",
58 msg.LastBlock, lastBlock)
60 if msg.DisableRelayTx {
61 t.Errorf("NewMsgVersion: disable relay tx is not false by "+
62 "default - got %v, want %v", msg.DisableRelayTx, false)
65 msg.AddUserAgent("myclient", "1.2.3", "optional", "comments")
66 customUserAgent := DefaultUserAgent + "myclient:1.2.3(optional; comments)/"
67 if msg.UserAgent != customUserAgent {
68 t.Errorf("AddUserAgent: wrong user agent - got %s, want %s",
69 msg.UserAgent, customUserAgent)
72 msg.AddUserAgent("mygui", "3.4.5")
73 customUserAgent += "mygui:3.4.5/"
74 if msg.UserAgent != customUserAgent {
75 t.Errorf("AddUserAgent: wrong user agent - got %s, want %s",
76 msg.UserAgent, customUserAgent)
79 // accounting for ":", "/"
80 err = msg.AddUserAgent(strings.Repeat("t",
81 MaxUserAgentLen-len(customUserAgent)-2+1), "")
82 if _, ok := err.(*MessageError); !ok {
83 t.Errorf("AddUserAgent: expected error not received "+
84 "- got %v, want %T", err, MessageError{})
88 // Version message should not have any services set by default.
89 if msg.Services != 0 {
90 t.Errorf("NewMsgVersion: wrong default services - got %v, want %v",
94 if msg.HasService(SFNodeNetwork) {
95 t.Errorf("HasService: SFNodeNetwork service is set")
98 // Ensure the command is expected value.
100 if cmd := msg.Command(); cmd != wantCmd {
101 t.Errorf("NewMsgVersion: wrong command - got %v want %v",
105 // Ensure max payload is expected value.
106 // Protocol version 4 bytes + services 8 bytes + timestamp 8 bytes +
107 // remote and local net addresses + nonce 8 bytes + length of user agent
108 // (varInt) + max allowed user agent length + last block 4 bytes +
109 // relay transactions flag 1 byte.
110 wantPayload := uint32(358)
111 maxPayload := msg.MaxPayloadLength(pver)
112 if maxPayload != wantPayload {
113 t.Errorf("MaxPayloadLength: wrong max payload length for "+
114 "protocol version %d - got %v, want %v", pver,
115 maxPayload, wantPayload)
118 // Ensure adding the full service node flag works.
119 msg.AddService(SFNodeNetwork)
120 if msg.Services != SFNodeNetwork {
121 t.Errorf("AddService: wrong services - got %v, want %v",
122 msg.Services, SFNodeNetwork)
124 if !msg.HasService(SFNodeNetwork) {
125 t.Errorf("HasService: SFNodeNetwork service not set")
129 // TestVersionWire tests the MsgVersion wire encode and decode for various
130 // protocol versions.
131 func TestVersionWire(t *testing.T) {
132 // verRelayTxFalse and verRelayTxFalseEncoded is a version message as of
133 // BIP0037Version with the transaction relay disabled.
134 baseVersionBIP0037Copy := *baseVersionBIP0037
135 verRelayTxFalse := &baseVersionBIP0037Copy
136 verRelayTxFalse.DisableRelayTx = true
137 verRelayTxFalseEncoded := make([]byte, len(baseVersionBIP0037Encoded))
138 copy(verRelayTxFalseEncoded, baseVersionBIP0037Encoded)
139 verRelayTxFalseEncoded[len(verRelayTxFalseEncoded)-1] = 0
142 in *MsgVersion // Message to encode
143 out *MsgVersion // Expected decoded message
144 buf []byte // Wire encoding
145 pver uint32 // Protocol version for wire encoding
146 enc MessageEncoding // Message encoding format
148 // Latest protocol version.
152 baseVersionBIP0037Encoded,
157 // Protocol version BIP0037Version with relay transactions field
162 baseVersionBIP0037Encoded,
167 // Protocol version BIP0037Version with relay transactions field
172 verRelayTxFalseEncoded,
177 // Protocol version BIP0035Version.
186 // Protocol version BIP0031Version.
195 // Protocol version NetAddressTimeVersion.
200 NetAddressTimeVersion,
204 // Protocol version MultipleAddressVersion.
209 MultipleAddressVersion,
214 t.Logf("Running %d tests", len(tests))
215 for i, test := range tests {
216 // Encode the message to wire format.
218 err := test.in.BtcEncode(&buf, test.pver, test.enc)
220 t.Errorf("BtcEncode #%d error %v", i, err)
223 if !bytes.Equal(buf.Bytes(), test.buf) {
224 t.Errorf("BtcEncode #%d\n got: %s want: %s", i,
225 spew.Sdump(buf.Bytes()), spew.Sdump(test.buf))
229 // Decode the message from wire format.
231 rbuf := bytes.NewBuffer(test.buf)
232 err = msg.BtcDecode(rbuf, test.pver, test.enc)
234 t.Errorf("BtcDecode #%d error %v", i, err)
237 if !reflect.DeepEqual(&msg, test.out) {
238 t.Errorf("BtcDecode #%d\n got: %s want: %s", i,
239 spew.Sdump(msg), spew.Sdump(test.out))
245 // TestVersionWireErrors performs negative tests against wire encode and
246 // decode of MsgGetHeaders to confirm error paths work correctly.
247 func TestVersionWireErrors(t *testing.T) {
248 // Use protocol version 60002 specifically here instead of the latest
249 // because the test data is using bytes encoded with that protocol
251 pver := uint32(60002)
253 wireErr := &MessageError{}
255 // Ensure calling MsgVersion.BtcDecode with a non *bytes.Buffer returns
257 fr := newFixedReader(0, []byte{})
258 if err := baseVersion.BtcDecode(fr, pver, enc); err == nil {
259 t.Errorf("Did not received error when calling " +
260 "MsgVersion.BtcDecode with non *bytes.Buffer")
263 // Copy the base version and change the user agent to exceed max limits.
266 newUA := "/" + strings.Repeat("t", MaxUserAgentLen-8+1) + ":0.0.1/"
267 exceedUAVer.UserAgent = newUA
269 // Encode the new UA length as a varint.
270 var newUAVarIntBuf bytes.Buffer
271 err := WriteVarInt(&newUAVarIntBuf, pver, uint64(len(newUA)))
273 t.Errorf("WriteVarInt: error %v", err)
276 // Make a new buffer big enough to hold the base version plus the new
277 // bytes for the bigger varint to hold the new size of the user agent
278 // and the new user agent string. Then stich it all together.
279 newLen := len(baseVersionEncoded) - len(baseVersion.UserAgent)
280 newLen = newLen + len(newUAVarIntBuf.Bytes()) - 1 + len(newUA)
281 exceedUAVerEncoded := make([]byte, newLen)
282 copy(exceedUAVerEncoded, baseVersionEncoded[0:80])
283 copy(exceedUAVerEncoded[80:], newUAVarIntBuf.Bytes())
284 copy(exceedUAVerEncoded[83:], []byte(newUA))
285 copy(exceedUAVerEncoded[83+len(newUA):], baseVersionEncoded[97:100])
288 in *MsgVersion // Value to encode
289 buf []byte // Wire encoding
290 pver uint32 // Protocol version for wire encoding
291 enc MessageEncoding // Message encoding format
292 max int // Max size of fixed buffer to induce errors
293 writeErr error // Expected write error
294 readErr error // Expected read error
296 // Force error in protocol version.
297 {baseVersion, baseVersionEncoded, pver, BaseEncoding, 0, io.ErrShortWrite, io.EOF},
298 // Force error in services.
299 {baseVersion, baseVersionEncoded, pver, BaseEncoding, 4, io.ErrShortWrite, io.EOF},
300 // Force error in timestamp.
301 {baseVersion, baseVersionEncoded, pver, BaseEncoding, 12, io.ErrShortWrite, io.EOF},
302 // Force error in remote address.
303 {baseVersion, baseVersionEncoded, pver, BaseEncoding, 20, io.ErrShortWrite, io.EOF},
304 // Force error in local address.
305 {baseVersion, baseVersionEncoded, pver, BaseEncoding, 47, io.ErrShortWrite, io.ErrUnexpectedEOF},
306 // Force error in nonce.
307 {baseVersion, baseVersionEncoded, pver, BaseEncoding, 73, io.ErrShortWrite, io.ErrUnexpectedEOF},
308 // Force error in user agent length.
309 {baseVersion, baseVersionEncoded, pver, BaseEncoding, 81, io.ErrShortWrite, io.EOF},
310 // Force error in user agent.
311 {baseVersion, baseVersionEncoded, pver, BaseEncoding, 82, io.ErrShortWrite, io.ErrUnexpectedEOF},
312 // Force error in last block.
313 {baseVersion, baseVersionEncoded, pver, BaseEncoding, 98, io.ErrShortWrite, io.ErrUnexpectedEOF},
314 // Force error in relay tx - no read error should happen since
317 baseVersionBIP0037, baseVersionBIP0037Encoded,
318 BIP0037Version, BaseEncoding, 101, io.ErrShortWrite, nil,
320 // Force error due to user agent too big
321 {exceedUAVer, exceedUAVerEncoded, pver, BaseEncoding, newLen, wireErr, wireErr},
324 t.Logf("Running %d tests", len(tests))
325 for i, test := range tests {
326 // Encode to wire format.
327 w := newFixedWriter(test.max)
328 err := test.in.BtcEncode(w, test.pver, test.enc)
329 if reflect.TypeOf(err) != reflect.TypeOf(test.writeErr) {
330 t.Errorf("BtcEncode #%d wrong error got: %v, want: %v",
331 i, err, test.writeErr)
335 // For errors which are not of type MessageError, check them for
337 if _, ok := err.(*MessageError); !ok {
338 if err != test.writeErr {
339 t.Errorf("BtcEncode #%d wrong error got: %v, "+
340 "want: %v", i, err, test.writeErr)
345 // Decode from wire format.
347 buf := bytes.NewBuffer(test.buf[0:test.max])
348 err = msg.BtcDecode(buf, test.pver, test.enc)
349 if reflect.TypeOf(err) != reflect.TypeOf(test.readErr) {
350 t.Errorf("BtcDecode #%d wrong error got: %v, want: %v",
351 i, err, test.readErr)
355 // For errors which are not of type MessageError, check them for
357 if _, ok := err.(*MessageError); !ok {
358 if err != test.readErr {
359 t.Errorf("BtcDecode #%d wrong error got: %v, "+
360 "want: %v", i, err, test.readErr)
367 // TestVersionOptionalFields performs tests to ensure that an encoded version
368 // messages that omit optional fields are handled correctly.
369 func TestVersionOptionalFields(t *testing.T) {
370 // onlyRequiredVersion is a version message that only contains the
371 // required versions and all other values set to their default values.
372 onlyRequiredVersion := MsgVersion{
373 ProtocolVersion: 60002,
374 Services: SFNodeNetwork,
375 Timestamp: time.Unix(0x495fab29, 0), // 2009-01-03 12:15:05 -0600 CST)
377 Timestamp: time.Time{}, // Zero value -- no timestamp in version
378 Services: SFNodeNetwork,
379 IP: net.ParseIP("192.168.0.1"),
383 onlyRequiredVersionEncoded := make([]byte, len(baseVersionEncoded)-55)
384 copy(onlyRequiredVersionEncoded, baseVersionEncoded)
386 // addrMeVersion is a version message that contains all fields through
388 addrMeVersion := onlyRequiredVersion
389 addrMeVersion.AddrMe = NetAddress{
390 Timestamp: time.Time{}, // Zero value -- no timestamp in version
391 Services: SFNodeNetwork,
392 IP: net.ParseIP("127.0.0.1"),
395 addrMeVersionEncoded := make([]byte, len(baseVersionEncoded)-29)
396 copy(addrMeVersionEncoded, baseVersionEncoded)
398 // nonceVersion is a version message that contains all fields through
400 nonceVersion := addrMeVersion
401 nonceVersion.Nonce = 123123 // 0x1e0f3
402 nonceVersionEncoded := make([]byte, len(baseVersionEncoded)-21)
403 copy(nonceVersionEncoded, baseVersionEncoded)
405 // uaVersion is a version message that contains all fields through
406 // the UserAgent field.
407 uaVersion := nonceVersion
408 uaVersion.UserAgent = "/btcdtest:0.0.1/"
409 uaVersionEncoded := make([]byte, len(baseVersionEncoded)-4)
410 copy(uaVersionEncoded, baseVersionEncoded)
412 // lastBlockVersion is a version message that contains all fields
413 // through the LastBlock field.
414 lastBlockVersion := uaVersion
415 lastBlockVersion.LastBlock = 234234 // 0x392fa
416 lastBlockVersionEncoded := make([]byte, len(baseVersionEncoded))
417 copy(lastBlockVersionEncoded, baseVersionEncoded)
420 msg *MsgVersion // Expected message
421 buf []byte // Wire encoding
422 pver uint32 // Protocol version for wire encoding
423 enc MessageEncoding // Message encoding format
426 &onlyRequiredVersion,
427 onlyRequiredVersionEncoded,
433 addrMeVersionEncoded,
451 lastBlockVersionEncoded,
457 for i, test := range tests {
458 // Decode the message from wire format.
460 rbuf := bytes.NewBuffer(test.buf)
461 err := msg.BtcDecode(rbuf, test.pver, test.enc)
463 t.Errorf("BtcDecode #%d error %v", i, err)
466 if !reflect.DeepEqual(&msg, test.msg) {
467 t.Errorf("BtcDecode #%d\n got: %s want: %s", i,
468 spew.Sdump(msg), spew.Sdump(test.msg))
474 // baseVersion is used in the various tests as a baseline MsgVersion.
475 var baseVersion = &MsgVersion{
476 ProtocolVersion: 60002,
477 Services: SFNodeNetwork,
478 Timestamp: time.Unix(0x495fab29, 0), // 2009-01-03 12:15:05 -0600 CST)
480 Timestamp: time.Time{}, // Zero value -- no timestamp in version
481 Services: SFNodeNetwork,
482 IP: net.ParseIP("192.168.0.1"),
486 Timestamp: time.Time{}, // Zero value -- no timestamp in version
487 Services: SFNodeNetwork,
488 IP: net.ParseIP("127.0.0.1"),
491 Nonce: 123123, // 0x1e0f3
492 UserAgent: "/btcdtest:0.0.1/",
493 LastBlock: 234234, // 0x392fa
496 // baseVersionEncoded is the wire encoded bytes for baseVersion using protocol
497 // version 60002 and is used in the various tests.
498 var baseVersionEncoded = []byte{
499 0x62, 0xea, 0x00, 0x00, // Protocol version 60002
500 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // SFNodeNetwork
501 0x29, 0xab, 0x5f, 0x49, 0x00, 0x00, 0x00, 0x00, // 64-bit Timestamp
502 // AddrYou -- No timestamp for NetAddress in version message
503 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // SFNodeNetwork
504 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
505 0x00, 0x00, 0xff, 0xff, 0xc0, 0xa8, 0x00, 0x01, // IP 192.168.0.1
506 0x20, 0x8d, // Port 8333 in big-endian
507 // AddrMe -- No timestamp for NetAddress in version message
508 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // SFNodeNetwork
509 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
510 0x00, 0x00, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x01, // IP 127.0.0.1
511 0x20, 0x8d, // Port 8333 in big-endian
512 0xf3, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, // Nonce
513 0x10, // Varint for user agent length
514 0x2f, 0x62, 0x74, 0x63, 0x64, 0x74, 0x65, 0x73,
515 0x74, 0x3a, 0x30, 0x2e, 0x30, 0x2e, 0x31, 0x2f, // User agent
516 0xfa, 0x92, 0x03, 0x00, // Last block
519 // baseVersionBIP0037 is used in the various tests as a baseline MsgVersion for
521 var baseVersionBIP0037 = &MsgVersion{
522 ProtocolVersion: 70001,
523 Services: SFNodeNetwork,
524 Timestamp: time.Unix(0x495fab29, 0), // 2009-01-03 12:15:05 -0600 CST)
526 Timestamp: time.Time{}, // Zero value -- no timestamp in version
527 Services: SFNodeNetwork,
528 IP: net.ParseIP("192.168.0.1"),
532 Timestamp: time.Time{}, // Zero value -- no timestamp in version
533 Services: SFNodeNetwork,
534 IP: net.ParseIP("127.0.0.1"),
537 Nonce: 123123, // 0x1e0f3
538 UserAgent: "/btcdtest:0.0.1/",
539 LastBlock: 234234, // 0x392fa
542 // baseVersionBIP0037Encoded is the wire encoded bytes for baseVersionBIP0037
543 // using protocol version BIP0037Version and is used in the various tests.
544 var baseVersionBIP0037Encoded = []byte{
545 0x71, 0x11, 0x01, 0x00, // Protocol version 70001
546 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // SFNodeNetwork
547 0x29, 0xab, 0x5f, 0x49, 0x00, 0x00, 0x00, 0x00, // 64-bit Timestamp
548 // AddrYou -- No timestamp for NetAddress in version message
549 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // SFNodeNetwork
550 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
551 0x00, 0x00, 0xff, 0xff, 0xc0, 0xa8, 0x00, 0x01, // IP 192.168.0.1
552 0x20, 0x8d, // Port 8333 in big-endian
553 // AddrMe -- No timestamp for NetAddress in version message
554 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // SFNodeNetwork
555 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
556 0x00, 0x00, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x01, // IP 127.0.0.1
557 0x20, 0x8d, // Port 8333 in big-endian
558 0xf3, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, // Nonce
559 0x10, // Varint for user agent length
560 0x2f, 0x62, 0x74, 0x63, 0x64, 0x74, 0x65, 0x73,
561 0x74, 0x3a, 0x30, 0x2e, 0x30, 0x2e, 0x31, 0x2f, // User agent
562 0xfa, 0x92, 0x03, 0x00, // Last block