421 lines
14 KiB
C++
421 lines
14 KiB
C++
/*
|
|
* This file is part of the Flowee project
|
|
* Copyright (C) 2009-2010 Satoshi Nakamoto
|
|
* Copyright (C) 2009-2015 The Bitcoin Core developers
|
|
* Copyright (C) 2019 Tom Zander <tomz@freedommail.ch>
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#ifndef __cplusplus
|
|
#error This header can only be compiled as C++.
|
|
#endif
|
|
|
|
#ifndef FLOWEE_PROTOCOL_H
|
|
#define FLOWEE_PROTOCOL_H
|
|
|
|
#include "netbase.h"
|
|
#include "serialize.h"
|
|
#include "uint256.h"
|
|
#include "version.h"
|
|
|
|
#define MESSAGE_START_SIZE 4
|
|
|
|
/** Message header.
|
|
* (4) message start.
|
|
* (12) command.
|
|
* (4) size.
|
|
* (4) checksum.
|
|
*/
|
|
class CMessageHeader
|
|
{
|
|
public:
|
|
typedef unsigned char MessageStartChars[MESSAGE_START_SIZE];
|
|
|
|
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, int nType, int nVersion)
|
|
{
|
|
READWRITE(FLATDATA(pchMessageStart));
|
|
READWRITE(FLATDATA(pchCommand));
|
|
READWRITE(nMessageSize);
|
|
READWRITE(nChecksum);
|
|
}
|
|
|
|
// TODO: make private (improves encapsulation)
|
|
public:
|
|
enum {
|
|
COMMAND_SIZE = 12,
|
|
MESSAGE_SIZE_SIZE = sizeof(int),
|
|
CHECKSUM_SIZE = sizeof(int),
|
|
|
|
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
|
|
};
|
|
char pchMessageStart[MESSAGE_START_SIZE];
|
|
char pchCommand[COMMAND_SIZE];
|
|
unsigned int nMessageSize;
|
|
unsigned int nChecksum;
|
|
};
|
|
|
|
/**
|
|
* 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://developer.bitcoin.org/reference/p2p_networking.html#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://developer.bitcoin.org/reference/p2p_networking.html#verack
|
|
*/
|
|
extern const char *VERACK;
|
|
/**
|
|
* The addr (IP address) message relays connection information for peers on the
|
|
* network.
|
|
* @see https://developer.bitcoin.org/reference/p2p_networking.html#addr
|
|
*/
|
|
extern const char *ADDR;
|
|
/**
|
|
* The inv message (inventory message) transmits one or more inventories of
|
|
* objects known to the transmitting peer.
|
|
* @see https://developer.bitcoin.org/reference/p2p_networking.html#inv
|
|
*/
|
|
extern const char *INV;
|
|
/**
|
|
* The getdata message requests one or more data objects from another node.
|
|
* @see https://developer.bitcoin.org/reference/p2p_networking.html#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://developer.bitcoin.org/reference/p2p_networking.html#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://developer.bitcoin.org/reference/p2p_networking.html#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://developer.bitcoin.org/reference/p2p_networking.html#getheaders
|
|
*/
|
|
extern const char *GETHEADERS;
|
|
/**
|
|
* The tx message transmits a single transaction.
|
|
* @see https://developer.bitcoin.org/reference/p2p_networking.html#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://developer.bitcoin.org/reference/p2p_networking.html#headers
|
|
*/
|
|
extern const char *HEADERS;
|
|
/**
|
|
* The block message transmits a single serialized block.
|
|
* @see https://developer.bitcoin.org/reference/p2p_networking.html#block
|
|
*/
|
|
extern const char *BLOCK;
|
|
/**
|
|
* The thinblock message transmits a single serialized thinblock.
|
|
*/
|
|
extern const char *THINBLOCK;
|
|
/**
|
|
* The xthinblock message transmits a single serializexd xthinblock.
|
|
*/
|
|
extern const char *XTHINBLOCK;
|
|
/**
|
|
* The xblocktx message transmits a single serialized xblocktx.
|
|
*/
|
|
extern const char *XBLOCKTX;
|
|
/**
|
|
* The get_xblocktx message transmits a single serialized get_xblocktx.
|
|
*/
|
|
extern const char *GET_XBLOCKTX;
|
|
/**
|
|
* The get_xthin message transmits a single serialized get_xthin.
|
|
*/
|
|
extern const char *GET_XTHIN;
|
|
|
|
/**
|
|
* The getaddr message requests an addr message from the receiving node,
|
|
* preferably one with lots of IP addresses of other receiving nodes.
|
|
* @see https://developer.bitcoin.org/reference/p2p_networking.html#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://developer.bitcoin.org/reference/p2p_networking.html#mempool
|
|
*/
|
|
extern const char *MEMPOOL;
|
|
/**
|
|
* The ping message is sent periodically to help confirm that the receiving
|
|
* peer is still connected.
|
|
* @see https://developer.bitcoin.org/reference/p2p_networking.html#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://developer.bitcoin.org/reference/p2p_networking.html#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.
|
|
* @ince protocol version 70001.
|
|
* @see https://developer.bitcoin.org/reference/p2p_networking.html#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://developer.bitcoin.org/reference/p2p_networking.html#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://developer.bitcoin.org/reference/p2p_networking.html#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://developer.bitcoin.org/reference/p2p_networking.html#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://developer.bitcoin.org/reference/p2p_networking.html#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://developer.bitcoin.org/reference/p2p_networking.html#sendheaders
|
|
*/
|
|
extern const char *SENDHEADERS;
|
|
|
|
/**
|
|
* Version2, request a verack2.
|
|
* @since protocol version 80002
|
|
*/
|
|
extern const char *VERSION2;
|
|
/**
|
|
* verack2, a followup message to verack since we can't extend or change old
|
|
* messages. This one is meant to exchange our port number.
|
|
* @since protocol version 80002
|
|
*/
|
|
extern const char *VERACK2;
|
|
/**
|
|
* Send this if your node prefers to receive new block announcements
|
|
* and transactions directly without INVs
|
|
* @since protocol version 80000
|
|
*/
|
|
extern const char *XPEDITEDREQUEST;
|
|
/**
|
|
* Block or transactions sent without explicit solicitation
|
|
* @since protocol version 80000
|
|
*/
|
|
extern const char *XPEDITEDBLK;
|
|
/**
|
|
* Block or transactions sent without explicit solicitation
|
|
* @since protocol version 80000
|
|
*/
|
|
extern const char *XPEDITEDTXN;
|
|
/**
|
|
* Double spend proof
|
|
*/
|
|
extern const char *DSPROOF;
|
|
}
|
|
|
|
/* Get a vector of all valid message types (see above) */
|
|
const std::vector<std::string> &getAllNetMessageTypes();
|
|
|
|
/** nServices flags */
|
|
enum {
|
|
// NODE_NETWORK means that the node is capable of serving the block chain. It is currently
|
|
// set by all Flowee 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_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_XTHIN means the node supports Xtreme Thinblocks
|
|
// If this is turned off then the node will not service xthin requests nor
|
|
// make xthin requests
|
|
NODE_XTHIN = (1 << 4),
|
|
|
|
// NODE_CASH means the node supports and follows the 'UAHF' chain.
|
|
NODE_BITCOIN_CASH = (1 << 5),
|
|
|
|
// obsolete
|
|
NODE_WEAKBLOCKS = (1 << 7),
|
|
|
|
// NODE_GRAPHENE means the node supports Graphene blocks
|
|
// If this is turned off then the node will not service graphene requests nor
|
|
// make graphene requests
|
|
NODE_GRAPHENE = (1 << 6),
|
|
// NODE_CF means that the node supports BIP 157/158 style
|
|
// compact filters on block data
|
|
NODE_CF = (1 << 8),
|
|
// NODE_NETWORK_LIMITED means the same as NODE_NETWORK with the limitation
|
|
// of only serving the last 288 (2 day) blocks
|
|
// See BIP159 for details on how this is implemented.
|
|
NODE_NETWORK_LIMITED = (1 << 10),
|
|
// indicates if node is using extversion
|
|
NODE_EXTVERSION = (1 << 11),
|
|
|
|
// 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.
|
|
};
|
|
|
|
/** A CService with information about it as peer */
|
|
class CAddress : public CService
|
|
{
|
|
public:
|
|
CAddress();
|
|
explicit CAddress(CService ipIn, uint64_t nServicesIn = NODE_NETWORK);
|
|
|
|
void Init();
|
|
|
|
ADD_SERIALIZE_METHODS
|
|
|
|
template <typename Stream, typename Operation>
|
|
inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion)
|
|
{
|
|
if (ser_action.ForRead())
|
|
Init();
|
|
if (nType & SER_DISK)
|
|
READWRITE(nVersion);
|
|
if ((nType & SER_DISK) ||
|
|
(nVersion >= CADDR_TIME_VERSION && !(nType & SER_GETHASH)))
|
|
READWRITE(nTime);
|
|
READWRITE(nServices);
|
|
READWRITE(*(CService*)this);
|
|
}
|
|
|
|
// TODO: make private (improves encapsulation)
|
|
public:
|
|
uint64_t nServices;
|
|
|
|
// disk and network only
|
|
unsigned int nTime;
|
|
};
|
|
|
|
/** 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, int nType, int nVersion) {
|
|
READWRITE(type);
|
|
READWRITE(hash);
|
|
}
|
|
|
|
friend bool operator<(const CInv& a, const CInv& b);
|
|
|
|
bool IsKnownType() const;
|
|
const char* GetCommand() const;
|
|
std::string ToString() const;
|
|
|
|
inline const uint256 &getHash() const {
|
|
return hash;
|
|
}
|
|
|
|
public:
|
|
// TODO: make private (improves encapsulation)
|
|
int type;
|
|
uint256 hash;
|
|
};
|
|
|
|
enum {
|
|
MSG_TX = 1,
|
|
MSG_BLOCK,
|
|
// Nodes may always request a MSG_FILTERED_BLOCK in a getdata, however,
|
|
// MSG_FILTERED_BLOCK should not appear in any invs except as a part of getdata.
|
|
MSG_FILTERED_BLOCK,
|
|
// BUIP010 Xtreme Thinblocks: a thin block contains all the transactions hashes in a block
|
|
// and also provides the missing transactions that are needed at the other end to reconstruct the block
|
|
MSG_THINBLOCK,
|
|
// BUIP010 Xtreme Thinblocks: an Xtreme thin block contains the first 8 bytes of all the tx hashes
|
|
// and also provides the missing transactions that are needed at the other end to reconstruct the block
|
|
MSG_XTHINBLOCK,
|
|
|
|
MSG_DOUBLESPENDPROOF = 0x94a0
|
|
};
|
|
|
|
|
|
inline Log::SilentItem operator<<(Log::SilentItem item, const CInv&) { return item; }
|
|
inline Log::Item operator<<(Log::Item item, const CInv &inv) {
|
|
const bool old = item.useSpace();
|
|
item.nospace() << inv.GetCommand() << '{' << inv.getHash() << '}';
|
|
if (old)
|
|
return item.space();
|
|
return item;
|
|
}
|
|
|
|
|
|
#endif // BITCOIN_PROTOCOL_H
|