github.com/dashpay/godash@v0.0.0-20160726055534-e038a21e0e3d/wire/msgnotfound_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  // TestNotFound tests the MsgNotFound API.
    19  func TestNotFound(t *testing.T) {
    20  	pver := wire.ProtocolVersion
    21  
    22  	// Ensure the command is expected value.
    23  	wantCmd := "notfound"
    24  	msg := wire.NewMsgNotFound()
    25  	if cmd := msg.Command(); cmd != wantCmd {
    26  		t.Errorf("NewMsgNotFound: wrong command - got %v want %v",
    27  			cmd, wantCmd)
    28  	}
    29  
    30  	// Ensure max payload is expected value for latest protocol version.
    31  	// Num inventory vectors (varInt) + max allowed inventory vectors.
    32  	wantPayload := uint32(1800009)
    33  	maxPayload := msg.MaxPayloadLength(pver)
    34  	if maxPayload != wantPayload {
    35  		t.Errorf("MaxPayloadLength: wrong max payload length for "+
    36  			"protocol version %d - got %v, want %v", pver,
    37  			maxPayload, wantPayload)
    38  	}
    39  
    40  	// Ensure inventory vectors are added properly.
    41  	hash := wire.ShaHash{}
    42  	iv := wire.NewInvVect(wire.InvTypeBlock, &hash)
    43  	err := msg.AddInvVect(iv)
    44  	if err != nil {
    45  		t.Errorf("AddInvVect: %v", err)
    46  	}
    47  	if msg.InvList[0] != iv {
    48  		t.Errorf("AddInvVect: wrong invvect added - got %v, want %v",
    49  			spew.Sprint(msg.InvList[0]), spew.Sprint(iv))
    50  	}
    51  
    52  	// Ensure adding more than the max allowed inventory vectors per
    53  	// message returns an error.
    54  	for i := 0; i < wire.MaxInvPerMsg; i++ {
    55  		err = msg.AddInvVect(iv)
    56  	}
    57  	if err == nil {
    58  		t.Errorf("AddInvVect: expected error on too many inventory " +
    59  			"vectors not received")
    60  	}
    61  
    62  	return
    63  }
    64  
    65  // TestNotFoundWire tests the MsgNotFound wire encode and decode for various
    66  // numbers of inventory vectors and protocol versions.
    67  func TestNotFoundWire(t *testing.T) {
    68  	// Block 203707 hash.
    69  	hashStr := "3264bc2ac36a60840790ba1d475d01367e7c723da941069e9dc"
    70  	blockHash, err := wire.NewShaHashFromStr(hashStr)
    71  	if err != nil {
    72  		t.Errorf("NewShaHashFromStr: %v", err)
    73  	}
    74  
    75  	// Transation 1 of Block 203707 hash.
    76  	hashStr = "d28a3dc7392bf00a9855ee93dd9a81eff82a2c4fe57fbd42cfe71b487accfaf0"
    77  	txHash, err := wire.NewShaHashFromStr(hashStr)
    78  	if err != nil {
    79  		t.Errorf("NewShaHashFromStr: %v", err)
    80  	}
    81  
    82  	iv := wire.NewInvVect(wire.InvTypeBlock, blockHash)
    83  	iv2 := wire.NewInvVect(wire.InvTypeTx, txHash)
    84  
    85  	// Empty notfound message.
    86  	NoInv := wire.NewMsgNotFound()
    87  	NoInvEncoded := []byte{
    88  		0x00, // Varint for number of inventory vectors
    89  	}
    90  
    91  	// NotFound message with multiple inventory vectors.
    92  	MultiInv := wire.NewMsgNotFound()
    93  	MultiInv.AddInvVect(iv)
    94  	MultiInv.AddInvVect(iv2)
    95  	MultiInvEncoded := []byte{
    96  		0x02,                   // Varint for number of inv vectors
    97  		0x02, 0x00, 0x00, 0x00, // InvTypeBlock
    98  		0xdc, 0xe9, 0x69, 0x10, 0x94, 0xda, 0x23, 0xc7,
    99  		0xe7, 0x67, 0x13, 0xd0, 0x75, 0xd4, 0xa1, 0x0b,
   100  		0x79, 0x40, 0x08, 0xa6, 0x36, 0xac, 0xc2, 0x4b,
   101  		0x26, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Block 203707 hash
   102  		0x01, 0x00, 0x00, 0x00, // InvTypeTx
   103  		0xf0, 0xfa, 0xcc, 0x7a, 0x48, 0x1b, 0xe7, 0xcf,
   104  		0x42, 0xbd, 0x7f, 0xe5, 0x4f, 0x2c, 0x2a, 0xf8,
   105  		0xef, 0x81, 0x9a, 0xdd, 0x93, 0xee, 0x55, 0x98,
   106  		0x0a, 0xf0, 0x2b, 0x39, 0xc7, 0x3d, 0x8a, 0xd2, // Tx 1 of block 203707 hash
   107  	}
   108  
   109  	tests := []struct {
   110  		in   *wire.MsgNotFound // Message to encode
   111  		out  *wire.MsgNotFound // Expected decoded message
   112  		buf  []byte            // Wire encoding
   113  		pver uint32            // Protocol version for wire encoding
   114  	}{
   115  		// Latest protocol version with no inv vectors.
   116  		{
   117  			NoInv,
   118  			NoInv,
   119  			NoInvEncoded,
   120  			wire.ProtocolVersion,
   121  		},
   122  
   123  		// Latest protocol version with multiple inv vectors.
   124  		{
   125  			MultiInv,
   126  			MultiInv,
   127  			MultiInvEncoded,
   128  			wire.ProtocolVersion,
   129  		},
   130  
   131  		// Protocol version BIP0035Version no inv vectors.
   132  		{
   133  			NoInv,
   134  			NoInv,
   135  			NoInvEncoded,
   136  			wire.BIP0035Version,
   137  		},
   138  
   139  		// Protocol version BIP0035Version with multiple inv vectors.
   140  		{
   141  			MultiInv,
   142  			MultiInv,
   143  			MultiInvEncoded,
   144  			wire.BIP0035Version,
   145  		},
   146  
   147  		// Protocol version BIP0031Version no inv vectors.
   148  		{
   149  			NoInv,
   150  			NoInv,
   151  			NoInvEncoded,
   152  			wire.BIP0031Version,
   153  		},
   154  
   155  		// Protocol version BIP0031Version with multiple inv vectors.
   156  		{
   157  			MultiInv,
   158  			MultiInv,
   159  			MultiInvEncoded,
   160  			wire.BIP0031Version,
   161  		},
   162  
   163  		// Protocol version NetAddressTimeVersion no inv vectors.
   164  		{
   165  			NoInv,
   166  			NoInv,
   167  			NoInvEncoded,
   168  			wire.NetAddressTimeVersion,
   169  		},
   170  
   171  		// Protocol version NetAddressTimeVersion with multiple inv vectors.
   172  		{
   173  			MultiInv,
   174  			MultiInv,
   175  			MultiInvEncoded,
   176  			wire.NetAddressTimeVersion,
   177  		},
   178  
   179  		// Protocol version MultipleAddressVersion no inv vectors.
   180  		{
   181  			NoInv,
   182  			NoInv,
   183  			NoInvEncoded,
   184  			wire.MultipleAddressVersion,
   185  		},
   186  
   187  		// Protocol version MultipleAddressVersion with multiple inv vectors.
   188  		{
   189  			MultiInv,
   190  			MultiInv,
   191  			MultiInvEncoded,
   192  			wire.MultipleAddressVersion,
   193  		},
   194  	}
   195  
   196  	t.Logf("Running %d tests", len(tests))
   197  	for i, test := range tests {
   198  		// Encode the message to wire format.
   199  		var buf bytes.Buffer
   200  		err := test.in.BtcEncode(&buf, test.pver)
   201  		if err != nil {
   202  			t.Errorf("BtcEncode #%d error %v", i, err)
   203  			continue
   204  		}
   205  		if !bytes.Equal(buf.Bytes(), test.buf) {
   206  			t.Errorf("BtcEncode #%d\n got: %s want: %s", i,
   207  				spew.Sdump(buf.Bytes()), spew.Sdump(test.buf))
   208  			continue
   209  		}
   210  
   211  		// Decode the message from wire format.
   212  		var msg wire.MsgNotFound
   213  		rbuf := bytes.NewReader(test.buf)
   214  		err = msg.BtcDecode(rbuf, test.pver)
   215  		if err != nil {
   216  			t.Errorf("BtcDecode #%d error %v", i, err)
   217  			continue
   218  		}
   219  		if !reflect.DeepEqual(&msg, test.out) {
   220  			t.Errorf("BtcDecode #%d\n got: %s want: %s", i,
   221  				spew.Sdump(msg), spew.Sdump(test.out))
   222  			continue
   223  		}
   224  	}
   225  }
   226  
   227  // TestNotFoundWireErrors performs negative tests against wire encode and decode
   228  // of MsgNotFound to confirm error paths work correctly.
   229  func TestNotFoundWireErrors(t *testing.T) {
   230  	pver := wire.ProtocolVersion
   231  	wireErr := &wire.MessageError{}
   232  
   233  	// Block 203707 hash.
   234  	hashStr := "3264bc2ac36a60840790ba1d475d01367e7c723da941069e9dc"
   235  	blockHash, err := wire.NewShaHashFromStr(hashStr)
   236  	if err != nil {
   237  		t.Errorf("NewShaHashFromStr: %v", err)
   238  	}
   239  
   240  	iv := wire.NewInvVect(wire.InvTypeBlock, blockHash)
   241  
   242  	// Base message used to induce errors.
   243  	baseNotFound := wire.NewMsgNotFound()
   244  	baseNotFound.AddInvVect(iv)
   245  	baseNotFoundEncoded := []byte{
   246  		0x02,                   // Varint for number of inv vectors
   247  		0x02, 0x00, 0x00, 0x00, // InvTypeBlock
   248  		0xdc, 0xe9, 0x69, 0x10, 0x94, 0xda, 0x23, 0xc7,
   249  		0xe7, 0x67, 0x13, 0xd0, 0x75, 0xd4, 0xa1, 0x0b,
   250  		0x79, 0x40, 0x08, 0xa6, 0x36, 0xac, 0xc2, 0x4b,
   251  		0x26, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Block 203707 hash
   252  	}
   253  
   254  	// Message that forces an error by having more than the max allowed inv
   255  	// vectors.
   256  	maxNotFound := wire.NewMsgNotFound()
   257  	for i := 0; i < wire.MaxInvPerMsg; i++ {
   258  		maxNotFound.AddInvVect(iv)
   259  	}
   260  	maxNotFound.InvList = append(maxNotFound.InvList, iv)
   261  	maxNotFoundEncoded := []byte{
   262  		0xfd, 0x51, 0xc3, // Varint for number of inv vectors (50001)
   263  	}
   264  
   265  	tests := []struct {
   266  		in       *wire.MsgNotFound // Value to encode
   267  		buf      []byte            // Wire encoding
   268  		pver     uint32            // Protocol version for wire encoding
   269  		max      int               // Max size of fixed buffer to induce errors
   270  		writeErr error             // Expected write error
   271  		readErr  error             // Expected read error
   272  	}{
   273  		// Force error in inventory vector count
   274  		{baseNotFound, baseNotFoundEncoded, pver, 0, io.ErrShortWrite, io.EOF},
   275  		// Force error in inventory list.
   276  		{baseNotFound, baseNotFoundEncoded, pver, 1, io.ErrShortWrite, io.EOF},
   277  		// Force error with greater than max inventory vectors.
   278  		{maxNotFound, maxNotFoundEncoded, pver, 3, wireErr, wireErr},
   279  	}
   280  
   281  	t.Logf("Running %d tests", len(tests))
   282  	for i, test := range tests {
   283  		// Encode to wire format.
   284  		w := newFixedWriter(test.max)
   285  		err := test.in.BtcEncode(w, test.pver)
   286  		if reflect.TypeOf(err) != reflect.TypeOf(test.writeErr) {
   287  			t.Errorf("BtcEncode #%d wrong error got: %v, want: %v",
   288  				i, err, test.writeErr)
   289  			continue
   290  		}
   291  
   292  		// For errors which are not of type wire.MessageError, check
   293  		// them for equality.
   294  		if _, ok := err.(*wire.MessageError); !ok {
   295  			if err != test.writeErr {
   296  				t.Errorf("BtcEncode #%d wrong error got: %v, "+
   297  					"want: %v", i, err, test.writeErr)
   298  				continue
   299  			}
   300  		}
   301  
   302  		// Decode from wire format.
   303  		var msg wire.MsgNotFound
   304  		r := newFixedReader(test.max, test.buf)
   305  		err = msg.BtcDecode(r, test.pver)
   306  		if reflect.TypeOf(err) != reflect.TypeOf(test.readErr) {
   307  			t.Errorf("BtcDecode #%d wrong error got: %v, want: %v",
   308  				i, err, test.readErr)
   309  			continue
   310  		}
   311  
   312  		// For errors which are not of type wire.MessageError, check
   313  		// them for equality.
   314  		if _, ok := err.(*wire.MessageError); !ok {
   315  			if err != test.readErr {
   316  				t.Errorf("BtcDecode #%d wrong error got: %v, "+
   317  					"want: %v", i, err, test.readErr)
   318  				continue
   319  			}
   320  		}
   321  	}
   322  }