msgmerkleblock_test.go raw

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