msgheaders_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 // TestHeaders tests the MsgHeaders API.
13 func TestHeaders(t *testing.T) {
14 pver := uint32(60002)
15 // Ensure the command is expected value.
16 wantCmd := "headers"
17 msg := NewMsgHeaders()
18 if cmd := msg.Command(); cmd != wantCmd {
19 t.Errorf("NewMsgHeaders: wrong command - got %v want %v",
20 cmd, wantCmd,
21 )
22 }
23 // Ensure max payload is expected value for latest protocol version. Num headers (varInt) + max allowed headers
24 // (header length + 1 byte for the number of transactions which is always 0).
25 wantPayload := uint32(162009)
26 maxPayload := msg.MaxPayloadLength(pver)
27 if maxPayload != wantPayload {
28 t.Errorf("MaxPayloadLength: wrong max payload length for "+
29 "protocol version %d - got %v, want %v", pver,
30 maxPayload, wantPayload,
31 )
32 }
33 // Ensure headers are added properly.
34 bh := &blockOne.Header
35 e := msg.AddBlockHeader(bh)
36 if e != nil {
37 t.Log(e)
38 }
39 if !reflect.DeepEqual(msg.Headers[0], bh) {
40 t.Errorf("AddHeader: wrong header - got %v, want %v",
41 spew.Sdump(msg.Headers),
42 spew.Sdump(bh),
43 )
44 }
45 // Ensure adding more than the max allowed headers per message returns error.
46 for i := 0; i < MaxBlockHeadersPerMsg+1; i++ {
47 e = msg.AddBlockHeader(bh)
48 }
49 if reflect.TypeOf(e) != reflect.TypeOf(&MessageError{}) {
50 t.Errorf("AddBlockHeader: expected error on too many headers " +
51 "not received",
52 )
53 }
54 }
55
56 // TestHeadersWire tests the MsgHeaders wire encode and decode for various numbers of headers and protocol versions.
57 func TestHeadersWire(t *testing.T) {
58 hash := mainNetGenesisHash
59 merkleHash := blockOne.Header.MerkleRoot
60 bits := uint32(0x1d00ffff)
61 nonce := uint32(0x9962e301)
62 bh := NewBlockHeader(1, &hash, &merkleHash, bits, nonce)
63 bh.Version = blockOne.Header.Version
64 bh.Timestamp = blockOne.Header.Timestamp
65 // Empty headers message.
66 noHeaders := NewMsgHeaders()
67 noHeadersEncoded := []byte{
68 0x00, // Varint for number of headers
69 }
70 // Headers message with one header.
71 oneHeader := NewMsgHeaders()
72 e := oneHeader.AddBlockHeader(bh)
73 if e != nil {
74 t.Log(e)
75 }
76 oneHeaderEncoded := []byte{
77 0x01, // VarInt for number of headers.
78 0x01, 0x00, 0x00, 0x00, // Version 1
79 0x6f, 0xe2, 0x8c, 0x0a, 0xb6, 0xf1, 0xb3, 0x72,
80 0xc1, 0xa6, 0xa2, 0x46, 0xae, 0x63, 0xf7, 0x4f,
81 0x93, 0x1e, 0x83, 0x65, 0xe1, 0x5a, 0x08, 0x9c,
82 0x68, 0xd6, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, // PrevBlock
83 0x98, 0x20, 0x51, 0xfd, 0x1e, 0x4b, 0xa7, 0x44,
84 0xbb, 0xbe, 0x68, 0x0e, 0x1f, 0xee, 0x14, 0x67,
85 0x7b, 0xa1, 0xa3, 0xc3, 0x54, 0x0b, 0xf7, 0xb1,
86 0xcd, 0xb6, 0x06, 0xe8, 0x57, 0x23, 0x3e, 0x0e, // MerkleRoot
87 0x61, 0xbc, 0x66, 0x49, // Timestamp
88 0xff, 0xff, 0x00, 0x1d, // Bits
89 0x01, 0xe3, 0x62, 0x99, // Nonce
90 0x00, // TxnCount (0 for headers message)
91 }
92 tests := []struct {
93 in *MsgHeaders // Message to encode
94 out *MsgHeaders // Expected decoded message
95 buf []byte // Wire encoding
96 pver uint32 // Protocol version for wire encoding
97 enc MessageEncoding // Message encoding format
98 }{
99 // Latest protocol version with no headers.
100 {
101 noHeaders,
102 noHeaders,
103 noHeadersEncoded,
104 ProtocolVersion,
105 BaseEncoding,
106 },
107 // Latest protocol version with one header.
108 {
109 oneHeader,
110 oneHeader,
111 oneHeaderEncoded,
112 ProtocolVersion,
113 BaseEncoding,
114 },
115 // Protocol version BIP0035Version with no headers.
116 {
117 noHeaders,
118 noHeaders,
119 noHeadersEncoded,
120 BIP0035Version,
121 BaseEncoding,
122 },
123 // Protocol version BIP0035Version with one header.
124 {
125 oneHeader,
126 oneHeader,
127 oneHeaderEncoded,
128 BIP0035Version,
129 BaseEncoding,
130 },
131 // Protocol version BIP0031Version with no headers.
132 {
133 noHeaders,
134 noHeaders,
135 noHeadersEncoded,
136 BIP0031Version,
137 BaseEncoding,
138 },
139 // Protocol version BIP0031Version with one header.
140 {
141 oneHeader,
142 oneHeader,
143 oneHeaderEncoded,
144 BIP0031Version,
145 BaseEncoding,
146 },
147 // Protocol version NetAddressTimeVersion with no headers.
148 {
149 noHeaders,
150 noHeaders,
151 noHeadersEncoded,
152 NetAddressTimeVersion,
153 BaseEncoding,
154 },
155 // Protocol version NetAddressTimeVersion with one header.
156 {
157 oneHeader,
158 oneHeader,
159 oneHeaderEncoded,
160 NetAddressTimeVersion,
161 BaseEncoding,
162 },
163 // Protocol version MultipleAddressVersion with no headers.
164 {
165 noHeaders,
166 noHeaders,
167 noHeadersEncoded,
168 MultipleAddressVersion,
169 BaseEncoding,
170 },
171 // Protocol version MultipleAddressVersion with one header.
172 {
173 oneHeader,
174 oneHeader,
175 oneHeaderEncoded,
176 MultipleAddressVersion,
177 BaseEncoding,
178 },
179 }
180 t.Logf("Running %d tests", len(tests))
181 for i, test := range tests {
182 // Encode the message to wire format.
183 var buf bytes.Buffer
184 e := test.in.BtcEncode(&buf, test.pver, test.enc)
185 if e != nil {
186 t.Errorf("BtcEncode #%d error %v", i, e)
187 continue
188 }
189 if !bytes.Equal(buf.Bytes(), test.buf) {
190 t.Errorf("BtcEncode #%d\n got: %s want: %s", i,
191 spew.Sdump(buf.Bytes()), spew.Sdump(test.buf),
192 )
193 continue
194 }
195 // Decode the message from wire format.
196 var msg MsgHeaders
197 rbuf := bytes.NewReader(test.buf)
198 e = msg.BtcDecode(rbuf, test.pver, test.enc)
199 if e != nil {
200 t.Errorf("BtcDecode #%d error %v", i, e)
201 continue
202 }
203 if !reflect.DeepEqual(&msg, test.out) {
204 t.Errorf("BtcDecode #%d\n got: %s want: %s", i,
205 spew.Sdump(&msg), spew.Sdump(test.out),
206 )
207 continue
208 }
209 }
210 }
211
212 // TestHeadersWireErrors performs negative tests against wire encode and decode of MsgHeaders to confirm error paths
213 // work correctly.
214 func TestHeadersWireErrors(t *testing.T) {
215 pver := ProtocolVersion
216 wireErr := &MessageError{}
217 hash := mainNetGenesisHash
218 merkleHash := blockOne.Header.MerkleRoot
219 bits := uint32(0x1d00ffff)
220 nonce := uint32(0x9962e301)
221 bh := NewBlockHeader(1, &hash, &merkleHash, bits, nonce)
222 bh.Version = blockOne.Header.Version
223 bh.Timestamp = blockOne.Header.Timestamp
224 // Headers message with one header.
225 oneHeader := NewMsgHeaders()
226 e := oneHeader.AddBlockHeader(bh)
227 if e != nil {
228 t.Log(e)
229 }
230 oneHeaderEncoded := []byte{
231 0x01, // VarInt for number of headers.
232 0x01, 0x00, 0x00, 0x00, // Version 1
233 0x6f, 0xe2, 0x8c, 0x0a, 0xb6, 0xf1, 0xb3, 0x72,
234 0xc1, 0xa6, 0xa2, 0x46, 0xae, 0x63, 0xf7, 0x4f,
235 0x93, 0x1e, 0x83, 0x65, 0xe1, 0x5a, 0x08, 0x9c,
236 0x68, 0xd6, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, // PrevBlock
237 0x98, 0x20, 0x51, 0xfd, 0x1e, 0x4b, 0xa7, 0x44,
238 0xbb, 0xbe, 0x68, 0x0e, 0x1f, 0xee, 0x14, 0x67,
239 0x7b, 0xa1, 0xa3, 0xc3, 0x54, 0x0b, 0xf7, 0xb1,
240 0xcd, 0xb6, 0x06, 0xe8, 0x57, 0x23, 0x3e, 0x0e, // MerkleRoot
241 0x61, 0xbc, 0x66, 0x49, // Timestamp
242 0xff, 0xff, 0x00, 0x1d, // Bits
243 0x01, 0xe3, 0x62, 0x99, // Nonce
244 0x00, // TxnCount (0 for headers message)
245 }
246 // Message that forces an error by having more than the max allowed headers.
247 maxHeaders := NewMsgHeaders()
248 for i := 0; i < MaxBlockHeadersPerMsg; i++ {
249 e = maxHeaders.AddBlockHeader(bh)
250 if e != nil {
251 t.Log(e)
252 }
253 }
254 maxHeaders.Headers = append(maxHeaders.Headers, bh)
255 maxHeadersEncoded := []byte{
256 0xfd, 0xd1, 0x07, // Varint for number of addresses (2001)7D1
257 }
258 // Intentionally invalid e header that has a transaction count used to force errors.
259 bhTrans := NewBlockHeader(1, &hash, &merkleHash, bits, nonce)
260 bhTrans.Version = blockOne.Header.Version
261 bhTrans.Timestamp = blockOne.Header.Timestamp
262 transHeader := NewMsgHeaders()
263 e = transHeader.AddBlockHeader(bhTrans)
264 if e != nil {
265 t.Log(e)
266 }
267 transHeaderEncoded := []byte{
268 0x01, // VarInt for number of headers.
269 0x01, 0x00, 0x00, 0x00, // Version 1
270 0x6f, 0xe2, 0x8c, 0x0a, 0xb6, 0xf1, 0xb3, 0x72,
271 0xc1, 0xa6, 0xa2, 0x46, 0xae, 0x63, 0xf7, 0x4f,
272 0x93, 0x1e, 0x83, 0x65, 0xe1, 0x5a, 0x08, 0x9c,
273 0x68, 0xd6, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, // PrevBlock
274 0x98, 0x20, 0x51, 0xfd, 0x1e, 0x4b, 0xa7, 0x44,
275 0xbb, 0xbe, 0x68, 0x0e, 0x1f, 0xee, 0x14, 0x67,
276 0x7b, 0xa1, 0xa3, 0xc3, 0x54, 0x0b, 0xf7, 0xb1,
277 0xcd, 0xb6, 0x06, 0xe8, 0x57, 0x23, 0x3e, 0x0e, // MerkleRoot
278 0x61, 0xbc, 0x66, 0x49, // Timestamp
279 0xff, 0xff, 0x00, 0x1d, // Bits
280 0x01, 0xe3, 0x62, 0x99, // Nonce
281 0x01, // TxnCount (should be 0 for headers message, but 1 to force error)
282 }
283 tests := []struct {
284 in *MsgHeaders // value to encode
285 buf []byte // Wire encoding
286 pver uint32 // Protocol version for wire encoding
287 enc MessageEncoding // Message encoding format
288 max int // Max size of fixed buffer to induce errors
289 writeErr error // Expected write error
290 readErr error // Expected read error
291 }{
292 // Latest protocol version with intentional read/write errors. Force error in header count.
293 {oneHeader, oneHeaderEncoded, pver, BaseEncoding, 0, io.ErrShortWrite, io.EOF},
294 // Force error in e header.
295 {oneHeader, oneHeaderEncoded, pver, BaseEncoding, 5, io.ErrShortWrite, io.EOF},
296 // Force error with greater than max headers.
297 {maxHeaders, maxHeadersEncoded, pver, BaseEncoding, 3, wireErr, wireErr},
298 // Force error with number of transactions.
299 {transHeader, transHeaderEncoded, pver, BaseEncoding, 81, io.ErrShortWrite, io.EOF},
300 // Force error with included transactions.
301 {transHeader, transHeaderEncoded, pver, BaseEncoding, len(transHeaderEncoded), nil, wireErr},
302 }
303 t.Logf("Running %d tests", len(tests))
304 for i, test := range tests {
305 // Encode to wire format.
306 w := newFixedWriter(test.max)
307 e := test.in.BtcEncode(w, test.pver, test.enc)
308 if reflect.TypeOf(e) != reflect.TypeOf(test.writeErr) {
309 t.Errorf("BtcEncode #%d wrong error got: %v, want: %v",
310 i, e, test.writeErr,
311 )
312 continue
313 }
314 // For errors which are not of type MessageError, check them for equality.
315 if _, ok := e.(*MessageError); !ok {
316 if e != test.writeErr {
317 t.Errorf("BtcEncode #%d wrong error got: %v, "+
318 "want: %v", i, e, test.writeErr,
319 )
320 continue
321 }
322 }
323 // Decode from wire format.
324 var msg MsgHeaders
325 r := newFixedReader(test.max, test.buf)
326 e = msg.BtcDecode(r, test.pver, test.enc)
327 if reflect.TypeOf(e) != reflect.TypeOf(test.readErr) {
328 t.Errorf("BtcDecode #%d wrong error got: %v, want: %v",
329 i, e, test.readErr,
330 )
331 continue
332 }
333 // For errors which are not of type MessageError, check them for equality.
334 if _, ok := e.(*MessageError); !ok {
335 if e != test.readErr {
336 t.Errorf("BtcDecode #%d wrong error got: %v, "+
337 "want: %v", i, e, test.readErr,
338 )
339 continue
340 }
341 }
342 }
343 }
344