github.com/btcsuite/btcd@v0.24.0/wire/blockheader_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  	"reflect"
    10  	"testing"
    11  	"time"
    12  
    13  	"github.com/davecgh/go-spew/spew"
    14  )
    15  
    16  // TestBlockHeader tests the BlockHeader API.
    17  func TestBlockHeader(t *testing.T) {
    18  	nonce64, err := RandomUint64()
    19  	if err != nil {
    20  		t.Errorf("RandomUint64: Error generating nonce: %v", err)
    21  	}
    22  	nonce := uint32(nonce64)
    23  
    24  	hash := mainNetGenesisHash
    25  	merkleHash := mainNetGenesisMerkleRoot
    26  	bits := uint32(0x1d00ffff)
    27  	bh := NewBlockHeader(1, &hash, &merkleHash, bits, nonce)
    28  
    29  	// Ensure we get the same data back out.
    30  	if !bh.PrevBlock.IsEqual(&hash) {
    31  		t.Errorf("NewBlockHeader: wrong prev hash - got %v, want %v",
    32  			spew.Sprint(bh.PrevBlock), spew.Sprint(hash))
    33  	}
    34  	if !bh.MerkleRoot.IsEqual(&merkleHash) {
    35  		t.Errorf("NewBlockHeader: wrong merkle root - got %v, want %v",
    36  			spew.Sprint(bh.MerkleRoot), spew.Sprint(merkleHash))
    37  	}
    38  	if bh.Bits != bits {
    39  		t.Errorf("NewBlockHeader: wrong bits - got %v, want %v",
    40  			bh.Bits, bits)
    41  	}
    42  	if bh.Nonce != nonce {
    43  		t.Errorf("NewBlockHeader: wrong nonce - got %v, want %v",
    44  			bh.Nonce, nonce)
    45  	}
    46  }
    47  
    48  // TestBlockHeaderWire tests the BlockHeader wire encode and decode for various
    49  // protocol versions.
    50  func TestBlockHeaderWire(t *testing.T) {
    51  	nonce := uint32(123123) // 0x1e0f3
    52  	pver := uint32(70001)
    53  
    54  	// baseBlockHdr is used in the various tests as a baseline BlockHeader.
    55  	bits := uint32(0x1d00ffff)
    56  	baseBlockHdr := &BlockHeader{
    57  		Version:    1,
    58  		PrevBlock:  mainNetGenesisHash,
    59  		MerkleRoot: mainNetGenesisMerkleRoot,
    60  		Timestamp:  time.Unix(0x495fab29, 0), // 2009-01-03 12:15:05 -0600 CST
    61  		Bits:       bits,
    62  		Nonce:      nonce,
    63  	}
    64  
    65  	// baseBlockHdrEncoded is the wire encoded bytes of baseBlockHdr.
    66  	baseBlockHdrEncoded := []byte{
    67  		0x01, 0x00, 0x00, 0x00, // Version 1
    68  		0x6f, 0xe2, 0x8c, 0x0a, 0xb6, 0xf1, 0xb3, 0x72,
    69  		0xc1, 0xa6, 0xa2, 0x46, 0xae, 0x63, 0xf7, 0x4f,
    70  		0x93, 0x1e, 0x83, 0x65, 0xe1, 0x5a, 0x08, 0x9c,
    71  		0x68, 0xd6, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, // PrevBlock
    72  		0x3b, 0xa3, 0xed, 0xfd, 0x7a, 0x7b, 0x12, 0xb2,
    73  		0x7a, 0xc7, 0x2c, 0x3e, 0x67, 0x76, 0x8f, 0x61,
    74  		0x7f, 0xc8, 0x1b, 0xc3, 0x88, 0x8a, 0x51, 0x32,
    75  		0x3a, 0x9f, 0xb8, 0xaa, 0x4b, 0x1e, 0x5e, 0x4a, // MerkleRoot
    76  		0x29, 0xab, 0x5f, 0x49, // Timestamp
    77  		0xff, 0xff, 0x00, 0x1d, // Bits
    78  		0xf3, 0xe0, 0x01, 0x00, // Nonce
    79  	}
    80  
    81  	tests := []struct {
    82  		in   *BlockHeader    // Data to encode
    83  		out  *BlockHeader    // Expected decoded data
    84  		buf  []byte          // Wire encoding
    85  		pver uint32          // Protocol version for wire encoding
    86  		enc  MessageEncoding // Message encoding variant to use
    87  	}{
    88  		// Latest protocol version.
    89  		{
    90  			baseBlockHdr,
    91  			baseBlockHdr,
    92  			baseBlockHdrEncoded,
    93  			ProtocolVersion,
    94  			BaseEncoding,
    95  		},
    96  
    97  		// Protocol version BIP0035Version.
    98  		{
    99  			baseBlockHdr,
   100  			baseBlockHdr,
   101  			baseBlockHdrEncoded,
   102  			BIP0035Version,
   103  			BaseEncoding,
   104  		},
   105  
   106  		// Protocol version BIP0031Version.
   107  		{
   108  			baseBlockHdr,
   109  			baseBlockHdr,
   110  			baseBlockHdrEncoded,
   111  			BIP0031Version,
   112  			BaseEncoding,
   113  		},
   114  
   115  		// Protocol version NetAddressTimeVersion.
   116  		{
   117  			baseBlockHdr,
   118  			baseBlockHdr,
   119  			baseBlockHdrEncoded,
   120  			NetAddressTimeVersion,
   121  			BaseEncoding,
   122  		},
   123  
   124  		// Protocol version MultipleAddressVersion.
   125  		{
   126  			baseBlockHdr,
   127  			baseBlockHdr,
   128  			baseBlockHdrEncoded,
   129  			MultipleAddressVersion,
   130  			BaseEncoding,
   131  		},
   132  	}
   133  
   134  	t.Logf("Running %d tests", len(tests))
   135  	for i, test := range tests {
   136  		// Encode to wire format.
   137  		var buf bytes.Buffer
   138  		err := writeBlockHeader(&buf, test.pver, test.in)
   139  		if err != nil {
   140  			t.Errorf("writeBlockHeader #%d error %v", i, err)
   141  			continue
   142  		}
   143  		if !bytes.Equal(buf.Bytes(), test.buf) {
   144  			t.Errorf("writeBlockHeader #%d\n got: %s want: %s", i,
   145  				spew.Sdump(buf.Bytes()), spew.Sdump(test.buf))
   146  			continue
   147  		}
   148  
   149  		buf.Reset()
   150  		err = test.in.BtcEncode(&buf, pver, 0)
   151  		if err != nil {
   152  			t.Errorf("BtcEncode #%d error %v", i, err)
   153  			continue
   154  		}
   155  		if !bytes.Equal(buf.Bytes(), test.buf) {
   156  			t.Errorf("BtcEncode #%d\n got: %s want: %s", i,
   157  				spew.Sdump(buf.Bytes()), spew.Sdump(test.buf))
   158  			continue
   159  		}
   160  
   161  		// Decode the block header from wire format.
   162  		var bh BlockHeader
   163  		rbuf := bytes.NewReader(test.buf)
   164  		err = readBlockHeader(rbuf, test.pver, &bh)
   165  		if err != nil {
   166  			t.Errorf("readBlockHeader #%d error %v", i, err)
   167  			continue
   168  		}
   169  		if !reflect.DeepEqual(&bh, test.out) {
   170  			t.Errorf("readBlockHeader #%d\n got: %s want: %s", i,
   171  				spew.Sdump(&bh), spew.Sdump(test.out))
   172  			continue
   173  		}
   174  
   175  		rbuf = bytes.NewReader(test.buf)
   176  		err = bh.BtcDecode(rbuf, pver, test.enc)
   177  		if err != nil {
   178  			t.Errorf("BtcDecode #%d error %v", i, err)
   179  			continue
   180  		}
   181  		if !reflect.DeepEqual(&bh, test.out) {
   182  			t.Errorf("BtcDecode #%d\n got: %s want: %s", i,
   183  				spew.Sdump(&bh), spew.Sdump(test.out))
   184  			continue
   185  		}
   186  	}
   187  }
   188  
   189  // TestBlockHeaderSerialize tests BlockHeader serialize and deserialize.
   190  func TestBlockHeaderSerialize(t *testing.T) {
   191  	nonce := uint32(123123) // 0x1e0f3
   192  
   193  	// baseBlockHdr is used in the various tests as a baseline BlockHeader.
   194  	bits := uint32(0x1d00ffff)
   195  	baseBlockHdr := &BlockHeader{
   196  		Version:    1,
   197  		PrevBlock:  mainNetGenesisHash,
   198  		MerkleRoot: mainNetGenesisMerkleRoot,
   199  		Timestamp:  time.Unix(0x495fab29, 0), // 2009-01-03 12:15:05 -0600 CST
   200  		Bits:       bits,
   201  		Nonce:      nonce,
   202  	}
   203  
   204  	// baseBlockHdrEncoded is the wire encoded bytes of baseBlockHdr.
   205  	baseBlockHdrEncoded := []byte{
   206  		0x01, 0x00, 0x00, 0x00, // Version 1
   207  		0x6f, 0xe2, 0x8c, 0x0a, 0xb6, 0xf1, 0xb3, 0x72,
   208  		0xc1, 0xa6, 0xa2, 0x46, 0xae, 0x63, 0xf7, 0x4f,
   209  		0x93, 0x1e, 0x83, 0x65, 0xe1, 0x5a, 0x08, 0x9c,
   210  		0x68, 0xd6, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, // PrevBlock
   211  		0x3b, 0xa3, 0xed, 0xfd, 0x7a, 0x7b, 0x12, 0xb2,
   212  		0x7a, 0xc7, 0x2c, 0x3e, 0x67, 0x76, 0x8f, 0x61,
   213  		0x7f, 0xc8, 0x1b, 0xc3, 0x88, 0x8a, 0x51, 0x32,
   214  		0x3a, 0x9f, 0xb8, 0xaa, 0x4b, 0x1e, 0x5e, 0x4a, // MerkleRoot
   215  		0x29, 0xab, 0x5f, 0x49, // Timestamp
   216  		0xff, 0xff, 0x00, 0x1d, // Bits
   217  		0xf3, 0xe0, 0x01, 0x00, // Nonce
   218  	}
   219  
   220  	tests := []struct {
   221  		in  *BlockHeader // Data to encode
   222  		out *BlockHeader // Expected decoded data
   223  		buf []byte       // Serialized data
   224  	}{
   225  		{
   226  			baseBlockHdr,
   227  			baseBlockHdr,
   228  			baseBlockHdrEncoded,
   229  		},
   230  	}
   231  
   232  	t.Logf("Running %d tests", len(tests))
   233  	for i, test := range tests {
   234  		// Serialize the block header.
   235  		var buf bytes.Buffer
   236  		err := test.in.Serialize(&buf)
   237  		if err != nil {
   238  			t.Errorf("Serialize #%d error %v", i, err)
   239  			continue
   240  		}
   241  		if !bytes.Equal(buf.Bytes(), test.buf) {
   242  			t.Errorf("Serialize #%d\n got: %s want: %s", i,
   243  				spew.Sdump(buf.Bytes()), spew.Sdump(test.buf))
   244  			continue
   245  		}
   246  
   247  		// Deserialize the block header.
   248  		var bh BlockHeader
   249  		rbuf := bytes.NewReader(test.buf)
   250  		err = bh.Deserialize(rbuf)
   251  		if err != nil {
   252  			t.Errorf("Deserialize #%d error %v", i, err)
   253  			continue
   254  		}
   255  		if !reflect.DeepEqual(&bh, test.out) {
   256  			t.Errorf("Deserialize #%d\n got: %s want: %s", i,
   257  				spew.Sdump(&bh), spew.Sdump(test.out))
   258  			continue
   259  		}
   260  	}
   261  }