github.com/BlockABC/godash@v0.0.0-20191112120524-f4aa3a32c566/wire/msggetblocks_test.go (about)

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