github.com/dashpay/godash@v0.0.0-20160726055534-e038a21e0e3d/wire/msgmerkleblock_test.go (about)

     1  // Copyright (c) 2014-2015 The btcsuite developers
     2  // Copyright (c) 2016 The Dash developers
     3  // Use of this source code is governed by an ISC
     4  // license that can be found in the LICENSE file.
     5  
     6  package wire_test
     7  
     8  import (
     9  	"bytes"
    10  	"crypto/rand"
    11  	"io"
    12  	"reflect"
    13  	"testing"
    14  	"time"
    15  
    16  	"github.com/dashpay/godash/wire"
    17  	"github.com/davecgh/go-spew/spew"
    18  )
    19  
    20  // TestMerkleBlock tests the MsgMerkleBlock API.
    21  func TestMerkleBlock(t *testing.T) {
    22  	pver := wire.ProtocolVersion
    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 := wire.NewBlockHeader(prevHash, merkleHash, bits, nonce)
    30  
    31  	// Ensure the command is expected value.
    32  	wantCmd := "merkleblock"
    33  	msg := wire.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(1000000)
    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 < wire.MaxTxPerBlock; i++ {
    52  		rand.Read(data)
    53  		hash, err := wire.NewShaHash(data)
    54  		if err != nil {
    55  			t.Errorf("NewShaHash 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 := wire.NewShaHash(data)
    68  	if err != nil {
    69  		t.Errorf("NewShaHash 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)
    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 := wire.MsgMerkleBlock{}
    87  	err = readmsg.BtcDecode(&buf, pver)
    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)
    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, wire.MaxFlagsPerMerkleBlock+1)
   105  	err = msg.BtcEncode(&buf, pver)
   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 := wire.NewBlockHeader(prevHash, merkleHash, bits, nonce)
   122  
   123  	msg := wire.NewMsgMerkleBlock(bh)
   124  
   125  	// Encode with latest protocol version.
   126  	var buf bytes.Buffer
   127  	err := msg.BtcEncode(&buf, wire.ProtocolVersion)
   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 wire.MsgFilterLoad
   135  	err = readmsg.BtcDecode(&buf, wire.BIP0031Version)
   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   *wire.MsgMerkleBlock // Message to encode
   147  		out  *wire.MsgMerkleBlock // Expected decoded message
   148  		buf  []byte               // Wire encoding
   149  		pver uint32               // Protocol version for wire encoding
   150  	}{
   151  		// Latest protocol version.
   152  		{
   153  			&merkleBlockOne, &merkleBlockOne, merkleBlockOneBytes,
   154  			wire.ProtocolVersion,
   155  		},
   156  
   157  		// Protocol version BIP0037Version.
   158  		{
   159  			&merkleBlockOne, &merkleBlockOne, merkleBlockOneBytes,
   160  			wire.BIP0037Version,
   161  		},
   162  	}
   163  
   164  	t.Logf("Running %d tests", len(tests))
   165  	for i, test := range tests {
   166  		// Encode the message to wire format.
   167  		var buf bytes.Buffer
   168  		err := test.in.BtcEncode(&buf, test.pver)
   169  		if err != nil {
   170  			t.Errorf("BtcEncode #%d error %v", i, err)
   171  			continue
   172  		}
   173  		if !bytes.Equal(buf.Bytes(), test.buf) {
   174  			t.Errorf("BtcEncode #%d\n got: %s want: %s", i,
   175  				spew.Sdump(buf.Bytes()), spew.Sdump(test.buf))
   176  			continue
   177  		}
   178  
   179  		// Decode the message from wire format.
   180  		var msg wire.MsgMerkleBlock
   181  		rbuf := bytes.NewReader(test.buf)
   182  		err = msg.BtcDecode(rbuf, test.pver)
   183  		if err != nil {
   184  			t.Errorf("BtcDecode #%d error %v", i, err)
   185  			continue
   186  		}
   187  		if !reflect.DeepEqual(&msg, test.out) {
   188  			t.Errorf("BtcDecode #%d\n got: %s want: %s", i,
   189  				spew.Sdump(&msg), spew.Sdump(test.out))
   190  			continue
   191  		}
   192  	}
   193  }
   194  
   195  // TestMerkleBlockWireErrors performs negative tests against wire encode and
   196  // decode of MsgBlock to confirm error paths work correctly.
   197  func TestMerkleBlockWireErrors(t *testing.T) {
   198  	// Use protocol version 70001 specifically here instead of the latest
   199  	// because the test data is using bytes encoded with that protocol
   200  	// version.
   201  	pver := uint32(70001)
   202  	pverNoMerkleBlock := wire.BIP0037Version - 1
   203  	wireErr := &wire.MessageError{}
   204  
   205  	tests := []struct {
   206  		in       *wire.MsgMerkleBlock // Value to encode
   207  		buf      []byte               // Wire encoding
   208  		pver     uint32               // Protocol version for wire encoding
   209  		max      int                  // Max size of fixed buffer to induce errors
   210  		writeErr error                // Expected write error
   211  		readErr  error                // Expected read error
   212  	}{
   213  		// Force error in version.
   214  		{
   215  			&merkleBlockOne, merkleBlockOneBytes, pver, 0,
   216  			io.ErrShortWrite, io.EOF,
   217  		},
   218  		// Force error in prev block hash.
   219  		{
   220  			&merkleBlockOne, merkleBlockOneBytes, pver, 4,
   221  			io.ErrShortWrite, io.EOF,
   222  		},
   223  		// Force error in merkle root.
   224  		{
   225  			&merkleBlockOne, merkleBlockOneBytes, pver, 36,
   226  			io.ErrShortWrite, io.EOF,
   227  		},
   228  		// Force error in timestamp.
   229  		{
   230  			&merkleBlockOne, merkleBlockOneBytes, pver, 68,
   231  			io.ErrShortWrite, io.EOF,
   232  		},
   233  		// Force error in difficulty bits.
   234  		{
   235  			&merkleBlockOne, merkleBlockOneBytes, pver, 72,
   236  			io.ErrShortWrite, io.EOF,
   237  		},
   238  		// Force error in header nonce.
   239  		{
   240  			&merkleBlockOne, merkleBlockOneBytes, pver, 76,
   241  			io.ErrShortWrite, io.EOF,
   242  		},
   243  		// Force error in transaction count.
   244  		{
   245  			&merkleBlockOne, merkleBlockOneBytes, pver, 80,
   246  			io.ErrShortWrite, io.EOF,
   247  		},
   248  		// Force error in num hashes.
   249  		{
   250  			&merkleBlockOne, merkleBlockOneBytes, pver, 84,
   251  			io.ErrShortWrite, io.EOF,
   252  		},
   253  		// Force error in hashes.
   254  		{
   255  			&merkleBlockOne, merkleBlockOneBytes, pver, 85,
   256  			io.ErrShortWrite, io.EOF,
   257  		},
   258  		// Force error in num flag bytes.
   259  		{
   260  			&merkleBlockOne, merkleBlockOneBytes, pver, 117,
   261  			io.ErrShortWrite, io.EOF,
   262  		},
   263  		// Force error in flag bytes.
   264  		{
   265  			&merkleBlockOne, merkleBlockOneBytes, pver, 118,
   266  			io.ErrShortWrite, io.EOF,
   267  		},
   268  		// Force error due to unsupported protocol version.
   269  		{
   270  			&merkleBlockOne, merkleBlockOneBytes, pverNoMerkleBlock,
   271  			119, wireErr, wireErr,
   272  		},
   273  	}
   274  
   275  	t.Logf("Running %d tests", len(tests))
   276  	for i, test := range tests {
   277  		// Encode to wire format.
   278  		w := newFixedWriter(test.max)
   279  		err := test.in.BtcEncode(w, test.pver)
   280  		if reflect.TypeOf(err) != reflect.TypeOf(test.writeErr) {
   281  			t.Errorf("BtcEncode #%d wrong error got: %v, want: %v",
   282  				i, err, test.writeErr)
   283  			continue
   284  		}
   285  
   286  		// For errors which are not of type wire.MessageError, check
   287  		// them for equality.
   288  		if _, ok := err.(*wire.MessageError); !ok {
   289  			if err != test.writeErr {
   290  				t.Errorf("BtcEncode #%d wrong error got: %v, "+
   291  					"want: %v", i, err, test.writeErr)
   292  				continue
   293  			}
   294  		}
   295  
   296  		// Decode from wire format.
   297  		var msg wire.MsgMerkleBlock
   298  		r := newFixedReader(test.max, test.buf)
   299  		err = msg.BtcDecode(r, test.pver)
   300  		if reflect.TypeOf(err) != reflect.TypeOf(test.readErr) {
   301  			t.Errorf("BtcDecode #%d wrong error got: %v, want: %v",
   302  				i, err, test.readErr)
   303  			continue
   304  		}
   305  
   306  		// For errors which are not of type wire.MessageError, check
   307  		// them for equality.
   308  		if _, ok := err.(*wire.MessageError); !ok {
   309  			if err != test.readErr {
   310  				t.Errorf("BtcDecode #%d wrong error got: %v, "+
   311  					"want: %v", i, err, test.readErr)
   312  				continue
   313  			}
   314  		}
   315  	}
   316  }
   317  
   318  // TestMerkleBlockOverflowErrors performs tests to ensure encoding and decoding
   319  // merkle blocks that are intentionally crafted to use large values for the
   320  // number of hashes and flags are handled properly.  This could otherwise
   321  // potentially be used as an attack vector.
   322  func TestMerkleBlockOverflowErrors(t *testing.T) {
   323  	// Use protocol version 70001 specifically here instead of the latest
   324  	// protocol version because the test data is using bytes encoded with
   325  	// that version.
   326  	pver := uint32(70001)
   327  
   328  	// Create bytes for a merkle block that claims to have more than the max
   329  	// allowed tx hashes.
   330  	var buf bytes.Buffer
   331  	wire.TstWriteVarInt(&buf, pver, wire.MaxTxPerBlock+1)
   332  	numHashesOffset := 84
   333  	exceedMaxHashes := make([]byte, numHashesOffset)
   334  	copy(exceedMaxHashes, merkleBlockOneBytes[:numHashesOffset])
   335  	exceedMaxHashes = append(exceedMaxHashes, buf.Bytes()...)
   336  
   337  	// Create bytes for a merkle block that claims to have more than the max
   338  	// allowed flag bytes.
   339  	buf.Reset()
   340  	wire.TstWriteVarInt(&buf, pver, wire.MaxFlagsPerMerkleBlock+1)
   341  	numFlagBytesOffset := 117
   342  	exceedMaxFlagBytes := make([]byte, numFlagBytesOffset)
   343  	copy(exceedMaxFlagBytes, merkleBlockOneBytes[:numFlagBytesOffset])
   344  	exceedMaxFlagBytes = append(exceedMaxFlagBytes, buf.Bytes()...)
   345  
   346  	tests := []struct {
   347  		buf  []byte // Wire encoding
   348  		pver uint32 // Protocol version for wire encoding
   349  		err  error  // Expected error
   350  	}{
   351  		// Block that claims to have more than max allowed hashes.
   352  		{exceedMaxHashes, pver, &wire.MessageError{}},
   353  		// Block that claims to have more than max allowed flag bytes.
   354  		{exceedMaxFlagBytes, pver, &wire.MessageError{}},
   355  	}
   356  
   357  	t.Logf("Running %d tests", len(tests))
   358  	for i, test := range tests {
   359  		// Decode from wire format.
   360  		var msg wire.MsgMerkleBlock
   361  		r := bytes.NewReader(test.buf)
   362  		err := msg.BtcDecode(r, test.pver)
   363  		if reflect.TypeOf(err) != reflect.TypeOf(test.err) {
   364  			t.Errorf("BtcDecode #%d wrong error got: %v, want: %v",
   365  				i, err, reflect.TypeOf(test.err))
   366  			continue
   367  		}
   368  	}
   369  }
   370  
   371  // merkleBlockOne is a merkle block created from block one of the block chain
   372  // where the first transaction matches.
   373  var merkleBlockOne = wire.MsgMerkleBlock{
   374  	Header: wire.BlockHeader{
   375  		Version: 1,
   376  		PrevBlock: wire.ShaHash([wire.HashSize]byte{ // Make go vet happy.
   377  			0x6f, 0xe2, 0x8c, 0x0a, 0xb6, 0xf1, 0xb3, 0x72,
   378  			0xc1, 0xa6, 0xa2, 0x46, 0xae, 0x63, 0xf7, 0x4f,
   379  			0x93, 0x1e, 0x83, 0x65, 0xe1, 0x5a, 0x08, 0x9c,
   380  			0x68, 0xd6, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00,
   381  		}),
   382  		MerkleRoot: wire.ShaHash([wire.HashSize]byte{ // Make go vet happy.
   383  			0x98, 0x20, 0x51, 0xfd, 0x1e, 0x4b, 0xa7, 0x44,
   384  			0xbb, 0xbe, 0x68, 0x0e, 0x1f, 0xee, 0x14, 0x67,
   385  			0x7b, 0xa1, 0xa3, 0xc3, 0x54, 0x0b, 0xf7, 0xb1,
   386  			0xcd, 0xb6, 0x06, 0xe8, 0x57, 0x23, 0x3e, 0x0e,
   387  		}),
   388  		Timestamp: time.Unix(0x4966bc61, 0), // 2009-01-08 20:54:25 -0600 CST
   389  		Bits:      0x1d00ffff,               // 486604799
   390  		Nonce:     0x9962e301,               // 2573394689
   391  	},
   392  	Transactions: 1,
   393  	Hashes: []*wire.ShaHash{
   394  		(*wire.ShaHash)(&[wire.HashSize]byte{ // Make go vet happy.
   395  			0x98, 0x20, 0x51, 0xfd, 0x1e, 0x4b, 0xa7, 0x44,
   396  			0xbb, 0xbe, 0x68, 0x0e, 0x1f, 0xee, 0x14, 0x67,
   397  			0x7b, 0xa1, 0xa3, 0xc3, 0x54, 0x0b, 0xf7, 0xb1,
   398  			0xcd, 0xb6, 0x06, 0xe8, 0x57, 0x23, 0x3e, 0x0e,
   399  		}),
   400  	},
   401  	Flags: []byte{0x80},
   402  }
   403  
   404  // merkleBlockOneBytes is the serialized bytes for a merkle block created from
   405  // block one of the block chain where the first transation matches.
   406  var merkleBlockOneBytes = []byte{
   407  	0x01, 0x00, 0x00, 0x00, // Version 1
   408  	0x6f, 0xe2, 0x8c, 0x0a, 0xb6, 0xf1, 0xb3, 0x72,
   409  	0xc1, 0xa6, 0xa2, 0x46, 0xae, 0x63, 0xf7, 0x4f,
   410  	0x93, 0x1e, 0x83, 0x65, 0xe1, 0x5a, 0x08, 0x9c,
   411  	0x68, 0xd6, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, // PrevBlock
   412  	0x98, 0x20, 0x51, 0xfd, 0x1e, 0x4b, 0xa7, 0x44,
   413  	0xbb, 0xbe, 0x68, 0x0e, 0x1f, 0xee, 0x14, 0x67,
   414  	0x7b, 0xa1, 0xa3, 0xc3, 0x54, 0x0b, 0xf7, 0xb1,
   415  	0xcd, 0xb6, 0x06, 0xe8, 0x57, 0x23, 0x3e, 0x0e, // MerkleRoot
   416  	0x61, 0xbc, 0x66, 0x49, // Timestamp
   417  	0xff, 0xff, 0x00, 0x1d, // Bits
   418  	0x01, 0xe3, 0x62, 0x99, // Nonce
   419  	0x01, 0x00, 0x00, 0x00, // TxnCount
   420  	0x01, // Num hashes
   421  	0x98, 0x20, 0x51, 0xfd, 0x1e, 0x4b, 0xa7, 0x44,
   422  	0xbb, 0xbe, 0x68, 0x0e, 0x1f, 0xee, 0x14, 0x67,
   423  	0x7b, 0xa1, 0xa3, 0xc3, 0x54, 0x0b, 0xf7, 0xb1,
   424  	0xcd, 0xb6, 0x06, 0xe8, 0x57, 0x23, 0x3e, 0x0e, // Hash
   425  	0x01, // Num flag bytes
   426  	0x80, // Flags
   427  }