github.com/dashpay/godash@v0.0.0-20160726055534-e038a21e0e3d/wire/msgreject_test.go (about)

     1  // Copyright (c) 2014-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  // TestRejectCodeStringer tests the stringized output for the reject code type.
    19  func TestRejectCodeStringer(t *testing.T) {
    20  	tests := []struct {
    21  		in   wire.RejectCode
    22  		want string
    23  	}{
    24  		{wire.RejectMalformed, "REJECT_MALFORMED"},
    25  		{wire.RejectInvalid, "REJECT_INVALID"},
    26  		{wire.RejectObsolete, "REJECT_OBSOLETE"},
    27  		{wire.RejectDuplicate, "REJECT_DUPLICATE"},
    28  		{wire.RejectNonstandard, "REJECT_NONSTANDARD"},
    29  		{wire.RejectDust, "REJECT_DUST"},
    30  		{wire.RejectInsufficientFee, "REJECT_INSUFFICIENTFEE"},
    31  		{wire.RejectCheckpoint, "REJECT_CHECKPOINT"},
    32  		{0xff, "Unknown RejectCode (255)"},
    33  	}
    34  
    35  	t.Logf("Running %d tests", len(tests))
    36  	for i, test := range tests {
    37  		result := test.in.String()
    38  		if result != test.want {
    39  			t.Errorf("String #%d\n got: %s want: %s", i, result,
    40  				test.want)
    41  			continue
    42  		}
    43  	}
    44  
    45  }
    46  
    47  // TestRejectLatest tests the MsgPong API against the latest protocol version.
    48  func TestRejectLatest(t *testing.T) {
    49  	pver := wire.ProtocolVersion
    50  
    51  	// Create reject message data.
    52  	rejCommand := (&wire.MsgBlock{}).Command()
    53  	rejCode := wire.RejectDuplicate
    54  	rejReason := "duplicate block"
    55  	rejHash := mainNetGenesisHash
    56  
    57  	// Ensure we get the correct data back out.
    58  	msg := wire.NewMsgReject(rejCommand, rejCode, rejReason)
    59  	msg.Hash = rejHash
    60  	if msg.Cmd != rejCommand {
    61  		t.Errorf("NewMsgReject: wrong rejected command - got %v, "+
    62  			"want %v", msg.Cmd, rejCommand)
    63  	}
    64  	if msg.Code != rejCode {
    65  		t.Errorf("NewMsgReject: wrong rejected code - got %v, "+
    66  			"want %v", msg.Code, rejCode)
    67  	}
    68  	if msg.Reason != rejReason {
    69  		t.Errorf("NewMsgReject: wrong rejected reason - got %v, "+
    70  			"want %v", msg.Reason, rejReason)
    71  	}
    72  
    73  	// Ensure the command is expected value.
    74  	wantCmd := "reject"
    75  	if cmd := msg.Command(); cmd != wantCmd {
    76  		t.Errorf("NewMsgReject: wrong command - got %v want %v",
    77  			cmd, wantCmd)
    78  	}
    79  
    80  	// Ensure max payload is expected value for latest protocol version.
    81  	wantPayload := uint32(wire.MaxMessagePayload)
    82  	maxPayload := msg.MaxPayloadLength(pver)
    83  	if maxPayload != wantPayload {
    84  		t.Errorf("MaxPayloadLength: wrong max payload length for "+
    85  			"protocol version %d - got %v, want %v", pver,
    86  			maxPayload, wantPayload)
    87  	}
    88  
    89  	// Test encode with latest protocol version.
    90  	var buf bytes.Buffer
    91  	err := msg.BtcEncode(&buf, pver)
    92  	if err != nil {
    93  		t.Errorf("encode of MsgReject failed %v err <%v>", msg, err)
    94  	}
    95  
    96  	// Test decode with latest protocol version.
    97  	readMsg := wire.MsgReject{}
    98  	err = readMsg.BtcDecode(&buf, pver)
    99  	if err != nil {
   100  		t.Errorf("decode of MsgReject failed %v err <%v>", buf.Bytes(),
   101  			err)
   102  	}
   103  
   104  	// Ensure decoded data is the same.
   105  	if msg.Cmd != readMsg.Cmd {
   106  		t.Errorf("Should get same reject command - got %v, want %v",
   107  			readMsg.Cmd, msg.Cmd)
   108  	}
   109  	if msg.Code != readMsg.Code {
   110  		t.Errorf("Should get same reject code - got %v, want %v",
   111  			readMsg.Code, msg.Code)
   112  	}
   113  	if msg.Reason != readMsg.Reason {
   114  		t.Errorf("Should get same reject reason - got %v, want %v",
   115  			readMsg.Reason, msg.Reason)
   116  	}
   117  	if msg.Hash != readMsg.Hash {
   118  		t.Errorf("Should get same reject hash - got %v, want %v",
   119  			readMsg.Hash, msg.Hash)
   120  	}
   121  }
   122  
   123  // TestRejectBeforeAdded tests the MsgReject API against a protocol version
   124  // before the version which introduced it (RejectVersion).
   125  func TestRejectBeforeAdded(t *testing.T) {
   126  	// Use the protocol version just prior to RejectVersion.
   127  	pver := wire.RejectVersion - 1
   128  
   129  	// Create reject message data.
   130  	rejCommand := (&wire.MsgBlock{}).Command()
   131  	rejCode := wire.RejectDuplicate
   132  	rejReason := "duplicate block"
   133  	rejHash := mainNetGenesisHash
   134  
   135  	msg := wire.NewMsgReject(rejCommand, rejCode, rejReason)
   136  	msg.Hash = rejHash
   137  
   138  	// Ensure max payload is expected value for old protocol version.
   139  	size := msg.MaxPayloadLength(pver)
   140  	if size != 0 {
   141  		t.Errorf("Max length should be 0 for reject protocol version %d.",
   142  			pver)
   143  	}
   144  
   145  	// Test encode with old protocol version.
   146  	var buf bytes.Buffer
   147  	err := msg.BtcEncode(&buf, pver)
   148  	if err == nil {
   149  		t.Errorf("encode of MsgReject succeeded when it shouldn't "+
   150  			"have %v", msg)
   151  	}
   152  
   153  	//	// Test decode with old protocol version.
   154  	readMsg := wire.MsgReject{}
   155  	err = readMsg.BtcDecode(&buf, pver)
   156  	if err == nil {
   157  		t.Errorf("decode of MsgReject succeeded when it shouldn't "+
   158  			"have %v", spew.Sdump(buf.Bytes()))
   159  	}
   160  
   161  	// Since this protocol version doesn't support reject, make sure various
   162  	// fields didn't get encoded and decoded back out.
   163  	if msg.Cmd == readMsg.Cmd {
   164  		t.Errorf("Should not get same reject command for protocol "+
   165  			"version %d", pver)
   166  	}
   167  	if msg.Code == readMsg.Code {
   168  		t.Errorf("Should not get same reject code for protocol "+
   169  			"version %d", pver)
   170  	}
   171  	if msg.Reason == readMsg.Reason {
   172  		t.Errorf("Should not get same reject reason for protocol "+
   173  			"version %d", pver)
   174  	}
   175  	if msg.Hash == readMsg.Hash {
   176  		t.Errorf("Should not get same reject hash for protocol "+
   177  			"version %d", pver)
   178  	}
   179  }
   180  
   181  // TestRejectCrossProtocol tests the MsgReject API when encoding with the latest
   182  // protocol version and decoded with a version before the version which
   183  // introduced it (RejectVersion).
   184  func TestRejectCrossProtocol(t *testing.T) {
   185  	// Create reject message data.
   186  	rejCommand := (&wire.MsgBlock{}).Command()
   187  	rejCode := wire.RejectDuplicate
   188  	rejReason := "duplicate block"
   189  	rejHash := mainNetGenesisHash
   190  
   191  	msg := wire.NewMsgReject(rejCommand, rejCode, rejReason)
   192  	msg.Hash = rejHash
   193  
   194  	// Encode with latest protocol version.
   195  	var buf bytes.Buffer
   196  	err := msg.BtcEncode(&buf, wire.ProtocolVersion)
   197  	if err != nil {
   198  		t.Errorf("encode of MsgReject failed %v err <%v>", msg, err)
   199  	}
   200  
   201  	// Decode with old protocol version.
   202  	readMsg := wire.MsgReject{}
   203  	err = readMsg.BtcDecode(&buf, wire.RejectVersion-1)
   204  	if err == nil {
   205  		t.Errorf("encode of MsgReject succeeded when it shouldn't "+
   206  			"have %v", msg)
   207  	}
   208  
   209  	// Since one of the protocol versions doesn't support the reject
   210  	// message, make sure the various fields didn't get encoded and decoded
   211  	// back out.
   212  	if msg.Cmd == readMsg.Cmd {
   213  		t.Errorf("Should not get same reject command for cross protocol")
   214  	}
   215  	if msg.Code == readMsg.Code {
   216  		t.Errorf("Should not get same reject code for cross protocol")
   217  	}
   218  	if msg.Reason == readMsg.Reason {
   219  		t.Errorf("Should not get same reject reason for cross protocol")
   220  	}
   221  	if msg.Hash == readMsg.Hash {
   222  		t.Errorf("Should not get same reject hash for cross protocol")
   223  	}
   224  }
   225  
   226  // TestRejectWire tests the MsgReject wire encode and decode for various
   227  // protocol versions.
   228  func TestRejectWire(t *testing.T) {
   229  	tests := []struct {
   230  		msg  wire.MsgReject // Message to encode
   231  		buf  []byte         // Wire encoding
   232  		pver uint32         // Protocol version for wire encoding
   233  	}{
   234  		// Latest protocol version rejected command version (no hash).
   235  		{
   236  			wire.MsgReject{
   237  				Cmd:    "version",
   238  				Code:   wire.RejectDuplicate,
   239  				Reason: "duplicate version",
   240  			},
   241  			[]byte{
   242  				0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, // "version"
   243  				0x12, // wire.RejectDuplicate
   244  				0x11, 0x64, 0x75, 0x70, 0x6c, 0x69, 0x63, 0x61,
   245  				0x74, 0x65, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69,
   246  				0x6f, 0x6e, // "duplicate version"
   247  			},
   248  			wire.ProtocolVersion,
   249  		},
   250  		// Latest protocol version rejected command block (has hash).
   251  		{
   252  			wire.MsgReject{
   253  				Cmd:    "block",
   254  				Code:   wire.RejectDuplicate,
   255  				Reason: "duplicate block",
   256  				Hash:   mainNetGenesisHash,
   257  			},
   258  			[]byte{
   259  				0x05, 0x62, 0x6c, 0x6f, 0x63, 0x6b, // "block"
   260  				0x12, // wire.RejectDuplicate
   261  				0x0f, 0x64, 0x75, 0x70, 0x6c, 0x69, 0x63, 0x61,
   262  				0x74, 0x65, 0x20, 0x62, 0x6c, 0x6f, 0x63, 0x6b, // "duplicate block"
   263  				0x6f, 0xe2, 0x8c, 0x0a, 0xb6, 0xf1, 0xb3, 0x72,
   264  				0xc1, 0xa6, 0xa2, 0x46, 0xae, 0x63, 0xf7, 0x4f,
   265  				0x93, 0x1e, 0x83, 0x65, 0xe1, 0x5a, 0x08, 0x9c,
   266  				0x68, 0xd6, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, // mainNetGenesisHash
   267  			},
   268  			wire.ProtocolVersion,
   269  		},
   270  	}
   271  
   272  	t.Logf("Running %d tests", len(tests))
   273  	for i, test := range tests {
   274  		// Encode the message to wire format.
   275  		var buf bytes.Buffer
   276  		err := test.msg.BtcEncode(&buf, test.pver)
   277  		if err != nil {
   278  			t.Errorf("BtcEncode #%d error %v", i, err)
   279  			continue
   280  		}
   281  		if !bytes.Equal(buf.Bytes(), test.buf) {
   282  			t.Errorf("BtcEncode #%d\n got: %s want: %s", i,
   283  				spew.Sdump(buf.Bytes()), spew.Sdump(test.buf))
   284  			continue
   285  		}
   286  
   287  		// Decode the message from wire format.
   288  		var msg wire.MsgReject
   289  		rbuf := bytes.NewReader(test.buf)
   290  		err = msg.BtcDecode(rbuf, test.pver)
   291  		if err != nil {
   292  			t.Errorf("BtcDecode #%d error %v", i, err)
   293  			continue
   294  		}
   295  		if !reflect.DeepEqual(msg, test.msg) {
   296  			t.Errorf("BtcDecode #%d\n got: %s want: %s", i,
   297  				spew.Sdump(msg), spew.Sdump(test.msg))
   298  			continue
   299  		}
   300  	}
   301  }
   302  
   303  // TestRejectWireErrors performs negative tests against wire encode and decode
   304  // of MsgReject to confirm error paths work correctly.
   305  func TestRejectWireErrors(t *testing.T) {
   306  	pver := wire.ProtocolVersion
   307  	pverNoReject := wire.RejectVersion - 1
   308  	wireErr := &wire.MessageError{}
   309  
   310  	baseReject := wire.NewMsgReject("block", wire.RejectDuplicate,
   311  		"duplicate block")
   312  	baseReject.Hash = mainNetGenesisHash
   313  	baseRejectEncoded := []byte{
   314  		0x05, 0x62, 0x6c, 0x6f, 0x63, 0x6b, // "block"
   315  		0x12, // wire.RejectDuplicate
   316  		0x0f, 0x64, 0x75, 0x70, 0x6c, 0x69, 0x63, 0x61,
   317  		0x74, 0x65, 0x20, 0x62, 0x6c, 0x6f, 0x63, 0x6b, // "duplicate block"
   318  		0x6f, 0xe2, 0x8c, 0x0a, 0xb6, 0xf1, 0xb3, 0x72,
   319  		0xc1, 0xa6, 0xa2, 0x46, 0xae, 0x63, 0xf7, 0x4f,
   320  		0x93, 0x1e, 0x83, 0x65, 0xe1, 0x5a, 0x08, 0x9c,
   321  		0x68, 0xd6, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, // mainNetGenesisHash
   322  	}
   323  
   324  	tests := []struct {
   325  		in       *wire.MsgReject // Value to encode
   326  		buf      []byte          // Wire encoding
   327  		pver     uint32          // Protocol version for wire encoding
   328  		max      int             // Max size of fixed buffer to induce errors
   329  		writeErr error           // Expected write error
   330  		readErr  error           // Expected read error
   331  	}{
   332  		// Latest protocol version with intentional read/write errors.
   333  		// Force error in reject command.
   334  		{baseReject, baseRejectEncoded, pver, 0, io.ErrShortWrite, io.EOF},
   335  		// Force error in reject code.
   336  		{baseReject, baseRejectEncoded, pver, 6, io.ErrShortWrite, io.EOF},
   337  		// Force error in reject reason.
   338  		{baseReject, baseRejectEncoded, pver, 7, io.ErrShortWrite, io.EOF},
   339  		// Force error in reject hash.
   340  		{baseReject, baseRejectEncoded, pver, 23, io.ErrShortWrite, io.EOF},
   341  		// Force error due to unsupported protocol version.
   342  		{baseReject, baseRejectEncoded, pverNoReject, 6, wireErr, wireErr},
   343  	}
   344  
   345  	t.Logf("Running %d tests", len(tests))
   346  	for i, test := range tests {
   347  		// Encode to wire format.
   348  		w := newFixedWriter(test.max)
   349  		err := test.in.BtcEncode(w, test.pver)
   350  		if reflect.TypeOf(err) != reflect.TypeOf(test.writeErr) {
   351  			t.Errorf("BtcEncode #%d wrong error got: %v, want: %v",
   352  				i, err, test.writeErr)
   353  			continue
   354  		}
   355  
   356  		// For errors which are not of type wire.MessageError, check
   357  		// them for equality.
   358  		if _, ok := err.(*wire.MessageError); !ok {
   359  			if err != test.writeErr {
   360  				t.Errorf("BtcEncode #%d wrong error got: %v, "+
   361  					"want: %v", i, err, test.writeErr)
   362  				continue
   363  			}
   364  		}
   365  
   366  		// Decode from wire format.
   367  		var msg wire.MsgReject
   368  		r := newFixedReader(test.max, test.buf)
   369  		err = msg.BtcDecode(r, test.pver)
   370  		if reflect.TypeOf(err) != reflect.TypeOf(test.readErr) {
   371  			t.Errorf("BtcDecode #%d wrong error got: %v, want: %v",
   372  				i, err, test.readErr)
   373  			continue
   374  		}
   375  
   376  		// For errors which are not of type wire.MessageError, check
   377  		// them for equality.
   378  		if _, ok := err.(*wire.MessageError); !ok {
   379  			if err != test.readErr {
   380  				t.Errorf("BtcDecode #%d wrong error got: %v, "+
   381  					"want: %v", i, err, test.readErr)
   382  				continue
   383  			}
   384  		}
   385  	}
   386  }