github.com/lbryio/lbcd@v0.22.119/wire/msggetblocks_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  	"io"
    10  	"reflect"
    11  	"testing"
    12  
    13  	"github.com/davecgh/go-spew/spew"
    14  	"github.com/lbryio/lbcd/chaincfg/chainhash"
    15  )
    16  
    17  // TestGetBlocks tests the MsgGetBlocks API.
    18  func TestGetBlocks(t *testing.T) {
    19  	pver := ProtocolVersion
    20  
    21  	// Block 99500 hash.
    22  	hashStr := "000000000002e7ad7b9eef9479e4aabc65cb831269cc20d2632c13684406dee0"
    23  	locatorHash, err := chainhash.NewHashFromStr(hashStr)
    24  	if err != nil {
    25  		t.Errorf("NewHashFromStr: %v", err)
    26  	}
    27  
    28  	// Block 100000 hash.
    29  	hashStr = "3ba27aa200b1cecaad478d2b00432346c3f1f3986da1afd33e506"
    30  	hashStop, err := chainhash.NewHashFromStr(hashStr)
    31  	if err != nil {
    32  		t.Errorf("NewHashFromStr: %v", err)
    33  	}
    34  
    35  	// Ensure we get the same data back out.
    36  	msg := NewMsgGetBlocks(hashStop)
    37  	if !msg.HashStop.IsEqual(hashStop) {
    38  		t.Errorf("NewMsgGetBlocks: wrong stop hash - got %v, want %v",
    39  			msg.HashStop, hashStop)
    40  	}
    41  
    42  	// Ensure the command is expected value.
    43  	wantCmd := "getblocks"
    44  	if cmd := msg.Command(); cmd != wantCmd {
    45  		t.Errorf("NewMsgGetBlocks: wrong command - got %v want %v",
    46  			cmd, wantCmd)
    47  	}
    48  
    49  	// Ensure max payload is expected value for latest protocol version.
    50  	// Protocol version 4 bytes + num hashes (varInt) + max block locator
    51  	// hashes + hash stop.
    52  	wantPayload := uint32(16045)
    53  	maxPayload := msg.MaxPayloadLength(pver)
    54  	if maxPayload != wantPayload {
    55  		t.Errorf("MaxPayloadLength: wrong max payload length for "+
    56  			"protocol version %d - got %v, want %v", pver,
    57  			maxPayload, wantPayload)
    58  	}
    59  
    60  	// Ensure block locator hashes are added properly.
    61  	err = msg.AddBlockLocatorHash(locatorHash)
    62  	if err != nil {
    63  		t.Errorf("AddBlockLocatorHash: %v", err)
    64  	}
    65  	if msg.BlockLocatorHashes[0] != locatorHash {
    66  		t.Errorf("AddBlockLocatorHash: wrong block locator added - "+
    67  			"got %v, want %v",
    68  			spew.Sprint(msg.BlockLocatorHashes[0]),
    69  			spew.Sprint(locatorHash))
    70  	}
    71  
    72  	// Ensure adding more than the max allowed block locator hashes per
    73  	// message returns an error.
    74  	for i := 0; i < MaxBlockLocatorsPerMsg; i++ {
    75  		err = msg.AddBlockLocatorHash(locatorHash)
    76  	}
    77  	if err == nil {
    78  		t.Errorf("AddBlockLocatorHash: expected error on too many " +
    79  			"block locator hashes not received")
    80  	}
    81  }
    82  
    83  // TestGetBlocksWire tests the MsgGetBlocks wire encode and decode for various
    84  // numbers of block locator hashes and protocol versions.
    85  func TestGetBlocksWire(t *testing.T) {
    86  	// Set protocol inside getblocks message.
    87  	pver := uint32(60002)
    88  
    89  	// Block 99499 hash.
    90  	hashStr := "2710f40c87ec93d010a6fd95f42c59a2cbacc60b18cf6b7957535"
    91  	hashLocator, err := chainhash.NewHashFromStr(hashStr)
    92  	if err != nil {
    93  		t.Errorf("NewHashFromStr: %v", err)
    94  	}
    95  
    96  	// Block 99500 hash.
    97  	hashStr = "2e7ad7b9eef9479e4aabc65cb831269cc20d2632c13684406dee0"
    98  	hashLocator2, err := chainhash.NewHashFromStr(hashStr)
    99  	if err != nil {
   100  		t.Errorf("NewHashFromStr: %v", err)
   101  	}
   102  
   103  	// Block 100000 hash.
   104  	hashStr = "3ba27aa200b1cecaad478d2b00432346c3f1f3986da1afd33e506"
   105  	hashStop, err := chainhash.NewHashFromStr(hashStr)
   106  	if err != nil {
   107  		t.Errorf("NewHashFromStr: %v", err)
   108  	}
   109  
   110  	// MsgGetBlocks message with no block locators or stop hash.
   111  	noLocators := NewMsgGetBlocks(&chainhash.Hash{})
   112  	noLocators.ProtocolVersion = pver
   113  	noLocatorsEncoded := []byte{
   114  		0x62, 0xea, 0x00, 0x00, // Protocol version 60002
   115  		0x00, // Varint for number of block locator hashes
   116  		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   117  		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   118  		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   119  		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Hash stop
   120  	}
   121  
   122  	// MsgGetBlocks message with multiple block locators and a stop hash.
   123  	multiLocators := NewMsgGetBlocks(hashStop)
   124  	multiLocators.AddBlockLocatorHash(hashLocator2)
   125  	multiLocators.AddBlockLocatorHash(hashLocator)
   126  	multiLocators.ProtocolVersion = pver
   127  	multiLocatorsEncoded := []byte{
   128  		0x62, 0xea, 0x00, 0x00, // Protocol version 60002
   129  		0x02, // Varint for number of block locator hashes
   130  		0xe0, 0xde, 0x06, 0x44, 0x68, 0x13, 0x2c, 0x63,
   131  		0xd2, 0x20, 0xcc, 0x69, 0x12, 0x83, 0xcb, 0x65,
   132  		0xbc, 0xaa, 0xe4, 0x79, 0x94, 0xef, 0x9e, 0x7b,
   133  		0xad, 0xe7, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, // Block 99500 hash
   134  		0x35, 0x75, 0x95, 0xb7, 0xf6, 0x8c, 0xb1, 0x60,
   135  		0xcc, 0xba, 0x2c, 0x9a, 0xc5, 0x42, 0x5f, 0xd9,
   136  		0x6f, 0x0a, 0x01, 0x3d, 0xc9, 0x7e, 0xc8, 0x40,
   137  		0x0f, 0x71, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, // Block 99499 hash
   138  		0x06, 0xe5, 0x33, 0xfd, 0x1a, 0xda, 0x86, 0x39,
   139  		0x1f, 0x3f, 0x6c, 0x34, 0x32, 0x04, 0xb0, 0xd2,
   140  		0x78, 0xd4, 0xaa, 0xec, 0x1c, 0x0b, 0x20, 0xaa,
   141  		0x27, 0xba, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, // Hash stop
   142  	}
   143  
   144  	tests := []struct {
   145  		in   *MsgGetBlocks   // Message to encode
   146  		out  *MsgGetBlocks   // Expected decoded message
   147  		buf  []byte          // Wire encoding
   148  		pver uint32          // Protocol version for wire encoding
   149  		enc  MessageEncoding // Message encoding format
   150  	}{
   151  		// Latest protocol version with no block locators.
   152  		{
   153  			noLocators,
   154  			noLocators,
   155  			noLocatorsEncoded,
   156  			ProtocolVersion,
   157  			BaseEncoding,
   158  		},
   159  
   160  		// Latest protocol version with multiple block locators.
   161  		{
   162  			multiLocators,
   163  			multiLocators,
   164  			multiLocatorsEncoded,
   165  			ProtocolVersion,
   166  			BaseEncoding,
   167  		},
   168  
   169  		// Protocol version BIP0035Version with no block locators.
   170  		{
   171  			noLocators,
   172  			noLocators,
   173  			noLocatorsEncoded,
   174  			BIP0035Version,
   175  			BaseEncoding,
   176  		},
   177  
   178  		// Protocol version BIP0035Version with multiple block locators.
   179  		{
   180  			multiLocators,
   181  			multiLocators,
   182  			multiLocatorsEncoded,
   183  			BIP0035Version,
   184  			BaseEncoding,
   185  		},
   186  
   187  		// Protocol version BIP0031Version with no block locators.
   188  		{
   189  			noLocators,
   190  			noLocators,
   191  			noLocatorsEncoded,
   192  			BIP0031Version,
   193  			BaseEncoding,
   194  		},
   195  
   196  		// Protocol version BIP0031Versionwith multiple block locators.
   197  		{
   198  			multiLocators,
   199  			multiLocators,
   200  			multiLocatorsEncoded,
   201  			BIP0031Version,
   202  			BaseEncoding,
   203  		},
   204  
   205  		// Protocol version NetAddressTimeVersion with no block locators.
   206  		{
   207  			noLocators,
   208  			noLocators,
   209  			noLocatorsEncoded,
   210  			NetAddressTimeVersion,
   211  			BaseEncoding,
   212  		},
   213  
   214  		// Protocol version NetAddressTimeVersion multiple block locators.
   215  		{
   216  			multiLocators,
   217  			multiLocators,
   218  			multiLocatorsEncoded,
   219  			NetAddressTimeVersion,
   220  			BaseEncoding,
   221  		},
   222  
   223  		// Protocol version MultipleAddressVersion with no block locators.
   224  		{
   225  			noLocators,
   226  			noLocators,
   227  			noLocatorsEncoded,
   228  			MultipleAddressVersion,
   229  			BaseEncoding,
   230  		},
   231  
   232  		// Protocol version MultipleAddressVersion multiple block locators.
   233  		{
   234  			multiLocators,
   235  			multiLocators,
   236  			multiLocatorsEncoded,
   237  			MultipleAddressVersion,
   238  			BaseEncoding,
   239  		},
   240  	}
   241  
   242  	t.Logf("Running %d tests", len(tests))
   243  	for i, test := range tests {
   244  		// Encode the message to wire format.
   245  		var buf bytes.Buffer
   246  		err := test.in.BtcEncode(&buf, test.pver, test.enc)
   247  		if err != nil {
   248  			t.Errorf("BtcEncode #%d error %v", i, err)
   249  			continue
   250  		}
   251  		if !bytes.Equal(buf.Bytes(), test.buf) {
   252  			t.Errorf("BtcEncode #%d\n got: %s want: %s", i,
   253  				spew.Sdump(buf.Bytes()), spew.Sdump(test.buf))
   254  			continue
   255  		}
   256  
   257  		// Decode the message from wire format.
   258  		var msg MsgGetBlocks
   259  		rbuf := bytes.NewReader(test.buf)
   260  		err = msg.BtcDecode(rbuf, test.pver, test.enc)
   261  		if err != nil {
   262  			t.Errorf("BtcDecode #%d error %v", i, err)
   263  			continue
   264  		}
   265  		if !reflect.DeepEqual(&msg, test.out) {
   266  			t.Errorf("BtcDecode #%d\n got: %s want: %s", i,
   267  				spew.Sdump(&msg), spew.Sdump(test.out))
   268  			continue
   269  		}
   270  	}
   271  }
   272  
   273  // TestGetBlocksWireErrors performs negative tests against wire encode and
   274  // decode of MsgGetBlocks to confirm error paths work correctly.
   275  func TestGetBlocksWireErrors(t *testing.T) {
   276  	// Set protocol inside getheaders message.  Use protocol version 60002
   277  	// specifically here instead of the latest because the test data is
   278  	// using bytes encoded with that protocol version.
   279  	pver := uint32(60002)
   280  	wireErr := &MessageError{}
   281  
   282  	// Block 99499 hash.
   283  	hashStr := "2710f40c87ec93d010a6fd95f42c59a2cbacc60b18cf6b7957535"
   284  	hashLocator, err := chainhash.NewHashFromStr(hashStr)
   285  	if err != nil {
   286  		t.Errorf("NewHashFromStr: %v", err)
   287  	}
   288  
   289  	// Block 99500 hash.
   290  	hashStr = "2e7ad7b9eef9479e4aabc65cb831269cc20d2632c13684406dee0"
   291  	hashLocator2, err := chainhash.NewHashFromStr(hashStr)
   292  	if err != nil {
   293  		t.Errorf("NewHashFromStr: %v", err)
   294  	}
   295  
   296  	// Block 100000 hash.
   297  	hashStr = "3ba27aa200b1cecaad478d2b00432346c3f1f3986da1afd33e506"
   298  	hashStop, err := chainhash.NewHashFromStr(hashStr)
   299  	if err != nil {
   300  		t.Errorf("NewHashFromStr: %v", err)
   301  	}
   302  
   303  	// MsgGetBlocks message with multiple block locators and a stop hash.
   304  	baseGetBlocks := NewMsgGetBlocks(hashStop)
   305  	baseGetBlocks.ProtocolVersion = pver
   306  	baseGetBlocks.AddBlockLocatorHash(hashLocator2)
   307  	baseGetBlocks.AddBlockLocatorHash(hashLocator)
   308  	baseGetBlocksEncoded := []byte{
   309  		0x62, 0xea, 0x00, 0x00, // Protocol version 60002
   310  		0x02, // Varint for number of block locator hashes
   311  		0xe0, 0xde, 0x06, 0x44, 0x68, 0x13, 0x2c, 0x63,
   312  		0xd2, 0x20, 0xcc, 0x69, 0x12, 0x83, 0xcb, 0x65,
   313  		0xbc, 0xaa, 0xe4, 0x79, 0x94, 0xef, 0x9e, 0x7b,
   314  		0xad, 0xe7, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, // Block 99500 hash
   315  		0x35, 0x75, 0x95, 0xb7, 0xf6, 0x8c, 0xb1, 0x60,
   316  		0xcc, 0xba, 0x2c, 0x9a, 0xc5, 0x42, 0x5f, 0xd9,
   317  		0x6f, 0x0a, 0x01, 0x3d, 0xc9, 0x7e, 0xc8, 0x40,
   318  		0x0f, 0x71, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, // Block 99499 hash
   319  		0x06, 0xe5, 0x33, 0xfd, 0x1a, 0xda, 0x86, 0x39,
   320  		0x1f, 0x3f, 0x6c, 0x34, 0x32, 0x04, 0xb0, 0xd2,
   321  		0x78, 0xd4, 0xaa, 0xec, 0x1c, 0x0b, 0x20, 0xaa,
   322  		0x27, 0xba, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, // Hash stop
   323  	}
   324  
   325  	// Message that forces an error by having more than the max allowed
   326  	// block locator hashes.
   327  	maxGetBlocks := NewMsgGetBlocks(hashStop)
   328  	for i := 0; i < MaxBlockLocatorsPerMsg; i++ {
   329  		maxGetBlocks.AddBlockLocatorHash(&mainNetGenesisHash)
   330  	}
   331  	maxGetBlocks.BlockLocatorHashes = append(maxGetBlocks.BlockLocatorHashes,
   332  		&mainNetGenesisHash)
   333  	maxGetBlocksEncoded := []byte{
   334  		0x62, 0xea, 0x00, 0x00, // Protocol version 60002
   335  		0xfd, 0xf5, 0x01, // Varint for number of block loc hashes (501)
   336  	}
   337  
   338  	tests := []struct {
   339  		in       *MsgGetBlocks   // Value to encode
   340  		buf      []byte          // Wire encoding
   341  		pver     uint32          // Protocol version for wire encoding
   342  		enc      MessageEncoding // Message encoding format
   343  		max      int             // Max size of fixed buffer to induce errors
   344  		writeErr error           // Expected write error
   345  		readErr  error           // Expected read error
   346  	}{
   347  		// Force error in protocol version.
   348  		{baseGetBlocks, baseGetBlocksEncoded, pver, BaseEncoding, 0, io.ErrShortWrite, io.EOF},
   349  		// Force error in block locator hash count.
   350  		{baseGetBlocks, baseGetBlocksEncoded, pver, BaseEncoding, 4, io.ErrShortWrite, io.EOF},
   351  		// Force error in block locator hashes.
   352  		{baseGetBlocks, baseGetBlocksEncoded, pver, BaseEncoding, 5, io.ErrShortWrite, io.EOF},
   353  		// Force error in stop hash.
   354  		{baseGetBlocks, baseGetBlocksEncoded, pver, BaseEncoding, 69, io.ErrShortWrite, io.EOF},
   355  		// Force error with greater than max block locator hashes.
   356  		{maxGetBlocks, maxGetBlocksEncoded, pver, BaseEncoding, 7, wireErr, wireErr},
   357  	}
   358  
   359  	t.Logf("Running %d tests", len(tests))
   360  	for i, test := range tests {
   361  		// Encode to wire format.
   362  		w := newFixedWriter(test.max)
   363  		err := test.in.BtcEncode(w, test.pver, test.enc)
   364  		if reflect.TypeOf(err) != reflect.TypeOf(test.writeErr) {
   365  			t.Errorf("BtcEncode #%d wrong error got: %v, want: %v",
   366  				i, err, test.writeErr)
   367  			continue
   368  		}
   369  
   370  		// For errors which are not of type MessageError, check them for
   371  		// equality.
   372  		if _, ok := err.(*MessageError); !ok {
   373  			if err != test.writeErr {
   374  				t.Errorf("BtcEncode #%d wrong error got: %v, "+
   375  					"want: %v", i, err, test.writeErr)
   376  				continue
   377  			}
   378  		}
   379  
   380  		// Decode from wire format.
   381  		var msg MsgGetBlocks
   382  		r := newFixedReader(test.max, test.buf)
   383  		err = msg.BtcDecode(r, test.pver, test.enc)
   384  		if reflect.TypeOf(err) != reflect.TypeOf(test.readErr) {
   385  			t.Errorf("BtcDecode #%d wrong error got: %v, want: %v",
   386  				i, err, test.readErr)
   387  			continue
   388  		}
   389  
   390  		// For errors which are not of type MessageError, check them for
   391  		// equality.
   392  		if _, ok := err.(*MessageError); !ok {
   393  			if err != test.readErr {
   394  				t.Errorf("BtcDecode #%d wrong error got: %v, "+
   395  					"want: %v", i, err, test.readErr)
   396  				continue
   397  			}
   398  		}
   399  	}
   400  }