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