github.com/palcoin-project/palcd@v1.0.0/wire/msgtx_test.go (about) 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. 4 5 package wire 6 7 import ( 8 "bytes" 9 "fmt" 10 "io" 11 "reflect" 12 "testing" 13 14 "github.com/davecgh/go-spew/spew" 15 "github.com/palcoin-project/palcd/chaincfg/chainhash" 16 ) 17 18 // TestTx tests the MsgTx API. 19 func TestTx(t *testing.T) { 20 pver := ProtocolVersion 21 22 // Block 100000 hash. 23 hashStr := "3ba27aa200b1cecaad478d2b00432346c3f1f3986da1afd33e506" 24 hash, err := chainhash.NewHashFromStr(hashStr) 25 if err != nil { 26 t.Errorf("NewHashFromStr: %v", err) 27 } 28 29 // Ensure the command is expected value. 30 wantCmd := "tx" 31 msg := NewMsgTx(1) 32 if cmd := msg.Command(); cmd != wantCmd { 33 t.Errorf("NewMsgAddr: wrong command - got %v want %v", 34 cmd, wantCmd) 35 } 36 37 // Ensure max payload is expected value for latest protocol version. 38 wantPayload := uint32(1000 * 4000) 39 maxPayload := msg.MaxPayloadLength(pver) 40 if maxPayload != wantPayload { 41 t.Errorf("MaxPayloadLength: wrong max payload length for "+ 42 "protocol version %d - got %v, want %v", pver, 43 maxPayload, wantPayload) 44 } 45 46 // Ensure we get the same transaction output point data back out. 47 // NOTE: This is a block hash and made up index, but we're only 48 // testing package functionality. 49 prevOutIndex := uint32(1) 50 prevOut := NewOutPoint(hash, prevOutIndex) 51 if !prevOut.Hash.IsEqual(hash) { 52 t.Errorf("NewOutPoint: wrong hash - got %v, want %v", 53 spew.Sprint(&prevOut.Hash), spew.Sprint(hash)) 54 } 55 if prevOut.Index != prevOutIndex { 56 t.Errorf("NewOutPoint: wrong index - got %v, want %v", 57 prevOut.Index, prevOutIndex) 58 } 59 prevOutStr := fmt.Sprintf("%s:%d", hash.String(), prevOutIndex) 60 if s := prevOut.String(); s != prevOutStr { 61 t.Errorf("OutPoint.String: unexpected result - got %v, "+ 62 "want %v", s, prevOutStr) 63 } 64 65 // Ensure we get the same transaction input back out. 66 sigScript := []byte{0x04, 0x31, 0xdc, 0x00, 0x1b, 0x01, 0x62} 67 witnessData := [][]byte{ 68 {0x04, 0x31}, 69 {0x01, 0x43}, 70 } 71 txIn := NewTxIn(prevOut, sigScript, witnessData) 72 if !reflect.DeepEqual(&txIn.PreviousOutPoint, prevOut) { 73 t.Errorf("NewTxIn: wrong prev outpoint - got %v, want %v", 74 spew.Sprint(&txIn.PreviousOutPoint), 75 spew.Sprint(prevOut)) 76 } 77 if !bytes.Equal(txIn.SignatureScript, sigScript) { 78 t.Errorf("NewTxIn: wrong signature script - got %v, want %v", 79 spew.Sdump(txIn.SignatureScript), 80 spew.Sdump(sigScript)) 81 } 82 if !reflect.DeepEqual(txIn.Witness, TxWitness(witnessData)) { 83 t.Errorf("NewTxIn: wrong witness data - got %v, want %v", 84 spew.Sdump(txIn.Witness), 85 spew.Sdump(witnessData)) 86 } 87 88 // Ensure we get the same transaction output back out. 89 txValue := int64(5000000000) 90 pkScript := []byte{ 91 0x41, // OP_DATA_65 92 0x04, 0xd6, 0x4b, 0xdf, 0xd0, 0x9e, 0xb1, 0xc5, 93 0xfe, 0x29, 0x5a, 0xbd, 0xeb, 0x1d, 0xca, 0x42, 94 0x81, 0xbe, 0x98, 0x8e, 0x2d, 0xa0, 0xb6, 0xc1, 95 0xc6, 0xa5, 0x9d, 0xc2, 0x26, 0xc2, 0x86, 0x24, 96 0xe1, 0x81, 0x75, 0xe8, 0x51, 0xc9, 0x6b, 0x97, 97 0x3d, 0x81, 0xb0, 0x1c, 0xc3, 0x1f, 0x04, 0x78, 98 0x34, 0xbc, 0x06, 0xd6, 0xd6, 0xed, 0xf6, 0x20, 99 0xd1, 0x84, 0x24, 0x1a, 0x6a, 0xed, 0x8b, 0x63, 100 0xa6, // 65-byte signature 101 0xac, // OP_CHECKSIG 102 } 103 txOut := NewTxOut(txValue, pkScript) 104 if txOut.Value != txValue { 105 t.Errorf("NewTxOut: wrong pk script - got %v, want %v", 106 txOut.Value, txValue) 107 108 } 109 if !bytes.Equal(txOut.PkScript, pkScript) { 110 t.Errorf("NewTxOut: wrong pk script - got %v, want %v", 111 spew.Sdump(txOut.PkScript), 112 spew.Sdump(pkScript)) 113 } 114 115 // Ensure transaction inputs are added properly. 116 msg.AddTxIn(txIn) 117 if !reflect.DeepEqual(msg.TxIn[0], txIn) { 118 t.Errorf("AddTxIn: wrong transaction input added - got %v, want %v", 119 spew.Sprint(msg.TxIn[0]), spew.Sprint(txIn)) 120 } 121 122 // Ensure transaction outputs are added properly. 123 msg.AddTxOut(txOut) 124 if !reflect.DeepEqual(msg.TxOut[0], txOut) { 125 t.Errorf("AddTxIn: wrong transaction output added - got %v, want %v", 126 spew.Sprint(msg.TxOut[0]), spew.Sprint(txOut)) 127 } 128 129 // Ensure the copy produced an identical transaction message. 130 newMsg := msg.Copy() 131 if !reflect.DeepEqual(newMsg, msg) { 132 t.Errorf("Copy: mismatched tx messages - got %v, want %v", 133 spew.Sdump(newMsg), spew.Sdump(msg)) 134 } 135 } 136 137 // TestTxHash tests the ability to generate the hash of a transaction accurately. 138 func TestTxHash(t *testing.T) { 139 // Hash of first transaction from block 113875. 140 hashStr := "f051e59b5e2503ac626d03aaeac8ab7be2d72ba4b7e97119c5852d70d52dcb86" 141 wantHash, err := chainhash.NewHashFromStr(hashStr) 142 if err != nil { 143 t.Errorf("NewHashFromStr: %v", err) 144 return 145 } 146 147 // First transaction from block 113875. 148 msgTx := NewMsgTx(1) 149 txIn := TxIn{ 150 PreviousOutPoint: OutPoint{ 151 Hash: chainhash.Hash{}, 152 Index: 0xffffffff, 153 }, 154 SignatureScript: []byte{0x04, 0x31, 0xdc, 0x00, 0x1b, 0x01, 0x62}, 155 Sequence: 0xffffffff, 156 } 157 txOut := TxOut{ 158 Value: 5000000000, 159 PkScript: []byte{ 160 0x41, // OP_DATA_65 161 0x04, 0xd6, 0x4b, 0xdf, 0xd0, 0x9e, 0xb1, 0xc5, 162 0xfe, 0x29, 0x5a, 0xbd, 0xeb, 0x1d, 0xca, 0x42, 163 0x81, 0xbe, 0x98, 0x8e, 0x2d, 0xa0, 0xb6, 0xc1, 164 0xc6, 0xa5, 0x9d, 0xc2, 0x26, 0xc2, 0x86, 0x24, 165 0xe1, 0x81, 0x75, 0xe8, 0x51, 0xc9, 0x6b, 0x97, 166 0x3d, 0x81, 0xb0, 0x1c, 0xc3, 0x1f, 0x04, 0x78, 167 0x34, 0xbc, 0x06, 0xd6, 0xd6, 0xed, 0xf6, 0x20, 168 0xd1, 0x84, 0x24, 0x1a, 0x6a, 0xed, 0x8b, 0x63, 169 0xa6, // 65-byte signature 170 0xac, // OP_CHECKSIG 171 }, 172 } 173 msgTx.AddTxIn(&txIn) 174 msgTx.AddTxOut(&txOut) 175 msgTx.LockTime = 0 176 177 // Ensure the hash produced is expected. 178 txHash := msgTx.TxHash() 179 if !txHash.IsEqual(wantHash) { 180 t.Errorf("TxHash: wrong hash - got %v, want %v", 181 spew.Sprint(txHash), spew.Sprint(wantHash)) 182 } 183 } 184 185 // TestTxSha tests the ability to generate the wtxid, and txid of a transaction 186 // with witness inputs accurately. 187 func TestWTxSha(t *testing.T) { 188 hashStrTxid := "0f167d1385a84d1518cfee208b653fc9163b605ccf1b75347e2850b3e2eb19f3" 189 wantHashTxid, err := chainhash.NewHashFromStr(hashStrTxid) 190 if err != nil { 191 t.Errorf("NewShaHashFromStr: %v", err) 192 return 193 } 194 hashStrWTxid := "0858eab78e77b6b033da30f46699996396cf48fcf625a783c85a51403e175e74" 195 wantHashWTxid, err := chainhash.NewHashFromStr(hashStrWTxid) 196 if err != nil { 197 t.Errorf("NewShaHashFromStr: %v", err) 198 return 199 } 200 201 // From block 23157 in a past version of segnet. 202 msgTx := NewMsgTx(1) 203 txIn := TxIn{ 204 PreviousOutPoint: OutPoint{ 205 Hash: chainhash.Hash{ 206 0xa5, 0x33, 0x52, 0xd5, 0x13, 0x57, 0x66, 0xf0, 207 0x30, 0x76, 0x59, 0x74, 0x18, 0x26, 0x3d, 0xa2, 208 0xd9, 0xc9, 0x58, 0x31, 0x59, 0x68, 0xfe, 0xa8, 209 0x23, 0x52, 0x94, 0x67, 0x48, 0x1f, 0xf9, 0xcd, 210 }, 211 Index: 19, 212 }, 213 Witness: [][]byte{ 214 { // 70-byte signature 215 0x30, 0x43, 0x02, 0x1f, 0x4d, 0x23, 0x81, 0xdc, 216 0x97, 0xf1, 0x82, 0xab, 0xd8, 0x18, 0x5f, 0x51, 217 0x75, 0x30, 0x18, 0x52, 0x32, 0x12, 0xf5, 0xdd, 218 0xc0, 0x7c, 0xc4, 0xe6, 0x3a, 0x8d, 0xc0, 0x36, 219 0x58, 0xda, 0x19, 0x02, 0x20, 0x60, 0x8b, 0x5c, 220 0x4d, 0x92, 0xb8, 0x6b, 0x6d, 0xe7, 0xd7, 0x8e, 221 0xf2, 0x3a, 0x2f, 0xa7, 0x35, 0xbc, 0xb5, 0x9b, 222 0x91, 0x4a, 0x48, 0xb0, 0xe1, 0x87, 0xc5, 0xe7, 223 0x56, 0x9a, 0x18, 0x19, 0x70, 0x01, 224 }, 225 { // 33-byte serialize pub key 226 0x03, 0x07, 0xea, 0xd0, 0x84, 0x80, 0x7e, 0xb7, 227 0x63, 0x46, 0xdf, 0x69, 0x77, 0x00, 0x0c, 0x89, 228 0x39, 0x2f, 0x45, 0xc7, 0x64, 0x25, 0xb2, 0x61, 229 0x81, 0xf5, 0x21, 0xd7, 0xf3, 0x70, 0x06, 0x6a, 230 0x8f, 231 }, 232 }, 233 Sequence: 0xffffffff, 234 } 235 txOut := TxOut{ 236 Value: 395019, 237 PkScript: []byte{ 238 0x00, // Version 0 witness program 239 0x14, // OP_DATA_20 240 0x9d, 0xda, 0xc6, 0xf3, 0x9d, 0x51, 0xe0, 0x39, 241 0x8e, 0x53, 0x2a, 0x22, 0xc4, 0x1b, 0xa1, 0x89, 242 0x40, 0x6a, 0x85, 0x23, // 20-byte pub key hash 243 }, 244 } 245 msgTx.AddTxIn(&txIn) 246 msgTx.AddTxOut(&txOut) 247 msgTx.LockTime = 0 248 249 // Ensure the correct txid, and wtxid is produced as expected. 250 txid := msgTx.TxHash() 251 if !txid.IsEqual(wantHashTxid) { 252 t.Errorf("TxSha: wrong hash - got %v, want %v", 253 spew.Sprint(txid), spew.Sprint(wantHashTxid)) 254 } 255 wtxid := msgTx.WitnessHash() 256 if !wtxid.IsEqual(wantHashWTxid) { 257 t.Errorf("WTxSha: wrong hash - got %v, want %v", 258 spew.Sprint(wtxid), spew.Sprint(wantHashWTxid)) 259 } 260 } 261 262 // TestTxWire tests the MsgTx wire encode and decode for various numbers 263 // of transaction inputs and outputs and protocol versions. 264 func TestTxWire(t *testing.T) { 265 // Empty tx message. 266 noTx := NewMsgTx(1) 267 noTx.Version = 1 268 noTxEncoded := []byte{ 269 0x01, 0x00, 0x00, 0x00, // Version 270 0x00, // Varint for number of input transactions 271 0x00, // Varint for number of output transactions 272 0x00, 0x00, 0x00, 0x00, // Lock time 273 } 274 275 tests := []struct { 276 in *MsgTx // Message to encode 277 out *MsgTx // Expected decoded message 278 buf []byte // Wire encoding 279 pver uint32 // Protocol version for wire encoding 280 enc MessageEncoding // Message encoding format 281 }{ 282 // Latest protocol version with no transactions. 283 { 284 noTx, 285 noTx, noTxEncoded, 286 ProtocolVersion, 287 BaseEncoding, 288 }, 289 290 // Latest protocol version with multiple transactions. 291 { 292 multiTx, 293 multiTx, 294 multiTxEncoded, 295 ProtocolVersion, 296 BaseEncoding, 297 }, 298 299 // Protocol version BIP0035Version with no transactions. 300 { 301 noTx, 302 noTx, 303 noTxEncoded, 304 BIP0035Version, 305 BaseEncoding, 306 }, 307 308 // Protocol version BIP0035Version with multiple transactions. 309 { 310 multiTx, 311 multiTx, 312 multiTxEncoded, 313 BIP0035Version, 314 BaseEncoding, 315 }, 316 317 // Protocol version BIP0031Version with no transactions. 318 { 319 noTx, 320 noTx, 321 noTxEncoded, 322 BIP0031Version, 323 BaseEncoding, 324 }, 325 326 // Protocol version BIP0031Version with multiple transactions. 327 { 328 multiTx, 329 multiTx, 330 multiTxEncoded, 331 BIP0031Version, 332 BaseEncoding, 333 }, 334 335 // Protocol version NetAddressTimeVersion with no transactions. 336 { 337 noTx, 338 noTx, 339 noTxEncoded, 340 NetAddressTimeVersion, 341 BaseEncoding, 342 }, 343 344 // Protocol version NetAddressTimeVersion with multiple transactions. 345 { 346 multiTx, 347 multiTx, 348 multiTxEncoded, 349 NetAddressTimeVersion, 350 BaseEncoding, 351 }, 352 353 // Protocol version MultipleAddressVersion with no transactions. 354 { 355 noTx, 356 noTx, 357 noTxEncoded, 358 MultipleAddressVersion, 359 BaseEncoding, 360 }, 361 362 // Protocol version MultipleAddressVersion with multiple transactions. 363 { 364 multiTx, 365 multiTx, 366 multiTxEncoded, 367 MultipleAddressVersion, 368 BaseEncoding, 369 }, 370 } 371 372 t.Logf("Running %d tests", len(tests)) 373 for i, test := range tests { 374 // Encode the message to wire format. 375 var buf bytes.Buffer 376 err := test.in.BtcEncode(&buf, test.pver, test.enc) 377 if err != nil { 378 t.Errorf("BtcEncode #%d error %v", i, err) 379 continue 380 } 381 if !bytes.Equal(buf.Bytes(), test.buf) { 382 t.Errorf("BtcEncode #%d\n got: %s want: %s", i, 383 spew.Sdump(buf.Bytes()), spew.Sdump(test.buf)) 384 continue 385 } 386 387 // Decode the message from wire format. 388 var msg MsgTx 389 rbuf := bytes.NewReader(test.buf) 390 err = msg.BtcDecode(rbuf, test.pver, test.enc) 391 if err != nil { 392 t.Errorf("BtcDecode #%d error %v", i, err) 393 continue 394 } 395 if !reflect.DeepEqual(&msg, test.out) { 396 t.Errorf("BtcDecode #%d\n got: %s want: %s", i, 397 spew.Sdump(&msg), spew.Sdump(test.out)) 398 continue 399 } 400 } 401 } 402 403 // TestTxWireErrors performs negative tests against wire encode and decode 404 // of MsgTx to confirm error paths work correctly. 405 func TestTxWireErrors(t *testing.T) { 406 // Use protocol version 60002 specifically here instead of the latest 407 // because the test data is using bytes encoded with that protocol 408 // version. 409 pver := uint32(60002) 410 411 tests := []struct { 412 in *MsgTx // Value to encode 413 buf []byte // Wire encoding 414 pver uint32 // Protocol version for wire encoding 415 enc MessageEncoding // Message encoding format 416 max int // Max size of fixed buffer to induce errors 417 writeErr error // Expected write error 418 readErr error // Expected read error 419 }{ 420 // Force error in version. 421 {multiTx, multiTxEncoded, pver, BaseEncoding, 0, io.ErrShortWrite, io.EOF}, 422 // Force error in number of transaction inputs. 423 {multiTx, multiTxEncoded, pver, BaseEncoding, 4, io.ErrShortWrite, io.EOF}, 424 // Force error in transaction input previous block hash. 425 {multiTx, multiTxEncoded, pver, BaseEncoding, 5, io.ErrShortWrite, io.EOF}, 426 // Force error in transaction input previous block output index. 427 {multiTx, multiTxEncoded, pver, BaseEncoding, 37, io.ErrShortWrite, io.EOF}, 428 // Force error in transaction input signature script length. 429 {multiTx, multiTxEncoded, pver, BaseEncoding, 41, io.ErrShortWrite, io.EOF}, 430 // Force error in transaction input signature script. 431 {multiTx, multiTxEncoded, pver, BaseEncoding, 42, io.ErrShortWrite, io.EOF}, 432 // Force error in transaction input sequence. 433 {multiTx, multiTxEncoded, pver, BaseEncoding, 49, io.ErrShortWrite, io.EOF}, 434 // Force error in number of transaction outputs. 435 {multiTx, multiTxEncoded, pver, BaseEncoding, 53, io.ErrShortWrite, io.EOF}, 436 // Force error in transaction output value. 437 {multiTx, multiTxEncoded, pver, BaseEncoding, 54, io.ErrShortWrite, io.EOF}, 438 // Force error in transaction output pk script length. 439 {multiTx, multiTxEncoded, pver, BaseEncoding, 62, io.ErrShortWrite, io.EOF}, 440 // Force error in transaction output pk script. 441 {multiTx, multiTxEncoded, pver, BaseEncoding, 63, io.ErrShortWrite, io.EOF}, 442 // Force error in transaction output lock time. 443 {multiTx, multiTxEncoded, pver, BaseEncoding, 206, io.ErrShortWrite, io.EOF}, 444 } 445 446 t.Logf("Running %d tests", len(tests)) 447 for i, test := range tests { 448 // Encode to wire format. 449 w := newFixedWriter(test.max) 450 err := test.in.BtcEncode(w, test.pver, test.enc) 451 if err != test.writeErr { 452 t.Errorf("BtcEncode #%d wrong error got: %v, want: %v", 453 i, err, test.writeErr) 454 continue 455 } 456 457 // Decode from wire format. 458 var msg MsgTx 459 r := newFixedReader(test.max, test.buf) 460 err = msg.BtcDecode(r, test.pver, test.enc) 461 if err != test.readErr { 462 t.Errorf("BtcDecode #%d wrong error got: %v, want: %v", 463 i, err, test.readErr) 464 continue 465 } 466 } 467 } 468 469 // TestTxSerialize tests MsgTx serialize and deserialize. 470 func TestTxSerialize(t *testing.T) { 471 noTx := NewMsgTx(1) 472 noTx.Version = 1 473 noTxEncoded := []byte{ 474 0x01, 0x00, 0x00, 0x00, // Version 475 0x00, // Varint for number of input transactions 476 0x00, // Varint for number of output transactions 477 0x00, 0x00, 0x00, 0x00, // Lock time 478 } 479 480 tests := []struct { 481 in *MsgTx // Message to encode 482 out *MsgTx // Expected decoded message 483 buf []byte // Serialized data 484 pkScriptLocs []int // Expected output script locations 485 witness bool // Serialize using the witness encoding 486 }{ 487 // No transactions. 488 { 489 noTx, 490 noTx, 491 noTxEncoded, 492 nil, 493 false, 494 }, 495 496 // Multiple transactions. 497 { 498 multiTx, 499 multiTx, 500 multiTxEncoded, 501 multiTxPkScriptLocs, 502 false, 503 }, 504 // Multiple outputs witness transaction. 505 { 506 multiWitnessTx, 507 multiWitnessTx, 508 multiWitnessTxEncoded, 509 multiWitnessTxPkScriptLocs, 510 true, 511 }, 512 } 513 514 t.Logf("Running %d tests", len(tests)) 515 for i, test := range tests { 516 // Serialize the transaction. 517 var buf bytes.Buffer 518 err := test.in.Serialize(&buf) 519 if err != nil { 520 t.Errorf("Serialize #%d error %v", i, err) 521 continue 522 } 523 if !bytes.Equal(buf.Bytes(), test.buf) { 524 t.Errorf("Serialize #%d\n got: %s want: %s", i, 525 spew.Sdump(buf.Bytes()), spew.Sdump(test.buf)) 526 continue 527 } 528 529 // Deserialize the transaction. 530 var tx MsgTx 531 rbuf := bytes.NewReader(test.buf) 532 if test.witness { 533 err = tx.Deserialize(rbuf) 534 } else { 535 err = tx.DeserializeNoWitness(rbuf) 536 } 537 if err != nil { 538 t.Errorf("Deserialize #%d error %v", i, err) 539 continue 540 } 541 if !reflect.DeepEqual(&tx, test.out) { 542 t.Errorf("Deserialize #%d\n got: %s want: %s", i, 543 spew.Sdump(&tx), spew.Sdump(test.out)) 544 continue 545 } 546 547 // Ensure the public key script locations are accurate. 548 pkScriptLocs := test.in.PkScriptLocs() 549 if !reflect.DeepEqual(pkScriptLocs, test.pkScriptLocs) { 550 t.Errorf("PkScriptLocs #%d\n got: %s want: %s", i, 551 spew.Sdump(pkScriptLocs), 552 spew.Sdump(test.pkScriptLocs)) 553 continue 554 } 555 for j, loc := range pkScriptLocs { 556 wantPkScript := test.in.TxOut[j].PkScript 557 gotPkScript := test.buf[loc : loc+len(wantPkScript)] 558 if !bytes.Equal(gotPkScript, wantPkScript) { 559 t.Errorf("PkScriptLocs #%d:%d\n unexpected "+ 560 "script got: %s want: %s", i, j, 561 spew.Sdump(gotPkScript), 562 spew.Sdump(wantPkScript)) 563 } 564 } 565 } 566 } 567 568 // TestTxSerializeErrors performs negative tests against wire encode and decode 569 // of MsgTx to confirm error paths work correctly. 570 func TestTxSerializeErrors(t *testing.T) { 571 tests := []struct { 572 in *MsgTx // Value to encode 573 buf []byte // Serialized data 574 max int // Max size of fixed buffer to induce errors 575 writeErr error // Expected write error 576 readErr error // Expected read error 577 }{ 578 // Force error in version. 579 {multiTx, multiTxEncoded, 0, io.ErrShortWrite, io.EOF}, 580 // Force error in number of transaction inputs. 581 {multiTx, multiTxEncoded, 4, io.ErrShortWrite, io.EOF}, 582 // Force error in transaction input previous block hash. 583 {multiTx, multiTxEncoded, 5, io.ErrShortWrite, io.EOF}, 584 // Force error in transaction input previous block output index. 585 {multiTx, multiTxEncoded, 37, io.ErrShortWrite, io.EOF}, 586 // Force error in transaction input signature script length. 587 {multiTx, multiTxEncoded, 41, io.ErrShortWrite, io.EOF}, 588 // Force error in transaction input signature script. 589 {multiTx, multiTxEncoded, 42, io.ErrShortWrite, io.EOF}, 590 // Force error in transaction input sequence. 591 {multiTx, multiTxEncoded, 49, io.ErrShortWrite, io.EOF}, 592 // Force error in number of transaction outputs. 593 {multiTx, multiTxEncoded, 53, io.ErrShortWrite, io.EOF}, 594 // Force error in transaction output value. 595 {multiTx, multiTxEncoded, 54, io.ErrShortWrite, io.EOF}, 596 // Force error in transaction output pk script length. 597 {multiTx, multiTxEncoded, 62, io.ErrShortWrite, io.EOF}, 598 // Force error in transaction output pk script. 599 {multiTx, multiTxEncoded, 63, io.ErrShortWrite, io.EOF}, 600 // Force error in transaction output lock time. 601 {multiTx, multiTxEncoded, 206, io.ErrShortWrite, io.EOF}, 602 } 603 604 t.Logf("Running %d tests", len(tests)) 605 for i, test := range tests { 606 // Serialize the transaction. 607 w := newFixedWriter(test.max) 608 err := test.in.Serialize(w) 609 if err != test.writeErr { 610 t.Errorf("Serialize #%d wrong error got: %v, want: %v", 611 i, err, test.writeErr) 612 continue 613 } 614 615 // Deserialize the transaction. 616 var tx MsgTx 617 r := newFixedReader(test.max, test.buf) 618 err = tx.Deserialize(r) 619 if err != test.readErr { 620 t.Errorf("Deserialize #%d wrong error got: %v, want: %v", 621 i, err, test.readErr) 622 continue 623 } 624 } 625 } 626 627 // TestTxOverflowErrors performs tests to ensure deserializing transactions 628 // which are intentionally crafted to use large values for the variable number 629 // of inputs and outputs are handled properly. This could otherwise potentially 630 // be used as an attack vector. 631 func TestTxOverflowErrors(t *testing.T) { 632 // Use protocol version 70001 and transaction version 1 specifically 633 // here instead of the latest values because the test data is using 634 // bytes encoded with those versions. 635 pver := uint32(70001) 636 txVer := uint32(1) 637 638 tests := []struct { 639 buf []byte // Wire encoding 640 pver uint32 // Protocol version for wire encoding 641 enc MessageEncoding // Message encoding format 642 version uint32 // Transaction version 643 err error // Expected error 644 }{ 645 // Transaction that claims to have ~uint64(0) inputs. 646 { 647 []byte{ 648 0x00, 0x00, 0x00, 0x01, // Version 649 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 650 0xff, // Varint for number of input transactions 651 }, pver, BaseEncoding, txVer, &MessageError{}, 652 }, 653 654 // Transaction that claims to have ~uint64(0) outputs. 655 { 656 []byte{ 657 0x00, 0x00, 0x00, 0x01, // Version 658 0x00, // Varint for number of input transactions 659 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 660 0xff, // Varint for number of output transactions 661 }, pver, BaseEncoding, txVer, &MessageError{}, 662 }, 663 664 // Transaction that has an input with a signature script that 665 // claims to have ~uint64(0) length. 666 { 667 []byte{ 668 0x00, 0x00, 0x00, 0x01, // Version 669 0x01, // Varint for number of input transactions 670 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 671 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 672 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 673 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Previous output hash 674 0xff, 0xff, 0xff, 0xff, // Prevous output index 675 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 676 0xff, // Varint for length of signature script 677 }, pver, BaseEncoding, txVer, &MessageError{}, 678 }, 679 680 // Transaction that has an output with a public key script 681 // that claims to have ~uint64(0) length. 682 { 683 []byte{ 684 0x00, 0x00, 0x00, 0x01, // Version 685 0x01, // Varint for number of input transactions 686 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 687 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 688 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 689 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Previous output hash 690 0xff, 0xff, 0xff, 0xff, // Prevous output index 691 0x00, // Varint for length of signature script 692 0xff, 0xff, 0xff, 0xff, // Sequence 693 0x01, // Varint for number of output transactions 694 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Transaction amount 695 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 696 0xff, // Varint for length of public key script 697 }, pver, BaseEncoding, txVer, &MessageError{}, 698 }, 699 } 700 701 t.Logf("Running %d tests", len(tests)) 702 for i, test := range tests { 703 // Decode from wire format. 704 var msg MsgTx 705 r := bytes.NewReader(test.buf) 706 err := msg.BtcDecode(r, test.pver, test.enc) 707 if reflect.TypeOf(err) != reflect.TypeOf(test.err) { 708 t.Errorf("BtcDecode #%d wrong error got: %v, want: %v", 709 i, err, reflect.TypeOf(test.err)) 710 continue 711 } 712 713 // Decode from wire format. 714 r = bytes.NewReader(test.buf) 715 err = msg.Deserialize(r) 716 if reflect.TypeOf(err) != reflect.TypeOf(test.err) { 717 t.Errorf("Deserialize #%d wrong error got: %v, want: %v", 718 i, err, reflect.TypeOf(test.err)) 719 continue 720 } 721 } 722 } 723 724 // TestTxSerializeSizeStripped performs tests to ensure the serialize size for 725 // various transactions is accurate. 726 func TestTxSerializeSizeStripped(t *testing.T) { 727 // Empty tx message. 728 noTx := NewMsgTx(1) 729 noTx.Version = 1 730 731 tests := []struct { 732 in *MsgTx // Tx to encode 733 size int // Expected serialized size 734 }{ 735 // No inputs or outpus. 736 {noTx, 10}, 737 738 // Transcaction with an input and an output. 739 {multiTx, 210}, 740 741 // Transaction with an input which includes witness data, and 742 // one output. Note that this uses SerializeSizeStripped which 743 // excludes the additional bytes due to witness data encoding. 744 {multiWitnessTx, 82}, 745 } 746 747 t.Logf("Running %d tests", len(tests)) 748 for i, test := range tests { 749 serializedSize := test.in.SerializeSizeStripped() 750 if serializedSize != test.size { 751 t.Errorf("MsgTx.SerializeSizeStripped: #%d got: %d, want: %d", i, 752 serializedSize, test.size) 753 continue 754 } 755 } 756 } 757 758 // TestTxWitnessSize performs tests to ensure that the serialized size for 759 // various types of transactions that include witness data is accurate. 760 func TestTxWitnessSize(t *testing.T) { 761 tests := []struct { 762 in *MsgTx // Tx to encode 763 size int // Expected serialized size w/ witnesses 764 }{ 765 // Transaction with an input which includes witness data, and 766 // one output. 767 {multiWitnessTx, 190}, 768 } 769 770 t.Logf("Running %d tests", len(tests)) 771 for i, test := range tests { 772 serializedSize := test.in.SerializeSize() 773 if serializedSize != test.size { 774 t.Errorf("MsgTx.SerializeSize: #%d got: %d, want: %d", i, 775 serializedSize, test.size) 776 continue 777 } 778 } 779 } 780 781 // multiTx is a MsgTx with an input and output and used in various tests. 782 var multiTx = &MsgTx{ 783 Version: 1, 784 TxIn: []*TxIn{ 785 { 786 PreviousOutPoint: OutPoint{ 787 Hash: chainhash.Hash{}, 788 Index: 0xffffffff, 789 }, 790 SignatureScript: []byte{ 791 0x04, 0x31, 0xdc, 0x00, 0x1b, 0x01, 0x62, 792 }, 793 Sequence: 0xffffffff, 794 }, 795 }, 796 TxOut: []*TxOut{ 797 { 798 Value: 0x12a05f200, 799 PkScript: []byte{ 800 0x41, // OP_DATA_65 801 0x04, 0xd6, 0x4b, 0xdf, 0xd0, 0x9e, 0xb1, 0xc5, 802 0xfe, 0x29, 0x5a, 0xbd, 0xeb, 0x1d, 0xca, 0x42, 803 0x81, 0xbe, 0x98, 0x8e, 0x2d, 0xa0, 0xb6, 0xc1, 804 0xc6, 0xa5, 0x9d, 0xc2, 0x26, 0xc2, 0x86, 0x24, 805 0xe1, 0x81, 0x75, 0xe8, 0x51, 0xc9, 0x6b, 0x97, 806 0x3d, 0x81, 0xb0, 0x1c, 0xc3, 0x1f, 0x04, 0x78, 807 0x34, 0xbc, 0x06, 0xd6, 0xd6, 0xed, 0xf6, 0x20, 808 0xd1, 0x84, 0x24, 0x1a, 0x6a, 0xed, 0x8b, 0x63, 809 0xa6, // 65-byte signature 810 0xac, // OP_CHECKSIG 811 }, 812 }, 813 { 814 Value: 0x5f5e100, 815 PkScript: []byte{ 816 0x41, // OP_DATA_65 817 0x04, 0xd6, 0x4b, 0xdf, 0xd0, 0x9e, 0xb1, 0xc5, 818 0xfe, 0x29, 0x5a, 0xbd, 0xeb, 0x1d, 0xca, 0x42, 819 0x81, 0xbe, 0x98, 0x8e, 0x2d, 0xa0, 0xb6, 0xc1, 820 0xc6, 0xa5, 0x9d, 0xc2, 0x26, 0xc2, 0x86, 0x24, 821 0xe1, 0x81, 0x75, 0xe8, 0x51, 0xc9, 0x6b, 0x97, 822 0x3d, 0x81, 0xb0, 0x1c, 0xc3, 0x1f, 0x04, 0x78, 823 0x34, 0xbc, 0x06, 0xd6, 0xd6, 0xed, 0xf6, 0x20, 824 0xd1, 0x84, 0x24, 0x1a, 0x6a, 0xed, 0x8b, 0x63, 825 0xa6, // 65-byte signature 826 0xac, // OP_CHECKSIG 827 }, 828 }, 829 }, 830 LockTime: 0, 831 } 832 833 // multiTxEncoded is the wire encoded bytes for multiTx using protocol version 834 // 60002 and is used in the various tests. 835 var multiTxEncoded = []byte{ 836 0x01, 0x00, 0x00, 0x00, // Version 837 0x01, // Varint for number of input transactions 838 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 839 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 840 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 841 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Previous output hash 842 0xff, 0xff, 0xff, 0xff, // Prevous output index 843 0x07, // Varint for length of signature script 844 0x04, 0x31, 0xdc, 0x00, 0x1b, 0x01, 0x62, // Signature script 845 0xff, 0xff, 0xff, 0xff, // Sequence 846 0x02, // Varint for number of output transactions 847 0x00, 0xf2, 0x05, 0x2a, 0x01, 0x00, 0x00, 0x00, // Transaction amount 848 0x43, // Varint for length of pk script 849 0x41, // OP_DATA_65 850 0x04, 0xd6, 0x4b, 0xdf, 0xd0, 0x9e, 0xb1, 0xc5, 851 0xfe, 0x29, 0x5a, 0xbd, 0xeb, 0x1d, 0xca, 0x42, 852 0x81, 0xbe, 0x98, 0x8e, 0x2d, 0xa0, 0xb6, 0xc1, 853 0xc6, 0xa5, 0x9d, 0xc2, 0x26, 0xc2, 0x86, 0x24, 854 0xe1, 0x81, 0x75, 0xe8, 0x51, 0xc9, 0x6b, 0x97, 855 0x3d, 0x81, 0xb0, 0x1c, 0xc3, 0x1f, 0x04, 0x78, 856 0x34, 0xbc, 0x06, 0xd6, 0xd6, 0xed, 0xf6, 0x20, 857 0xd1, 0x84, 0x24, 0x1a, 0x6a, 0xed, 0x8b, 0x63, 858 0xa6, // 65-byte signature 859 0xac, // OP_CHECKSIG 860 0x00, 0xe1, 0xf5, 0x05, 0x00, 0x00, 0x00, 0x00, // Transaction amount 861 0x43, // Varint for length of pk script 862 0x41, // OP_DATA_65 863 0x04, 0xd6, 0x4b, 0xdf, 0xd0, 0x9e, 0xb1, 0xc5, 864 0xfe, 0x29, 0x5a, 0xbd, 0xeb, 0x1d, 0xca, 0x42, 865 0x81, 0xbe, 0x98, 0x8e, 0x2d, 0xa0, 0xb6, 0xc1, 866 0xc6, 0xa5, 0x9d, 0xc2, 0x26, 0xc2, 0x86, 0x24, 867 0xe1, 0x81, 0x75, 0xe8, 0x51, 0xc9, 0x6b, 0x97, 868 0x3d, 0x81, 0xb0, 0x1c, 0xc3, 0x1f, 0x04, 0x78, 869 0x34, 0xbc, 0x06, 0xd6, 0xd6, 0xed, 0xf6, 0x20, 870 0xd1, 0x84, 0x24, 0x1a, 0x6a, 0xed, 0x8b, 0x63, 871 0xa6, // 65-byte signature 872 0xac, // OP_CHECKSIG 873 0x00, 0x00, 0x00, 0x00, // Lock time 874 } 875 876 // multiTxPkScriptLocs is the location information for the public key scripts 877 // located in multiTx. 878 var multiTxPkScriptLocs = []int{63, 139} 879 880 // multiWitnessTx is a MsgTx with an input with witness data, and an 881 // output used in various tests. 882 var multiWitnessTx = &MsgTx{ 883 Version: 1, 884 TxIn: []*TxIn{ 885 { 886 PreviousOutPoint: OutPoint{ 887 Hash: chainhash.Hash{ 888 0xa5, 0x33, 0x52, 0xd5, 0x13, 0x57, 0x66, 0xf0, 889 0x30, 0x76, 0x59, 0x74, 0x18, 0x26, 0x3d, 0xa2, 890 0xd9, 0xc9, 0x58, 0x31, 0x59, 0x68, 0xfe, 0xa8, 891 0x23, 0x52, 0x94, 0x67, 0x48, 0x1f, 0xf9, 0xcd, 892 }, 893 Index: 19, 894 }, 895 SignatureScript: []byte{}, 896 Witness: [][]byte{ 897 { // 70-byte signature 898 0x30, 0x43, 0x02, 0x1f, 0x4d, 0x23, 0x81, 0xdc, 899 0x97, 0xf1, 0x82, 0xab, 0xd8, 0x18, 0x5f, 0x51, 900 0x75, 0x30, 0x18, 0x52, 0x32, 0x12, 0xf5, 0xdd, 901 0xc0, 0x7c, 0xc4, 0xe6, 0x3a, 0x8d, 0xc0, 0x36, 902 0x58, 0xda, 0x19, 0x02, 0x20, 0x60, 0x8b, 0x5c, 903 0x4d, 0x92, 0xb8, 0x6b, 0x6d, 0xe7, 0xd7, 0x8e, 904 0xf2, 0x3a, 0x2f, 0xa7, 0x35, 0xbc, 0xb5, 0x9b, 905 0x91, 0x4a, 0x48, 0xb0, 0xe1, 0x87, 0xc5, 0xe7, 906 0x56, 0x9a, 0x18, 0x19, 0x70, 0x01, 907 }, 908 { // 33-byte serialize pub key 909 0x03, 0x07, 0xea, 0xd0, 0x84, 0x80, 0x7e, 0xb7, 910 0x63, 0x46, 0xdf, 0x69, 0x77, 0x00, 0x0c, 0x89, 911 0x39, 0x2f, 0x45, 0xc7, 0x64, 0x25, 0xb2, 0x61, 912 0x81, 0xf5, 0x21, 0xd7, 0xf3, 0x70, 0x06, 0x6a, 913 0x8f, 914 }, 915 }, 916 Sequence: 0xffffffff, 917 }, 918 }, 919 TxOut: []*TxOut{ 920 { 921 Value: 395019, 922 PkScript: []byte{ // p2wkh output 923 0x00, // Version 0 witness program 924 0x14, // OP_DATA_20 925 0x9d, 0xda, 0xc6, 0xf3, 0x9d, 0x51, 0xe0, 0x39, 926 0x8e, 0x53, 0x2a, 0x22, 0xc4, 0x1b, 0xa1, 0x89, 927 0x40, 0x6a, 0x85, 0x23, // 20-byte pub key hash 928 }, 929 }, 930 }, 931 } 932 933 // multiWitnessTxEncoded is the wire encoded bytes for multiWitnessTx including inputs 934 // with witness data using protocol version 70012 and is used in the various 935 // tests. 936 var multiWitnessTxEncoded = []byte{ 937 0x1, 0x0, 0x0, 0x0, // Version 938 TxFlagMarker, // Marker byte indicating 0 inputs, or a segwit encoded tx 939 WitnessFlag, // Flag byte 940 0x1, // Varint for number of inputs 941 0xa5, 0x33, 0x52, 0xd5, 0x13, 0x57, 0x66, 0xf0, 942 0x30, 0x76, 0x59, 0x74, 0x18, 0x26, 0x3d, 0xa2, 943 0xd9, 0xc9, 0x58, 0x31, 0x59, 0x68, 0xfe, 0xa8, 944 0x23, 0x52, 0x94, 0x67, 0x48, 0x1f, 0xf9, 0xcd, // Previous output hash 945 0x13, 0x0, 0x0, 0x0, // Little endian previous output index 946 0x0, // No sig script (this is a witness input) 947 0xff, 0xff, 0xff, 0xff, // Sequence 948 0x1, // Varint for number of outputs 949 0xb, 0x7, 0x6, 0x0, 0x0, 0x0, 0x0, 0x0, // Output amount 950 0x16, // Varint for length of pk script 951 0x0, // Version 0 witness program 952 0x14, // OP_DATA_20 953 0x9d, 0xda, 0xc6, 0xf3, 0x9d, 0x51, 0xe0, 0x39, 954 0x8e, 0x53, 0x2a, 0x22, 0xc4, 0x1b, 0xa1, 0x89, 955 0x40, 0x6a, 0x85, 0x23, // 20-byte pub key hash 956 0x2, // Two items on the witness stack 957 0x46, // 70 byte stack item 958 0x30, 0x43, 0x2, 0x1f, 0x4d, 0x23, 0x81, 0xdc, 959 0x97, 0xf1, 0x82, 0xab, 0xd8, 0x18, 0x5f, 0x51, 960 0x75, 0x30, 0x18, 0x52, 0x32, 0x12, 0xf5, 0xdd, 961 0xc0, 0x7c, 0xc4, 0xe6, 0x3a, 0x8d, 0xc0, 0x36, 962 0x58, 0xda, 0x19, 0x2, 0x20, 0x60, 0x8b, 0x5c, 963 0x4d, 0x92, 0xb8, 0x6b, 0x6d, 0xe7, 0xd7, 0x8e, 964 0xf2, 0x3a, 0x2f, 0xa7, 0x35, 0xbc, 0xb5, 0x9b, 965 0x91, 0x4a, 0x48, 0xb0, 0xe1, 0x87, 0xc5, 0xe7, 966 0x56, 0x9a, 0x18, 0x19, 0x70, 0x1, 967 0x21, // 33 byte stack item 968 0x3, 0x7, 0xea, 0xd0, 0x84, 0x80, 0x7e, 0xb7, 969 0x63, 0x46, 0xdf, 0x69, 0x77, 0x0, 0xc, 0x89, 970 0x39, 0x2f, 0x45, 0xc7, 0x64, 0x25, 0xb2, 0x61, 971 0x81, 0xf5, 0x21, 0xd7, 0xf3, 0x70, 0x6, 0x6a, 972 0x8f, 973 0x0, 0x0, 0x0, 0x0, // Lock time 974 } 975 976 // multiWitnessTxEncodedNonZeroFlag is an incorrect wire encoded bytes for 977 // multiWitnessTx including inputs with witness data. Instead of the flag byte 978 // being set to 0x01, the flag is 0x00, which should trigger a decoding error. 979 var multiWitnessTxEncodedNonZeroFlag = []byte{ 980 0x1, 0x0, 0x0, 0x0, // Version 981 TxFlagMarker, // Marker byte indicating 0 inputs, or a segwit encoded tx 982 0x0, // Incorrect flag byte (should be 0x01) 983 0x1, // Varint for number of inputs 984 0xa5, 0x33, 0x52, 0xd5, 0x13, 0x57, 0x66, 0xf0, 985 0x30, 0x76, 0x59, 0x74, 0x18, 0x26, 0x3d, 0xa2, 986 0xd9, 0xc9, 0x58, 0x31, 0x59, 0x68, 0xfe, 0xa8, 987 0x23, 0x52, 0x94, 0x67, 0x48, 0x1f, 0xf9, 0xcd, // Previous output hash 988 0x13, 0x0, 0x0, 0x0, // Little endian previous output index 989 0x0, // No sig script (this is a witness input) 990 0xff, 0xff, 0xff, 0xff, // Sequence 991 0x1, // Varint for number of outputs 992 0xb, 0x7, 0x6, 0x0, 0x0, 0x0, 0x0, 0x0, // Output amount 993 0x16, // Varint for length of pk script 994 0x0, // Version 0 witness program 995 0x14, // OP_DATA_20 996 0x9d, 0xda, 0xc6, 0xf3, 0x9d, 0x51, 0xe0, 0x39, 997 0x8e, 0x53, 0x2a, 0x22, 0xc4, 0x1b, 0xa1, 0x89, 998 0x40, 0x6a, 0x85, 0x23, // 20-byte pub key hash 999 0x2, // Two items on the witness stack 1000 0x46, // 70 byte stack item 1001 0x30, 0x43, 0x2, 0x1f, 0x4d, 0x23, 0x81, 0xdc, 1002 0x97, 0xf1, 0x82, 0xab, 0xd8, 0x18, 0x5f, 0x51, 1003 0x75, 0x30, 0x18, 0x52, 0x32, 0x12, 0xf5, 0xdd, 1004 0xc0, 0x7c, 0xc4, 0xe6, 0x3a, 0x8d, 0xc0, 0x36, 1005 0x58, 0xda, 0x19, 0x2, 0x20, 0x60, 0x8b, 0x5c, 1006 0x4d, 0x92, 0xb8, 0x6b, 0x6d, 0xe7, 0xd7, 0x8e, 1007 0xf2, 0x3a, 0x2f, 0xa7, 0x35, 0xbc, 0xb5, 0x9b, 1008 0x91, 0x4a, 0x48, 0xb0, 0xe1, 0x87, 0xc5, 0xe7, 1009 0x56, 0x9a, 0x18, 0x19, 0x70, 0x1, 1010 0x21, // 33 byte stack item 1011 0x3, 0x7, 0xea, 0xd0, 0x84, 0x80, 0x7e, 0xb7, 1012 0x63, 0x46, 0xdf, 0x69, 0x77, 0x0, 0xc, 0x89, 1013 0x39, 0x2f, 0x45, 0xc7, 0x64, 0x25, 0xb2, 0x61, 1014 0x81, 0xf5, 0x21, 0xd7, 0xf3, 0x70, 0x6, 0x6a, 1015 0x8f, 1016 0x0, 0x0, 0x0, 0x0, // Lock time 1017 } 1018 1019 // multiTxPkScriptLocs is the location information for the public key scripts 1020 // located in multiWitnessTx. 1021 var multiWitnessTxPkScriptLocs = []int{58}