version.go raw

   1  package btcwire
   2  
   3  import (
   4  	"fmt"
   5  )
   6  
   7  // ProtocolVersion is the peer protocol version implemented by this package.
   8  // It advertises support for compact filters, witness data, and the
   9  // sendaddrv2 and wtxidrelay messages.
  10  const ProtocolVersion = 70016
  11  
  12  // Service bits advertised by peers in the version message and in network
  13  // addresses.
  14  const (
  15  	// ServiceNodeNetwork indicates a peer that can serve the full block chain.
  16  	ServiceNodeNetwork uint64 = 1
  17  
  18  	// ServiceNodeWitness indicates a peer that can serve witness data.
  19  	ServiceNodeWitness uint64 = 1 << 3
  20  
  21  	// ServiceNodeCompactFilters indicates a peer that can serve BIP157
  22  	// compact filters.
  23  	ServiceNodeCompactFilters uint64 = 1 << 6
  24  )
  25  
  26  // MaxUserAgentSize is the largest user agent string accepted in a version
  27  // message, as specified by BIP14.
  28  const MaxUserAgentSize = 256
  29  
  30  // Version is the first message exchanged with a peer. It announces the
  31  // protocol version, the services each side offers, and the sender's view of
  32  // the chain tip.
  33  type Version struct {
  34  	// ProtocolVersion is the sender's protocol version.
  35  	ProtocolVersion int32
  36  
  37  	// Services is the set of services offered by the sender.
  38  	Services uint64
  39  
  40  	// Timestamp is the sender's time in seconds since the Unix epoch.
  41  	Timestamp int64
  42  
  43  	// AddrRecv is the address the sender believes this message is reaching.
  44  	AddrRecv NetAddress
  45  
  46  	// AddrFrom is the address of the sender.
  47  	AddrFrom NetAddress
  48  
  49  	// Nonce is a randomly generated value used to detect self connections.
  50  	Nonce uint64
  51  
  52  	// UserAgent is the BIP14 user agent string.
  53  	UserAgent string
  54  
  55  	// LastBlock is the height of the sender's best block.
  56  	LastBlock int32
  57  
  58  	// Relay is whether the sender wants to receive unannounced transactions.
  59  	// When decoding a payload that predates the field it defaults to true,
  60  	// matching the behaviour of Bitcoin Core.
  61  	Relay bool
  62  }
  63  
  64  // EncodePayload returns the wire encoding of the version message. Every
  65  // integer is little endian except the ports inside the network addresses,
  66  // which are big endian.
  67  func (v *Version) EncodePayload() ([]byte, error) {
  68  	if len(v.UserAgent) > MaxUserAgentSize {
  69  		return nil, fmt.Errorf(
  70  			"btcwire: user agent is %d bytes, maximum is %d: %w",
  71  			len(v.UserAgent), MaxUserAgentSize, ErrInvalidPayload,
  72  		)
  73  	}
  74  	var e Encoder
  75  	e.Uint32(uint32(v.ProtocolVersion))
  76  	e.Uint64(v.Services)
  77  	e.Uint64(uint64(v.Timestamp))
  78  	v.AddrRecv.encode(&e)
  79  	v.AddrFrom.encode(&e)
  80  	e.Uint64(v.Nonce)
  81  	if err := WriteVarBytes(&e, []byte(v.UserAgent)); err != nil {
  82  		return nil, fmt.Errorf("btcwire: encoding user agent: %w", err)
  83  	}
  84  	e.Uint32(uint32(v.LastBlock))
  85  	if v.Relay {
  86  		e.Uint8(1)
  87  	} else {
  88  		e.Uint8(0)
  89  	}
  90  	return e.Bytes(), nil
  91  }
  92  
  93  // DecodePayload replaces v with the version message decoded from b. Unknown
  94  // trailing bytes are ignored so that newer protocol fields do not break
  95  // decoding.
  96  func (v *Version) DecodePayload(b []byte) error {
  97  	d := NewDecoder(b)
  98  	var (
  99  		out Version
 100  		err error
 101  	)
 102  	pv, err := d.Uint32()
 103  	if err != nil {
 104  		return fmt.Errorf("btcwire: decoding version protocol version: %w", err)
 105  	}
 106  	out.ProtocolVersion = int32(pv)
 107  	if out.Services, err = d.Uint64(); err != nil {
 108  		return fmt.Errorf("btcwire: decoding version services: %w", err)
 109  	}
 110  	timestamp, err := d.Uint64()
 111  	if err != nil {
 112  		return fmt.Errorf("btcwire: decoding version timestamp: %w", err)
 113  	}
 114  	out.Timestamp = int64(timestamp)
 115  	if err = out.AddrRecv.decode(d); err != nil {
 116  		return fmt.Errorf("btcwire: decoding version receiving address: %w", err)
 117  	}
 118  	if err = out.AddrFrom.decode(d); err != nil {
 119  		return fmt.Errorf("btcwire: decoding version sending address: %w", err)
 120  	}
 121  	if out.Nonce, err = d.Uint64(); err != nil {
 122  		return fmt.Errorf("btcwire: decoding version nonce: %w", err)
 123  	}
 124  	userAgent, err := ReadVarBytes(d, MaxUserAgentSize)
 125  	if err != nil {
 126  		return fmt.Errorf("btcwire: decoding version user agent: %w", err)
 127  	}
 128  	out.UserAgent = string(userAgent)
 129  	lastBlock, err := d.Uint32()
 130  	if err != nil {
 131  		return fmt.Errorf("btcwire: decoding version last block: %w", err)
 132  	}
 133  	out.LastBlock = int32(lastBlock)
 134  	// The relay flag is optional: it was added in protocol version 70001.
 135  	out.Relay = true
 136  	if d.Remaining() > 0 {
 137  		relay, err := d.Uint8()
 138  		if err != nil {
 139  			return fmt.Errorf("btcwire: decoding version relay flag: %w", err)
 140  		}
 141  		out.Relay = relay != 0
 142  	}
 143  	*v = out
 144  	return nil
 145  }
 146  
 147  // VerAck acknowledges a peer's version message.
 148  type VerAck struct{}
 149  
 150  // EncodePayload returns the empty verack payload.
 151  func (v *VerAck) EncodePayload() ([]byte, error) {
 152  	return encodeEmptyPayload()
 153  }
 154  
 155  // DecodePayload verifies that a verack payload is empty.
 156  func (v *VerAck) DecodePayload(b []byte) error {
 157  	return decodeEmptyPayload("verack", b)
 158  }
 159  
 160  // SendHeaders asks a peer to announce new blocks with a headers message
 161  // instead of an inv message.
 162  type SendHeaders struct{}
 163  
 164  // EncodePayload returns the empty sendheaders payload.
 165  func (s *SendHeaders) EncodePayload() ([]byte, error) {
 166  	return encodeEmptyPayload()
 167  }
 168  
 169  // DecodePayload verifies that a sendheaders payload is empty.
 170  func (s *SendHeaders) DecodePayload(b []byte) error {
 171  	return decodeEmptyPayload("sendheaders", b)
 172  }
 173  
 174  // WtxidRelay tells a peer to compute transaction relay identifiers from the
 175  // wtxid.
 176  type WtxidRelay struct{}
 177  
 178  // EncodePayload returns the empty wtxidrelay payload.
 179  func (w *WtxidRelay) EncodePayload() ([]byte, error) {
 180  	return encodeEmptyPayload()
 181  }
 182  
 183  // DecodePayload verifies that a wtxidrelay payload is empty.
 184  func (w *WtxidRelay) DecodePayload(b []byte) error {
 185  	return decodeEmptyPayload("wtxidrelay", b)
 186  }
 187  
 188  // SendAddrV2 tells a peer that the sender understands the addrv2 message.
 189  type SendAddrV2 struct{}
 190  
 191  // EncodePayload returns the empty sendaddrv2 payload.
 192  func (s *SendAddrV2) EncodePayload() ([]byte, error) {
 193  	return encodeEmptyPayload()
 194  }
 195  
 196  // DecodePayload verifies that a sendaddrv2 payload is empty.
 197  func (s *SendAddrV2) DecodePayload(b []byte) error {
 198  	return decodeEmptyPayload("sendaddrv2", b)
 199  }
 200  
 201  // Ping is sent to check that a peer is still reachable.
 202  type Ping struct {
 203  	// Nonce is echoed by the peer in its pong.
 204  	Nonce uint64
 205  }
 206  
 207  // EncodePayload returns the wire encoding of the ping message.
 208  func (p *Ping) EncodePayload() ([]byte, error) {
 209  	return encodeNonceMessage(p.Nonce)
 210  }
 211  
 212  // DecodePayload replaces p with the ping message decoded from b.
 213  func (p *Ping) DecodePayload(b []byte) error {
 214  	nonce, err := decodeNonceMessage("ping", b)
 215  	if err != nil {
 216  		return err
 217  	}
 218  	p.Nonce = nonce
 219  	return nil
 220  }
 221  
 222  // Pong answers a ping.
 223  type Pong struct {
 224  	// Nonce is the nonce of the ping being answered.
 225  	Nonce uint64
 226  }
 227  
 228  // EncodePayload returns the wire encoding of the pong message.
 229  func (p *Pong) EncodePayload() ([]byte, error) {
 230  	return encodeNonceMessage(p.Nonce)
 231  }
 232  
 233  // DecodePayload replaces p with the pong message decoded from b.
 234  func (p *Pong) DecodePayload(b []byte) error {
 235  	nonce, err := decodeNonceMessage("pong", b)
 236  	if err != nil {
 237  		return err
 238  	}
 239  	p.Nonce = nonce
 240  	return nil
 241  }
 242  
 243  // FeeFilter asks a peer to announce only transactions that pay at least
 244  // FeeRate satoshis per kilobyte.
 245  type FeeFilter struct {
 246  	// FeeRate is the minimum fee rate in satoshis per kilobyte.
 247  	FeeRate int64
 248  }
 249  
 250  // EncodePayload returns the wire encoding of the feefilter message.
 251  func (f *FeeFilter) EncodePayload() ([]byte, error) {
 252  	var e Encoder
 253  	e.Uint64(uint64(f.FeeRate))
 254  	return e.Bytes(), nil
 255  }
 256  
 257  // DecodePayload replaces f with the feefilter message decoded from b.
 258  func (f *FeeFilter) DecodePayload(b []byte) error {
 259  	if len(b) != 8 {
 260  		return fmt.Errorf(
 261  			"btcwire: feefilter payload must be 8 bytes, got %d: %w",
 262  			len(b), ErrInvalidPayload,
 263  		)
 264  	}
 265  	d := NewDecoder(b)
 266  	rate, err := d.Int64()
 267  	if err != nil {
 268  		return fmt.Errorf("btcwire: decoding feefilter rate: %w", err)
 269  	}
 270  	f.FeeRate = rate
 271  	return nil
 272  }
 273  
 274  // encodeEmptyPayload is the EncodePayload implementation shared by messages
 275  // whose payload has no fields.
 276  func encodeEmptyPayload() ([]byte, error) {
 277  	return nil, nil
 278  }
 279  
 280  // decodeEmptyPayload rejects a payload for a message whose payload must be
 281  // empty.
 282  func decodeEmptyPayload(name string, b []byte) error {
 283  	if len(b) != 0 {
 284  		return fmt.Errorf(
 285  			"btcwire: %s payload must be empty, got %d bytes: %w",
 286  			name, len(b), ErrInvalidPayload,
 287  		)
 288  	}
 289  	return nil
 290  }
 291  
 292  // encodeNonceMessage encodes the payload shared by ping and pong.
 293  func encodeNonceMessage(nonce uint64) ([]byte, error) {
 294  	var e Encoder
 295  	e.Uint64(nonce)
 296  	return e.Bytes(), nil
 297  }
 298  
 299  // decodeNonceMessage decodes the payload shared by ping and pong.
 300  func decodeNonceMessage(name string, b []byte) (uint64, error) {
 301  	if len(b) != 8 {
 302  		return 0, fmt.Errorf(
 303  			"btcwire: %s payload must be 8 bytes, got %d: %w",
 304  			name, len(b), ErrInvalidPayload,
 305  		)
 306  	}
 307  	nonce, err := NewDecoder(b).Uint64()
 308  	if err != nil {
 309  		return 0, fmt.Errorf("btcwire: decoding %s nonce: %w", name, err)
 310  	}
 311  	return nonce, nil
 312  }
 313