2020-04-17 19:33:06 +02:00
|
|
|
/*
|
|
|
|
|
* This file is part of the Flowee project
|
2023-02-24 19:40:28 +01:00
|
|
|
* Copyright (C) 2020-2023 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>
|
2020-05-16 10:30:55 +02:00
|
|
|
#include <deque>
|
2020-04-17 19:33:06 +02:00
|
|
|
|
|
|
|
|
class PrivacySegment;
|
|
|
|
|
class Blockchain;
|
|
|
|
|
class ConnectionManager;
|
|
|
|
|
class CBloomFilter;
|
2020-06-08 21:35:10 +02:00
|
|
|
class BroadcastTxData;
|
2020-04-17 19:33:06 +02:00
|
|
|
|
2023-03-29 16:00:25 +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.
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
2020-06-08 21:35:10 +02:00
|
|
|
// 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
|
|
|
/**
|
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);
|
|
|
|
|
|
2023-03-29 16:00:25 +02:00
|
|
|
// \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);
|
|
|
|
|
|
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.
|
2023-02-24 19:40:28 +01:00
|
|
|
void sendFilter(bool mempoolMessage = false);
|
2020-05-18 14:32:34 +02:00
|
|
|
|
2020-06-08 21:35:10 +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
|
|
|
|
|
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;
|
2020-05-16 10:30:55 +02:00
|
|
|
std::deque<Tx> m_blockTransactions;
|
2020-04-17 19:33:06 +02:00
|
|
|
BlockHeader m_merkleHeader;
|
2020-06-08 21:35:10 +02:00
|
|
|
|
|
|
|
|
std::deque<std::weak_ptr<BroadcastTxData> > m_transactions;
|
2020-04-17 19:33:06 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
#endif
|