b4a3da2642
These are technically static libs, but not in any way shared libs. They are used solely only by this repo and really only by the hub. Most important, no header files are installed and basically none of the normal rules for reusable libraries are applied to these files.
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 <tom@flowee.org>
|
|
*
|
|
* 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
|