github.com/BlockABC/godash@v0.0.0-20191112120524-f4aa3a32c566/wire/msggetdata_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/BlockABC/godash/wire" 15 "github.com/davecgh/go-spew/spew" 16 ) 17 18 // TestGetData tests the MsgGetData API. 19 func TestGetData(t *testing.T) { 20 pver := wire.ProtocolVersion 21 22 // Ensure the command is expected value. 23 wantCmd := "getdata" 24 msg := wire.NewMsgGetData() 25 if cmd := msg.Command(); cmd != wantCmd { 26 t.Errorf("NewMsgGetData: wrong command - got %v want %v", 27 cmd, wantCmd) 28 } 29 30 // Ensure max payload is expected value for latest protocol version. 31 // Num inventory vectors (varInt) + max allowed inventory vectors. 32 wantPayload := uint32(1800009) 33 maxPayload := msg.MaxPayloadLength(pver) 34 if maxPayload != wantPayload { 35 t.Errorf("MaxPayloadLength: wrong max payload length for "+ 36 "protocol version %d - got %v, want %v", pver, 37 maxPayload, wantPayload) 38 } 39 40 // Ensure inventory vectors are added properly. 41 hash := wire.ShaHash{} 42 iv := wire.NewInvVect(wire.InvTypeBlock, &hash) 43 err := msg.AddInvVect(iv) 44 if err != nil { 45 t.Errorf("AddInvVect: %v", err) 46 } 47 if msg.InvList[0] != iv { 48 t.Errorf("AddInvVect: wrong invvect added - got %v, want %v", 49 spew.Sprint(msg.InvList[0]), spew.Sprint(iv)) 50 } 51 52 // Ensure adding more than the max allowed inventory vectors per 53 // message returns an error. 54 for i := 0; i < wire.MaxInvPerMsg; i++ { 55 err = msg.AddInvVect(iv) 56 } 57 if err == nil { 58 t.Errorf("AddInvVect: expected error on too many inventory " + 59 "vectors not received") 60 } 61 62 // Ensure creating the message with a size hint larger than the max 63 // works as expected. 64 msg = wire.NewMsgGetDataSizeHint(wire.MaxInvPerMsg + 1) 65 wantCap := wire.MaxInvPerMsg 66 if cap(msg.InvList) != wantCap { 67 t.Errorf("NewMsgGetDataSizeHint: wrong cap for size hint - "+ 68 "got %v, want %v", cap(msg.InvList), wantCap) 69 } 70 71 return 72 } 73 74 // TestGetDataWire tests the MsgGetData wire encode and decode for various 75 // numbers of inventory vectors and protocol versions. 76 func TestGetDataWire(t *testing.T) { 77 // Block 203707 hash. 78 hashStr := "3264bc2ac36a60840790ba1d475d01367e7c723da941069e9dc" 79 blockHash, err := wire.NewShaHashFromStr(hashStr) 80 if err != nil { 81 t.Errorf("NewShaHashFromStr: %v", err) 82 } 83 84 // Transation 1 of Block 203707 hash. 85 hashStr = "d28a3dc7392bf00a9855ee93dd9a81eff82a2c4fe57fbd42cfe71b487accfaf0" 86 txHash, err := wire.NewShaHashFromStr(hashStr) 87 if err != nil { 88 t.Errorf("NewShaHashFromStr: %v", err) 89 } 90 91 iv := wire.NewInvVect(wire.InvTypeBlock, blockHash) 92 iv2 := wire.NewInvVect(wire.InvTypeTx, txHash) 93 94 // Empty MsgGetData message. 95 NoInv := wire.NewMsgGetData() 96 NoInvEncoded := []byte{ 97 0x00, // Varint for number of inventory vectors 98 } 99 100 // MsgGetData message with multiple inventory vectors. 101 MultiInv := wire.NewMsgGetData() 102 MultiInv.AddInvVect(iv) 103 MultiInv.AddInvVect(iv2) 104 MultiInvEncoded := []byte{ 105 0x02, // Varint for number of inv vectors 106 0x02, 0x00, 0x00, 0x00, // InvTypeBlock 107 0xdc, 0xe9, 0x69, 0x10, 0x94, 0xda, 0x23, 0xc7, 108 0xe7, 0x67, 0x13, 0xd0, 0x75, 0xd4, 0xa1, 0x0b, 109 0x79, 0x40, 0x08, 0xa6, 0x36, 0xac, 0xc2, 0x4b, 110 0x26, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Block 203707 hash 111 0x01, 0x00, 0x00, 0x00, // InvTypeTx 112 0xf0, 0xfa, 0xcc, 0x7a, 0x48, 0x1b, 0xe7, 0xcf, 113 0x42, 0xbd, 0x7f, 0xe5, 0x4f, 0x2c, 0x2a, 0xf8, 114 0xef, 0x81, 0x9a, 0xdd, 0x93, 0xee, 0x55, 0x98, 115 0x0a, 0xf0, 0x2b, 0x39, 0xc7, 0x3d, 0x8a, 0xd2, // Tx 1 of block 203707 hash 116 } 117 118 tests := []struct { 119 in *wire.MsgGetData // Message to encode 120 out *wire.MsgGetData // Expected decoded message 121 buf []byte // Wire encoding 122 pver uint32 // Protocol version for wire encoding 123 }{ 124 // Latest protocol version with no inv vectors. 125 { 126 NoInv, 127 NoInv, 128 NoInvEncoded, 129 wire.ProtocolVersion, 130 }, 131 132 // Latest protocol version with multiple inv vectors. 133 { 134 MultiInv, 135 MultiInv, 136 MultiInvEncoded, 137 wire.ProtocolVersion, 138 }, 139 140 // Protocol version BIP0035Version no inv vectors. 141 { 142 NoInv, 143 NoInv, 144 NoInvEncoded, 145 wire.BIP0035Version, 146 }, 147 148 // Protocol version BIP0035Version with multiple inv vectors. 149 { 150 MultiInv, 151 MultiInv, 152 MultiInvEncoded, 153 wire.BIP0035Version, 154 }, 155 156 // Protocol version BIP0031Version no inv vectors. 157 { 158 NoInv, 159 NoInv, 160 NoInvEncoded, 161 wire.BIP0031Version, 162 }, 163 164 // Protocol version BIP0031Version with multiple inv vectors. 165 { 166 MultiInv, 167 MultiInv, 168 MultiInvEncoded, 169 wire.BIP0031Version, 170 }, 171 172 // Protocol version NetAddressTimeVersion no inv vectors. 173 { 174 NoInv, 175 NoInv, 176 NoInvEncoded, 177 wire.NetAddressTimeVersion, 178 }, 179 180 // Protocol version NetAddressTimeVersion with multiple inv vectors. 181 { 182 MultiInv, 183 MultiInv, 184 MultiInvEncoded, 185 wire.NetAddressTimeVersion, 186 }, 187 188 // Protocol version MultipleAddressVersion no inv vectors. 189 { 190 NoInv, 191 NoInv, 192 NoInvEncoded, 193 wire.MultipleAddressVersion, 194 }, 195 196 // Protocol version MultipleAddressVersion with multiple inv vectors. 197 { 198 MultiInv, 199 MultiInv, 200 MultiInvEncoded, 201 wire.MultipleAddressVersion, 202 }, 203 } 204 205 t.Logf("Running %d tests", len(tests)) 206 for i, test := range tests { 207 // Encode the message to wire format. 208 var buf bytes.Buffer 209 err := test.in.BtcEncode(&buf, test.pver) 210 if err != nil { 211 t.Errorf("BtcEncode #%d error %v", i, err) 212 continue 213 } 214 if !bytes.Equal(buf.Bytes(), test.buf) { 215 t.Errorf("BtcEncode #%d\n got: %s want: %s", i, 216 spew.Sdump(buf.Bytes()), spew.Sdump(test.buf)) 217 continue 218 } 219 220 // Decode the message from wire format. 221 var msg wire.MsgGetData 222 rbuf := bytes.NewReader(test.buf) 223 err = msg.BtcDecode(rbuf, test.pver) 224 if err != nil { 225 t.Errorf("BtcDecode #%d error %v", i, err) 226 continue 227 } 228 if !reflect.DeepEqual(&msg, test.out) { 229 t.Errorf("BtcDecode #%d\n got: %s want: %s", i, 230 spew.Sdump(msg), spew.Sdump(test.out)) 231 continue 232 } 233 } 234 } 235 236 // TestGetDataWireErrors performs negative tests against wire encode and decode 237 // of MsgGetData to confirm error paths work correctly. 238 func TestGetDataWireErrors(t *testing.T) { 239 pver := wire.ProtocolVersion 240 wireErr := &wire.MessageError{} 241 242 // Block 203707 hash. 243 hashStr := "3264bc2ac36a60840790ba1d475d01367e7c723da941069e9dc" 244 blockHash, err := wire.NewShaHashFromStr(hashStr) 245 if err != nil { 246 t.Errorf("NewShaHashFromStr: %v", err) 247 } 248 249 iv := wire.NewInvVect(wire.InvTypeBlock, blockHash) 250 251 // Base message used to induce errors. 252 baseGetData := wire.NewMsgGetData() 253 baseGetData.AddInvVect(iv) 254 baseGetDataEncoded := []byte{ 255 0x02, // Varint for number of inv vectors 256 0x02, 0x00, 0x00, 0x00, // InvTypeBlock 257 0xdc, 0xe9, 0x69, 0x10, 0x94, 0xda, 0x23, 0xc7, 258 0xe7, 0x67, 0x13, 0xd0, 0x75, 0xd4, 0xa1, 0x0b, 259 0x79, 0x40, 0x08, 0xa6, 0x36, 0xac, 0xc2, 0x4b, 260 0x26, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Block 203707 hash 261 } 262 263 // Message that forces an error by having more than the max allowed inv 264 // vectors. 265 maxGetData := wire.NewMsgGetData() 266 for i := 0; i < wire.MaxInvPerMsg; i++ { 267 maxGetData.AddInvVect(iv) 268 } 269 maxGetData.InvList = append(maxGetData.InvList, iv) 270 maxGetDataEncoded := []byte{ 271 0xfd, 0x51, 0xc3, // Varint for number of inv vectors (50001) 272 } 273 274 tests := []struct { 275 in *wire.MsgGetData // Value to encode 276 buf []byte // Wire encoding 277 pver uint32 // Protocol version for wire encoding 278 max int // Max size of fixed buffer to induce errors 279 writeErr error // Expected write error 280 readErr error // Expected read error 281 }{ 282 // Latest protocol version with intentional read/write errors. 283 // Force error in inventory vector count 284 {baseGetData, baseGetDataEncoded, pver, 0, io.ErrShortWrite, io.EOF}, 285 // Force error in inventory list. 286 {baseGetData, baseGetDataEncoded, pver, 1, io.ErrShortWrite, io.EOF}, 287 // Force error with greater than max inventory vectors. 288 {maxGetData, maxGetDataEncoded, pver, 3, wireErr, wireErr}, 289 } 290 291 t.Logf("Running %d tests", len(tests)) 292 for i, test := range tests { 293 // Encode to wire format. 294 w := newFixedWriter(test.max) 295 err := test.in.BtcEncode(w, test.pver) 296 if reflect.TypeOf(err) != reflect.TypeOf(test.writeErr) { 297 t.Errorf("BtcEncode #%d wrong error got: %v, want: %v", 298 i, err, test.writeErr) 299 continue 300 } 301 302 // For errors which are not of type wire.MessageError, check 303 // them for equality. 304 if _, ok := err.(*wire.MessageError); !ok { 305 if err != test.writeErr { 306 t.Errorf("BtcEncode #%d wrong error got: %v, "+ 307 "want: %v", i, err, test.writeErr) 308 continue 309 } 310 } 311 312 // Decode from wire format. 313 var msg wire.MsgGetData 314 r := newFixedReader(test.max, test.buf) 315 err = msg.BtcDecode(r, test.pver) 316 if reflect.TypeOf(err) != reflect.TypeOf(test.readErr) { 317 t.Errorf("BtcDecode #%d wrong error got: %v, want: %v", 318 i, err, test.readErr) 319 continue 320 } 321 322 // For errors which are not of type wire.MessageError, check 323 // them for equality. 324 if _, ok := err.(*wire.MessageError); !ok { 325 if err != test.readErr { 326 t.Errorf("BtcDecode #%d wrong error got: %v, "+ 327 "want: %v", i, err, test.readErr) 328 continue 329 } 330 } 331 } 332 }