Files
thehub/libs/p2p/Peer.h
T

210 lines
6.5 KiB
C++
Raw Permalink Normal View History

2020-04-17 19:33:06 +02:00
/*
* This file is part of the Flowee project
2021-02-02 13:08:07 +01:00
* Copyright (C) 2020 Tom Zander <tom@flowee.org>
2020-04-17 19:33:06 +02:00
*
* 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 PEER_H
#define PEER_H
#include "PeerAddressDB.h"
#include "BlockHeader.h"
2020-05-18 14:32:34 +02:00
#include "PrivacySegmentListener.h"
2020-04-17 19:33:06 +02:00
#include <networkmanager/NetworkConnection.h>
#include <uint256.h>
#include <deque>
2020-04-17 19:33:06 +02:00
class PrivacySegment;
class Blockchain;
class Tx;
class ConnectionManager;
class CBloomFilter;
class BroadcastTxData;
2020-04-17 19:33:06 +02:00
2020-05-18 14:32:34 +02:00
class Peer : public std::enable_shared_from_this<Peer>, private PrivacySegmentListener
2020-04-17 19:33:06 +02:00
{
public:
enum PeerStatus {
Connecting,
2020-05-03 21:01:57 +02:00
Connected,
ShuttingDown
2020-04-17 19:33:06 +02:00
};
2020-05-05 22:53:25 +02:00
explicit Peer(ConnectionManager *parent, const PeerAddress &address);
2020-04-17 19:33:06 +02:00
~Peer();
2020-05-05 22:53:25 +02:00
void connect(NetworkConnection && server);
2020-04-27 15:47:15 +02:00
/**
2020-05-06 10:42:58 +02:00
* @brief shutdown will cause this peer stop processing network request.
*
* Calling this is required for the shared_ptr based peer to be deletable.
* Specificially: it breaks a cyclic loop with the network layer.
2020-04-27 15:47:15 +02:00
*/
void shutdown();
2020-04-17 19:33:06 +02:00
2020-05-06 10:42:58 +02:00
/// Returns the services bitfield of the remote peer.
2020-04-17 19:33:06 +02:00
uint64_t services() const;
2020-05-06 10:42:58 +02:00
/// Returns the amount of seconds that this peer is ahead/behind us.
2020-04-17 19:33:06 +02:00
int timeOffset() const;
2020-05-06 10:42:58 +02:00
/// Return the protocol version the remote peer reported.
2020-04-17 19:33:06 +02:00
int protocolVersion() const;
2020-05-06 10:42:58 +02:00
/// Returns the internal ID our network connection is on.
2020-04-17 19:33:06 +02:00
inline int connectionId() const {
return m_con.connectionId();
}
2020-05-06 10:42:58 +02:00
/// Returns the user-agent of the remote peer.
2020-04-17 19:33:06 +02:00
std::string userAgent() const;
2020-05-06 10:42:58 +02:00
/// Returns the blockheight the peer reported at connection time.
2020-04-17 19:33:06 +02:00
int startHeight() const;
2020-05-06 10:42:58 +02:00
/// Returns if the remote peer is willing to relay transactions.
2020-04-17 19:33:06 +02:00
bool relaysTransactions() const;
2020-05-06 10:42:58 +02:00
/// Returns if the remote peer prefers headers over INV messages for new block announcements.
2020-04-17 19:33:06 +02:00
bool preferHeaders() const;
2020-05-06 10:42:58 +02:00
/// Return the current connection status of this peer.
2020-04-17 19:33:06 +02:00
PeerStatus status() const {
return m_peerStatus;
}
2020-05-06 10:42:58 +02:00
/// Returns true if the peers services indicate it supplies serving blockdata over the network.
2020-04-17 19:33:06 +02:00
bool supplies_network() {
return (m_services & 1) == 1;
}
// bip 159
2020-05-06 10:42:58 +02:00
/// Returns true if the peer services indicate it is partial (pruned) blockdata it serves over the net.
2020-04-17 19:33:06 +02:00
bool supplies_partialNetwork() {
return (m_services & 2) != 0;
}
2020-05-06 10:42:58 +02:00
/// Returns true if the peer supplies bloom services.
2020-04-17 19:33:06 +02:00
bool supplies_bloom() {
return (m_services & 4) != 0;
}
2020-05-06 10:42:58 +02:00
/// Sends a message to the remote peer.
2020-04-17 19:33:06 +02:00
inline void sendMessage(const Message &message) {
m_con.send(message);
}
2020-05-06 10:42:58 +02:00
/// Returns the address of the remote peer.
2020-04-17 19:33:06 +02:00
inline PeerAddress& peerAddress() { return m_peerAddress; }
2020-05-06 10:42:58 +02:00
/// Returns the address of the remote peer.
2020-04-17 19:33:06 +02:00
inline const PeerAddress& peerAddress() const { return m_peerAddress; }
2020-05-06 10:42:58 +02:00
/// peer has received the response to 'getheaders', implying it is following the same chain as us.
2021-07-30 14:03:03 +02:00
/// @see PeerAddress::lastReceivedGoodHeaders() for a historical one.
2020-05-11 18:49:16 +02:00
/// @see requestedHeaders()
2020-04-17 19:33:06 +02:00
bool receivedHeaders() const;
2020-05-11 18:49:16 +02:00
/// Peer asked for getheaders, see @receivedHeaders()
bool requestedHeader() const;
/// set if the peer requested headers.
void setRequestedHeader(bool requestedHeader);
2020-05-06 10:42:58 +02:00
/// Assigns this peer a wallet in the shape of a PrivacySegment.
2020-04-17 19:33:06 +02:00
void setPrivacySegment(PrivacySegment *ps);
2020-05-06 10:42:58 +02:00
/// Return the set privacy segment, if any.
2020-04-17 19:33:06 +02:00
inline PrivacySegment *privacySegment() const {
return m_segment;
}
// request this peer to please broadcast this Tx.
void sendTx(const std::shared_ptr<BroadcastTxData> &txOwner);
2020-05-06 10:42:58 +02:00
/// the blockheight of the last merkle block we received.
2020-04-17 19:33:06 +02:00
int lastReceivedMerkle() const;
2020-05-06 10:42:58 +02:00
/// Return true if the merkle-block based fetches are in-progress.
2020-04-17 19:33:06 +02:00
bool merkleDownloadInProgress() const;
2020-11-09 18:38:38 +01:00
/// start downloads of merkle (aka SPV) blocks to the current height.
2020-04-17 19:33:06 +02:00
void startMerkleDownload(int from);
2020-05-06 10:42:58 +02:00
/// Return the timestamp of first-connection time.
2020-04-26 16:20:45 +02:00
uint32_t connectTime() const;
2020-11-13 20:11:06 +01:00
/**
* The peer-local blockheight. nnything higher than this is
* likely not present on that peer yet.
*
* Notice that the height is counted as it is in OUR blockchain.
*/
int peerHeight() const;
/**
* This is called when our messages are processed and they show
* our peer has a (possibly) higher blockHeight.
*/
void updatePeerHeight(int peerHeight);
2020-04-17 19:33:06 +02:00
private:
void connected(const EndPoint&);
void disconnected(const EndPoint&);
void processMessage(const Message &message);
void processTransaction(const Tx &tx);
2020-05-06 10:42:58 +02:00
/// sends the bloom filter to peer.
2022-07-13 14:00:47 +02:00
void sendFilter();
2020-05-18 14:32:34 +02:00
// PrivacySegmentListener interface
void filterUpdated();
2020-04-17 19:33:06 +02:00
void registerTxToSend(std::shared_ptr<BroadcastTxData> txOwner);
2020-11-13 20:11:06 +01:00
std::string m_userAgent;
2020-04-17 19:33:06 +02:00
uint64_t m_services = 0;
int m_timeOffset = 0;
2020-04-26 16:20:45 +02:00
uint32_t m_connectTime = 0;
2020-04-17 19:33:06 +02:00
int m_protocolVersion = 0;
int m_startHeight = 0;
2020-11-13 20:11:06 +01:00
int m_peerHeight = 0;
2020-04-17 19:33:06 +02:00
bool m_relaysTransactions = false;
bool m_preferHeaders = false;
2020-05-11 18:49:16 +02:00
bool m_requestedHeader = false;
2020-04-17 19:33:06 +02:00
bool m_receivedHeaders = false;
PeerAddress m_peerAddress;
2020-05-03 21:01:57 +02:00
std::atomic<PeerStatus> m_peerStatus;
2020-04-17 19:33:06 +02:00
NetworkConnection m_con;
ConnectionManager * const m_connectionManager;
// privacy segment data
PrivacySegment *m_segment = nullptr;
2022-07-13 14:00:47 +02:00
int m_bloomUploaded = 0; // the bloom filter we uploaded as referenced by segment->filterChangedHeight()
2020-04-17 19:33:06 +02:00
int m_lastReceivedMerkle = 0;
int m_merkleDownloadFrom = -1;
2020-11-13 20:11:06 +01:00
int m_merkleDownloadTo = -1;
2021-11-26 18:10:31 +01:00
int m_highestMerkleReceived = -1;
2020-04-17 19:33:06 +02:00
// SPV merkle block data
int m_merkleBlockHeight = -1;
std::vector<uint256> m_transactionHashes;
std::deque<Tx> m_blockTransactions;
2020-04-17 19:33:06 +02:00
BlockHeader m_merkleHeader;
std::deque<std::weak_ptr<BroadcastTxData> > m_transactions;
2020-04-17 19:33:06 +02:00
};
#endif