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
5package wire
6
7import (
8	"bytes"
9	"io"
10	"math/rand"
11	"reflect"
12	"testing"
13
14	"github.com/davecgh/go-spew/spew"
15)
16
17// TestFeeFilterLatest tests the MsgFeeFilter API against the latest protocol version.
18func TestFeeFilterLatest(t *testing.T) {
19	pver := ProtocolVersion
20
21	minfee := rand.Int63()
22	msg := NewMsgFeeFilter(minfee)
23	if msg.MinFee != minfee {
24		t.Errorf("NewMsgFeeFilter: wrong minfee - got %v, want %v",
25			msg.MinFee, minfee)
26	}
27
28	// Ensure the command is expected value.
29	wantCmd := "feefilter"
30	if cmd := msg.Command(); cmd != wantCmd {
31		t.Errorf("NewMsgFeeFilter: wrong command - got %v want %v",
32			cmd, wantCmd)
33	}
34
35	// Ensure max payload is expected value for latest protocol version.
36	wantPayload := uint32(8)
37	maxPayload := msg.MaxPayloadLength(pver)
38	if maxPayload != wantPayload {
39		t.Errorf("MaxPayloadLength: wrong max payload length for "+
40			"protocol version %d - got %v, want %v", pver,
41			maxPayload, wantPayload)
42	}
43
44	// Test encode with latest protocol version.
45	var buf bytes.Buffer
46	err := msg.BtcEncode(&buf, pver, BaseEncoding)
47	if err != nil {
48		t.Errorf("encode of MsgFeeFilter failed %v err <%v>", msg, err)
49	}
50
51	// Test decode with latest protocol version.
52	readmsg := NewMsgFeeFilter(0)
53	err = readmsg.BtcDecode(&buf, pver, BaseEncoding)
54	if err != nil {
55		t.Errorf("decode of MsgFeeFilter failed [%v] err <%v>", buf, err)
56	}
57
58	// Ensure minfee is the same.
59	if msg.MinFee != readmsg.MinFee {
60		t.Errorf("Should get same minfee for protocol version %d", pver)
61	}
62}
63
64// TestFeeFilterWire tests the MsgFeeFilter wire encode and decode for various protocol
65// versions.
66func TestFeeFilterWire(t *testing.T) {
67	tests := []struct {
68		in   MsgFeeFilter // Message to encode
69		out  MsgFeeFilter // Expected decoded message
70		buf  []byte       // Wire encoding
71		pver uint32       // Protocol version for wire encoding
72	}{
73		// Latest protocol version.
74		{
75			MsgFeeFilter{MinFee: 123123}, // 0x1e0f3
76			MsgFeeFilter{MinFee: 123123}, // 0x1e0f3
77			[]byte{0xf3, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00},
78			ProtocolVersion,
79		},
80
81		// Protocol version FeeFilterVersion
82		{
83			MsgFeeFilter{MinFee: 456456}, // 0x6f708
84			MsgFeeFilter{MinFee: 456456}, // 0x6f708
85			[]byte{0x08, 0xf7, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00},
86			FeeFilterVersion,
87		},
88	}
89
90	t.Logf("Running %d tests", len(tests))
91	for i, test := range tests {
92		// Encode the message to wire format.
93		var buf bytes.Buffer
94		err := test.in.BtcEncode(&buf, test.pver, BaseEncoding)
95		if err != nil {
96			t.Errorf("BtcEncode #%d error %v", i, err)
97			continue
98		}
99		if !bytes.Equal(buf.Bytes(), test.buf) {
100			t.Errorf("BtcEncode #%d\n got: %s want: %s", i,
101				spew.Sdump(buf.Bytes()), spew.Sdump(test.buf))
102			continue
103		}
104
105		// Decode the message from wire format.
106		var msg MsgFeeFilter
107		rbuf := bytes.NewReader(test.buf)
108		err = msg.BtcDecode(rbuf, test.pver, BaseEncoding)
109		if err != nil {
110			t.Errorf("BtcDecode #%d error %v", i, err)
111			continue
112		}
113		if !reflect.DeepEqual(msg, test.out) {
114			t.Errorf("BtcDecode #%d\n got: %s want: %s", i,
115				spew.Sdump(msg), spew.Sdump(test.out))
116			continue
117		}
118	}
119}
120
121// TestFeeFilterWireErrors performs negative tests against wire encode and decode
122// of MsgFeeFilter to confirm error paths work correctly.
123func TestFeeFilterWireErrors(t *testing.T) {
124	pver := ProtocolVersion
125	pverNoFeeFilter := FeeFilterVersion - 1
126	wireErr := &MessageError{}
127
128	baseFeeFilter := NewMsgFeeFilter(123123) // 0x1e0f3
129	baseFeeFilterEncoded := []byte{
130		0xf3, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
131	}
132
133	tests := []struct {
134		in       *MsgFeeFilter // Value to encode
135		buf      []byte        // Wire encoding
136		pver     uint32        // Protocol version for wire encoding
137		max      int           // Max size of fixed buffer to induce errors
138		writeErr error         // Expected write error
139		readErr  error         // Expected read error
140	}{
141		// Latest protocol version with intentional read/write errors.
142		// Force error in minfee.
143		{baseFeeFilter, baseFeeFilterEncoded, pver, 0, io.ErrShortWrite, io.EOF},
144		// Force error due to unsupported protocol version.
145		{baseFeeFilter, baseFeeFilterEncoded, pverNoFeeFilter, 4, wireErr, wireErr},
146	}
147
148	t.Logf("Running %d tests", len(tests))
149	for i, test := range tests {
150		// Encode to wire format.
151		w := newFixedWriter(test.max)
152		err := test.in.BtcEncode(w, test.pver, BaseEncoding)
153		if reflect.TypeOf(err) != reflect.TypeOf(test.writeErr) {
154			t.Errorf("BtcEncode #%d wrong error got: %v, want: %v",
155				i, err, test.writeErr)
156			continue
157		}
158
159		// For errors which are not of type MessageError, check them for
160		// equality.
161		if _, ok := err.(*MessageError); !ok {
162			if err != test.writeErr {
163				t.Errorf("BtcEncode #%d wrong error got: %v, "+
164					"want: %v", i, err, test.writeErr)
165				continue
166			}
167		}
168
169		// Decode from wire format.
170		var msg MsgFeeFilter
171		r := newFixedReader(test.max, test.buf)
172		err = msg.BtcDecode(r, test.pver, BaseEncoding)
173		if reflect.TypeOf(err) != reflect.TypeOf(test.readErr) {
174			t.Errorf("BtcDecode #%d wrong error got: %v, want: %v",
175				i, err, test.readErr)
176			continue
177		}
178
179		// For errors which are not of type MessageError, check them for
180		// equality.
181		if _, ok := err.(*MessageError); !ok {
182			if err != test.readErr {
183				t.Errorf("BtcDecode #%d wrong error got: %v, "+
184					"want: %v", i, err, test.readErr)
185				continue
186			}
187		}
188
189	}
190}
191