github.com/BlockABC/godash@v0.0.0-20191112120524-f4aa3a32c566/wire/msgpong_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  // TestPongLatest tests the MsgPong API against the latest protocol version.
    19  func TestPongLatest(t *testing.T) {
    20  	pver := wire.ProtocolVersion
    21  
    22  	nonce, err := wire.RandomUint64()
    23  	if err != nil {
    24  		t.Errorf("RandomUint64: error generating nonce: %v", err)
    25  	}
    26  	msg := wire.NewMsgPong(nonce)
    27  	if msg.Nonce != nonce {
    28  		t.Errorf("NewMsgPong: wrong nonce - got %v, want %v",
    29  			msg.Nonce, nonce)
    30  	}
    31  
    32  	// Ensure the command is expected value.
    33  	wantCmd := "pong"
    34  	if cmd := msg.Command(); cmd != wantCmd {
    35  		t.Errorf("NewMsgPong: wrong command - got %v want %v",
    36  			cmd, wantCmd)
    37  	}
    38  
    39  	// Ensure max payload is expected value for latest protocol version.
    40  	wantPayload := uint32(8)
    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  	// Test encode with latest protocol version.
    49  	var buf bytes.Buffer
    50  	err = msg.BtcEncode(&buf, pver)
    51  	if err != nil {
    52  		t.Errorf("encode of MsgPong failed %v err <%v>", msg, err)
    53  	}
    54  
    55  	// Test decode with latest protocol version.
    56  	readmsg := wire.NewMsgPong(0)
    57  	err = readmsg.BtcDecode(&buf, pver)
    58  	if err != nil {
    59  		t.Errorf("decode of MsgPong failed [%v] err <%v>", buf, err)
    60  	}
    61  
    62  	// Ensure nonce is the same.
    63  	if msg.Nonce != readmsg.Nonce {
    64  		t.Errorf("Should get same nonce for protocol version %d", pver)
    65  	}
    66  
    67  	return
    68  }
    69  
    70  // TestPongBIP0031 tests the MsgPong API against the protocol version
    71  // BIP0031Version.
    72  func TestPongBIP0031(t *testing.T) {
    73  	// Use the protocol version just prior to BIP0031Version changes.
    74  	pver := wire.BIP0031Version
    75  
    76  	nonce, err := wire.RandomUint64()
    77  	if err != nil {
    78  		t.Errorf("Error generating nonce: %v", err)
    79  	}
    80  	msg := wire.NewMsgPong(nonce)
    81  	if msg.Nonce != nonce {
    82  		t.Errorf("Should get same nonce back out.")
    83  	}
    84  
    85  	// Ensure max payload is expected value for old protocol version.
    86  	size := msg.MaxPayloadLength(pver)
    87  	if size != 0 {
    88  		t.Errorf("Max length should be 0 for pong protocol version %d.",
    89  			pver)
    90  	}
    91  
    92  	// Test encode with old protocol version.
    93  	var buf bytes.Buffer
    94  	err = msg.BtcEncode(&buf, pver)
    95  	if err == nil {
    96  		t.Errorf("encode of MsgPong succeeded when it shouldn't have %v",
    97  			msg)
    98  	}
    99  
   100  	// Test decode with old protocol version.
   101  	readmsg := wire.NewMsgPong(0)
   102  	err = readmsg.BtcDecode(&buf, pver)
   103  	if err == nil {
   104  		t.Errorf("decode of MsgPong succeeded when it shouldn't have %v",
   105  			spew.Sdump(buf))
   106  	}
   107  
   108  	// Since this protocol version doesn't support pong, make sure the
   109  	// nonce didn't get encoded and decoded back out.
   110  	if msg.Nonce == readmsg.Nonce {
   111  		t.Errorf("Should not get same nonce for protocol version %d", pver)
   112  	}
   113  
   114  	return
   115  }
   116  
   117  // TestPongCrossProtocol tests the MsgPong API when encoding with the latest
   118  // protocol version and decoding with BIP0031Version.
   119  func TestPongCrossProtocol(t *testing.T) {
   120  	nonce, err := wire.RandomUint64()
   121  	if err != nil {
   122  		t.Errorf("Error generating nonce: %v", err)
   123  	}
   124  	msg := wire.NewMsgPong(nonce)
   125  	if msg.Nonce != nonce {
   126  		t.Errorf("Should get same nonce back out.")
   127  	}
   128  
   129  	// Encode with latest protocol version.
   130  	var buf bytes.Buffer
   131  	err = msg.BtcEncode(&buf, wire.ProtocolVersion)
   132  	if err != nil {
   133  		t.Errorf("encode of MsgPong failed %v err <%v>", msg, err)
   134  	}
   135  
   136  	// Decode with old protocol version.
   137  	readmsg := wire.NewMsgPong(0)
   138  	err = readmsg.BtcDecode(&buf, wire.BIP0031Version)
   139  	if err == nil {
   140  		t.Errorf("encode of MsgPong succeeded when it shouldn't have %v",
   141  			msg)
   142  	}
   143  
   144  	// Since one of the protocol versions doesn't support the pong message,
   145  	// make sure the nonce didn't get encoded and decoded back out.
   146  	if msg.Nonce == readmsg.Nonce {
   147  		t.Error("Should not get same nonce for cross protocol")
   148  	}
   149  }
   150  
   151  // TestPongWire tests the MsgPong wire encode and decode for various protocol
   152  // versions.
   153  func TestPongWire(t *testing.T) {
   154  	tests := []struct {
   155  		in   wire.MsgPong // Message to encode
   156  		out  wire.MsgPong // Expected decoded message
   157  		buf  []byte       // Wire encoding
   158  		pver uint32       // Protocol version for wire encoding
   159  	}{
   160  		// Latest protocol version.
   161  		{
   162  			wire.MsgPong{Nonce: 123123}, // 0x1e0f3
   163  			wire.MsgPong{Nonce: 123123}, // 0x1e0f3
   164  			[]byte{0xf3, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00},
   165  			wire.ProtocolVersion,
   166  		},
   167  
   168  		// Protocol version BIP0031Version+1
   169  		{
   170  			wire.MsgPong{Nonce: 456456}, // 0x6f708
   171  			wire.MsgPong{Nonce: 456456}, // 0x6f708
   172  			[]byte{0x08, 0xf7, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00},
   173  			wire.BIP0031Version + 1,
   174  		},
   175  	}
   176  
   177  	t.Logf("Running %d tests", len(tests))
   178  	for i, test := range tests {
   179  		// Encode the message to wire format.
   180  		var buf bytes.Buffer
   181  		err := test.in.BtcEncode(&buf, test.pver)
   182  		if err != nil {
   183  			t.Errorf("BtcEncode #%d error %v", i, err)
   184  			continue
   185  		}
   186  		if !bytes.Equal(buf.Bytes(), test.buf) {
   187  			t.Errorf("BtcEncode #%d\n got: %s want: %s", i,
   188  				spew.Sdump(buf.Bytes()), spew.Sdump(test.buf))
   189  			continue
   190  		}
   191  
   192  		// Decode the message from wire format.
   193  		var msg wire.MsgPong
   194  		rbuf := bytes.NewReader(test.buf)
   195  		err = msg.BtcDecode(rbuf, test.pver)
   196  		if err != nil {
   197  			t.Errorf("BtcDecode #%d error %v", i, err)
   198  			continue
   199  		}
   200  		if !reflect.DeepEqual(msg, test.out) {
   201  			t.Errorf("BtcDecode #%d\n got: %s want: %s", i,
   202  				spew.Sdump(msg), spew.Sdump(test.out))
   203  			continue
   204  		}
   205  	}
   206  }
   207  
   208  // TestPongWireErrors performs negative tests against wire encode and decode
   209  // of MsgPong to confirm error paths work correctly.
   210  func TestPongWireErrors(t *testing.T) {
   211  	pver := wire.ProtocolVersion
   212  	pverNoPong := wire.BIP0031Version
   213  	wireErr := &wire.MessageError{}
   214  
   215  	basePong := wire.NewMsgPong(123123) // 0x1e0f3
   216  	basePongEncoded := []byte{
   217  		0xf3, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
   218  	}
   219  
   220  	tests := []struct {
   221  		in       *wire.MsgPong // Value to encode
   222  		buf      []byte        // Wire encoding
   223  		pver     uint32        // Protocol version for wire encoding
   224  		max      int           // Max size of fixed buffer to induce errors
   225  		writeErr error         // Expected write error
   226  		readErr  error         // Expected read error
   227  	}{
   228  		// Latest protocol version with intentional read/write errors.
   229  		// Force error in nonce.
   230  		{basePong, basePongEncoded, pver, 0, io.ErrShortWrite, io.EOF},
   231  		// Force error due to unsupported protocol version.
   232  		{basePong, basePongEncoded, pverNoPong, 4, wireErr, wireErr},
   233  	}
   234  
   235  	t.Logf("Running %d tests", len(tests))
   236  	for i, test := range tests {
   237  		// Encode to wire format.
   238  		w := newFixedWriter(test.max)
   239  		err := test.in.BtcEncode(w, test.pver)
   240  		if reflect.TypeOf(err) != reflect.TypeOf(test.writeErr) {
   241  			t.Errorf("BtcEncode #%d wrong error got: %v, want: %v",
   242  				i, err, test.writeErr)
   243  			continue
   244  		}
   245  
   246  		// For errors which are not of type wire.MessageError, check
   247  		// them for equality.
   248  		if _, ok := err.(*wire.MessageError); !ok {
   249  			if err != test.writeErr {
   250  				t.Errorf("BtcEncode #%d wrong error got: %v, "+
   251  					"want: %v", i, err, test.writeErr)
   252  				continue
   253  			}
   254  		}
   255  
   256  		// Decode from wire format.
   257  		var msg wire.MsgPong
   258  		r := newFixedReader(test.max, test.buf)
   259  		err = msg.BtcDecode(r, test.pver)
   260  		if reflect.TypeOf(err) != reflect.TypeOf(test.readErr) {
   261  			t.Errorf("BtcDecode #%d wrong error got: %v, want: %v",
   262  				i, err, test.readErr)
   263  			continue
   264  		}
   265  
   266  		// For errors which are not of type wire.MessageError, check
   267  		// them for equality.
   268  		if _, ok := err.(*wire.MessageError); !ok {
   269  			if err != test.readErr {
   270  				t.Errorf("BtcDecode #%d wrong error got: %v, "+
   271  					"want: %v", i, err, test.readErr)
   272  				continue
   273  			}
   274  		}
   275  
   276  	}
   277  }