mirror of
https://github.com/btcsuite/btcd.git
synced 2024-11-19 01:40:07 +01:00
Add support for wtxidrelay message. (#2272)
* Add support for wtxidrelay message. This adds support for the wtxidrelay (BIP339) message in wire. While here, add tests for sendaddrv2 and rename AddrV2Version to SendAddrV2Version in order to make the code consistent with all other messages. This diff does keep the old AddrV2Version constant for backwards compatibility. * Bump copyrights
This commit is contained in:
parent
24eb815168
commit
684d64ad74
2
LICENSE
2
LICENSE
@ -1,6 +1,6 @@
|
|||||||
ISC License
|
ISC License
|
||||||
|
|
||||||
Copyright (c) 2013-2023 The btcsuite developers
|
Copyright (c) 2013-2024 The btcsuite developers
|
||||||
Copyright (c) 2015-2016 The Decred developers
|
Copyright (c) 2015-2016 The Decred developers
|
||||||
|
|
||||||
Permission to use, copy, modify, and distribute this software for any
|
Permission to use, copy, modify, and distribute this software for any
|
||||||
|
21
peer/peer.go
21
peer/peer.go
@ -18,18 +18,19 @@ import (
|
|||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/btcsuite/go-socks/socks"
|
||||||
|
"github.com/davecgh/go-spew/spew"
|
||||||
|
"github.com/decred/dcrd/lru"
|
||||||
|
|
||||||
"github.com/btcsuite/btcd/blockchain"
|
"github.com/btcsuite/btcd/blockchain"
|
||||||
"github.com/btcsuite/btcd/chaincfg"
|
"github.com/btcsuite/btcd/chaincfg"
|
||||||
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||||
"github.com/btcsuite/btcd/wire"
|
"github.com/btcsuite/btcd/wire"
|
||||||
"github.com/btcsuite/go-socks/socks"
|
|
||||||
"github.com/davecgh/go-spew/spew"
|
|
||||||
"github.com/decred/dcrd/lru"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// MaxProtocolVersion is the max protocol version the peer supports.
|
// MaxProtocolVersion is the max protocol version the peer supports.
|
||||||
MaxProtocolVersion = wire.AddrV2Version
|
MaxProtocolVersion = wire.SendAddrV2Version
|
||||||
|
|
||||||
// DefaultTrickleInterval is the min time between attempts to send an
|
// DefaultTrickleInterval is the min time between attempts to send an
|
||||||
// inv message to a peer.
|
// inv message to a peer.
|
||||||
@ -877,8 +878,8 @@ func (p *Peer) PushAddrMsg(addresses []*wire.NetAddress) ([]*wire.NetAddress, er
|
|||||||
//
|
//
|
||||||
// This function is safe for concurrent access.
|
// This function is safe for concurrent access.
|
||||||
func (p *Peer) PushAddrV2Msg(addrs []*wire.NetAddressV2) (
|
func (p *Peer) PushAddrV2Msg(addrs []*wire.NetAddressV2) (
|
||||||
[]*wire.NetAddressV2, error) {
|
[]*wire.NetAddressV2, error,
|
||||||
|
) {
|
||||||
count := len(addrs)
|
count := len(addrs)
|
||||||
|
|
||||||
// Nothing to send.
|
// Nothing to send.
|
||||||
@ -1900,8 +1901,8 @@ func (p *Peer) QueueMessage(msg wire.Message, doneChan chan<- struct{}) {
|
|||||||
//
|
//
|
||||||
// This function is safe for concurrent access.
|
// This function is safe for concurrent access.
|
||||||
func (p *Peer) QueueMessageWithEncoding(msg wire.Message, doneChan chan<- struct{},
|
func (p *Peer) QueueMessageWithEncoding(msg wire.Message, doneChan chan<- struct{},
|
||||||
encoding wire.MessageEncoding) {
|
encoding wire.MessageEncoding,
|
||||||
|
) {
|
||||||
// Avoid risk of deadlock if goroutine already exited. The goroutine
|
// Avoid risk of deadlock if goroutine already exited. The goroutine
|
||||||
// we will be sending to hangs around until it knows for a fact that
|
// we will be sending to hangs around until it knows for a fact that
|
||||||
// it is marked as disconnected and *then* it drains the channels.
|
// it is marked as disconnected and *then* it drains the channels.
|
||||||
@ -2152,7 +2153,7 @@ func (p *Peer) writeLocalVersionMsg() error {
|
|||||||
// writeSendAddrV2Msg writes our sendaddrv2 message to the remote peer if the
|
// writeSendAddrV2Msg writes our sendaddrv2 message to the remote peer if the
|
||||||
// peer supports protocol version 70016 and above.
|
// peer supports protocol version 70016 and above.
|
||||||
func (p *Peer) writeSendAddrV2Msg(pver uint32) error {
|
func (p *Peer) writeSendAddrV2Msg(pver uint32) error {
|
||||||
if pver < wire.AddrV2Version {
|
if pver < wire.SendAddrV2Version {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2180,7 +2181,7 @@ func (p *Peer) waitToFinishNegotiation(pver uint32) error {
|
|||||||
|
|
||||||
switch m := remoteMsg.(type) {
|
switch m := remoteMsg.(type) {
|
||||||
case *wire.MsgSendAddrV2:
|
case *wire.MsgSendAddrV2:
|
||||||
if pver >= wire.AddrV2Version {
|
if pver >= wire.SendAddrV2Version {
|
||||||
p.flagsMtx.Lock()
|
p.flagsMtx.Lock()
|
||||||
p.sendAddrV2 = true
|
p.sendAddrV2 = true
|
||||||
p.flagsMtx.Unlock()
|
p.flagsMtx.Unlock()
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright (c) 2013-2016 The btcsuite developers
|
// Copyright (c) 2013-2024 The btcsuite developers
|
||||||
// Use of this source code is governed by an ISC
|
// Use of this source code is governed by an ISC
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
@ -59,6 +59,7 @@ const (
|
|||||||
CmdCFHeaders = "cfheaders"
|
CmdCFHeaders = "cfheaders"
|
||||||
CmdCFCheckpt = "cfcheckpt"
|
CmdCFCheckpt = "cfcheckpt"
|
||||||
CmdSendAddrV2 = "sendaddrv2"
|
CmdSendAddrV2 = "sendaddrv2"
|
||||||
|
CmdWTxIdRelay = "wtxidrelay"
|
||||||
)
|
)
|
||||||
|
|
||||||
// MessageEncoding represents the wire message encoding format to be used.
|
// MessageEncoding represents the wire message encoding format to be used.
|
||||||
@ -111,6 +112,9 @@ func makeEmptyMessage(command string) (Message, error) {
|
|||||||
case CmdSendAddrV2:
|
case CmdSendAddrV2:
|
||||||
msg = &MsgSendAddrV2{}
|
msg = &MsgSendAddrV2{}
|
||||||
|
|
||||||
|
case CmdWTxIdRelay:
|
||||||
|
msg = &MsgWTxIdRelay{}
|
||||||
|
|
||||||
case CmdGetAddr:
|
case CmdGetAddr:
|
||||||
msg = &MsgGetAddr{}
|
msg = &MsgGetAddr{}
|
||||||
|
|
||||||
@ -276,8 +280,8 @@ func WriteMessage(w io.Writer, msg Message, pver uint32, btcnet BitcoinNet) erro
|
|||||||
// to specify the message encoding format to be used when serializing wire
|
// to specify the message encoding format to be used when serializing wire
|
||||||
// messages.
|
// messages.
|
||||||
func WriteMessageWithEncodingN(w io.Writer, msg Message, pver uint32,
|
func WriteMessageWithEncodingN(w io.Writer, msg Message, pver uint32,
|
||||||
btcnet BitcoinNet, encoding MessageEncoding) (int, error) {
|
btcnet BitcoinNet, encoding MessageEncoding,
|
||||||
|
) (int, error) {
|
||||||
totalBytes := 0
|
totalBytes := 0
|
||||||
|
|
||||||
// Enforce max command size.
|
// Enforce max command size.
|
||||||
@ -353,8 +357,8 @@ func WriteMessageWithEncodingN(w io.Writer, msg Message, pver uint32,
|
|||||||
// allows the caller to specify which message encoding is to to consult when
|
// allows the caller to specify which message encoding is to to consult when
|
||||||
// decoding wire messages.
|
// decoding wire messages.
|
||||||
func ReadMessageWithEncodingN(r io.Reader, pver uint32, btcnet BitcoinNet,
|
func ReadMessageWithEncodingN(r io.Reader, pver uint32, btcnet BitcoinNet,
|
||||||
enc MessageEncoding) (int, Message, []byte, error) {
|
enc MessageEncoding,
|
||||||
|
) (int, Message, []byte, error) {
|
||||||
totalBytes := 0
|
totalBytes := 0
|
||||||
n, hdr, err := readMessageHeader(r)
|
n, hdr, err := readMessageHeader(r)
|
||||||
totalBytes += n
|
totalBytes += n
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package wire
|
package wire
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -14,12 +15,24 @@ type MsgSendAddrV2 struct{}
|
|||||||
// BtcDecode decodes r using the bitcoin protocol encoding into the receiver.
|
// BtcDecode decodes r using the bitcoin protocol encoding into the receiver.
|
||||||
// This is part of the Message interface implementation.
|
// This is part of the Message interface implementation.
|
||||||
func (msg *MsgSendAddrV2) BtcDecode(r io.Reader, pver uint32, enc MessageEncoding) error {
|
func (msg *MsgSendAddrV2) BtcDecode(r io.Reader, pver uint32, enc MessageEncoding) error {
|
||||||
|
if pver < SendAddrV2Version {
|
||||||
|
str := fmt.Sprintf("sendaddrv2 message invalid for protocol "+
|
||||||
|
"version %d", pver)
|
||||||
|
return messageError("MsgSendAddrV2.BtcDecode", str)
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// BtcEncode encodes the receiver to w using the bitcoin protocol encoding.
|
// BtcEncode encodes the receiver to w using the bitcoin protocol encoding.
|
||||||
// This is part of the Message interface implementation.
|
// This is part of the Message interface implementation.
|
||||||
func (msg *MsgSendAddrV2) BtcEncode(w io.Writer, pver uint32, enc MessageEncoding) error {
|
func (msg *MsgSendAddrV2) BtcEncode(w io.Writer, pver uint32, enc MessageEncoding) error {
|
||||||
|
if pver < SendAddrV2Version {
|
||||||
|
str := fmt.Sprintf("sendaddrv2 message invalid for protocol "+
|
||||||
|
"version %d", pver)
|
||||||
|
return messageError("MsgSendAddrV2.BtcEncode", str)
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
193
wire/msgsendaddrv2_test.go
Normal file
193
wire/msgsendaddrv2_test.go
Normal file
@ -0,0 +1,193 @@
|
|||||||
|
// Copyright (c) 2024 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 (
|
||||||
|
"bytes"
|
||||||
|
"reflect"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/davecgh/go-spew/spew"
|
||||||
|
)
|
||||||
|
|
||||||
|
// TestSendAddrV2 tests the MsgSendAddrV2 API against the latest protocol
|
||||||
|
// version.
|
||||||
|
func TestSendAddrV2(t *testing.T) {
|
||||||
|
pver := ProtocolVersion
|
||||||
|
enc := BaseEncoding
|
||||||
|
|
||||||
|
// Ensure the command is expected value.
|
||||||
|
wantCmd := "sendaddrv2"
|
||||||
|
msg := NewMsgSendAddrV2()
|
||||||
|
if cmd := msg.Command(); cmd != wantCmd {
|
||||||
|
t.Errorf("NewMsgSendAddrV2: 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, enc)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("encode of MsgSendAddrV2 failed %v err <%v>", msg,
|
||||||
|
err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Older protocol versions should fail encode since message didn't
|
||||||
|
// exist yet.
|
||||||
|
oldPver := SendAddrV2Version - 1
|
||||||
|
err = msg.BtcEncode(&buf, oldPver, enc)
|
||||||
|
if err == nil {
|
||||||
|
s := "encode of MsgSendAddrV2 passed for old protocol " +
|
||||||
|
"version %v err <%v>"
|
||||||
|
t.Errorf(s, msg, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test decode with latest protocol version.
|
||||||
|
readmsg := NewMsgSendAddrV2()
|
||||||
|
err = readmsg.BtcDecode(&buf, pver, enc)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("decode of MsgSendAddrV2 failed [%v] err <%v>", buf,
|
||||||
|
err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Older protocol versions should fail decode since message didn't
|
||||||
|
// exist yet.
|
||||||
|
err = readmsg.BtcDecode(&buf, oldPver, enc)
|
||||||
|
if err == nil {
|
||||||
|
s := "decode of MsgSendAddrV2 passed for old protocol " +
|
||||||
|
"version %v err <%v>"
|
||||||
|
t.Errorf(s, msg, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestSendAddrV2BIP0130 tests the MsgSendAddrV2 API against the protocol
|
||||||
|
// prior to version SendAddrV2Version.
|
||||||
|
func TestSendAddrV2BIP0130(t *testing.T) {
|
||||||
|
// Use the protocol version just prior to SendAddrV2Version changes.
|
||||||
|
pver := SendAddrV2Version - 1
|
||||||
|
enc := BaseEncoding
|
||||||
|
|
||||||
|
msg := NewMsgSendAddrV2()
|
||||||
|
|
||||||
|
// Test encode with old protocol version.
|
||||||
|
var buf bytes.Buffer
|
||||||
|
err := msg.BtcEncode(&buf, pver, enc)
|
||||||
|
if err == nil {
|
||||||
|
t.Errorf("encode of MsgSendAddrV2 succeeded when it should " +
|
||||||
|
"have failed")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test decode with old protocol version.
|
||||||
|
readmsg := NewMsgSendAddrV2()
|
||||||
|
err = readmsg.BtcDecode(&buf, pver, enc)
|
||||||
|
if err == nil {
|
||||||
|
t.Errorf("decode of MsgSendAddrV2 succeeded when it should " +
|
||||||
|
"have failed")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestSendAddrV2CrossProtocol tests the MsgSendAddrV2 API when encoding with
|
||||||
|
// the latest protocol version and decoding with SendAddrV2Version.
|
||||||
|
func TestSendAddrV2CrossProtocol(t *testing.T) {
|
||||||
|
enc := BaseEncoding
|
||||||
|
msg := NewMsgSendAddrV2()
|
||||||
|
|
||||||
|
// Encode with latest protocol version.
|
||||||
|
var buf bytes.Buffer
|
||||||
|
err := msg.BtcEncode(&buf, ProtocolVersion, enc)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("encode of MsgSendAddrV2 failed %v err <%v>", msg,
|
||||||
|
err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decode with old protocol version.
|
||||||
|
readmsg := NewMsgSendAddrV2()
|
||||||
|
err = readmsg.BtcDecode(&buf, SendAddrV2Version, enc)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("decode of MsgSendAddrV2 failed [%v] err <%v>", buf,
|
||||||
|
err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestSendAddrV2Wire tests the MsgSendAddrV2 wire encode and decode for
|
||||||
|
// various protocol versions.
|
||||||
|
func TestSendAddrV2Wire(t *testing.T) {
|
||||||
|
msgSendAddrV2 := NewMsgSendAddrV2()
|
||||||
|
msgSendAddrV2Encoded := []byte{}
|
||||||
|
|
||||||
|
tests := []struct {
|
||||||
|
in *MsgSendAddrV2 // Message to encode
|
||||||
|
out *MsgSendAddrV2 // Expected decoded message
|
||||||
|
buf []byte // Wire encoding
|
||||||
|
pver uint32 // Protocol version for wire encoding
|
||||||
|
enc MessageEncoding // Message encoding format
|
||||||
|
}{
|
||||||
|
// Latest protocol version.
|
||||||
|
{
|
||||||
|
msgSendAddrV2,
|
||||||
|
msgSendAddrV2,
|
||||||
|
msgSendAddrV2Encoded,
|
||||||
|
ProtocolVersion,
|
||||||
|
BaseEncoding,
|
||||||
|
},
|
||||||
|
|
||||||
|
// Protocol version SendAddrV2Version+1
|
||||||
|
{
|
||||||
|
msgSendAddrV2,
|
||||||
|
msgSendAddrV2,
|
||||||
|
msgSendAddrV2Encoded,
|
||||||
|
SendAddrV2Version + 1,
|
||||||
|
BaseEncoding,
|
||||||
|
},
|
||||||
|
|
||||||
|
// Protocol version SendAddrV2Version
|
||||||
|
{
|
||||||
|
msgSendAddrV2,
|
||||||
|
msgSendAddrV2,
|
||||||
|
msgSendAddrV2Encoded,
|
||||||
|
SendAddrV2Version,
|
||||||
|
BaseEncoding,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
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, test.enc)
|
||||||
|
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 MsgSendAddrV2
|
||||||
|
rbuf := bytes.NewReader(test.buf)
|
||||||
|
err = msg.BtcDecode(rbuf, test.pver, test.enc)
|
||||||
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
59
wire/msgwtxidrelay.go
Normal file
59
wire/msgwtxidrelay.go
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
// Copyright (c) 2024 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"
|
||||||
|
)
|
||||||
|
|
||||||
|
// MsgWTxIdRelay defines a bitcoin wtxidrelay message which is used for a peer
|
||||||
|
// to signal support for relaying witness transaction id (BIP141). It
|
||||||
|
// implements the Message interface.
|
||||||
|
//
|
||||||
|
// This message has no payload.
|
||||||
|
type MsgWTxIdRelay struct{}
|
||||||
|
|
||||||
|
// BtcDecode decodes r using the bitcoin protocol encoding into the receiver.
|
||||||
|
// This is part of the Message interface implementation.
|
||||||
|
func (msg *MsgWTxIdRelay) BtcDecode(r io.Reader, pver uint32, enc MessageEncoding) error {
|
||||||
|
if pver < WTxIdRelayVersion {
|
||||||
|
str := fmt.Sprintf("wtxidrelay message invalid for protocol "+
|
||||||
|
"version %d", pver)
|
||||||
|
return messageError("MsgWTxIdRelay.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 *MsgWTxIdRelay) BtcEncode(w io.Writer, pver uint32, enc MessageEncoding) error {
|
||||||
|
if pver < WTxIdRelayVersion {
|
||||||
|
str := fmt.Sprintf("wtxidrelay message invalid for protocol "+
|
||||||
|
"version %d", pver)
|
||||||
|
return messageError("MsgWTxIdRelay.BtcEncode", str)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Command returns the protocol command string for the message. This is part
|
||||||
|
// of the Message interface implementation.
|
||||||
|
func (msg *MsgWTxIdRelay) Command() string {
|
||||||
|
return CmdWTxIdRelay
|
||||||
|
}
|
||||||
|
|
||||||
|
// MaxPayloadLength returns the maximum length the payload can be for the
|
||||||
|
// receiver. This is part of the Message interface implementation.
|
||||||
|
func (msg *MsgWTxIdRelay) MaxPayloadLength(pver uint32) uint32 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewMsgWTxIdRelay returns a new bitcoin wtxidrelay message that conforms
|
||||||
|
// to the Message interface.
|
||||||
|
func NewMsgWTxIdRelay() *MsgWTxIdRelay {
|
||||||
|
return &MsgWTxIdRelay{}
|
||||||
|
}
|
193
wire/msgwtxidrelay_test.go
Normal file
193
wire/msgwtxidrelay_test.go
Normal file
@ -0,0 +1,193 @@
|
|||||||
|
// Copyright (c) 2024 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 (
|
||||||
|
"bytes"
|
||||||
|
"reflect"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/davecgh/go-spew/spew"
|
||||||
|
)
|
||||||
|
|
||||||
|
// TestWTxIdRelay tests the MsgWTxIdRelay API against the latest protocol
|
||||||
|
// version.
|
||||||
|
func TestWTxIdRelay(t *testing.T) {
|
||||||
|
pver := ProtocolVersion
|
||||||
|
enc := BaseEncoding
|
||||||
|
|
||||||
|
// Ensure the command is expected value.
|
||||||
|
wantCmd := "wtxidrelay"
|
||||||
|
msg := NewMsgWTxIdRelay()
|
||||||
|
if cmd := msg.Command(); cmd != wantCmd {
|
||||||
|
t.Errorf("NewMsgWTxIdRelay: 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, enc)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("encode of MsgWTxIdRelay failed %v err <%v>", msg,
|
||||||
|
err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Older protocol versions should fail encode since message didn't
|
||||||
|
// exist yet.
|
||||||
|
oldPver := WTxIdRelayVersion - 1
|
||||||
|
err = msg.BtcEncode(&buf, oldPver, enc)
|
||||||
|
if err == nil {
|
||||||
|
s := "encode of MsgWTxIdRelay passed for old protocol " +
|
||||||
|
"version %v err <%v>"
|
||||||
|
t.Errorf(s, msg, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test decode with latest protocol version.
|
||||||
|
readmsg := NewMsgWTxIdRelay()
|
||||||
|
err = readmsg.BtcDecode(&buf, pver, enc)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("decode of MsgWTxIdRelay failed [%v] err <%v>", buf,
|
||||||
|
err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Older protocol versions should fail decode since message didn't
|
||||||
|
// exist yet.
|
||||||
|
err = readmsg.BtcDecode(&buf, oldPver, enc)
|
||||||
|
if err == nil {
|
||||||
|
s := "decode of MsgWTxIdRelay passed for old protocol " +
|
||||||
|
"version %v err <%v>"
|
||||||
|
t.Errorf(s, msg, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestWTxIdRelayBIP0130 tests the MsgWTxIdRelay API against the protocol
|
||||||
|
// prior to version WTxIdRelayVersion.
|
||||||
|
func TestWTxIdRelayBIP0130(t *testing.T) {
|
||||||
|
// Use the protocol version just prior to WTxIdRelayVersion changes.
|
||||||
|
pver := WTxIdRelayVersion - 1
|
||||||
|
enc := BaseEncoding
|
||||||
|
|
||||||
|
msg := NewMsgWTxIdRelay()
|
||||||
|
|
||||||
|
// Test encode with old protocol version.
|
||||||
|
var buf bytes.Buffer
|
||||||
|
err := msg.BtcEncode(&buf, pver, enc)
|
||||||
|
if err == nil {
|
||||||
|
t.Errorf("encode of MsgWTxIdRelay succeeded when it should " +
|
||||||
|
"have failed")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test decode with old protocol version.
|
||||||
|
readmsg := NewMsgWTxIdRelay()
|
||||||
|
err = readmsg.BtcDecode(&buf, pver, enc)
|
||||||
|
if err == nil {
|
||||||
|
t.Errorf("decode of MsgWTxIdRelay succeeded when it should " +
|
||||||
|
"have failed")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestWTxIdRelayCrossProtocol tests the MsgWTxIdRelay API when encoding with
|
||||||
|
// the latest protocol version and decoding with WTxIdRelayVersion.
|
||||||
|
func TestWTxIdRelayCrossProtocol(t *testing.T) {
|
||||||
|
enc := BaseEncoding
|
||||||
|
msg := NewMsgWTxIdRelay()
|
||||||
|
|
||||||
|
// Encode with latest protocol version.
|
||||||
|
var buf bytes.Buffer
|
||||||
|
err := msg.BtcEncode(&buf, ProtocolVersion, enc)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("encode of MsgWTxIdRelay failed %v err <%v>", msg,
|
||||||
|
err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decode with old protocol version.
|
||||||
|
readmsg := NewMsgWTxIdRelay()
|
||||||
|
err = readmsg.BtcDecode(&buf, WTxIdRelayVersion, enc)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("decode of MsgWTxIdRelay failed [%v] err <%v>", buf,
|
||||||
|
err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestWTxIdRelayWire tests the MsgWTxIdRelay wire encode and decode for
|
||||||
|
// various protocol versions.
|
||||||
|
func TestWTxIdRelayWire(t *testing.T) {
|
||||||
|
msgWTxIdRelay := NewMsgWTxIdRelay()
|
||||||
|
msgWTxIdRelayEncoded := []byte{}
|
||||||
|
|
||||||
|
tests := []struct {
|
||||||
|
in *MsgWTxIdRelay // Message to encode
|
||||||
|
out *MsgWTxIdRelay // Expected decoded message
|
||||||
|
buf []byte // Wire encoding
|
||||||
|
pver uint32 // Protocol version for wire encoding
|
||||||
|
enc MessageEncoding // Message encoding format
|
||||||
|
}{
|
||||||
|
// Latest protocol version.
|
||||||
|
{
|
||||||
|
msgWTxIdRelay,
|
||||||
|
msgWTxIdRelay,
|
||||||
|
msgWTxIdRelayEncoded,
|
||||||
|
ProtocolVersion,
|
||||||
|
BaseEncoding,
|
||||||
|
},
|
||||||
|
|
||||||
|
// Protocol version WTxIdRelayVersion+1
|
||||||
|
{
|
||||||
|
msgWTxIdRelay,
|
||||||
|
msgWTxIdRelay,
|
||||||
|
msgWTxIdRelayEncoded,
|
||||||
|
WTxIdRelayVersion + 1,
|
||||||
|
BaseEncoding,
|
||||||
|
},
|
||||||
|
|
||||||
|
// Protocol version WTxIdRelayVersion
|
||||||
|
{
|
||||||
|
msgWTxIdRelay,
|
||||||
|
msgWTxIdRelay,
|
||||||
|
msgWTxIdRelayEncoded,
|
||||||
|
WTxIdRelayVersion,
|
||||||
|
BaseEncoding,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
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, test.enc)
|
||||||
|
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 MsgWTxIdRelay
|
||||||
|
rbuf := bytes.NewReader(test.buf)
|
||||||
|
err = msg.BtcDecode(rbuf, test.pver, test.enc)
|
||||||
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright (c) 2013-2016 The btcsuite developers
|
// Copyright (c) 2013-2024 The btcsuite developers
|
||||||
// Use of this source code is governed by an ISC
|
// Use of this source code is governed by an ISC
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
@ -52,12 +52,16 @@ const (
|
|||||||
// feefilter message.
|
// feefilter message.
|
||||||
FeeFilterVersion uint32 = 70013
|
FeeFilterVersion uint32 = 70013
|
||||||
|
|
||||||
// AddrV2Version is the protocol version which added two new messages.
|
// SendAddrV2Version is the protocol version which added two new
|
||||||
// sendaddrv2 is sent during the version-verack handshake and signals
|
// messages. sendaddrv2 is sent during the version-verack handshake
|
||||||
// support for sending and receiving the addrv2 message. In the future,
|
// and signals support for sending and receiving the addrv2 message. In
|
||||||
// new messages that occur during the version-verack handshake will not
|
// the future, new messages that occur during the version-verack
|
||||||
// come with a protocol version bump.
|
// handshake will not come with a protocol version bump.
|
||||||
AddrV2Version uint32 = 70016
|
// In addition, wtxidrelay was also added as an optional message in the
|
||||||
|
// same protocol version.
|
||||||
|
SendAddrV2Version uint32 = 70016
|
||||||
|
WTxIdRelayVersion uint32 = SendAddrV2Version
|
||||||
|
AddrV2Version uint32 = SendAddrV2Version // Keep for upstream compatibility
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
Loading…
Reference in New Issue
Block a user