mirror of
https://github.com/btcsuite/btcd.git
synced 2024-11-19 18:00:11 +01:00
103 lines
2.7 KiB
Go
103 lines
2.7 KiB
Go
package wire
|
|
|
|
import (
|
|
"fmt"
|
|
"io"
|
|
)
|
|
|
|
// MaxV2AddrPerMsg is the maximum number of version 2 addresses that will exist
|
|
// in a single addrv2 message (MsgAddrV2).
|
|
const MaxV2AddrPerMsg = 1000
|
|
|
|
// MsgAddrV2 implements the Message interface and represents a bitcoin addrv2
|
|
// message that can support longer-length addresses like torv3, cjdns, and i2p.
|
|
// It is used to gossip addresses on the network. Each message is limited to
|
|
// MaxV2AddrPerMsg addresses. This is the same limit as MsgAddr.
|
|
type MsgAddrV2 struct {
|
|
AddrList []*NetAddressV2
|
|
}
|
|
|
|
// BtcDecode decodes r using the bitcoin protocol into a MsgAddrV2.
|
|
func (m *MsgAddrV2) BtcDecode(r io.Reader, pver uint32,
|
|
enc MessageEncoding) error {
|
|
|
|
count, err := ReadVarInt(r, pver)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// Limit to max addresses per message.
|
|
if count > MaxV2AddrPerMsg {
|
|
str := fmt.Sprintf("too many addresses for message [count %v,"+
|
|
" max %v]", count, MaxV2AddrPerMsg)
|
|
return messageError("MsgAddrV2.BtcDecode", str)
|
|
}
|
|
|
|
addrList := make([]NetAddressV2, count)
|
|
m.AddrList = make([]*NetAddressV2, 0, count)
|
|
for i := uint64(0); i < count; i++ {
|
|
na := &addrList[i]
|
|
err := readNetAddressV2(r, pver, na)
|
|
switch err {
|
|
case ErrSkippedNetworkID:
|
|
// This may be a network ID we don't know of, but is
|
|
// still valid. We can safely skip those.
|
|
continue
|
|
case ErrInvalidAddressSize:
|
|
// The encoding used by the peer does not follow
|
|
// BIP-155 and we should stop processing this message.
|
|
return err
|
|
}
|
|
|
|
m.AddrList = append(m.AddrList, na)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// BtcEncode encodes the MsgAddrV2 into a writer w.
|
|
func (m *MsgAddrV2) BtcEncode(w io.Writer, pver uint32,
|
|
enc MessageEncoding) error {
|
|
|
|
count := len(m.AddrList)
|
|
if count > MaxV2AddrPerMsg {
|
|
str := fmt.Sprintf("too many addresses for message [count %v,"+
|
|
" max %v]", count, MaxV2AddrPerMsg)
|
|
return messageError("MsgAddrV2.BtcEncode", str)
|
|
}
|
|
|
|
err := WriteVarInt(w, pver, uint64(count))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
for _, na := range m.AddrList {
|
|
err = writeNetAddressV2(w, pver, na)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// Command returns the protocol command string for MsgAddrV2.
|
|
func (m *MsgAddrV2) Command() string {
|
|
return CmdAddrV2
|
|
}
|
|
|
|
// MaxPayloadLength returns the maximum length payload possible for MsgAddrV2.
|
|
func (m *MsgAddrV2) MaxPayloadLength(pver uint32) uint32 {
|
|
// The varint that can store the maximum number of addresses is 3 bytes
|
|
// long. The maximum payload is then 3 + 1000 * maxNetAddressV2Payload.
|
|
return 3 + (MaxV2AddrPerMsg * maxNetAddressV2Payload())
|
|
}
|
|
|
|
// NewMsgAddrV2 returns a new bitcoin addrv2 message that conforms to the
|
|
// Message interface.
|
|
func NewMsgAddrV2() *MsgAddrV2 {
|
|
return &MsgAddrV2{
|
|
AddrList: make([]*NetAddressV2, 0, MaxV2AddrPerMsg),
|
|
}
|
|
}
|