msgaddr_test.go raw
1 package wire
2
3 import (
4 "bytes"
5 "io"
6 "net"
7 "reflect"
8 "testing"
9 "time"
10
11 "github.com/davecgh/go-spew/spew"
12 )
13
14 // TestAddr tests the MsgAddr API.
15 func TestAddr(t *testing.T) {
16 pver := ProtocolVersion
17 // Ensure the command is expected value.
18 wantCmd := "addr"
19 msg := NewMsgAddr()
20 if cmd := msg.Command(); cmd != wantCmd {
21 t.Errorf("NewMsgAddr: wrong command - got %v want %v",
22 cmd, wantCmd,
23 )
24 }
25 // Ensure max payload is expected value for latest protocol version. Num addresses (varInt) + max allowed addresses.
26 wantPayload := uint32(30009)
27 maxPayload := msg.MaxPayloadLength(pver)
28 if maxPayload != wantPayload {
29 t.Errorf("MaxPayloadLength: wrong max payload length for "+
30 "protocol version %d - got %v, want %v", pver,
31 maxPayload, wantPayload,
32 )
33 }
34 // Ensure NetAddresses are added properly.
35 tcpAddr := &net.TCPAddr{IP: net.ParseIP("127.0.0.1"), Port: 11047}
36 na := NewNetAddress(tcpAddr, SFNodeNetwork)
37 e := msg.AddAddress(na)
38 if e != nil {
39 t.Errorf("AddAddress: %v", e)
40 }
41 if msg.AddrList[0] != na {
42 t.Errorf("AddAddress: wrong address added - got %v, want %v",
43 spew.Sprint(msg.AddrList[0]), spew.Sprint(na),
44 )
45 }
46 // Ensure the address list is cleared properly.
47 msg.ClearAddresses()
48 if len(msg.AddrList) != 0 {
49 t.Errorf("ClearAddresses: address list is not empty - "+
50 "got %v [%v], want %v", len(msg.AddrList),
51 spew.Sprint(msg.AddrList[0]), 0,
52 )
53 }
54 // Ensure adding more than the max allowed addresses per message returns error.
55 for i := 0; i < MaxAddrPerMsg+1; i++ {
56 e = msg.AddAddress(na)
57 }
58 if e == nil {
59 t.Errorf("AddAddress: expected error on too many addresses " +
60 "not received",
61 )
62 }
63 e = msg.AddAddresses(na)
64 if e == nil {
65 t.Errorf("AddAddresses: expected error on too many addresses " +
66 "not received",
67 )
68 }
69 // Ensure max payload is expected value for protocol versions before timestamp was added to NetAddress. Num
70 // addresses (varInt) + max allowed addresses.
71 pver = NetAddressTimeVersion - 1
72 wantPayload = uint32(26009)
73 maxPayload = msg.MaxPayloadLength(pver)
74 if maxPayload != wantPayload {
75 t.Errorf("MaxPayloadLength: wrong max payload length for "+
76 "protocol version %d - got %v, want %v", pver,
77 maxPayload, wantPayload,
78 )
79 }
80 // Ensure max payload is expected value for protocol versions before multiple addresses were allowed. Num addresses
81 // (varInt) + a single net addresses.
82 pver = MultipleAddressVersion - 1
83 wantPayload = uint32(35)
84 maxPayload = msg.MaxPayloadLength(pver)
85 if maxPayload != wantPayload {
86 t.Errorf("MaxPayloadLength: wrong max payload length for "+
87 "protocol version %d - got %v, want %v", pver,
88 maxPayload, wantPayload,
89 )
90 }
91 }
92
93 // TestAddrWire tests the MsgAddr wire encode and decode for various numbers of addresses and protocol versions.
94 func TestAddrWire(t *testing.T) {
95 // A couple of NetAddresses to use for testing.
96 na := &NetAddress{
97 Timestamp: time.Unix(0x495fab29, 0), // 2009-01-03 12:15:05 -0600 CST
98 Services: SFNodeNetwork,
99 IP: net.ParseIP("127.0.0.1"),
100 Port: 11047,
101 }
102 na2 := &NetAddress{
103 Timestamp: time.Unix(0x495fab29, 0), // 2009-01-03 12:15:05 -0600 CST
104 Services: SFNodeNetwork,
105 IP: net.ParseIP("192.168.0.1"),
106 Port: 11048,
107 }
108 // Empty address message.
109 noAddr := NewMsgAddr()
110 noAddrEncoded := []byte{
111 0x00, // Varint for number of addresses
112 }
113 // Address message with multiple addresses.
114 multiAddr := NewMsgAddr()
115 _ = multiAddr.AddAddresses(na, na2)
116 multiAddrEncoded := []byte{
117 0x02, // Varint for number of addresses
118 0x29, 0xab, 0x5f, 0x49, // Timestamp
119 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // SFNodeNetwork
120 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
121 0x00, 0x00, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x01, // IP 127.0.0.1
122 0x2b, 0x27, // Port 11047 in big-endian
123 0x29, 0xab, 0x5f, 0x49, // Timestamp
124 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // SFNodeNetwork
125 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
126 0x00, 0x00, 0xff, 0xff, 0xc0, 0xa8, 0x00, 0x01, // IP 192.168.0.1
127 0x2b, 0x28, // Port 11048 in big-endian
128 }
129 tests := []struct {
130 in *MsgAddr // Message to encode
131 out *MsgAddr // Expected decoded message
132 buf []byte // Wire encoding
133 pver uint32 // Protocol version for wire encoding
134 enc MessageEncoding // Message encoding format
135 }{
136 // Latest protocol version with no addresses.
137 {
138 noAddr,
139 noAddr,
140 noAddrEncoded,
141 ProtocolVersion,
142 BaseEncoding,
143 },
144 // Latest protocol version with multiple addresses.
145 {
146 multiAddr,
147 multiAddr,
148 multiAddrEncoded,
149 ProtocolVersion,
150 BaseEncoding,
151 },
152 // Protocol version MultipleAddressVersion-1 with no addresses.
153 {
154 noAddr,
155 noAddr,
156 noAddrEncoded,
157 MultipleAddressVersion - 1,
158 BaseEncoding,
159 },
160 }
161 t.Logf("Running %d tests", len(tests))
162 for i, test := range tests {
163 // Encode the message to wire format.
164 var buf bytes.Buffer
165 e := test.in.BtcEncode(&buf, test.pver, test.enc)
166 if e != nil {
167 t.Errorf("BtcEncode #%d error %v", i, e)
168 continue
169 }
170 if !bytes.Equal(buf.Bytes(), test.buf) {
171 t.Errorf("BtcEncode #%d\n got: %s want: %s", i,
172 spew.Sdump(buf.Bytes()), spew.Sdump(test.buf),
173 )
174 continue
175 }
176 // Decode the message from wire format.
177 var msg MsgAddr
178 rbuf := bytes.NewReader(test.buf)
179 e = msg.BtcDecode(rbuf, test.pver, test.enc)
180 if e != nil {
181 t.Errorf("BtcDecode #%d error %v", i, e)
182 continue
183 }
184 if !reflect.DeepEqual(&msg, test.out) {
185 t.Errorf("BtcDecode #%d\n got: %s want: %s", i,
186 spew.Sdump(msg), spew.Sdump(test.out),
187 )
188 continue
189 }
190 }
191 }
192
193 // TestAddrWireErrors performs negative tests against wire encode and decode of MsgAddr to confirm error paths work correctly.
194 func TestAddrWireErrors(t *testing.T) {
195 pver := ProtocolVersion
196 pverMA := MultipleAddressVersion
197 wireErr := &MessageError{}
198 // A couple of NetAddresses to use for testing.
199 na := &NetAddress{
200 Timestamp: time.Unix(0x495fab29, 0), // 2009-01-03 12:15:05 -0600 CST
201 Services: SFNodeNetwork,
202 IP: net.ParseIP("127.0.0.1"),
203 Port: 11047,
204 }
205 na2 := &NetAddress{
206 Timestamp: time.Unix(0x495fab29, 0), // 2009-01-03 12:15:05 -0600 CST
207 Services: SFNodeNetwork,
208 IP: net.ParseIP("192.168.0.1"),
209 Port: 11048,
210 }
211 // Address message with multiple addresses.
212 baseAddr := NewMsgAddr()
213 e := baseAddr.AddAddresses(na, na2)
214 if e != nil {
215 t.Log(e)
216 }
217 baseAddrEncoded := []byte{
218 0x02, // Varint for number of addresses
219 0x29, 0xab, 0x5f, 0x49, // Timestamp
220 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // SFNodeNetwork
221 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
222 0x00, 0x00, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x01, // IP 127.0.0.1
223 0x2b, 0x27, // Port 11047 in big-endian
224 0x29, 0xab, 0x5f, 0x49, // Timestamp
225 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // SFNodeNetwork
226 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
227 0x00, 0x00, 0xff, 0xff, 0xc0, 0xa8, 0x00, 0x01, // IP 192.168.0.1
228 0x2b, 0x28, // Port 11048 in big-endian
229 }
230 // Message that forces an error by having more than the max allowed addresses.
231 maxAddr := NewMsgAddr()
232 for i := 0; i < MaxAddrPerMsg; i++ {
233 e := maxAddr.AddAddress(na)
234 if e != nil {
235 t.Log(e)
236 }
237 }
238 maxAddr.AddrList = append(maxAddr.AddrList, na)
239 maxAddrEncoded := []byte{
240 0xfd, 0x03, 0xe9, // Varint for number of addresses (1001)
241 }
242 tests := []struct {
243 in *MsgAddr // value to encode
244 buf []byte // Wire encoding
245 pver uint32 // Protocol version for wire encoding
246 enc MessageEncoding // Message encoding format
247 max int // Max size of fixed buffer to induce errors
248 writeErr error // Expected write error
249 readErr error // Expected read error
250 }{
251 // Latest protocol version with intentional read/write errors.
252 // Force error in addresses count
253 {baseAddr, baseAddrEncoded, pver, BaseEncoding, 0, io.ErrShortWrite, io.EOF},
254 // Force error in address list.
255 {baseAddr, baseAddrEncoded, pver, BaseEncoding, 1, io.ErrShortWrite, io.EOF},
256 // Force error with greater than max inventory vectors.
257 {maxAddr, maxAddrEncoded, pver, BaseEncoding, 3, wireErr, wireErr},
258 // Force error with greater than max inventory vectors for protocol versions before multiple addresses were
259 // allowed.
260 {maxAddr, maxAddrEncoded, pverMA - 1, BaseEncoding, 3, wireErr, wireErr},
261 }
262 t.Logf("Running %d tests", len(tests))
263 for i, test := range tests {
264 // Encode to wire format.
265 w := newFixedWriter(test.max)
266 e := test.in.BtcEncode(w, test.pver, test.enc)
267 if reflect.TypeOf(e) != reflect.TypeOf(test.writeErr) {
268 t.Errorf("BtcEncode #%d wrong error got: %v, want: %v",
269 i, e, test.writeErr,
270 )
271 continue
272 }
273 // For errors which are not of type MessageError, check them for equality.
274 if _, ok := e.(*MessageError); !ok {
275 if e != test.writeErr {
276 t.Errorf("BtcEncode #%d wrong error got: %v, "+
277 "want: %v", i, e, test.writeErr,
278 )
279 continue
280 }
281 }
282 // Decode from wire format.
283 var msg MsgAddr
284 r := newFixedReader(test.max, test.buf)
285 e = msg.BtcDecode(r, test.pver, test.enc)
286 if reflect.TypeOf(e) != reflect.TypeOf(test.readErr) {
287 t.Errorf("BtcDecode #%d wrong error got: %v, want: %v",
288 i, e, test.readErr,
289 )
290 continue
291 }
292 // For errors which are not of type MessageError, check them for equality.
293 if _, ok := e.(*MessageError); !ok {
294 if e != test.readErr {
295 t.Errorf("BtcDecode #%d wrong error got: %v, "+
296 "want: %v", i, e, test.readErr,
297 )
298 continue
299 }
300 }
301 }
302 }
303