github.com/palcoin-project/palcd@v1.0.0/wire/msgmerkleblock_test.go (about) 1 // Copyright (c) 2014-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. 4 5 package wire 6 7 import ( 8 "bytes" 9 "crypto/rand" 10 "io" 11 "reflect" 12 "testing" 13 "time" 14 15 "github.com/davecgh/go-spew/spew" 16 "github.com/palcoin-project/palcd/chaincfg/chainhash" 17 ) 18 19 // TestMerkleBlock tests the MsgMerkleBlock API. 20 func TestMerkleBlock(t *testing.T) { 21 pver := ProtocolVersion 22 enc := BaseEncoding 23 24 // Block 1 header. 25 prevHash := &blockOne.Header.PrevBlock 26 merkleHash := &blockOne.Header.MerkleRoot 27 bits := blockOne.Header.Bits 28 nonce := blockOne.Header.Nonce 29 bh := NewBlockHeader(1, prevHash, merkleHash, bits, nonce) 30 31 // Ensure the command is expected value. 32 wantCmd := "merkleblock" 33 msg := NewMsgMerkleBlock(bh) 34 if cmd := msg.Command(); cmd != wantCmd { 35 t.Errorf("NewMsgBlock: wrong command - got %v want %v", 36 cmd, wantCmd) 37 } 38 39 // Ensure max payload is expected value for latest protocol version. 40 // Num addresses (varInt) + max allowed addresses. 41 wantPayload := uint32(4000000) 42 maxPayload := msg.MaxPayloadLength(pver) 43 if maxPayload != wantPayload { 44 t.Errorf("MaxPayloadLength: wrong max payload length for "+ 45 "protocol version %d - got %v, want %v", pver, 46 maxPayload, wantPayload) 47 } 48 49 // Load maxTxPerBlock hashes 50 data := make([]byte, 32) 51 for i := 0; i < maxTxPerBlock; i++ { 52 rand.Read(data) 53 hash, err := chainhash.NewHash(data) 54 if err != nil { 55 t.Errorf("NewHash failed: %v\n", err) 56 return 57 } 58 59 if err = msg.AddTxHash(hash); err != nil { 60 t.Errorf("AddTxHash failed: %v\n", err) 61 return 62 } 63 } 64 65 // Add one more Tx to test failure. 66 rand.Read(data) 67 hash, err := chainhash.NewHash(data) 68 if err != nil { 69 t.Errorf("NewHash failed: %v\n", err) 70 return 71 } 72 73 if err = msg.AddTxHash(hash); err == nil { 74 t.Errorf("AddTxHash succeeded when it should have failed") 75 return 76 } 77 78 // Test encode with latest protocol version. 79 var buf bytes.Buffer 80 err = msg.BtcEncode(&buf, pver, enc) 81 if err != nil { 82 t.Errorf("encode of MsgMerkleBlock failed %v err <%v>", msg, err) 83 } 84 85 // Test decode with latest protocol version. 86 readmsg := MsgMerkleBlock{} 87 err = readmsg.BtcDecode(&buf, pver, enc) 88 if err != nil { 89 t.Errorf("decode of MsgMerkleBlock failed [%v] err <%v>", buf, err) 90 } 91 92 // Force extra hash to test maxTxPerBlock. 93 msg.Hashes = append(msg.Hashes, hash) 94 err = msg.BtcEncode(&buf, pver, enc) 95 if err == nil { 96 t.Errorf("encode of MsgMerkleBlock succeeded with too many " + 97 "tx hashes when it should have failed") 98 return 99 } 100 101 // Force too many flag bytes to test maxFlagsPerMerkleBlock. 102 // Reset the number of hashes back to a valid value. 103 msg.Hashes = msg.Hashes[len(msg.Hashes)-1:] 104 msg.Flags = make([]byte, maxFlagsPerMerkleBlock+1) 105 err = msg.BtcEncode(&buf, pver, enc) 106 if err == nil { 107 t.Errorf("encode of MsgMerkleBlock succeeded with too many " + 108 "flag bytes when it should have failed") 109 return 110 } 111 } 112 113 // TestMerkleBlockCrossProtocol tests the MsgMerkleBlock API when encoding with 114 // the latest protocol version and decoding with BIP0031Version. 115 func TestMerkleBlockCrossProtocol(t *testing.T) { 116 // Block 1 header. 117 prevHash := &blockOne.Header.PrevBlock 118 merkleHash := &blockOne.Header.MerkleRoot 119 bits := blockOne.Header.Bits 120 nonce := blockOne.Header.Nonce 121 bh := NewBlockHeader(1, prevHash, merkleHash, bits, nonce) 122 123 msg := NewMsgMerkleBlock(bh) 124 125 // Encode with latest protocol version. 126 var buf bytes.Buffer 127 err := msg.BtcEncode(&buf, ProtocolVersion, BaseEncoding) 128 if err != nil { 129 t.Errorf("encode of NewMsgFilterLoad failed %v err <%v>", msg, 130 err) 131 } 132 133 // Decode with old protocol version. 134 var readmsg MsgFilterLoad 135 err = readmsg.BtcDecode(&buf, BIP0031Version, BaseEncoding) 136 if err == nil { 137 t.Errorf("decode of MsgFilterLoad succeeded when it shouldn't have %v", 138 msg) 139 } 140 } 141 142 // TestMerkleBlockWire tests the MsgMerkleBlock wire encode and decode for 143 // various numbers of transaction hashes and protocol versions. 144 func TestMerkleBlockWire(t *testing.T) { 145 tests := []struct { 146 in *MsgMerkleBlock // Message to encode 147 out *MsgMerkleBlock // Expected decoded message 148 buf []byte // Wire encoding 149 pver uint32 // Protocol version for wire encoding 150 enc MessageEncoding // Message encoding format 151 }{ 152 // Latest protocol version. 153 { 154 &merkleBlockOne, &merkleBlockOne, merkleBlockOneBytes, 155 ProtocolVersion, BaseEncoding, 156 }, 157 158 // Protocol version BIP0037Version. 159 { 160 &merkleBlockOne, &merkleBlockOne, merkleBlockOneBytes, 161 BIP0037Version, BaseEncoding, 162 }, 163 } 164 165 t.Logf("Running %d tests", len(tests)) 166 for i, test := range tests { 167 // Encode the message to wire format. 168 var buf bytes.Buffer 169 err := test.in.BtcEncode(&buf, test.pver, test.enc) 170 if err != nil { 171 t.Errorf("BtcEncode #%d error %v", i, err) 172 continue 173 } 174 if !bytes.Equal(buf.Bytes(), test.buf) { 175 t.Errorf("BtcEncode #%d\n got: %s want: %s", i, 176 spew.Sdump(buf.Bytes()), spew.Sdump(test.buf)) 177 continue 178 } 179 180 // Decode the message from wire format. 181 var msg MsgMerkleBlock 182 rbuf := bytes.NewReader(test.buf) 183 err = msg.BtcDecode(rbuf, test.pver, test.enc) 184 if err != nil { 185 t.Errorf("BtcDecode #%d error %v", i, err) 186 continue 187 } 188 if !reflect.DeepEqual(&msg, test.out) { 189 t.Errorf("BtcDecode #%d\n got: %s want: %s", i, 190 spew.Sdump(&msg), spew.Sdump(test.out)) 191 continue 192 } 193 } 194 } 195 196 // TestMerkleBlockWireErrors performs negative tests against wire encode and 197 // decode of MsgBlock to confirm error paths work correctly. 198 func TestMerkleBlockWireErrors(t *testing.T) { 199 // Use protocol version 70001 specifically here instead of the latest 200 // because the test data is using bytes encoded with that protocol 201 // version. 202 pver := uint32(70001) 203 pverNoMerkleBlock := BIP0037Version - 1 204 wireErr := &MessageError{} 205 206 tests := []struct { 207 in *MsgMerkleBlock // Value to encode 208 buf []byte // Wire encoding 209 pver uint32 // Protocol version for wire encoding 210 enc MessageEncoding // Message encoding format 211 max int // Max size of fixed buffer to induce errors 212 writeErr error // Expected write error 213 readErr error // Expected read error 214 }{ 215 // Force error in version. 216 { 217 &merkleBlockOne, merkleBlockOneBytes, pver, BaseEncoding, 0, 218 io.ErrShortWrite, io.EOF, 219 }, 220 // Force error in prev block hash. 221 { 222 &merkleBlockOne, merkleBlockOneBytes, pver, BaseEncoding, 4, 223 io.ErrShortWrite, io.EOF, 224 }, 225 // Force error in merkle root. 226 { 227 &merkleBlockOne, merkleBlockOneBytes, pver, BaseEncoding, 36, 228 io.ErrShortWrite, io.EOF, 229 }, 230 // Force error in timestamp. 231 { 232 &merkleBlockOne, merkleBlockOneBytes, pver, BaseEncoding, 68, 233 io.ErrShortWrite, io.EOF, 234 }, 235 // Force error in difficulty bits. 236 { 237 &merkleBlockOne, merkleBlockOneBytes, pver, BaseEncoding, 72, 238 io.ErrShortWrite, io.EOF, 239 }, 240 // Force error in header nonce. 241 { 242 &merkleBlockOne, merkleBlockOneBytes, pver, BaseEncoding, 76, 243 io.ErrShortWrite, io.EOF, 244 }, 245 // Force error in transaction count. 246 { 247 &merkleBlockOne, merkleBlockOneBytes, pver, BaseEncoding, 80, 248 io.ErrShortWrite, io.EOF, 249 }, 250 // Force error in num hashes. 251 { 252 &merkleBlockOne, merkleBlockOneBytes, pver, BaseEncoding, 84, 253 io.ErrShortWrite, io.EOF, 254 }, 255 // Force error in hashes. 256 { 257 &merkleBlockOne, merkleBlockOneBytes, pver, BaseEncoding, 85, 258 io.ErrShortWrite, io.EOF, 259 }, 260 // Force error in num flag bytes. 261 { 262 &merkleBlockOne, merkleBlockOneBytes, pver, BaseEncoding, 117, 263 io.ErrShortWrite, io.EOF, 264 }, 265 // Force error in flag bytes. 266 { 267 &merkleBlockOne, merkleBlockOneBytes, pver, BaseEncoding, 118, 268 io.ErrShortWrite, io.EOF, 269 }, 270 // Force error due to unsupported protocol version. 271 { 272 &merkleBlockOne, merkleBlockOneBytes, pverNoMerkleBlock, 273 BaseEncoding, 119, wireErr, wireErr, 274 }, 275 } 276 277 t.Logf("Running %d tests", len(tests)) 278 for i, test := range tests { 279 // Encode to wire format. 280 w := newFixedWriter(test.max) 281 err := test.in.BtcEncode(w, test.pver, test.enc) 282 if reflect.TypeOf(err) != reflect.TypeOf(test.writeErr) { 283 t.Errorf("BtcEncode #%d wrong error got: %v, want: %v", 284 i, err, test.writeErr) 285 continue 286 } 287 288 // For errors which are not of type MessageError, check them for 289 // equality. 290 if _, ok := err.(*MessageError); !ok { 291 if err != test.writeErr { 292 t.Errorf("BtcEncode #%d wrong error got: %v, "+ 293 "want: %v", i, err, test.writeErr) 294 continue 295 } 296 } 297 298 // Decode from wire format. 299 var msg MsgMerkleBlock 300 r := newFixedReader(test.max, test.buf) 301 err = msg.BtcDecode(r, test.pver, test.enc) 302 if reflect.TypeOf(err) != reflect.TypeOf(test.readErr) { 303 t.Errorf("BtcDecode #%d wrong error got: %v, want: %v", 304 i, err, test.readErr) 305 continue 306 } 307 308 // For errors which are not of type MessageError, check them for 309 // equality. 310 if _, ok := err.(*MessageError); !ok { 311 if err != test.readErr { 312 t.Errorf("BtcDecode #%d wrong error got: %v, "+ 313 "want: %v", i, err, test.readErr) 314 continue 315 } 316 } 317 } 318 } 319 320 // TestMerkleBlockOverflowErrors performs tests to ensure encoding and decoding 321 // merkle blocks that are intentionally crafted to use large values for the 322 // number of hashes and flags are handled properly. This could otherwise 323 // potentially be used as an attack vector. 324 func TestMerkleBlockOverflowErrors(t *testing.T) { 325 // Use protocol version 70001 specifically here instead of the latest 326 // protocol version because the test data is using bytes encoded with 327 // that version. 328 pver := uint32(70001) 329 330 // Create bytes for a merkle block that claims to have more than the max 331 // allowed tx hashes. 332 var buf bytes.Buffer 333 WriteVarInt(&buf, pver, maxTxPerBlock+1) 334 numHashesOffset := 84 335 exceedMaxHashes := make([]byte, numHashesOffset) 336 copy(exceedMaxHashes, merkleBlockOneBytes[:numHashesOffset]) 337 exceedMaxHashes = append(exceedMaxHashes, buf.Bytes()...) 338 339 // Create bytes for a merkle block that claims to have more than the max 340 // allowed flag bytes. 341 buf.Reset() 342 WriteVarInt(&buf, pver, maxFlagsPerMerkleBlock+1) 343 numFlagBytesOffset := 117 344 exceedMaxFlagBytes := make([]byte, numFlagBytesOffset) 345 copy(exceedMaxFlagBytes, merkleBlockOneBytes[:numFlagBytesOffset]) 346 exceedMaxFlagBytes = append(exceedMaxFlagBytes, buf.Bytes()...) 347 348 tests := []struct { 349 buf []byte // Wire encoding 350 pver uint32 // Protocol version for wire encoding 351 enc MessageEncoding // Message encoding format 352 err error // Expected error 353 }{ 354 // Block that claims to have more than max allowed hashes. 355 {exceedMaxHashes, pver, BaseEncoding, &MessageError{}}, 356 // Block that claims to have more than max allowed flag bytes. 357 {exceedMaxFlagBytes, pver, BaseEncoding, &MessageError{}}, 358 } 359 360 t.Logf("Running %d tests", len(tests)) 361 for i, test := range tests { 362 // Decode from wire format. 363 var msg MsgMerkleBlock 364 r := bytes.NewReader(test.buf) 365 err := msg.BtcDecode(r, test.pver, test.enc) 366 if reflect.TypeOf(err) != reflect.TypeOf(test.err) { 367 t.Errorf("BtcDecode #%d wrong error got: %v, want: %v", 368 i, err, reflect.TypeOf(test.err)) 369 continue 370 } 371 } 372 } 373 374 // merkleBlockOne is a merkle block created from block one of the block chain 375 // where the first transaction matches. 376 var merkleBlockOne = MsgMerkleBlock{ 377 Header: BlockHeader{ 378 Version: 1, 379 PrevBlock: chainhash.Hash([chainhash.HashSize]byte{ // Make go vet happy. 380 0x6f, 0xe2, 0x8c, 0x0a, 0xb6, 0xf1, 0xb3, 0x72, 381 0xc1, 0xa6, 0xa2, 0x46, 0xae, 0x63, 0xf7, 0x4f, 382 0x93, 0x1e, 0x83, 0x65, 0xe1, 0x5a, 0x08, 0x9c, 383 0x68, 0xd6, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 384 }), 385 MerkleRoot: chainhash.Hash([chainhash.HashSize]byte{ // Make go vet happy. 386 0x98, 0x20, 0x51, 0xfd, 0x1e, 0x4b, 0xa7, 0x44, 387 0xbb, 0xbe, 0x68, 0x0e, 0x1f, 0xee, 0x14, 0x67, 388 0x7b, 0xa1, 0xa3, 0xc3, 0x54, 0x0b, 0xf7, 0xb1, 389 0xcd, 0xb6, 0x06, 0xe8, 0x57, 0x23, 0x3e, 0x0e, 390 }), 391 Timestamp: time.Unix(0x4966bc61, 0), // 2009-01-08 20:54:25 -0600 CST 392 Bits: 0x1d00ffff, // 486604799 393 Nonce: 0x9962e301, // 2573394689 394 }, 395 Transactions: 1, 396 Hashes: []*chainhash.Hash{ 397 (*chainhash.Hash)(&[chainhash.HashSize]byte{ // Make go vet happy. 398 0x98, 0x20, 0x51, 0xfd, 0x1e, 0x4b, 0xa7, 0x44, 399 0xbb, 0xbe, 0x68, 0x0e, 0x1f, 0xee, 0x14, 0x67, 400 0x7b, 0xa1, 0xa3, 0xc3, 0x54, 0x0b, 0xf7, 0xb1, 401 0xcd, 0xb6, 0x06, 0xe8, 0x57, 0x23, 0x3e, 0x0e, 402 }), 403 }, 404 Flags: []byte{0x80}, 405 } 406 407 // merkleBlockOneBytes is the serialized bytes for a merkle block created from 408 // block one of the block chain where the first transaction matches. 409 var merkleBlockOneBytes = []byte{ 410 0x01, 0x00, 0x00, 0x00, // Version 1 411 0x6f, 0xe2, 0x8c, 0x0a, 0xb6, 0xf1, 0xb3, 0x72, 412 0xc1, 0xa6, 0xa2, 0x46, 0xae, 0x63, 0xf7, 0x4f, 413 0x93, 0x1e, 0x83, 0x65, 0xe1, 0x5a, 0x08, 0x9c, 414 0x68, 0xd6, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, // PrevBlock 415 0x98, 0x20, 0x51, 0xfd, 0x1e, 0x4b, 0xa7, 0x44, 416 0xbb, 0xbe, 0x68, 0x0e, 0x1f, 0xee, 0x14, 0x67, 417 0x7b, 0xa1, 0xa3, 0xc3, 0x54, 0x0b, 0xf7, 0xb1, 418 0xcd, 0xb6, 0x06, 0xe8, 0x57, 0x23, 0x3e, 0x0e, // MerkleRoot 419 0x61, 0xbc, 0x66, 0x49, // Timestamp 420 0xff, 0xff, 0x00, 0x1d, // Bits 421 0x01, 0xe3, 0x62, 0x99, // Nonce 422 0x01, 0x00, 0x00, 0x00, // TxnCount 423 0x01, // Num hashes 424 0x98, 0x20, 0x51, 0xfd, 0x1e, 0x4b, 0xa7, 0x44, 425 0xbb, 0xbe, 0x68, 0x0e, 0x1f, 0xee, 0x14, 0x67, 426 0x7b, 0xa1, 0xa3, 0xc3, 0x54, 0x0b, 0xf7, 0xb1, 427 0xcd, 0xb6, 0x06, 0xe8, 0x57, 0x23, 0x3e, 0x0e, // Hash 428 0x01, // Num flag bytes 429 0x80, // Flags 430 }