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
5package wire
6
7import (
8	"bytes"
9	"fmt"
10	"io"
11	"reflect"
12	"testing"
13
14	"github.com/btcsuite/btcd/chaincfg/chainhash"
15	"github.com/davecgh/go-spew/spew"
16)
17
18// TestTx tests the MsgTx API.
19func 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.
138func 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.
187func 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.
264func 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.
405func 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.
470func 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.
570func 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.
631func 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.
726func 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.
760func 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.
782var 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.
835var 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.
878var multiTxPkScriptLocs = []int{63, 139}
879
880// multiWitnessTx is a MsgTx with an input with witness data, and an
881// output used in various tests.
882var 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.
936var multiWitnessTxEncoded = []byte{
937	0x1, 0x0, 0x0, 0x0, // Version
938	0x0, // Marker byte indicating 0 inputs, or a segwit encoded tx
939	0x1, // 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.
979var multiWitnessTxEncodedNonZeroFlag = []byte{
980	0x1, 0x0, 0x0, 0x0, // Version
981	0x0, // 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.
1021var multiWitnessTxPkScriptLocs = []int{58}
1022