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