Files

222 lines
7.3 KiB
C++
Raw Permalink Normal View History

2020-04-17 19:33:06 +02:00
/*
* This file is part of the Flowee project
2025-02-19 17:46:38 +01:00
* Copyright (C) 2020-2025 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/>.
*/
2024-01-22 19:32:15 +01:00
#ifndef FLOWEE_PEER_H
#define FLOWEE_PEER_H
2020-04-17 19:33:06 +02:00
#include "PeerAddressDB.h"
#include "BlockHeader.h"
2022-09-13 20:30:38 +02:00
#include <primitives/Tx.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 ConnectionManager;
class CBloomFilter;
class BroadcastTxData;
2020-04-17 19:33:06 +02:00
class Peer : public std::enable_shared_from_this<Peer>
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.
2024-11-29 15:12:13 +01:00
void setPrivacySegment(const std::shared_ptr<PrivacySegment> &ps);
2020-05-06 10:42:58 +02:00
/// Return the set privacy segment, if any.
2024-11-29 15:12:13 +01:00
inline const std::weak_ptr<PrivacySegment> &privacySegment() const {
2020-04-17 19:33:06 +02:00
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.
2024-02-23 22:08:28 +01:00
/// @param maxHeight can be given to stop earlier than current height.
void startMerkleDownload(int from, int maxHeight = -1);
2020-04-17 19:33:06 +02:00
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
/**
2023-03-27 15:19:05 +02:00
* returns the peer-local blockheight.
* This is verfiied to be more than a number, it actually reflects
* an index in our, locally verified, longest chain.
2020-11-13 20:11:06 +01:00
*/
int peerHeight() const;
2023-03-27 15:19:05 +02:00
2020-11-13 20:11:06 +01:00
/**
* This is called when our messages are processed and they show
2023-03-27 15:19:05 +02:00
* our peer has proven to have reached a valid height of at least \a peerHeight.
*
* Passing in a lower number than the current peerHeight will silently be ignored.
2020-11-13 20:11:06 +01:00
*/
void updatePeerHeight(int peerHeight);
// \internal callback from PrivacySegment
// @param mempoolMessage if true, the privacy segments wants the `mempool` p2p message
// to be sent directly after the bloom filter update.
void filterUpdated(bool mempoolMessage);
2025-02-19 17:46:38 +01:00
int highestMerkleReceived() const;
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.
void sendFilter(bool mempoolMessage = false);
2020-05-18 14:32:34 +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;
2023-04-06 13:32:30 +02:00
bool m_mempoolSent = false;
2020-04-17 19:33:06 +02:00
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
2024-11-29 15:12:13 +01:00
std::weak_ptr<PrivacySegment> m_segment;
2022-07-13 14:00:47 +02:00
int m_bloomUploaded = 0; // the bloom filter we uploaded as referenced by segment->filterChangedHeight()
2024-02-23 22:08:28 +01:00
/*
* Merkle blocks are downloaded in a sliding window style.
* The next 5 properties show which blocks are in-flight.
*/
int m_lastReceivedMerkle = 0; ///< most recently received block
int m_merkleDownloadFrom = -1; ///< sliding-window bottom
int m_merkleDownloadTo = -1; ///< sliding-window top. (highest requested)
int m_highestMerkleReceived = -1; ///< highest received block
int m_merkleDownloadBoundary = -1; ///< Instead of stopping at the headers-tip, stop at this boundary.
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