1// Copyright (c) 2013-2016 The btcsuite developers
2// Use of this source code is governed by an ISC
3// license that can be found in the LICENSE file.
4
5package wire
6
7import (
8	"fmt"
9	"strconv"
10	"strings"
11)
12
13// XXX pedro: we will probably need to bump this.
14const (
15	// ProtocolVersion is the latest protocol version this package supports.
16	ProtocolVersion uint32 = 70013
17
18	// MultipleAddressVersion is the protocol version which added multiple
19	// addresses per message (pver >= MultipleAddressVersion).
20	MultipleAddressVersion uint32 = 209
21
22	// NetAddressTimeVersion is the protocol version which added the
23	// timestamp field (pver >= NetAddressTimeVersion).
24	NetAddressTimeVersion uint32 = 31402
25
26	// BIP0031Version is the protocol version AFTER which a pong message
27	// and nonce field in ping were added (pver > BIP0031Version).
28	BIP0031Version uint32 = 60000
29
30	// BIP0035Version is the protocol version which added the mempool
31	// message (pver >= BIP0035Version).
32	BIP0035Version uint32 = 60002
33
34	// BIP0037Version is the protocol version which added new connection
35	// bloom filtering related messages and extended the version message
36	// with a relay flag (pver >= BIP0037Version).
37	BIP0037Version uint32 = 70001
38
39	// RejectVersion is the protocol version which added a new reject
40	// message.
41	RejectVersion uint32 = 70002
42
43	// BIP0111Version is the protocol version which added the SFNodeBloom
44	// service flag.
45	BIP0111Version uint32 = 70011
46
47	// SendHeadersVersion is the protocol version which added a new
48	// sendheaders message.
49	SendHeadersVersion uint32 = 70012
50
51	// FeeFilterVersion is the protocol version which added a new
52	// feefilter message.
53	FeeFilterVersion uint32 = 70013
54)
55
56// ServiceFlag identifies services supported by a bitcoin peer.
57type ServiceFlag uint64
58
59const (
60	// SFNodeNetwork is a flag used to indicate a peer is a full node.
61	SFNodeNetwork ServiceFlag = 1 << iota
62
63	// SFNodeGetUTXO is a flag used to indicate a peer supports the
64	// getutxos and utxos commands (BIP0064).
65	SFNodeGetUTXO
66
67	// SFNodeBloom is a flag used to indicate a peer supports bloom
68	// filtering.
69	SFNodeBloom
70
71	// SFNodeWitness is a flag used to indicate a peer supports blocks
72	// and transactions including witness data (BIP0144).
73	SFNodeWitness
74
75	// SFNodeXthin is a flag used to indicate a peer supports xthin blocks.
76	SFNodeXthin
77
78	// SFNodeBit5 is a flag used to indicate a peer supports a service
79	// defined by bit 5.
80	SFNodeBit5
81
82	// SFNodeCF is a flag used to indicate a peer supports committed
83	// filters (CFs).
84	SFNodeCF
85
86	// SFNode2X is a flag used to indicate a peer is running the Segwit2X
87	// software.
88	SFNode2X
89)
90
91// Map of service flags back to their constant names for pretty printing.
92var sfStrings = map[ServiceFlag]string{
93	SFNodeNetwork: "SFNodeNetwork",
94	SFNodeGetUTXO: "SFNodeGetUTXO",
95	SFNodeBloom:   "SFNodeBloom",
96	SFNodeWitness: "SFNodeWitness",
97	SFNodeXthin:   "SFNodeXthin",
98	SFNodeBit5:    "SFNodeBit5",
99	SFNodeCF:      "SFNodeCF",
100	SFNode2X:      "SFNode2X",
101}
102
103// orderedSFStrings is an ordered list of service flags from highest to
104// lowest.
105var orderedSFStrings = []ServiceFlag{
106	SFNodeNetwork,
107	SFNodeGetUTXO,
108	SFNodeBloom,
109	SFNodeWitness,
110	SFNodeXthin,
111	SFNodeBit5,
112	SFNodeCF,
113	SFNode2X,
114}
115
116// String returns the ServiceFlag in human-readable form.
117func (f ServiceFlag) String() string {
118	// No flags are set.
119	if f == 0 {
120		return "0x0"
121	}
122
123	// Add individual bit flags.
124	s := ""
125	for _, flag := range orderedSFStrings {
126		if f&flag == flag {
127			s += sfStrings[flag] + "|"
128			f -= flag
129		}
130	}
131
132	// Add any remaining flags which aren't accounted for as hex.
133	s = strings.TrimRight(s, "|")
134	if f != 0 {
135		s += "|0x" + strconv.FormatUint(uint64(f), 16)
136	}
137	s = strings.TrimLeft(s, "|")
138	return s
139}
140
141// BitcoinNet represents which bitcoin network a message belongs to.
142type BitcoinNet uint32
143
144// Constants used to indicate the message bitcoin network.  They can also be
145// used to seek to the next message when a stream's state is unknown, but
146// this package does not provide that functionality since it's generally a
147// better idea to simply disconnect clients that are misbehaving over TCP.
148const (
149	// MainNet represents the main bitcoin network.
150	MainNet BitcoinNet = 0xd9b4bef9
151
152	// TestNet represents the regression test network.
153	TestNet BitcoinNet = 0xdab5bffa
154
155	// TestNet3 represents the test network (version 3).
156	TestNet3 BitcoinNet = 0x0709110b
157
158	// SimNet represents the simulation test network.
159	SimNet BitcoinNet = 0x12141c16
160)
161
162// bnStrings is a map of bitcoin networks back to their constant names for
163// pretty printing.
164var bnStrings = map[BitcoinNet]string{
165	MainNet:  "MainNet",
166	TestNet:  "TestNet",
167	TestNet3: "TestNet3",
168	SimNet:   "SimNet",
169}
170
171// String returns the BitcoinNet in human-readable form.
172func (n BitcoinNet) String() string {
173	if s, ok := bnStrings[n]; ok {
174		return s
175	}
176
177	return fmt.Sprintf("Unknown BitcoinNet (%d)", uint32(n))
178}
179