/workdir/bitcoin/src/protocol.h
Line | Count | Source (jump to first uncovered line) |
1 | | // Copyright (c) 2009-2010 Satoshi Nakamoto |
2 | | // Copyright (c) 2009-2022 The Bitcoin Core developers |
3 | | // Distributed under the MIT software license, see the accompanying |
4 | | // file COPYING or http://www.opensource.org/licenses/mit-license.php. |
5 | | |
6 | | #ifndef BITCOIN_PROTOCOL_H |
7 | | #define BITCOIN_PROTOCOL_H |
8 | | |
9 | | #include <kernel/messagestartchars.h> // IWYU pragma: export |
10 | | #include <netaddress.h> |
11 | | #include <primitives/transaction.h> |
12 | | #include <serialize.h> |
13 | | #include <streams.h> |
14 | | #include <uint256.h> |
15 | | #include <util/time.h> |
16 | | |
17 | | #include <array> |
18 | | #include <cstdint> |
19 | | #include <limits> |
20 | | #include <string> |
21 | | |
22 | | /** Message header. |
23 | | * (4) message start. |
24 | | * (12) command. |
25 | | * (4) size. |
26 | | * (4) checksum. |
27 | | */ |
28 | | class CMessageHeader |
29 | | { |
30 | | public: |
31 | | static constexpr size_t COMMAND_SIZE = 12; |
32 | | static constexpr size_t MESSAGE_SIZE_SIZE = 4; |
33 | | static constexpr size_t CHECKSUM_SIZE = 4; |
34 | | static constexpr size_t MESSAGE_SIZE_OFFSET = std::tuple_size_v<MessageStartChars> + COMMAND_SIZE; |
35 | | static constexpr size_t CHECKSUM_OFFSET = MESSAGE_SIZE_OFFSET + MESSAGE_SIZE_SIZE; |
36 | | static constexpr size_t HEADER_SIZE = std::tuple_size_v<MessageStartChars> + COMMAND_SIZE + MESSAGE_SIZE_SIZE + CHECKSUM_SIZE; |
37 | | |
38 | 870 | explicit CMessageHeader() = default; |
39 | | |
40 | | /** Construct a P2P message header from message-start characters, a command and the size of the message. |
41 | | * @note Passing in a `pszCommand` longer than COMMAND_SIZE will result in a run-time assertion error. |
42 | | */ |
43 | | CMessageHeader(const MessageStartChars& pchMessageStartIn, const char* pszCommand, unsigned int nMessageSizeIn); |
44 | | |
45 | | std::string GetCommand() const; |
46 | | bool IsCommandValid() const; |
47 | | |
48 | 30.9k | SERIALIZE_METHODS(CMessageHeader, obj) { READWRITE(obj.pchMessageStart, obj.pchCommand, obj.nMessageSize, obj.pchChecksum); } void CMessageHeader::SerializationOps<DataStream, CMessageHeader, ActionUnserialize>(CMessageHeader&, DataStream&, ActionUnserialize) Line | Count | Source | 48 | 13.5k | SERIALIZE_METHODS(CMessageHeader, obj) { READWRITE(obj.pchMessageStart, obj.pchCommand, obj.nMessageSize, obj.pchChecksum); } |
Unexecuted instantiation: void CMessageHeader::SerializationOps<DataStream, CMessageHeader const, ActionSerialize>(CMessageHeader const&, DataStream&, ActionSerialize) void CMessageHeader::SerializationOps<VectorWriter, CMessageHeader const, ActionSerialize>(CMessageHeader const&, VectorWriter&, ActionSerialize) Line | Count | Source | 48 | 17.4k | SERIALIZE_METHODS(CMessageHeader, obj) { READWRITE(obj.pchMessageStart, obj.pchCommand, obj.nMessageSize, obj.pchChecksum); } |
|
49 | | |
50 | | MessageStartChars pchMessageStart{}; |
51 | | char pchCommand[COMMAND_SIZE]{}; |
52 | | uint32_t nMessageSize{std::numeric_limits<uint32_t>::max()}; |
53 | | uint8_t pchChecksum[CHECKSUM_SIZE]{}; |
54 | | }; |
55 | | |
56 | | /** |
57 | | * Bitcoin protocol message types. When adding new message types, don't forget |
58 | | * to update ALL_NET_MESSAGE_TYPES below. |
59 | | */ |
60 | | namespace NetMsgType { |
61 | | /** |
62 | | * The version message provides information about the transmitting node to the |
63 | | * receiving node at the beginning of a connection. |
64 | | */ |
65 | | inline constexpr const char* VERSION{"version"}; |
66 | | /** |
67 | | * The verack message acknowledges a previously-received version message, |
68 | | * informing the connecting node that it can begin to send other messages. |
69 | | */ |
70 | | inline constexpr const char* VERACK{"verack"}; |
71 | | /** |
72 | | * The addr (IP address) message relays connection information for peers on the |
73 | | * network. |
74 | | */ |
75 | | inline constexpr const char* ADDR{"addr"}; |
76 | | /** |
77 | | * The addrv2 message relays connection information for peers on the network just |
78 | | * like the addr message, but is extended to allow gossiping of longer node |
79 | | * addresses (see BIP155). |
80 | | */ |
81 | | inline constexpr const char* ADDRV2{"addrv2"}; |
82 | | /** |
83 | | * The sendaddrv2 message signals support for receiving ADDRV2 messages (BIP155). |
84 | | * It also implies that its sender can encode as ADDRV2 and would send ADDRV2 |
85 | | * instead of ADDR to a peer that has signaled ADDRV2 support by sending SENDADDRV2. |
86 | | */ |
87 | | inline constexpr const char* SENDADDRV2{"sendaddrv2"}; |
88 | | /** |
89 | | * The inv message (inventory message) transmits one or more inventories of |
90 | | * objects known to the transmitting peer. |
91 | | */ |
92 | | inline constexpr const char* INV{"inv"}; |
93 | | /** |
94 | | * The getdata message requests one or more data objects from another node. |
95 | | */ |
96 | | inline constexpr const char* GETDATA{"getdata"}; |
97 | | /** |
98 | | * The merkleblock message is a reply to a getdata message which requested a |
99 | | * block using the inventory type MSG_MERKLEBLOCK. |
100 | | * @since protocol version 70001 as described by BIP37. |
101 | | */ |
102 | | inline constexpr const char* MERKLEBLOCK{"merkleblock"}; |
103 | | /** |
104 | | * The getblocks message requests an inv message that provides block header |
105 | | * hashes starting from a particular point in the block chain. |
106 | | */ |
107 | | inline constexpr const char* GETBLOCKS{"getblocks"}; |
108 | | /** |
109 | | * The getheaders message requests a headers message that provides block |
110 | | * headers starting from a particular point in the block chain. |
111 | | * @since protocol version 31800. |
112 | | */ |
113 | | inline constexpr const char* GETHEADERS{"getheaders"}; |
114 | | /** |
115 | | * The tx message transmits a single transaction. |
116 | | */ |
117 | | inline constexpr const char* TX{"tx"}; |
118 | | /** |
119 | | * The headers message sends one or more block headers to a node which |
120 | | * previously requested certain headers with a getheaders message. |
121 | | * @since protocol version 31800. |
122 | | */ |
123 | | inline constexpr const char* HEADERS{"headers"}; |
124 | | /** |
125 | | * The block message transmits a single serialized block. |
126 | | */ |
127 | | inline constexpr const char* BLOCK{"block"}; |
128 | | /** |
129 | | * The getaddr message requests an addr message from the receiving node, |
130 | | * preferably one with lots of IP addresses of other receiving nodes. |
131 | | */ |
132 | | inline constexpr const char* GETADDR{"getaddr"}; |
133 | | /** |
134 | | * The mempool message requests the TXIDs of transactions that the receiving |
135 | | * node has verified as valid but which have not yet appeared in a block. |
136 | | * @since protocol version 60002 as described by BIP35. |
137 | | * Only available with service bit NODE_BLOOM, see also BIP111. |
138 | | */ |
139 | | inline constexpr const char* MEMPOOL{"mempool"}; |
140 | | /** |
141 | | * The ping message is sent periodically to help confirm that the receiving |
142 | | * peer is still connected. |
143 | | */ |
144 | | inline constexpr const char* PING{"ping"}; |
145 | | /** |
146 | | * The pong message replies to a ping message, proving to the pinging node that |
147 | | * the ponging node is still alive. |
148 | | * @since protocol version 60001 as described by BIP31. |
149 | | */ |
150 | | inline constexpr const char* PONG{"pong"}; |
151 | | /** |
152 | | * The notfound message is a reply to a getdata message which requested an |
153 | | * object the receiving node does not have available for relay. |
154 | | * @since protocol version 70001. |
155 | | */ |
156 | | inline constexpr const char* NOTFOUND{"notfound"}; |
157 | | /** |
158 | | * The filterload message tells the receiving peer to filter all relayed |
159 | | * transactions and requested merkle blocks through the provided filter. |
160 | | * @since protocol version 70001 as described by BIP37. |
161 | | * Only available with service bit NODE_BLOOM since protocol version |
162 | | * 70011 as described by BIP111. |
163 | | */ |
164 | | inline constexpr const char* FILTERLOAD{"filterload"}; |
165 | | /** |
166 | | * The filteradd message tells the receiving peer to add a single element to a |
167 | | * previously-set bloom filter, such as a new public key. |
168 | | * @since protocol version 70001 as described by BIP37. |
169 | | * Only available with service bit NODE_BLOOM since protocol version |
170 | | * 70011 as described by BIP111. |
171 | | */ |
172 | | inline constexpr const char* FILTERADD{"filteradd"}; |
173 | | /** |
174 | | * The filterclear message tells the receiving peer to remove a previously-set |
175 | | * bloom filter. |
176 | | * @since protocol version 70001 as described by BIP37. |
177 | | * Only available with service bit NODE_BLOOM since protocol version |
178 | | * 70011 as described by BIP111. |
179 | | */ |
180 | | inline constexpr const char* FILTERCLEAR{"filterclear"}; |
181 | | /** |
182 | | * Indicates that a node prefers to receive new block announcements via a |
183 | | * "headers" message rather than an "inv". |
184 | | * @since protocol version 70012 as described by BIP130. |
185 | | */ |
186 | | inline constexpr const char* SENDHEADERS{"sendheaders"}; |
187 | | /** |
188 | | * The feefilter message tells the receiving peer not to inv us any txs |
189 | | * which do not meet the specified min fee rate. |
190 | | * @since protocol version 70013 as described by BIP133 |
191 | | */ |
192 | | inline constexpr const char* FEEFILTER{"feefilter"}; |
193 | | /** |
194 | | * Contains a 1-byte bool and 8-byte LE version number. |
195 | | * Indicates that a node is willing to provide blocks via "cmpctblock" messages. |
196 | | * May indicate that a node prefers to receive new block announcements via a |
197 | | * "cmpctblock" message rather than an "inv", depending on message contents. |
198 | | * @since protocol version 70014 as described by BIP 152 |
199 | | */ |
200 | | inline constexpr const char* SENDCMPCT{"sendcmpct"}; |
201 | | /** |
202 | | * Contains a CBlockHeaderAndShortTxIDs object - providing a header and |
203 | | * list of "short txids". |
204 | | * @since protocol version 70014 as described by BIP 152 |
205 | | */ |
206 | | inline constexpr const char* CMPCTBLOCK{"cmpctblock"}; |
207 | | /** |
208 | | * Contains a BlockTransactionsRequest |
209 | | * Peer should respond with "blocktxn" message. |
210 | | * @since protocol version 70014 as described by BIP 152 |
211 | | */ |
212 | | inline constexpr const char* GETBLOCKTXN{"getblocktxn"}; |
213 | | /** |
214 | | * Contains a BlockTransactions. |
215 | | * Sent in response to a "getblocktxn" message. |
216 | | * @since protocol version 70014 as described by BIP 152 |
217 | | */ |
218 | | inline constexpr const char* BLOCKTXN{"blocktxn"}; |
219 | | /** |
220 | | * getcfilters requests compact filters for a range of blocks. |
221 | | * Only available with service bit NODE_COMPACT_FILTERS as described by |
222 | | * BIP 157 & 158. |
223 | | */ |
224 | | inline constexpr const char* GETCFILTERS{"getcfilters"}; |
225 | | /** |
226 | | * cfilter is a response to a getcfilters request containing a single compact |
227 | | * filter. |
228 | | */ |
229 | | inline constexpr const char* CFILTER{"cfilter"}; |
230 | | /** |
231 | | * getcfheaders requests a compact filter header and the filter hashes for a |
232 | | * range of blocks, which can then be used to reconstruct the filter headers |
233 | | * for those blocks. |
234 | | * Only available with service bit NODE_COMPACT_FILTERS as described by |
235 | | * BIP 157 & 158. |
236 | | */ |
237 | | inline constexpr const char* GETCFHEADERS{"getcfheaders"}; |
238 | | /** |
239 | | * cfheaders is a response to a getcfheaders request containing a filter header |
240 | | * and a vector of filter hashes for each subsequent block in the requested range. |
241 | | */ |
242 | | inline constexpr const char* CFHEADERS{"cfheaders"}; |
243 | | /** |
244 | | * getcfcheckpt requests evenly spaced compact filter headers, enabling |
245 | | * parallelized download and validation of the headers between them. |
246 | | * Only available with service bit NODE_COMPACT_FILTERS as described by |
247 | | * BIP 157 & 158. |
248 | | */ |
249 | | inline constexpr const char* GETCFCHECKPT{"getcfcheckpt"}; |
250 | | /** |
251 | | * cfcheckpt is a response to a getcfcheckpt request containing a vector of |
252 | | * evenly spaced filter headers for blocks on the requested chain. |
253 | | */ |
254 | | inline constexpr const char* CFCHECKPT{"cfcheckpt"}; |
255 | | /** |
256 | | * Indicates that a node prefers to relay transactions via wtxid, rather than |
257 | | * txid. |
258 | | * @since protocol version 70016 as described by BIP 339. |
259 | | */ |
260 | | inline constexpr const char* WTXIDRELAY{"wtxidrelay"}; |
261 | | /** |
262 | | * Contains a 4-byte version number and an 8-byte salt. |
263 | | * The salt is used to compute short txids needed for efficient |
264 | | * txreconciliation, as described by BIP 330. |
265 | | */ |
266 | | inline constexpr const char* SENDTXRCNCL{"sendtxrcncl"}; |
267 | | }; // namespace NetMsgType |
268 | | |
269 | | /** All known message types (see above). Keep this in the same order as the list of messages above. */ |
270 | | inline const std::array ALL_NET_MESSAGE_TYPES{std::to_array<std::string>({ |
271 | | NetMsgType::VERSION, |
272 | | NetMsgType::VERACK, |
273 | | NetMsgType::ADDR, |
274 | | NetMsgType::ADDRV2, |
275 | | NetMsgType::SENDADDRV2, |
276 | | NetMsgType::INV, |
277 | | NetMsgType::GETDATA, |
278 | | NetMsgType::MERKLEBLOCK, |
279 | | NetMsgType::GETBLOCKS, |
280 | | NetMsgType::GETHEADERS, |
281 | | NetMsgType::TX, |
282 | | NetMsgType::HEADERS, |
283 | | NetMsgType::BLOCK, |
284 | | NetMsgType::GETADDR, |
285 | | NetMsgType::MEMPOOL, |
286 | | NetMsgType::PING, |
287 | | NetMsgType::PONG, |
288 | | NetMsgType::NOTFOUND, |
289 | | NetMsgType::FILTERLOAD, |
290 | | NetMsgType::FILTERADD, |
291 | | NetMsgType::FILTERCLEAR, |
292 | | NetMsgType::SENDHEADERS, |
293 | | NetMsgType::FEEFILTER, |
294 | | NetMsgType::SENDCMPCT, |
295 | | NetMsgType::CMPCTBLOCK, |
296 | | NetMsgType::GETBLOCKTXN, |
297 | | NetMsgType::BLOCKTXN, |
298 | | NetMsgType::GETCFILTERS, |
299 | | NetMsgType::CFILTER, |
300 | | NetMsgType::GETCFHEADERS, |
301 | | NetMsgType::CFHEADERS, |
302 | | NetMsgType::GETCFCHECKPT, |
303 | | NetMsgType::CFCHECKPT, |
304 | | NetMsgType::WTXIDRELAY, |
305 | | NetMsgType::SENDTXRCNCL, |
306 | | })}; |
307 | | |
308 | | /** nServices flags */ |
309 | | enum ServiceFlags : uint64_t { |
310 | | // NOTE: When adding here, be sure to update serviceFlagToStr too |
311 | | // Nothing |
312 | | NODE_NONE = 0, |
313 | | // NODE_NETWORK means that the node is capable of serving the complete block chain. It is currently |
314 | | // set by all Bitcoin Core non pruned nodes, and is unset by SPV clients or other light clients. |
315 | | NODE_NETWORK = (1 << 0), |
316 | | // NODE_BLOOM means the node is capable and willing to handle bloom-filtered connections. |
317 | | NODE_BLOOM = (1 << 2), |
318 | | // NODE_WITNESS indicates that a node can be asked for blocks and transactions including |
319 | | // witness data. |
320 | | NODE_WITNESS = (1 << 3), |
321 | | // NODE_COMPACT_FILTERS means the node will service basic block filter requests. |
322 | | // See BIP157 and BIP158 for details on how this is implemented. |
323 | | NODE_COMPACT_FILTERS = (1 << 6), |
324 | | // NODE_NETWORK_LIMITED means the same as NODE_NETWORK with the limitation of only |
325 | | // serving the last 288 (2 day) blocks |
326 | | // See BIP159 for details on how this is implemented. |
327 | | NODE_NETWORK_LIMITED = (1 << 10), |
328 | | |
329 | | // NODE_P2P_V2 means the node supports BIP324 transport |
330 | | NODE_P2P_V2 = (1 << 11), |
331 | | |
332 | | // Bits 24-31 are reserved for temporary experiments. Just pick a bit that |
333 | | // isn't getting used, or one not being used much, and notify the |
334 | | // bitcoin-development mailing list. Remember that service bits are just |
335 | | // unauthenticated advertisements, so your code must be robust against |
336 | | // collisions and other cases where nodes may be advertising a service they |
337 | | // do not actually support. Other service bits should be allocated via the |
338 | | // BIP process. |
339 | | }; |
340 | | |
341 | | /** |
342 | | * Convert service flags (a bitmask of NODE_*) to human readable strings. |
343 | | * It supports unknown service flags which will be returned as "UNKNOWN[...]". |
344 | | * @param[in] flags multiple NODE_* bitwise-OR-ed together |
345 | | */ |
346 | | std::vector<std::string> serviceFlagsToStr(uint64_t flags); |
347 | | |
348 | | /** |
349 | | * State independent service flags. |
350 | | * If the return value is changed, contrib/seeds/makeseeds.py |
351 | | * should be updated appropriately to filter for nodes with |
352 | | * desired service flags (compatible with our new flags). |
353 | | */ |
354 | 0 | constexpr ServiceFlags SeedsServiceFlags() { return ServiceFlags(NODE_NETWORK | NODE_WITNESS); } |
355 | | |
356 | | /** |
357 | | * Checks if a peer with the given service flags may be capable of having a |
358 | | * robust address-storage DB. |
359 | | */ |
360 | | static inline bool MayHaveUsefulAddressDB(ServiceFlags services) |
361 | 0 | { |
362 | 0 | return (services & NODE_NETWORK) || (services & NODE_NETWORK_LIMITED); Branch (362:12): [True: 0, False: 0]
Branch (362:41): [True: 0, False: 0]
Branch (362:12): [True: 0, False: 0]
Branch (362:41): [True: 0, False: 0]
Branch (362:12): [True: 0, False: 0]
Branch (362:41): [True: 0, False: 0]
|
363 | 0 | } Unexecuted instantiation: addrman.cpp:MayHaveUsefulAddressDB(ServiceFlags) Unexecuted instantiation: banman.cpp:MayHaveUsefulAddressDB(ServiceFlags) Unexecuted instantiation: connman.cpp:MayHaveUsefulAddressDB(ServiceFlags) Unexecuted instantiation: deserialize.cpp:MayHaveUsefulAddressDB(ServiceFlags) Unexecuted instantiation: headerssync.cpp:MayHaveUsefulAddressDB(ServiceFlags) Unexecuted instantiation: i2p.cpp:MayHaveUsefulAddressDB(ServiceFlags) Unexecuted instantiation: integer.cpp:MayHaveUsefulAddressDB(ServiceFlags) Unexecuted instantiation: net.cpp:MayHaveUsefulAddressDB(ServiceFlags) Unexecuted instantiation: net_permissions.cpp:MayHaveUsefulAddressDB(ServiceFlags) Unexecuted instantiation: netaddress.cpp:MayHaveUsefulAddressDB(ServiceFlags) Unexecuted instantiation: netbase_dns_lookup.cpp:MayHaveUsefulAddressDB(ServiceFlags) Unexecuted instantiation: node_eviction.cpp:MayHaveUsefulAddressDB(ServiceFlags) Unexecuted instantiation: p2p_handshake.cpp:MayHaveUsefulAddressDB(ServiceFlags) Unexecuted instantiation: p2p_headers_sync.cpp:MayHaveUsefulAddressDB(ServiceFlags) Unexecuted instantiation: p2p_transport_serialization.cpp:MayHaveUsefulAddressDB(ServiceFlags) Unexecuted instantiation: process_message.cpp:MayHaveUsefulAddressDB(ServiceFlags) Unexecuted instantiation: process_messages.cpp:MayHaveUsefulAddressDB(ServiceFlags) Unexecuted instantiation: protocol.cpp:MayHaveUsefulAddressDB(ServiceFlags) Unexecuted instantiation: socks5.cpp:MayHaveUsefulAddressDB(ServiceFlags) Unexecuted instantiation: txorphan.cpp:MayHaveUsefulAddressDB(ServiceFlags) Unexecuted instantiation: txrequest.cpp:MayHaveUsefulAddressDB(ServiceFlags) Unexecuted instantiation: setup_common.cpp:MayHaveUsefulAddressDB(ServiceFlags) Unexecuted instantiation: addrdb.cpp:MayHaveUsefulAddressDB(ServiceFlags) Unexecuted instantiation: init.cpp:MayHaveUsefulAddressDB(ServiceFlags) Unexecuted instantiation: mapport.cpp:MayHaveUsefulAddressDB(ServiceFlags) Unexecuted instantiation: net_processing.cpp:MayHaveUsefulAddressDB(ServiceFlags) Unexecuted instantiation: context.cpp:MayHaveUsefulAddressDB(ServiceFlags) Unexecuted instantiation: interfaces.cpp:MayHaveUsefulAddressDB(ServiceFlags) Unexecuted instantiation: peerman_args.cpp:MayHaveUsefulAddressDB(ServiceFlags) Unexecuted instantiation: transaction.cpp:MayHaveUsefulAddressDB(ServiceFlags) Unexecuted instantiation: txreconciliation.cpp:MayHaveUsefulAddressDB(ServiceFlags) Unexecuted instantiation: blockchain.cpp:MayHaveUsefulAddressDB(ServiceFlags) Unexecuted instantiation: mining.cpp:MayHaveUsefulAddressDB(ServiceFlags) Unexecuted instantiation: node.cpp:MayHaveUsefulAddressDB(ServiceFlags) Unexecuted instantiation: server_util.cpp:MayHaveUsefulAddressDB(ServiceFlags) Unexecuted instantiation: torcontrol.cpp:MayHaveUsefulAddressDB(ServiceFlags) Unexecuted instantiation: txorphanage.cpp:MayHaveUsefulAddressDB(ServiceFlags) Unexecuted instantiation: walletdb.cpp:MayHaveUsefulAddressDB(ServiceFlags) |
364 | | |
365 | | /** A CService with information about it as peer */ |
366 | | class CAddress : public CService |
367 | | { |
368 | | static constexpr std::chrono::seconds TIME_INIT{100000000}; |
369 | | |
370 | | /** Historically, CAddress disk serialization stored the CLIENT_VERSION, optionally OR'ed with |
371 | | * the ADDRV2_FORMAT flag to indicate V2 serialization. The first field has since been |
372 | | * disentangled from client versioning, and now instead: |
373 | | * - The low bits (masked by DISK_VERSION_IGNORE_MASK) store the fixed value DISK_VERSION_INIT, |
374 | | * (in case any code exists that treats it as a client version) but are ignored on |
375 | | * deserialization. |
376 | | * - The high bits (masked by ~DISK_VERSION_IGNORE_MASK) store actual serialization information. |
377 | | * Only 0 or DISK_VERSION_ADDRV2 (equal to the historical ADDRV2_FORMAT) are valid now, and |
378 | | * any other value triggers a deserialization failure. Other values can be added later if |
379 | | * needed. |
380 | | * |
381 | | * For disk deserialization, ADDRV2_FORMAT in the stream version signals that ADDRV2 |
382 | | * deserialization is permitted, but the actual format is determined by the high bits in the |
383 | | * stored version field. For network serialization, the stream version having ADDRV2_FORMAT or |
384 | | * not determines the actual format used (as it has no embedded version number). |
385 | | */ |
386 | | static constexpr uint32_t DISK_VERSION_INIT{220000}; |
387 | | static constexpr uint32_t DISK_VERSION_IGNORE_MASK{0b00000000'00000111'11111111'11111111}; |
388 | | /** The version number written in disk serialized addresses to indicate V2 serializations. |
389 | | * It must be exactly 1<<29, as that is the value that historical versions used for this |
390 | | * (they used their internal ADDRV2_FORMAT flag here). */ |
391 | | static constexpr uint32_t DISK_VERSION_ADDRV2{1 << 29}; |
392 | | static_assert((DISK_VERSION_INIT & ~DISK_VERSION_IGNORE_MASK) == 0, "DISK_VERSION_INIT must be covered by DISK_VERSION_IGNORE_MASK"); |
393 | | static_assert((DISK_VERSION_ADDRV2 & DISK_VERSION_IGNORE_MASK) == 0, "DISK_VERSION_ADDRV2 must not be covered by DISK_VERSION_IGNORE_MASK"); |
394 | | |
395 | | public: |
396 | 870 | CAddress() : CService{} {}; |
397 | 0 | CAddress(CService ipIn, ServiceFlags nServicesIn) : CService{ipIn}, nServices{nServicesIn} {}; |
398 | 0 | CAddress(CService ipIn, ServiceFlags nServicesIn, NodeSeconds time) : CService{ipIn}, nTime{time}, nServices{nServicesIn} {}; |
399 | | |
400 | | enum class Format { |
401 | | Disk, |
402 | | Network, |
403 | | }; |
404 | | struct SerParams : CNetAddr::SerParams { |
405 | | const Format fmt; |
406 | | SER_PARAMS_OPFUNC |
407 | | }; |
408 | | static constexpr SerParams V1_NETWORK{{CNetAddr::Encoding::V1}, Format::Network}; |
409 | | static constexpr SerParams V2_NETWORK{{CNetAddr::Encoding::V2}, Format::Network}; |
410 | | static constexpr SerParams V1_DISK{{CNetAddr::Encoding::V1}, Format::Disk}; |
411 | | static constexpr SerParams V2_DISK{{CNetAddr::Encoding::V2}, Format::Disk}; |
412 | | |
413 | | SERIALIZE_METHODS(CAddress, obj) |
414 | 0 | { |
415 | 0 | bool use_v2; |
416 | 0 | auto& params = SER_PARAMS(SerParams); |
417 | 0 | if (params.fmt == Format::Disk) { Branch (417:13): [True: 0, False: 0]
Branch (417:13): [True: 0, False: 0]
Branch (417:13): [True: 0, False: 0]
Branch (417:13): [True: 0, False: 0]
Branch (417:13): [True: 0, False: 0]
Branch (417:13): [True: 0, False: 0]
Branch (417:13): [True: 0, False: 0]
|
418 | | // In the disk serialization format, the encoding (v1 or v2) is determined by a flag version |
419 | | // that's part of the serialization itself. ADDRV2_FORMAT in the stream version only determines |
420 | | // whether V2 is chosen/permitted at all. |
421 | 0 | uint32_t stored_format_version = DISK_VERSION_INIT; |
422 | 0 | if (params.enc == Encoding::V2) stored_format_version |= DISK_VERSION_ADDRV2; Branch (422:17): [True: 0, False: 0]
Branch (422:17): [True: 0, False: 0]
Branch (422:17): [True: 0, False: 0]
Branch (422:17): [True: 0, False: 0]
Branch (422:17): [True: 0, False: 0]
Branch (422:17): [True: 0, False: 0]
Branch (422:17): [True: 0, False: 0]
|
423 | 0 | READWRITE(stored_format_version); |
424 | 0 | stored_format_version &= ~DISK_VERSION_IGNORE_MASK; // ignore low bits |
425 | 0 | if (stored_format_version == 0) { Branch (425:17): [True: 0, False: 0]
Branch (425:17): [True: 0, False: 0]
Branch (425:17): [True: 0, False: 0]
Branch (425:17): [True: 0, False: 0]
Branch (425:17): [True: 0, False: 0]
Branch (425:17): [True: 0, False: 0]
Branch (425:17): [True: 0, False: 0]
|
426 | 0 | use_v2 = false; |
427 | 0 | } else if (stored_format_version == DISK_VERSION_ADDRV2 && params.enc == Encoding::V2) { Branch (427:24): [True: 0, False: 0]
Branch (427:72): [True: 0, False: 0]
Branch (427:24): [True: 0, False: 0]
Branch (427:72): [True: 0, False: 0]
Branch (427:24): [True: 0, False: 0]
Branch (427:72): [True: 0, False: 0]
Branch (427:24): [True: 0, False: 0]
Branch (427:72): [True: 0, False: 0]
Branch (427:24): [True: 0, False: 0]
Branch (427:72): [True: 0, False: 0]
Branch (427:24): [True: 0, False: 0]
Branch (427:72): [True: 0, False: 0]
Branch (427:24): [True: 0, False: 0]
Branch (427:72): [True: 0, False: 0]
|
428 | | // Only support v2 deserialization if V2 is set. |
429 | 0 | use_v2 = true; |
430 | 0 | } else { |
431 | 0 | throw std::ios_base::failure("Unsupported CAddress disk format version"); |
432 | 0 | } |
433 | 0 | } else { |
434 | 0 | assert(params.fmt == Format::Network); |
435 | | // In the network serialization format, the encoding (v1 or v2) is determined directly by |
436 | | // the value of enc in the stream params, as no explicitly encoded version |
437 | | // exists in the stream. |
438 | 0 | use_v2 = params.enc == Encoding::V2; |
439 | 0 | } |
440 | | |
441 | 0 | READWRITE(Using<LossyChronoFormatter<uint32_t>>(obj.nTime)); |
442 | | // nServices is serialized as CompactSize in V2; as uint64_t in V1. |
443 | 0 | if (use_v2) { Branch (443:13): [True: 0, False: 0]
Branch (443:13): [True: 0, False: 0]
Branch (443:13): [True: 0, False: 0]
Branch (443:13): [True: 0, False: 0]
Branch (443:13): [True: 0, False: 0]
Branch (443:13): [True: 0, False: 0]
Branch (443:13): [True: 0, False: 0]
|
444 | 0 | uint64_t services_tmp; |
445 | 0 | SER_WRITE(obj, services_tmp = obj.nServices); |
446 | 0 | READWRITE(Using<CompactSizeFormatter<false>>(services_tmp)); |
447 | 0 | SER_READ(obj, obj.nServices = static_cast<ServiceFlags>(services_tmp)); |
448 | 0 | } else { |
449 | 0 | READWRITE(Using<CustomUintFormatter<8>>(obj.nServices)); |
450 | 0 | } |
451 | | // Invoke V1/V2 serializer for CService parent object. |
452 | 0 | const auto ser_params{use_v2 ? CNetAddr::V2 : CNetAddr::V1}; Branch (452:31): [True: 0, False: 0]
Branch (452:31): [True: 0, False: 0]
Branch (452:31): [True: 0, False: 0]
Branch (452:31): [True: 0, False: 0]
Branch (452:31): [True: 0, False: 0]
Branch (452:31): [True: 0, False: 0]
Branch (452:31): [True: 0, False: 0]
|
453 | 0 | READWRITE(ser_params(AsBase<CService>(obj))); |
454 | 0 | } Unexecuted instantiation: void CAddress::SerializationOps<ParamsStream<DataStream&, CAddress::SerParams>, CAddress, ActionUnserialize>(CAddress&, ParamsStream<DataStream&, CAddress::SerParams>&, ActionUnserialize) Unexecuted instantiation: void CAddress::SerializationOps<ParamsStream<DataStream&, CAddress::SerParams>, CAddress const, ActionSerialize>(CAddress const&, ParamsStream<DataStream&, CAddress::SerParams>&, ActionSerialize) Unexecuted instantiation: void CAddress::SerializationOps<ParamsStream<HashedSourceWriter<AutoFile>&, CAddress::SerParams>, CAddress const, ActionSerialize>(CAddress const&, ParamsStream<HashedSourceWriter<AutoFile>&, CAddress::SerParams>&, ActionSerialize) Unexecuted instantiation: void CAddress::SerializationOps<ParamsStream<HashVerifier<AutoFile>&, CAddress::SerParams>, CAddress, ActionUnserialize>(CAddress&, ParamsStream<HashVerifier<AutoFile>&, CAddress::SerParams>&, ActionUnserialize) Unexecuted instantiation: void CAddress::SerializationOps<ParamsStream<AutoFile&, CAddress::SerParams>, CAddress, ActionUnserialize>(CAddress&, ParamsStream<AutoFile&, CAddress::SerParams>&, ActionUnserialize) Unexecuted instantiation: void CAddress::SerializationOps<ParamsStream<HashVerifier<DataStream>&, CAddress::SerParams>, CAddress, ActionUnserialize>(CAddress&, ParamsStream<HashVerifier<DataStream>&, CAddress::SerParams>&, ActionUnserialize) Unexecuted instantiation: void CAddress::SerializationOps<ParamsStream<VectorWriter&, CAddress::SerParams>, CAddress const, ActionSerialize>(CAddress const&, ParamsStream<VectorWriter&, CAddress::SerParams>&, ActionSerialize) |
455 | | |
456 | | //! Always included in serialization. The behavior is unspecified if the value is not representable as uint32_t. |
457 | | NodeSeconds nTime{TIME_INIT}; |
458 | | //! Serialized as uint64_t in V1, and as CompactSize in V2. |
459 | | ServiceFlags nServices{NODE_NONE}; |
460 | | |
461 | | friend bool operator==(const CAddress& a, const CAddress& b) |
462 | 0 | { |
463 | 0 | return a.nTime == b.nTime && Branch (463:16): [True: 0, False: 0]
|
464 | 0 | a.nServices == b.nServices && Branch (464:16): [True: 0, False: 0]
|
465 | 0 | static_cast<const CService&>(a) == static_cast<const CService&>(b); Branch (465:16): [True: 0, False: 0]
|
466 | 0 | } |
467 | | }; |
468 | | |
469 | | /** getdata message type flags */ |
470 | | const uint32_t MSG_WITNESS_FLAG = 1 << 30; |
471 | | const uint32_t MSG_TYPE_MASK = 0xffffffff >> 2; |
472 | | |
473 | | /** getdata / inv message types. |
474 | | * These numbers are defined by the protocol. When adding a new value, be sure |
475 | | * to mention it in the respective BIP. |
476 | | */ |
477 | | enum GetDataMsg : uint32_t { |
478 | | UNDEFINED = 0, |
479 | | MSG_TX = 1, |
480 | | MSG_BLOCK = 2, |
481 | | MSG_WTX = 5, //!< Defined in BIP 339 |
482 | | // The following can only occur in getdata. Invs always use TX/WTX or BLOCK. |
483 | | MSG_FILTERED_BLOCK = 3, //!< Defined in BIP37 |
484 | | MSG_CMPCT_BLOCK = 4, //!< Defined in BIP152 |
485 | | MSG_WITNESS_BLOCK = MSG_BLOCK | MSG_WITNESS_FLAG, //!< Defined in BIP144 |
486 | | MSG_WITNESS_TX = MSG_TX | MSG_WITNESS_FLAG, //!< Defined in BIP144 |
487 | | // MSG_FILTERED_WITNESS_BLOCK is defined in BIP144 as reserved for future |
488 | | // use and remains unused. |
489 | | // MSG_FILTERED_WITNESS_BLOCK = MSG_FILTERED_BLOCK | MSG_WITNESS_FLAG, |
490 | | }; |
491 | | |
492 | | /** inv message data */ |
493 | | class CInv |
494 | | { |
495 | | public: |
496 | | CInv(); |
497 | | CInv(uint32_t typeIn, const uint256& hashIn); |
498 | | |
499 | 0 | SERIALIZE_METHODS(CInv, obj) { READWRITE(obj.type, obj.hash); } Unexecuted instantiation: void CInv::SerializationOps<DataStream, CInv, ActionUnserialize>(CInv&, DataStream&, ActionUnserialize) Unexecuted instantiation: void CInv::SerializationOps<DataStream, CInv const, ActionSerialize>(CInv const&, DataStream&, ActionSerialize) Unexecuted instantiation: void CInv::SerializationOps<VectorWriter, CInv const, ActionSerialize>(CInv const&, VectorWriter&, ActionSerialize) |
500 | | |
501 | | friend bool operator<(const CInv& a, const CInv& b); |
502 | | |
503 | | std::string GetCommand() const; |
504 | | std::string ToString() const; |
505 | | |
506 | | // Single-message helper methods |
507 | 0 | bool IsMsgTx() const { return type == MSG_TX; } |
508 | 0 | bool IsMsgBlk() const { return type == MSG_BLOCK; } |
509 | 0 | bool IsMsgWtx() const { return type == MSG_WTX; } |
510 | 0 | bool IsMsgFilteredBlk() const { return type == MSG_FILTERED_BLOCK; } |
511 | 0 | bool IsMsgCmpctBlk() const { return type == MSG_CMPCT_BLOCK; } |
512 | 0 | bool IsMsgWitnessBlk() const { return type == MSG_WITNESS_BLOCK; } |
513 | | |
514 | | // Combined-message helper methods |
515 | | bool IsGenTxMsg() const |
516 | 0 | { |
517 | 0 | return type == MSG_TX || type == MSG_WTX || type == MSG_WITNESS_TX; Branch (517:16): [True: 0, False: 0]
Branch (517:34): [True: 0, False: 0]
Branch (517:53): [True: 0, False: 0]
|
518 | 0 | } |
519 | | bool IsGenBlkMsg() const |
520 | 0 | { |
521 | 0 | return type == MSG_BLOCK || type == MSG_FILTERED_BLOCK || type == MSG_CMPCT_BLOCK || type == MSG_WITNESS_BLOCK; Branch (521:16): [True: 0, False: 0]
Branch (521:37): [True: 0, False: 0]
Branch (521:67): [True: 0, False: 0]
Branch (521:94): [True: 0, False: 0]
|
522 | 0 | } |
523 | | |
524 | | uint32_t type; |
525 | | uint256 hash; |
526 | | }; |
527 | | |
528 | | /** Convert a TX/WITNESS_TX/WTX CInv to a GenTxid. */ |
529 | | GenTxid ToGenTxid(const CInv& inv); |
530 | | |
531 | | #endif // BITCOIN_PROTOCOL_H |