github.com/btcsuite/btcd@v0.24.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/btcsuite/btcd/chaincfg/chainhash"
    16  	"github.com/davecgh/go-spew/spew"
    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  }