wire, peer: fix broken ibd

IBD for new nodes were broken due to the version handshake failing
between nodes that recognized wtxid based relays.  Reverting the changes
that were made so that the node is able to connect to those nodes.
This commit is contained in:
Calvin Kim 2024-11-29 15:00:11 +09:00
parent e9d95eed43
commit 48c02954d2
7 changed files with 44 additions and 52 deletions

View file

@ -18,19 +18,18 @@ 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.SendAddrV2Version MaxProtocolVersion = wire.AddrV2Version
// 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.
@ -878,8 +877,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.
@ -1901,8 +1900,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.
@ -2153,7 +2152,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.SendAddrV2Version { if pver < wire.AddrV2Version {
return nil return nil
} }
@ -2181,7 +2180,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.SendAddrV2Version { if pver >= wire.AddrV2Version {
p.flagsMtx.Lock() p.flagsMtx.Lock()
p.sendAddrV2 = true p.sendAddrV2 = true
p.flagsMtx.Unlock() p.flagsMtx.Unlock()

View file

@ -112,9 +112,6 @@ 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{}
@ -280,8 +277,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, btcnet BitcoinNet, encoding MessageEncoding) (int, error) {
) (int, error) {
totalBytes := 0 totalBytes := 0
// Enforce max command size. // Enforce max command size.
@ -357,8 +354,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, enc MessageEncoding) (int, Message, []byte, error) {
) (int, Message, []byte, error) {
totalBytes := 0 totalBytes := 0
n, hdr, err := readMessageHeader(r) n, hdr, err := readMessageHeader(r)
totalBytes += n totalBytes += n

View file

@ -15,7 +15,7 @@ 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 { if pver < AddrV2Version {
str := fmt.Sprintf("sendaddrv2 message invalid for protocol "+ str := fmt.Sprintf("sendaddrv2 message invalid for protocol "+
"version %d", pver) "version %d", pver)
return messageError("MsgSendAddrV2.BtcDecode", str) return messageError("MsgSendAddrV2.BtcDecode", str)
@ -27,7 +27,7 @@ func (msg *MsgSendAddrV2) BtcDecode(r io.Reader, pver uint32, enc MessageEncodin
// 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 { if pver < AddrV2Version {
str := fmt.Sprintf("sendaddrv2 message invalid for protocol "+ str := fmt.Sprintf("sendaddrv2 message invalid for protocol "+
"version %d", pver) "version %d", pver)
return messageError("MsgSendAddrV2.BtcEncode", str) return messageError("MsgSendAddrV2.BtcEncode", str)

View file

@ -45,7 +45,7 @@ func TestSendAddrV2(t *testing.T) {
// Older protocol versions should fail encode since message didn't // Older protocol versions should fail encode since message didn't
// exist yet. // exist yet.
oldPver := SendAddrV2Version - 1 oldPver := AddrV2Version - 1
err = msg.BtcEncode(&buf, oldPver, enc) err = msg.BtcEncode(&buf, oldPver, enc)
if err == nil { if err == nil {
s := "encode of MsgSendAddrV2 passed for old protocol " + s := "encode of MsgSendAddrV2 passed for old protocol " +
@ -72,10 +72,10 @@ func TestSendAddrV2(t *testing.T) {
} }
// TestSendAddrV2BIP0130 tests the MsgSendAddrV2 API against the protocol // TestSendAddrV2BIP0130 tests the MsgSendAddrV2 API against the protocol
// prior to version SendAddrV2Version. // prior to version AddrV2Version.
func TestSendAddrV2BIP0130(t *testing.T) { func TestSendAddrV2BIP0130(t *testing.T) {
// Use the protocol version just prior to SendAddrV2Version changes. // Use the protocol version just prior to AddrV2Version changes.
pver := SendAddrV2Version - 1 pver := AddrV2Version - 1
enc := BaseEncoding enc := BaseEncoding
msg := NewMsgSendAddrV2() msg := NewMsgSendAddrV2()
@ -98,7 +98,7 @@ func TestSendAddrV2BIP0130(t *testing.T) {
} }
// TestSendAddrV2CrossProtocol tests the MsgSendAddrV2 API when encoding with // TestSendAddrV2CrossProtocol tests the MsgSendAddrV2 API when encoding with
// the latest protocol version and decoding with SendAddrV2Version. // the latest protocol version and decoding with AddrV2Version.
func TestSendAddrV2CrossProtocol(t *testing.T) { func TestSendAddrV2CrossProtocol(t *testing.T) {
enc := BaseEncoding enc := BaseEncoding
msg := NewMsgSendAddrV2() msg := NewMsgSendAddrV2()
@ -113,7 +113,7 @@ func TestSendAddrV2CrossProtocol(t *testing.T) {
// Decode with old protocol version. // Decode with old protocol version.
readmsg := NewMsgSendAddrV2() readmsg := NewMsgSendAddrV2()
err = readmsg.BtcDecode(&buf, SendAddrV2Version, enc) err = readmsg.BtcDecode(&buf, AddrV2Version, enc)
if err != nil { if err != nil {
t.Errorf("decode of MsgSendAddrV2 failed [%v] err <%v>", buf, t.Errorf("decode of MsgSendAddrV2 failed [%v] err <%v>", buf,
err) err)
@ -142,21 +142,21 @@ func TestSendAddrV2Wire(t *testing.T) {
BaseEncoding, BaseEncoding,
}, },
// Protocol version SendAddrV2Version+1 // Protocol version AddrV2Version+1
{ {
msgSendAddrV2, msgSendAddrV2,
msgSendAddrV2, msgSendAddrV2,
msgSendAddrV2Encoded, msgSendAddrV2Encoded,
SendAddrV2Version + 1, AddrV2Version + 1,
BaseEncoding, BaseEncoding,
}, },
// Protocol version SendAddrV2Version // Protocol version AddrV2Version
{ {
msgSendAddrV2, msgSendAddrV2,
msgSendAddrV2, msgSendAddrV2,
msgSendAddrV2Encoded, msgSendAddrV2Encoded,
SendAddrV2Version, AddrV2Version,
BaseEncoding, BaseEncoding,
}, },
} }

View file

@ -19,7 +19,7 @@ type MsgWTxIdRelay 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 *MsgWTxIdRelay) BtcDecode(r io.Reader, pver uint32, enc MessageEncoding) error { func (msg *MsgWTxIdRelay) BtcDecode(r io.Reader, pver uint32, enc MessageEncoding) error {
if pver < WTxIdRelayVersion { if pver < AddrV2Version {
str := fmt.Sprintf("wtxidrelay message invalid for protocol "+ str := fmt.Sprintf("wtxidrelay message invalid for protocol "+
"version %d", pver) "version %d", pver)
return messageError("MsgWTxIdRelay.BtcDecode", str) return messageError("MsgWTxIdRelay.BtcDecode", str)
@ -31,7 +31,7 @@ func (msg *MsgWTxIdRelay) BtcDecode(r io.Reader, pver uint32, enc MessageEncodin
// 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 *MsgWTxIdRelay) BtcEncode(w io.Writer, pver uint32, enc MessageEncoding) error { func (msg *MsgWTxIdRelay) BtcEncode(w io.Writer, pver uint32, enc MessageEncoding) error {
if pver < WTxIdRelayVersion { if pver < AddrV2Version {
str := fmt.Sprintf("wtxidrelay message invalid for protocol "+ str := fmt.Sprintf("wtxidrelay message invalid for protocol "+
"version %d", pver) "version %d", pver)
return messageError("MsgWTxIdRelay.BtcEncode", str) return messageError("MsgWTxIdRelay.BtcEncode", str)

View file

@ -45,7 +45,7 @@ func TestWTxIdRelay(t *testing.T) {
// Older protocol versions should fail encode since message didn't // Older protocol versions should fail encode since message didn't
// exist yet. // exist yet.
oldPver := WTxIdRelayVersion - 1 oldPver := AddrV2Version - 1
err = msg.BtcEncode(&buf, oldPver, enc) err = msg.BtcEncode(&buf, oldPver, enc)
if err == nil { if err == nil {
s := "encode of MsgWTxIdRelay passed for old protocol " + s := "encode of MsgWTxIdRelay passed for old protocol " +
@ -72,10 +72,10 @@ func TestWTxIdRelay(t *testing.T) {
} }
// TestWTxIdRelayBIP0130 tests the MsgWTxIdRelay API against the protocol // TestWTxIdRelayBIP0130 tests the MsgWTxIdRelay API against the protocol
// prior to version WTxIdRelayVersion. // prior to version AddrV2Version.
func TestWTxIdRelayBIP0130(t *testing.T) { func TestWTxIdRelayBIP0130(t *testing.T) {
// Use the protocol version just prior to WTxIdRelayVersion changes. // Use the protocol version just prior to AddrV2Version changes.
pver := WTxIdRelayVersion - 1 pver := AddrV2Version - 1
enc := BaseEncoding enc := BaseEncoding
msg := NewMsgWTxIdRelay() msg := NewMsgWTxIdRelay()
@ -98,7 +98,7 @@ func TestWTxIdRelayBIP0130(t *testing.T) {
} }
// TestWTxIdRelayCrossProtocol tests the MsgWTxIdRelay API when encoding with // TestWTxIdRelayCrossProtocol tests the MsgWTxIdRelay API when encoding with
// the latest protocol version and decoding with WTxIdRelayVersion. // the latest protocol version and decoding with AddrV2Version.
func TestWTxIdRelayCrossProtocol(t *testing.T) { func TestWTxIdRelayCrossProtocol(t *testing.T) {
enc := BaseEncoding enc := BaseEncoding
msg := NewMsgWTxIdRelay() msg := NewMsgWTxIdRelay()
@ -113,7 +113,7 @@ func TestWTxIdRelayCrossProtocol(t *testing.T) {
// Decode with old protocol version. // Decode with old protocol version.
readmsg := NewMsgWTxIdRelay() readmsg := NewMsgWTxIdRelay()
err = readmsg.BtcDecode(&buf, WTxIdRelayVersion, enc) err = readmsg.BtcDecode(&buf, AddrV2Version, enc)
if err != nil { if err != nil {
t.Errorf("decode of MsgWTxIdRelay failed [%v] err <%v>", buf, t.Errorf("decode of MsgWTxIdRelay failed [%v] err <%v>", buf,
err) err)
@ -142,21 +142,21 @@ func TestWTxIdRelayWire(t *testing.T) {
BaseEncoding, BaseEncoding,
}, },
// Protocol version WTxIdRelayVersion+1 // Protocol version AddrV2Version+1
{ {
msgWTxIdRelay, msgWTxIdRelay,
msgWTxIdRelay, msgWTxIdRelay,
msgWTxIdRelayEncoded, msgWTxIdRelayEncoded,
WTxIdRelayVersion + 1, AddrV2Version + 1,
BaseEncoding, BaseEncoding,
}, },
// Protocol version WTxIdRelayVersion // Protocol version AddrV2Version
{ {
msgWTxIdRelay, msgWTxIdRelay,
msgWTxIdRelay, msgWTxIdRelay,
msgWTxIdRelayEncoded, msgWTxIdRelayEncoded,
WTxIdRelayVersion, AddrV2Version,
BaseEncoding, BaseEncoding,
}, },
} }

View file

@ -52,16 +52,12 @@ const (
// feefilter message. // feefilter message.
FeeFilterVersion uint32 = 70013 FeeFilterVersion uint32 = 70013
// SendAddrV2Version is the protocol version which added two new // AddrV2Version is the protocol version which added two new messages.
// messages. sendaddrv2 is sent during the version-verack handshake // sendaddrv2 is sent during the version-verack handshake and signals
// and signals support for sending and receiving the addrv2 message. In // support for sending and receiving the addrv2 message. In the future,
// the future, new messages that occur during the version-verack // new messages that occur during the version-verack handshake will not
// handshake will not come with a protocol version bump. // come with a protocol version bump.
// In addition, wtxidrelay was also added as an optional message in the AddrV2Version uint32 = 70016
// same protocol version.
SendAddrV2Version uint32 = 70016
WTxIdRelayVersion uint32 = SendAddrV2Version
AddrV2Version uint32 = SendAddrV2Version // Keep for upstream compatibility
) )
const ( const (