forked from btcsuite/btcd
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
wire: Implement sendheaders command (BIP0130)
This implements the wire protocol encoding portion of a new sendheaders message as described by BIP0130. It purpose is to request that a peer sends header commands instead of inv commands when announcing new blocks. This includes a protocol version bump to 70012 and a wire version bump to 0.4.0. Note that this does not implement logic to handle the command in btcd, rather it only makes the command available at the wire protocol level. A future commit which honors the command and therefore provides full BIP0130 support is still required.
- Loading branch information
Showing
6 changed files
with
264 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
// Copyright (c) 2016 The btcsuite developers | ||
// Use of this source code is governed by an ISC | ||
// license that can be found in the LICENSE file. | ||
|
||
package wire | ||
|
||
import ( | ||
"fmt" | ||
"io" | ||
) | ||
|
||
// MsgSendHeaders implements the Message interface and represents a bitcoin | ||
// sendheaders message. It is used to request the peer send block headers | ||
// rather than inventory vectors. | ||
// | ||
// This message has no payload and was not added until protocol versions | ||
// starting with SendHeadersVersion. | ||
type MsgSendHeaders struct{} | ||
|
||
// BtcDecode decodes r using the bitcoin protocol encoding into the receiver. | ||
// This is part of the Message interface implementation. | ||
func (msg *MsgSendHeaders) BtcDecode(r io.Reader, pver uint32) error { | ||
if pver < SendHeadersVersion { | ||
str := fmt.Sprintf("sendheaders message invalid for protocol "+ | ||
"version %d", pver) | ||
return messageError("MsgSendHeaders.BtcDecode", str) | ||
} | ||
|
||
return nil | ||
} | ||
|
||
// BtcEncode encodes the receiver to w using the bitcoin protocol encoding. | ||
// This is part of the Message interface implementation. | ||
func (msg *MsgSendHeaders) BtcEncode(w io.Writer, pver uint32) error { | ||
if pver < SendHeadersVersion { | ||
str := fmt.Sprintf("sendheaders message invalid for protocol "+ | ||
"version %d", pver) | ||
return messageError("MsgSendHeaders.BtcEncode", str) | ||
} | ||
|
||
return nil | ||
} | ||
|
||
// Command returns the protocol command string for the message. This is part | ||
// of the Message interface implementation. | ||
func (msg *MsgSendHeaders) Command() string { | ||
return CmdSendHeaders | ||
} | ||
|
||
// MaxPayloadLength returns the maximum length the payload can be for the | ||
// receiver. This is part of the Message interface implementation. | ||
func (msg *MsgSendHeaders) MaxPayloadLength(pver uint32) uint32 { | ||
return 0 | ||
} | ||
|
||
// NewMsgSendHeaders returns a new bitcoin sendheaders message that conforms to | ||
// the Message interface. See MsgSendHeaders for details. | ||
func NewMsgSendHeaders() *MsgSendHeaders { | ||
return &MsgSendHeaders{} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,191 @@ | ||
// Copyright (c) 2016 The btcsuite developers | ||
// Use of this source code is governed by an ISC | ||
// license that can be found in the LICENSE file. | ||
|
||
package wire_test | ||
|
||
import ( | ||
"bytes" | ||
"reflect" | ||
"testing" | ||
|
||
"github.com/btcsuite/btcd/wire" | ||
"github.com/davecgh/go-spew/spew" | ||
) | ||
|
||
// TestSendHeaders tests the MsgSendHeaders API against the latest protocol | ||
// version. | ||
func TestSendHeaders(t *testing.T) { | ||
pver := wire.ProtocolVersion | ||
|
||
// Ensure the command is expected value. | ||
wantCmd := "sendheaders" | ||
msg := wire.NewMsgSendHeaders() | ||
if cmd := msg.Command(); cmd != wantCmd { | ||
t.Errorf("NewMsgSendHeaders: wrong command - got %v want %v", | ||
cmd, wantCmd) | ||
} | ||
|
||
// Ensure max payload is expected value. | ||
wantPayload := uint32(0) | ||
maxPayload := msg.MaxPayloadLength(pver) | ||
if maxPayload != wantPayload { | ||
t.Errorf("MaxPayloadLength: wrong max payload length for "+ | ||
"protocol version %d - got %v, want %v", pver, | ||
maxPayload, wantPayload) | ||
} | ||
|
||
// Test encode with latest protocol version. | ||
var buf bytes.Buffer | ||
err := msg.BtcEncode(&buf, pver) | ||
if err != nil { | ||
t.Errorf("encode of MsgSendHeaders failed %v err <%v>", msg, | ||
err) | ||
} | ||
|
||
// Older protocol versions should fail encode since message didn't | ||
// exist yet. | ||
oldPver := wire.SendHeadersVersion - 1 | ||
err = msg.BtcEncode(&buf, oldPver) | ||
if err == nil { | ||
s := "encode of MsgSendHeaders passed for old protocol " + | ||
"version %v err <%v>" | ||
t.Errorf(s, msg, err) | ||
} | ||
|
||
// Test decode with latest protocol version. | ||
readmsg := wire.NewMsgSendHeaders() | ||
err = readmsg.BtcDecode(&buf, pver) | ||
if err != nil { | ||
t.Errorf("decode of MsgSendHeaders failed [%v] err <%v>", buf, | ||
err) | ||
} | ||
|
||
// Older protocol versions should fail decode since message didn't | ||
// exist yet. | ||
err = readmsg.BtcDecode(&buf, oldPver) | ||
if err == nil { | ||
s := "decode of MsgSendHeaders passed for old protocol " + | ||
"version %v err <%v>" | ||
t.Errorf(s, msg, err) | ||
} | ||
|
||
return | ||
} | ||
|
||
// TestSendHeadersBIP0130 tests the MsgSendHeaders API against the protocol | ||
// prior to version SendHeadersVersion. | ||
func TestSendHeadersBIP0130(t *testing.T) { | ||
// Use the protocol version just prior to SendHeadersVersion changes. | ||
pver := wire.SendHeadersVersion - 1 | ||
|
||
msg := wire.NewMsgSendHeaders() | ||
|
||
// Test encode with old protocol version. | ||
var buf bytes.Buffer | ||
err := msg.BtcEncode(&buf, pver) | ||
if err == nil { | ||
t.Errorf("encode of MsgSendHeaders succeeded when it should " + | ||
"have failed") | ||
} | ||
|
||
// Test decode with old protocol version. | ||
readmsg := wire.NewMsgSendHeaders() | ||
err = readmsg.BtcDecode(&buf, pver) | ||
if err == nil { | ||
t.Errorf("decode of MsgSendHeaders succeeded when it should " + | ||
"have failed") | ||
} | ||
|
||
return | ||
} | ||
|
||
// TestSendHeadersCrossProtocol tests the MsgSendHeaders API when encoding with | ||
// the latest protocol version and decoding with SendHeadersVersion. | ||
func TestSendHeadersCrossProtocol(t *testing.T) { | ||
msg := wire.NewMsgSendHeaders() | ||
|
||
// Encode with latest protocol version. | ||
var buf bytes.Buffer | ||
err := msg.BtcEncode(&buf, wire.ProtocolVersion) | ||
if err != nil { | ||
t.Errorf("encode of MsgSendHeaders failed %v err <%v>", msg, | ||
err) | ||
} | ||
|
||
// Decode with old protocol version. | ||
readmsg := wire.NewMsgSendHeaders() | ||
err = readmsg.BtcDecode(&buf, wire.SendHeadersVersion) | ||
if err != nil { | ||
t.Errorf("decode of MsgSendHeaders failed [%v] err <%v>", buf, | ||
err) | ||
} | ||
} | ||
|
||
// TestSendHeadersWire tests the MsgSendHeaders wire encode and decode for | ||
// various protocol versions. | ||
func TestSendHeadersWire(t *testing.T) { | ||
msgSendHeaders := wire.NewMsgSendHeaders() | ||
msgSendHeadersEncoded := []byte{} | ||
|
||
tests := []struct { | ||
in *wire.MsgSendHeaders // Message to encode | ||
out *wire.MsgSendHeaders // Expected decoded message | ||
buf []byte // Wire encoding | ||
pver uint32 // Protocol version for wire encoding | ||
}{ | ||
// Latest protocol version. | ||
{ | ||
msgSendHeaders, | ||
msgSendHeaders, | ||
msgSendHeadersEncoded, | ||
wire.ProtocolVersion, | ||
}, | ||
|
||
// Protocol version SendHeadersVersion+1 | ||
{ | ||
msgSendHeaders, | ||
msgSendHeaders, | ||
msgSendHeadersEncoded, | ||
wire.SendHeadersVersion + 1, | ||
}, | ||
|
||
// Protocol version SendHeadersVersion | ||
{ | ||
msgSendHeaders, | ||
msgSendHeaders, | ||
msgSendHeadersEncoded, | ||
wire.SendHeadersVersion, | ||
}, | ||
} | ||
|
||
t.Logf("Running %d tests", len(tests)) | ||
for i, test := range tests { | ||
// Encode the message to wire format. | ||
var buf bytes.Buffer | ||
err := test.in.BtcEncode(&buf, test.pver) | ||
if err != nil { | ||
t.Errorf("BtcEncode #%d error %v", i, err) | ||
continue | ||
} | ||
if !bytes.Equal(buf.Bytes(), test.buf) { | ||
t.Errorf("BtcEncode #%d\n got: %s want: %s", i, | ||
spew.Sdump(buf.Bytes()), spew.Sdump(test.buf)) | ||
continue | ||
} | ||
|
||
// Decode the message from wire format. | ||
var msg wire.MsgSendHeaders | ||
rbuf := bytes.NewReader(test.buf) | ||
err = msg.BtcDecode(rbuf, test.pver) | ||
if err != nil { | ||
t.Errorf("BtcDecode #%d error %v", i, err) | ||
continue | ||
} | ||
if !reflect.DeepEqual(&msg, test.out) { | ||
t.Errorf("BtcDecode #%d\n got: %s want: %s", i, | ||
spew.Sdump(msg), spew.Sdump(test.out)) | ||
continue | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters