You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
401 lines
14 KiB
401 lines
14 KiB
// Copyright (c) 2009-2010 Satoshi Nakamoto |
|
// Copyright (c) 2009-2016 The Bitcoin Core developers |
|
// Distributed under the MIT software license, see the accompanying |
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php. |
|
|
|
#ifndef __cplusplus |
|
#error This header can only be compiled as C++. |
|
#endif |
|
|
|
#ifndef BITCOIN_PROTOCOL_H |
|
#define BITCOIN_PROTOCOL_H |
|
|
|
#include "netaddress.h" |
|
#include "serialize.h" |
|
#include "uint256.h" |
|
#include "version.h" |
|
|
|
#include <stdint.h> |
|
#include <string> |
|
|
|
/** Message header. |
|
* (4) message start. |
|
* (12) command. |
|
* (4) size. |
|
* (4) checksum. |
|
*/ |
|
class CMessageHeader |
|
{ |
|
public: |
|
enum { |
|
MESSAGE_START_SIZE = 4, |
|
COMMAND_SIZE = 12, |
|
MESSAGE_SIZE_SIZE = 4, |
|
CHECKSUM_SIZE = 4, |
|
|
|
MESSAGE_SIZE_OFFSET = MESSAGE_START_SIZE + COMMAND_SIZE, |
|
CHECKSUM_OFFSET = MESSAGE_SIZE_OFFSET + MESSAGE_SIZE_SIZE, |
|
HEADER_SIZE = MESSAGE_START_SIZE + COMMAND_SIZE + MESSAGE_SIZE_SIZE + CHECKSUM_SIZE |
|
}; |
|
typedef unsigned char MessageStartChars[MESSAGE_START_SIZE]; |
|
|
|
explicit CMessageHeader(const MessageStartChars& pchMessageStartIn); |
|
CMessageHeader(const MessageStartChars& pchMessageStartIn, const char* pszCommand, unsigned int nMessageSizeIn); |
|
|
|
std::string GetCommand() const; |
|
bool IsValid(const MessageStartChars& messageStart) const; |
|
|
|
ADD_SERIALIZE_METHODS; |
|
|
|
template <typename Stream, typename Operation> |
|
inline void SerializationOp(Stream& s, Operation ser_action) |
|
{ |
|
READWRITE(FLATDATA(pchMessageStart)); |
|
READWRITE(FLATDATA(pchCommand)); |
|
READWRITE(nMessageSize); |
|
READWRITE(FLATDATA(pchChecksum)); |
|
} |
|
|
|
char pchMessageStart[MESSAGE_START_SIZE]; |
|
char pchCommand[COMMAND_SIZE]; |
|
uint32_t nMessageSize; |
|
uint8_t pchChecksum[CHECKSUM_SIZE]; |
|
}; |
|
|
|
/** |
|
* Bitcoin protocol message types. When adding new message types, don't forget |
|
* to update allNetMessageTypes in protocol.cpp. |
|
*/ |
|
namespace NetMsgType { |
|
|
|
/** |
|
* The version message provides information about the transmitting node to the |
|
* receiving node at the beginning of a connection. |
|
* @see https://bitcoin.org/en/developer-reference#version |
|
*/ |
|
extern const char *VERSION; |
|
/** |
|
* The verack message acknowledges a previously-received version message, |
|
* informing the connecting node that it can begin to send other messages. |
|
* @see https://bitcoin.org/en/developer-reference#verack |
|
*/ |
|
extern const char *VERACK; |
|
/** |
|
* The addr (IP address) message relays connection information for peers on the |
|
* network. |
|
* @see https://bitcoin.org/en/developer-reference#addr |
|
*/ |
|
extern const char *ADDR; |
|
/** |
|
* The inv message (inventory message) transmits one or more inventories of |
|
* objects known to the transmitting peer. |
|
* @see https://bitcoin.org/en/developer-reference#inv |
|
*/ |
|
extern const char *INV; |
|
/** |
|
* The getdata message requests one or more data objects from another node. |
|
* @see https://bitcoin.org/en/developer-reference#getdata |
|
*/ |
|
extern const char *GETDATA; |
|
/** |
|
* The merkleblock message is a reply to a getdata message which requested a |
|
* block using the inventory type MSG_MERKLEBLOCK. |
|
* @since protocol version 70001 as described by BIP37. |
|
* @see https://bitcoin.org/en/developer-reference#merkleblock |
|
*/ |
|
extern const char *MERKLEBLOCK; |
|
/** |
|
* The getblocks message requests an inv message that provides block header |
|
* hashes starting from a particular point in the block chain. |
|
* @see https://bitcoin.org/en/developer-reference#getblocks |
|
*/ |
|
extern const char *GETBLOCKS; |
|
/** |
|
* The getheaders message requests a headers message that provides block |
|
* headers starting from a particular point in the block chain. |
|
* @since protocol version 31800. |
|
* @see https://bitcoin.org/en/developer-reference#getheaders |
|
*/ |
|
extern const char *GETHEADERS; |
|
/** |
|
* The tx message transmits a single transaction. |
|
* @see https://bitcoin.org/en/developer-reference#tx |
|
*/ |
|
extern const char *TX; |
|
/** |
|
* The headers message sends one or more block headers to a node which |
|
* previously requested certain headers with a getheaders message. |
|
* @since protocol version 31800. |
|
* @see https://bitcoin.org/en/developer-reference#headers |
|
*/ |
|
extern const char *HEADERS; |
|
/** |
|
* The block message transmits a single serialized block. |
|
* @see https://bitcoin.org/en/developer-reference#block |
|
*/ |
|
extern const char *BLOCK; |
|
/** |
|
* The getaddr message requests an addr message from the receiving node, |
|
* preferably one with lots of IP addresses of other receiving nodes. |
|
* @see https://bitcoin.org/en/developer-reference#getaddr |
|
*/ |
|
extern const char *GETADDR; |
|
/** |
|
* The mempool message requests the TXIDs of transactions that the receiving |
|
* node has verified as valid but which have not yet appeared in a block. |
|
* @since protocol version 60002. |
|
* @see https://bitcoin.org/en/developer-reference#mempool |
|
*/ |
|
extern const char *MEMPOOL; |
|
/** |
|
* The ping message is sent periodically to help confirm that the receiving |
|
* peer is still connected. |
|
* @see https://bitcoin.org/en/developer-reference#ping |
|
*/ |
|
extern const char *PING; |
|
/** |
|
* The pong message replies to a ping message, proving to the pinging node that |
|
* the ponging node is still alive. |
|
* @since protocol version 60001 as described by BIP31. |
|
* @see https://bitcoin.org/en/developer-reference#pong |
|
*/ |
|
extern const char *PONG; |
|
/** |
|
* The notfound message is a reply to a getdata message which requested an |
|
* object the receiving node does not have available for relay. |
|
* @since protocol version 70001. |
|
* @see https://bitcoin.org/en/developer-reference#notfound |
|
*/ |
|
extern const char *NOTFOUND; |
|
/** |
|
* The filterload message tells the receiving peer to filter all relayed |
|
* transactions and requested merkle blocks through the provided filter. |
|
* @since protocol version 70001 as described by BIP37. |
|
* Only available with service bit NODE_BLOOM since protocol version |
|
* 70011 as described by BIP111. |
|
* @see https://bitcoin.org/en/developer-reference#filterload |
|
*/ |
|
extern const char *FILTERLOAD; |
|
/** |
|
* The filteradd message tells the receiving peer to add a single element to a |
|
* previously-set bloom filter, such as a new public key. |
|
* @since protocol version 70001 as described by BIP37. |
|
* Only available with service bit NODE_BLOOM since protocol version |
|
* 70011 as described by BIP111. |
|
* @see https://bitcoin.org/en/developer-reference#filteradd |
|
*/ |
|
extern const char *FILTERADD; |
|
/** |
|
* The filterclear message tells the receiving peer to remove a previously-set |
|
* bloom filter. |
|
* @since protocol version 70001 as described by BIP37. |
|
* Only available with service bit NODE_BLOOM since protocol version |
|
* 70011 as described by BIP111. |
|
* @see https://bitcoin.org/en/developer-reference#filterclear |
|
*/ |
|
extern const char *FILTERCLEAR; |
|
/** |
|
* The reject message informs the receiving node that one of its previous |
|
* messages has been rejected. |
|
* @since protocol version 70002 as described by BIP61. |
|
* @see https://bitcoin.org/en/developer-reference#reject |
|
*/ |
|
extern const char *REJECT; |
|
/** |
|
* Indicates that a node prefers to receive new block announcements via a |
|
* "headers" message rather than an "inv". |
|
* @since protocol version 70012 as described by BIP130. |
|
* @see https://bitcoin.org/en/developer-reference#sendheaders |
|
*/ |
|
extern const char *SENDHEADERS; |
|
/** |
|
* The feefilter message tells the receiving peer not to inv us any txs |
|
* which do not meet the specified min fee rate. |
|
* @since protocol version 70013 as described by BIP133 |
|
*/ |
|
extern const char *FEEFILTER; |
|
/** |
|
* Contains a 1-byte bool and 8-byte LE version number. |
|
* Indicates that a node is willing to provide blocks via "cmpctblock" messages. |
|
* May indicate that a node prefers to receive new block announcements via a |
|
* "cmpctblock" message rather than an "inv", depending on message contents. |
|
* @since protocol version 70014 as described by BIP 152 |
|
*/ |
|
extern const char *SENDCMPCT; |
|
/** |
|
* Contains a CBlockHeaderAndShortTxIDs object - providing a header and |
|
* list of "short txids". |
|
* @since protocol version 70014 as described by BIP 152 |
|
*/ |
|
extern const char *CMPCTBLOCK; |
|
/** |
|
* Contains a BlockTransactionsRequest |
|
* Peer should respond with "blocktxn" message. |
|
* @since protocol version 70014 as described by BIP 152 |
|
*/ |
|
extern const char *GETBLOCKTXN; |
|
/** |
|
* Contains a BlockTransactions. |
|
* Sent in response to a "getblocktxn" message. |
|
* @since protocol version 70014 as described by BIP 152 |
|
*/ |
|
extern const char *BLOCKTXN; |
|
}; |
|
|
|
/* Get a vector of all valid message types (see above) */ |
|
const std::vector<std::string> &getAllNetMessageTypes(); |
|
|
|
/** nServices flags */ |
|
enum ServiceFlags : uint64_t { |
|
// Nothing |
|
NODE_NONE = 0, |
|
// NODE_NETWORK means that the node is capable of serving the block chain. It is currently |
|
// set by all Bitcoin Core nodes, and is unset by SPV clients or other peers that just want |
|
// network services but don't provide them. |
|
NODE_NETWORK = (1 << 0), |
|
// NODE_GETUTXO means the node is capable of responding to the getutxo protocol request. |
|
// Bitcoin Core does not support this but a patch set called Bitcoin XT does. |
|
// See BIP 64 for details on how this is implemented. |
|
NODE_GETUTXO = (1 << 1), |
|
// NODE_BLOOM means the node is capable and willing to handle bloom-filtered connections. |
|
// Bitcoin Core nodes used to support this by default, without advertising this bit, |
|
// but no longer do as of protocol version 70011 (= NO_BLOOM_VERSION) |
|
NODE_BLOOM = (1 << 2), |
|
// NODE_WITNESS indicates that a node can be asked for blocks and transactions including |
|
// witness data. |
|
NODE_WITNESS = (1 << 3), |
|
// NODE_XTHIN means the node supports Xtreme Thinblocks |
|
// If this is turned off then the node will not service nor make xthin requests |
|
NODE_XTHIN = (1 << 4), |
|
|
|
// Bits 24-31 are reserved for temporary experiments. Just pick a bit that |
|
// isn't getting used, or one not being used much, and notify the |
|
// bitcoin-development mailing list. Remember that service bits are just |
|
// unauthenticated advertisements, so your code must be robust against |
|
// collisions and other cases where nodes may be advertising a service they |
|
// do not actually support. Other service bits should be allocated via the |
|
// BIP process. |
|
}; |
|
|
|
/** |
|
* Gets the set of service flags which are "desirable" for a given peer. |
|
* |
|
* These are the flags which are required for a peer to support for them |
|
* to be "interesting" to us, ie for us to wish to use one of our few |
|
* outbound connection slots for or for us to wish to prioritize keeping |
|
* their connection around. |
|
* |
|
* Relevant service flags may be peer- and state-specific in that the |
|
* version of the peer may determine which flags are required (eg in the |
|
* case of NODE_NETWORK_LIMITED where we seek out NODE_NETWORK peers |
|
* unless they set NODE_NETWORK_LIMITED and we are out of IBD, in which |
|
* case NODE_NETWORK_LIMITED suffices). |
|
* |
|
* Thus, generally, avoid calling with peerServices == NODE_NONE. |
|
*/ |
|
static ServiceFlags GetDesirableServiceFlags(ServiceFlags services) { |
|
return ServiceFlags(NODE_NETWORK | NODE_WITNESS); |
|
} |
|
|
|
/** |
|
* A shortcut for (services & GetDesirableServiceFlags(services)) |
|
* == GetDesirableServiceFlags(services), ie determines whether the given |
|
* set of service flags are sufficient for a peer to be "relevant". |
|
*/ |
|
static inline bool HasAllDesirableServiceFlags(ServiceFlags services) { |
|
return !(GetDesirableServiceFlags(services) & (~services)); |
|
} |
|
|
|
/** |
|
* Checks if a peer with the given service flags may be capable of having a |
|
* robust address-storage DB. Currently an alias for checking NODE_NETWORK. |
|
*/ |
|
static inline bool MayHaveUsefulAddressDB(ServiceFlags services) { |
|
return services & NODE_NETWORK; |
|
} |
|
|
|
/** A CService with information about it as peer */ |
|
class CAddress : public CService |
|
{ |
|
public: |
|
CAddress(); |
|
explicit CAddress(CService ipIn, ServiceFlags nServicesIn); |
|
|
|
void Init(); |
|
|
|
ADD_SERIALIZE_METHODS; |
|
|
|
template <typename Stream, typename Operation> |
|
inline void SerializationOp(Stream& s, Operation ser_action) |
|
{ |
|
if (ser_action.ForRead()) |
|
Init(); |
|
int nVersion = s.GetVersion(); |
|
if (s.GetType() & SER_DISK) |
|
READWRITE(nVersion); |
|
if ((s.GetType() & SER_DISK) || |
|
(nVersion >= CADDR_TIME_VERSION && !(s.GetType() & SER_GETHASH))) |
|
READWRITE(nTime); |
|
uint64_t nServicesInt = nServices; |
|
READWRITE(nServicesInt); |
|
nServices = (ServiceFlags)nServicesInt; |
|
READWRITE(*(CService*)this); |
|
} |
|
|
|
// TODO: make private (improves encapsulation) |
|
public: |
|
ServiceFlags nServices; |
|
|
|
// disk and network only |
|
unsigned int nTime; |
|
}; |
|
|
|
/** getdata message type flags */ |
|
const uint32_t MSG_WITNESS_FLAG = 1 << 30; |
|
const uint32_t MSG_TYPE_MASK = 0xffffffff >> 2; |
|
|
|
/** getdata / inv message types. |
|
* These numbers are defined by the protocol. When adding a new value, be sure |
|
* to mention it in the respective BIP. |
|
*/ |
|
enum GetDataMsg |
|
{ |
|
UNDEFINED = 0, |
|
MSG_TX = 1, |
|
MSG_BLOCK = 2, |
|
// The following can only occur in getdata. Invs always use TX or BLOCK. |
|
MSG_FILTERED_BLOCK = 3, //!< Defined in BIP37 |
|
MSG_CMPCT_BLOCK = 4, //!< Defined in BIP152 |
|
MSG_WITNESS_BLOCK = MSG_BLOCK | MSG_WITNESS_FLAG, //!< Defined in BIP144 |
|
MSG_WITNESS_TX = MSG_TX | MSG_WITNESS_FLAG, //!< Defined in BIP144 |
|
MSG_FILTERED_WITNESS_BLOCK = MSG_FILTERED_BLOCK | MSG_WITNESS_FLAG, |
|
}; |
|
|
|
/** inv message data */ |
|
class CInv |
|
{ |
|
public: |
|
CInv(); |
|
CInv(int typeIn, const uint256& hashIn); |
|
|
|
ADD_SERIALIZE_METHODS; |
|
|
|
template <typename Stream, typename Operation> |
|
inline void SerializationOp(Stream& s, Operation ser_action) |
|
{ |
|
READWRITE(type); |
|
READWRITE(hash); |
|
} |
|
|
|
friend bool operator<(const CInv& a, const CInv& b); |
|
|
|
std::string GetCommand() const; |
|
std::string ToString() const; |
|
|
|
// TODO: make private (improves encapsulation) |
|
public: |
|
int type; |
|
uint256 hash; |
|
}; |
|
|
|
#endif // BITCOIN_PROTOCOL_H
|
|
|