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