Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for wtxidrelay message. #2272

Merged
merged 2 commits into from
Nov 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
ISC License

Copyright (c) 2013-2023 The btcsuite developers
Copyright (c) 2013-2024 The btcsuite developers
Copyright (c) 2015-2016 The Decred developers

Permission to use, copy, modify, and distribute this software for any
Expand Down
21 changes: 11 additions & 10 deletions peer/peer.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,19 @@ import (
"sync/atomic"
"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/chaincfg"
"github.com/btcsuite/btcd/chaincfg/chainhash"
"github.com/btcsuite/btcd/wire"
"github.com/btcsuite/go-socks/socks"
"github.com/davecgh/go-spew/spew"
"github.com/decred/dcrd/lru"
)

const (
// 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
// inv message to a peer.
Expand Down Expand Up @@ -877,8 +878,8 @@ func (p *Peer) PushAddrMsg(addresses []*wire.NetAddress) ([]*wire.NetAddress, er
//
// This function is safe for concurrent access.
func (p *Peer) PushAddrV2Msg(addrs []*wire.NetAddressV2) (
[]*wire.NetAddressV2, error) {

[]*wire.NetAddressV2, error,
) {
count := len(addrs)

// Nothing to send.
Expand Down Expand Up @@ -1900,8 +1901,8 @@ func (p *Peer) QueueMessage(msg wire.Message, doneChan chan<- struct{}) {
//
// This function is safe for concurrent access.
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
// 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.
Expand Down Expand Up @@ -2152,7 +2153,7 @@ func (p *Peer) writeLocalVersionMsg() error {
// writeSendAddrV2Msg writes our sendaddrv2 message to the remote peer if the
// peer supports protocol version 70016 and above.
func (p *Peer) writeSendAddrV2Msg(pver uint32) error {
if pver < wire.AddrV2Version {
if pver < wire.SendAddrV2Version {
return nil
}

Expand Down Expand Up @@ -2180,7 +2181,7 @@ func (p *Peer) waitToFinishNegotiation(pver uint32) error {

switch m := remoteMsg.(type) {
case *wire.MsgSendAddrV2:
if pver >= wire.AddrV2Version {
if pver >= wire.SendAddrV2Version {
p.flagsMtx.Lock()
p.sendAddrV2 = true
p.flagsMtx.Unlock()
Expand Down
14 changes: 9 additions & 5 deletions wire/message.go
Original file line number Diff line number Diff line change
@@ -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
// license that can be found in the LICENSE file.

Expand Down Expand Up @@ -59,6 +59,7 @@ const (
CmdCFHeaders = "cfheaders"
CmdCFCheckpt = "cfcheckpt"
CmdSendAddrV2 = "sendaddrv2"
CmdWTxIdRelay = "wtxidrelay"
)

// MessageEncoding represents the wire message encoding format to be used.
Expand Down Expand Up @@ -111,6 +112,9 @@ func makeEmptyMessage(command string) (Message, error) {
case CmdSendAddrV2:
msg = &MsgSendAddrV2{}

case CmdWTxIdRelay:
msg = &MsgWTxIdRelay{}

case CmdGetAddr:
msg = &MsgGetAddr{}

Expand Down Expand Up @@ -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
// messages.
func WriteMessageWithEncodingN(w io.Writer, msg Message, pver uint32,
btcnet BitcoinNet, encoding MessageEncoding) (int, error) {

btcnet BitcoinNet, encoding MessageEncoding,
) (int, error) {
totalBytes := 0

// Enforce max command size.
Expand Down Expand Up @@ -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
// decoding wire messages.
func ReadMessageWithEncodingN(r io.Reader, pver uint32, btcnet BitcoinNet,
enc MessageEncoding) (int, Message, []byte, error) {

enc MessageEncoding,
) (int, Message, []byte, error) {
totalBytes := 0
n, hdr, err := readMessageHeader(r)
totalBytes += n
Expand Down
13 changes: 13 additions & 0 deletions wire/msgsendaddrv2.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package wire

import (
"fmt"
"io"
)

Expand All @@ -14,12 +15,24 @@ type MsgSendAddrV2 struct{}
// BtcDecode decodes r using the bitcoin protocol encoding into the receiver.
// This is part of the Message interface implementation.
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
}

// BtcEncode encodes the receiver to w using the bitcoin protocol encoding.
// This is part of the Message interface implementation.
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
}

Expand Down
193 changes: 193 additions & 0 deletions wire/msgsendaddrv2_test.go
Original file line number Diff line number Diff line change
@@ -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
}
}
}
Loading
Loading