mirror of
https://github.com/dashpay/dash.git
synced 2024-12-26 12:32:48 +01:00
partial bitcoin#19829: Move block inventory state to net_processing
This commit is contained in:
parent
ec77bd3ab4
commit
18f2dc0865
@ -671,7 +671,6 @@ void CNode::copyStats(CNodeStats &stats, const std::vector<bool> &m_asmap)
|
|||||||
}
|
}
|
||||||
stats.fInbound = IsInboundConn();
|
stats.fInbound = IsInboundConn();
|
||||||
stats.m_manual_connection = IsManualConn();
|
stats.m_manual_connection = IsManualConn();
|
||||||
X(nStartingHeight);
|
|
||||||
{
|
{
|
||||||
LOCK(cs_vSend);
|
LOCK(cs_vSend);
|
||||||
X(mapSendBytesPerMsgCmd);
|
X(mapSendBytesPerMsgCmd);
|
||||||
@ -4020,7 +4019,6 @@ CNode::CNode(NodeId idIn, ServiceFlags nLocalServicesIn, SOCKET hSocketIn, const
|
|||||||
if (inbound_onion) assert(conn_type_in == ConnectionType::INBOUND);
|
if (inbound_onion) assert(conn_type_in == ConnectionType::INBOUND);
|
||||||
hSocket = hSocketIn;
|
hSocket = hSocketIn;
|
||||||
addrName = addrNameIn == "" ? addr.ToStringIPPort() : addrNameIn;
|
addrName = addrNameIn == "" ? addr.ToStringIPPort() : addrNameIn;
|
||||||
hashContinue = uint256();
|
|
||||||
|
|
||||||
if (conn_type_in != ConnectionType::BLOCK_RELAY) {
|
if (conn_type_in != ConnectionType::BLOCK_RELAY) {
|
||||||
m_addr_known = std::make_unique<CRollingBloomFilter>(5000, 0.001);
|
m_addr_known = std::make_unique<CRollingBloomFilter>(5000, 0.001);
|
||||||
|
14
src/net.h
14
src/net.h
@ -279,7 +279,7 @@ public:
|
|||||||
std::string cleanSubVer;
|
std::string cleanSubVer;
|
||||||
bool fInbound;
|
bool fInbound;
|
||||||
bool m_manual_connection;
|
bool m_manual_connection;
|
||||||
int nStartingHeight;
|
int m_starting_height;
|
||||||
uint64_t nSendBytes;
|
uint64_t nSendBytes;
|
||||||
mapMsgCmdSize mapSendBytesPerMsgCmd;
|
mapMsgCmdSize mapSendBytesPerMsgCmd;
|
||||||
uint64_t nRecvBytes;
|
uint64_t nRecvBytes;
|
||||||
@ -590,9 +590,6 @@ protected:
|
|||||||
mapMsgCmdSize mapRecvBytesPerMsgCmd GUARDED_BY(cs_vRecv);
|
mapMsgCmdSize mapRecvBytesPerMsgCmd GUARDED_BY(cs_vRecv);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
uint256 hashContinue;
|
|
||||||
std::atomic<int> nStartingHeight{-1};
|
|
||||||
|
|
||||||
// flood relay
|
// flood relay
|
||||||
std::vector<CAddress> vAddrToSend;
|
std::vector<CAddress> vAddrToSend;
|
||||||
std::unique_ptr<CRollingBloomFilter> m_addr_known{nullptr};
|
std::unique_ptr<CRollingBloomFilter> m_addr_known{nullptr};
|
||||||
@ -602,12 +599,6 @@ public:
|
|||||||
|
|
||||||
bool IsBlockRelayOnly() const;
|
bool IsBlockRelayOnly() const;
|
||||||
|
|
||||||
// List of block ids we still have announce.
|
|
||||||
// There is no final sorting before sending, as they are always sent immediately
|
|
||||||
// and in the order requested.
|
|
||||||
std::vector<uint256> vInventoryBlockToSend GUARDED_BY(cs_inventory);
|
|
||||||
Mutex cs_inventory;
|
|
||||||
|
|
||||||
struct TxRelay {
|
struct TxRelay {
|
||||||
mutable RecursiveMutex cs_filter;
|
mutable RecursiveMutex cs_filter;
|
||||||
// We use fRelayTxes for two purposes -
|
// We use fRelayTxes for two purposes -
|
||||||
@ -636,9 +627,6 @@ public:
|
|||||||
// in dash: m_tx_relay should never be nullptr, use `RelayAddrsWithConn() == false` instead
|
// in dash: m_tx_relay should never be nullptr, use `RelayAddrsWithConn() == false` instead
|
||||||
std::unique_ptr<TxRelay> m_tx_relay{std::make_unique<TxRelay>()};
|
std::unique_ptr<TxRelay> m_tx_relay{std::make_unique<TxRelay>()};
|
||||||
|
|
||||||
// Used for headers announcements - unfiltered blocks to relay
|
|
||||||
std::vector<uint256> vBlockHashesToAnnounce GUARDED_BY(cs_inventory);
|
|
||||||
|
|
||||||
/** UNIX epoch time of the last block received from this peer that we had
|
/** UNIX epoch time of the last block received from this peer that we had
|
||||||
* not yet seen (e.g. not already received from another peer), that passed
|
* not yet seen (e.g. not already received from another peer), that passed
|
||||||
* preliminary validity checks and was saved to disk, even if we don't
|
* preliminary validity checks and was saved to disk, even if we don't
|
||||||
|
@ -206,6 +206,8 @@ struct QueuedBlock {
|
|||||||
* Memory is owned by shared pointers and this object is destructed when
|
* Memory is owned by shared pointers and this object is destructed when
|
||||||
* the refcount drops to zero.
|
* the refcount drops to zero.
|
||||||
*
|
*
|
||||||
|
* Mutexes inside this struct must not be held when locking m_peer_mutex.
|
||||||
|
*
|
||||||
* TODO: move most members from CNodeState to this structure.
|
* TODO: move most members from CNodeState to this structure.
|
||||||
* TODO: move remaining application-layer data members from CNode to this structure.
|
* TODO: move remaining application-layer data members from CNode to this structure.
|
||||||
*/
|
*/
|
||||||
@ -220,6 +222,26 @@ struct Peer {
|
|||||||
/** Whether this peer should be disconnected and marked as discouraged (unless it has the noban permission). */
|
/** Whether this peer should be disconnected and marked as discouraged (unless it has the noban permission). */
|
||||||
bool m_should_discourage GUARDED_BY(m_misbehavior_mutex){false};
|
bool m_should_discourage GUARDED_BY(m_misbehavior_mutex){false};
|
||||||
|
|
||||||
|
/** Protects block inventory data members */
|
||||||
|
Mutex m_block_inv_mutex;
|
||||||
|
/** List of blocks that we'll anounce via an `inv` message.
|
||||||
|
* There is no final sorting before sending, as they are always sent
|
||||||
|
* immediately and in the order requested. */
|
||||||
|
std::vector<uint256> m_blocks_for_inv_relay GUARDED_BY(m_block_inv_mutex);
|
||||||
|
/** Unfiltered list of blocks that we'd like to announce via a `headers`
|
||||||
|
* message. If we can't announce via a `headers` message, we'll fall back to
|
||||||
|
* announcing via `inv`. */
|
||||||
|
std::vector<uint256> m_blocks_for_headers_relay GUARDED_BY(m_block_inv_mutex);
|
||||||
|
|
||||||
|
/** The final block hash that we sent in an `inv` message to this peer.
|
||||||
|
* When the peer requests this block, we send an `inv` message to trigger
|
||||||
|
* the peer to request the next sequence of block hashes.
|
||||||
|
* Most peers use headers-first syncing, which doesn't use this mechanism */
|
||||||
|
uint256 m_continuation_block GUARDED_BY(m_block_inv_mutex) {};
|
||||||
|
|
||||||
|
/** This peer's reported block height when we connected */
|
||||||
|
std::atomic<int> m_starting_height{-1};
|
||||||
|
|
||||||
/** Set of txids to reconsider once their parent transactions have been accepted **/
|
/** Set of txids to reconsider once their parent transactions have been accepted **/
|
||||||
std::set<uint256> m_orphan_work_set GUARDED_BY(g_cs_orphans);
|
std::set<uint256> m_orphan_work_set GUARDED_BY(g_cs_orphans);
|
||||||
|
|
||||||
@ -321,7 +343,9 @@ private:
|
|||||||
void ProcessOrphanTx(std::set<uint256>& orphan_work_set)
|
void ProcessOrphanTx(std::set<uint256>& orphan_work_set)
|
||||||
EXCLUSIVE_LOCKS_REQUIRED(cs_main, g_cs_orphans);
|
EXCLUSIVE_LOCKS_REQUIRED(cs_main, g_cs_orphans);
|
||||||
/** Process a single headers message from a peer. */
|
/** Process a single headers message from a peer. */
|
||||||
void ProcessHeadersMessage(CNode& pfrom, const std::vector<CBlockHeader>& headers, bool via_compact_block);
|
void ProcessHeadersMessage(CNode& pfrom, const Peer& peer,
|
||||||
|
const std::vector<CBlockHeader>& headers,
|
||||||
|
bool via_compact_block);
|
||||||
|
|
||||||
void SendBlockTransactions(CNode& pfrom, const CBlock& block, const BlockTransactionsRequest& req);
|
void SendBlockTransactions(CNode& pfrom, const CBlock& block, const BlockTransactionsRequest& req);
|
||||||
|
|
||||||
@ -350,7 +374,8 @@ private:
|
|||||||
/** Whether this node is running in blocks only mode */
|
/** Whether this node is running in blocks only mode */
|
||||||
const bool m_ignore_incoming_txs;
|
const bool m_ignore_incoming_txs;
|
||||||
|
|
||||||
/** Protects m_peer_map */
|
/** Protects m_peer_map. This mutex must not be locked while holding a lock
|
||||||
|
* on any of the mutexes inside a Peer object. */
|
||||||
mutable Mutex m_peer_mutex;
|
mutable Mutex m_peer_mutex;
|
||||||
/**
|
/**
|
||||||
* Map of all Peer objects, keyed by peer id. This map is protected
|
* Map of all Peer objects, keyed by peer id. This map is protected
|
||||||
@ -374,7 +399,7 @@ private:
|
|||||||
*/
|
*/
|
||||||
bool BlockRequestAllowed(const CBlockIndex* pindex, const Consensus::Params& consensusParams) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
|
bool BlockRequestAllowed(const CBlockIndex* pindex, const Consensus::Params& consensusParams) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
|
||||||
bool AlreadyHaveBlock(const uint256& block_hash) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
|
bool AlreadyHaveBlock(const uint256& block_hash) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
|
||||||
void ProcessGetBlockData(CNode& pfrom, const CChainParams& chainparams, const CInv& inv, CConnman& connman, llmq::CInstantSendManager& isman);
|
void ProcessGetBlockData(CNode& pfrom, Peer& peer, const CChainParams& chainparams, const CInv& inv, CConnman& connman, llmq::CInstantSendManager& isman);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validation logic for compact filters request handling.
|
* Validation logic for compact filters request handling.
|
||||||
@ -1244,6 +1269,11 @@ void PeerManagerImpl::FinalizeNode(const CNode& node) {
|
|||||||
LOCK(cs_main);
|
LOCK(cs_main);
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
|
// We remove the PeerRef from g_peer_map here, but we don't always
|
||||||
|
// destruct the Peer. Sometimes another thread is still holding a
|
||||||
|
// PeerRef, so the refcount is >= 1. Be careful not to do any
|
||||||
|
// processing here that assumes Peer won't be changed before it's
|
||||||
|
// destructed.
|
||||||
PeerRef peer = RemovePeer(nodeid);
|
PeerRef peer = RemovePeer(nodeid);
|
||||||
assert(peer != nullptr);
|
assert(peer != nullptr);
|
||||||
misbehavior = WITH_LOCK(peer->m_misbehavior_mutex, return peer->m_misbehavior_score);
|
misbehavior = WITH_LOCK(peer->m_misbehavior_mutex, return peer->m_misbehavior_score);
|
||||||
@ -1322,6 +1352,7 @@ bool PeerManagerImpl::GetNodeStateStats(NodeId nodeid, CNodeStateStats &stats)
|
|||||||
PeerRef peer = GetPeerRef(nodeid);
|
PeerRef peer = GetPeerRef(nodeid);
|
||||||
if (peer == nullptr) return false;
|
if (peer == nullptr) return false;
|
||||||
stats.m_misbehavior_score = WITH_LOCK(peer->m_misbehavior_mutex, return peer->m_misbehavior_score);
|
stats.m_misbehavior_score = WITH_LOCK(peer->m_misbehavior_mutex, return peer->m_misbehavior_score);
|
||||||
|
stats.m_starting_height = peer->m_starting_height;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -1786,13 +1817,16 @@ void PeerManagerImpl::UpdatedBlockTip(const CBlockIndex *pindexNew, const CBlock
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Relay to all peers
|
// Relay to all peers
|
||||||
m_connman.ForEachNode([&vHashes](CNode* pnode) {
|
// TODO: Move CanRelay() to Peer and migrate to iteration through m_peer_map
|
||||||
if (!pnode->CanRelay()) {
|
m_connman.ForEachNode([this, &vHashes](CNode* pnode) {
|
||||||
return;
|
if (!pnode->CanRelay()) return;
|
||||||
}
|
|
||||||
LOCK(pnode->cs_inventory);
|
PeerRef peer = GetPeerRef(pnode->GetId());
|
||||||
|
if (peer == nullptr) return;
|
||||||
|
|
||||||
|
LOCK(peer->m_block_inv_mutex);
|
||||||
for (const uint256& hash : reverse_iterate(vHashes)) {
|
for (const uint256& hash : reverse_iterate(vHashes)) {
|
||||||
pnode->vBlockHashesToAnnounce.push_back(hash);
|
peer->m_blocks_for_headers_relay.push_back(hash);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
m_connman.WakeMessageHandler();
|
m_connman.WakeMessageHandler();
|
||||||
@ -1979,7 +2013,7 @@ static void RelayAddress(const CAddress& addr, bool fReachable, const CConnman&
|
|||||||
connman.ForEachNodeThen(std::move(sortfunc), std::move(pushfunc));
|
connman.ForEachNodeThen(std::move(sortfunc), std::move(pushfunc));
|
||||||
}
|
}
|
||||||
|
|
||||||
void PeerManagerImpl::ProcessGetBlockData(CNode& pfrom, const CChainParams& chainparams, const CInv& inv, CConnman& connman, llmq::CInstantSendManager& isman)
|
void PeerManagerImpl::ProcessGetBlockData(CNode& pfrom, Peer& peer, const CChainParams& chainparams, const CInv& inv, CConnman& connman, llmq::CInstantSendManager& isman)
|
||||||
{
|
{
|
||||||
bool send = false;
|
bool send = false;
|
||||||
std::shared_ptr<const CBlock> a_recent_block;
|
std::shared_ptr<const CBlock> a_recent_block;
|
||||||
@ -2112,16 +2146,19 @@ void PeerManagerImpl::ProcessGetBlockData(CNode& pfrom, const CChainParams& chai
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Trigger the peer node to send a getblocks request for the next batch of inventory
|
|
||||||
if (inv.hash == pfrom.hashContinue)
|
|
||||||
{
|
{
|
||||||
// Send immediately. This must send even if redundant,
|
LOCK(peer.m_block_inv_mutex);
|
||||||
// and we want it right after the last block so they don't
|
// Trigger the peer node to send a getblocks request for the next batch of inventory
|
||||||
// wait for other stuff first.
|
if (inv.hash == peer.m_continuation_block) {
|
||||||
std::vector<CInv> vInv;
|
// Send immediately. This must send even if redundant,
|
||||||
vInv.push_back(CInv(MSG_BLOCK, m_chainman.ActiveChain().Tip()->GetBlockHash()));
|
// and we want it right after the last block so they don't
|
||||||
connman.PushMessage(&pfrom, msgMaker.Make(NetMsgType::INV, vInv));
|
// wait for other stuff first.
|
||||||
pfrom.hashContinue.SetNull();
|
std::vector<CInv> vInv;
|
||||||
|
vInv.push_back(CInv(MSG_BLOCK, m_chainman.ActiveChain().Tip()->GetBlockHash()));
|
||||||
|
connman.PushMessage(&pfrom, msgMaker.Make(NetMsgType::INV, vInv));
|
||||||
|
peer.m_continuation_block.SetNull();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2347,7 +2384,7 @@ void PeerManagerImpl::ProcessGetData(CNode& pfrom, Peer& peer, const std::atomic
|
|||||||
if (it != peer.m_getdata_requests.end() && !pfrom.fPauseSend) {
|
if (it != peer.m_getdata_requests.end() && !pfrom.fPauseSend) {
|
||||||
const CInv &inv = *it++;
|
const CInv &inv = *it++;
|
||||||
if (inv.IsGenBlkMsg()) {
|
if (inv.IsGenBlkMsg()) {
|
||||||
ProcessGetBlockData(pfrom, m_chainparams, inv, m_connman, *m_llmq_ctx->isman);
|
ProcessGetBlockData(pfrom, peer, m_chainparams, inv, m_connman, *m_llmq_ctx->isman);
|
||||||
}
|
}
|
||||||
// else: If the first item on the queue is an unknown type, we erase it
|
// else: If the first item on the queue is an unknown type, we erase it
|
||||||
// and continue processing the queue on the next call.
|
// and continue processing the queue on the next call.
|
||||||
@ -2388,7 +2425,9 @@ void PeerManagerImpl::SendBlockTransactions(CNode& pfrom, const CBlock& block, c
|
|||||||
m_connman.PushMessage(&pfrom, msgMaker.Make(NetMsgType::BLOCKTXN, resp));
|
m_connman.PushMessage(&pfrom, msgMaker.Make(NetMsgType::BLOCKTXN, resp));
|
||||||
}
|
}
|
||||||
|
|
||||||
void PeerManagerImpl::ProcessHeadersMessage(CNode& pfrom, const std::vector<CBlockHeader>& headers, bool via_compact_block)
|
void PeerManagerImpl::ProcessHeadersMessage(CNode& pfrom, const Peer& peer,
|
||||||
|
const std::vector<CBlockHeader>& headers,
|
||||||
|
bool via_compact_block)
|
||||||
{
|
{
|
||||||
const CNetMsgMaker msgMaker(pfrom.GetCommonVersion());
|
const CNetMsgMaker msgMaker(pfrom.GetCommonVersion());
|
||||||
size_t nCount = headers.size();
|
size_t nCount = headers.size();
|
||||||
@ -2481,7 +2520,8 @@ void PeerManagerImpl::ProcessHeadersMessage(CNode& pfrom, const std::vector<CBlo
|
|||||||
// TODO: optimize: if pindexLast is an ancestor of m_chainman.ActiveChain().Tip or pindexBestHeader, continue
|
// TODO: optimize: if pindexLast is an ancestor of m_chainman.ActiveChain().Tip or pindexBestHeader, continue
|
||||||
// from there instead.
|
// from there instead.
|
||||||
std::string msg_type = (pfrom.nServices & NODE_HEADERS_COMPRESSED) ? NetMsgType::GETHEADERS2 : NetMsgType::GETHEADERS;
|
std::string msg_type = (pfrom.nServices & NODE_HEADERS_COMPRESSED) ? NetMsgType::GETHEADERS2 : NetMsgType::GETHEADERS;
|
||||||
LogPrint(BCLog::NET, "more %s (%d) to end to peer=%d (startheight:%d)\n", msg_type, pindexLast->nHeight, pfrom.GetId(), pfrom.nStartingHeight);
|
LogPrint(BCLog::NET, "more %s (%d) to end to peer=%d (startheight:%d)\n",
|
||||||
|
msg_type, pindexLast->nHeight, pfrom.GetId(), peer.m_starting_height);
|
||||||
m_connman.PushMessage(&pfrom, msgMaker.Make(msg_type, m_chainman.ActiveChain().GetLocator(pindexLast), uint256()));
|
m_connman.PushMessage(&pfrom, msgMaker.Make(msg_type, m_chainman.ActiveChain().GetLocator(pindexLast), uint256()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2912,7 +2952,7 @@ void PeerManagerImpl::ProcessMessage(
|
|||||||
ServiceFlags nServices;
|
ServiceFlags nServices;
|
||||||
int nVersion;
|
int nVersion;
|
||||||
std::string cleanSubVer;
|
std::string cleanSubVer;
|
||||||
int nStartingHeight = -1;
|
int starting_height = -1;
|
||||||
bool fRelay = true;
|
bool fRelay = true;
|
||||||
|
|
||||||
vRecv >> nVersion >> nServiceInt >> nTime >> addrMe;
|
vRecv >> nVersion >> nServiceInt >> nTime >> addrMe;
|
||||||
@ -2946,7 +2986,7 @@ void PeerManagerImpl::ProcessMessage(
|
|||||||
cleanSubVer = SanitizeString(strSubVer);
|
cleanSubVer = SanitizeString(strSubVer);
|
||||||
}
|
}
|
||||||
if (!vRecv.empty()) {
|
if (!vRecv.empty()) {
|
||||||
vRecv >> nStartingHeight;
|
vRecv >> starting_height;
|
||||||
}
|
}
|
||||||
if (!vRecv.empty())
|
if (!vRecv.empty())
|
||||||
vRecv >> fRelay;
|
vRecv >> fRelay;
|
||||||
@ -3021,7 +3061,7 @@ void PeerManagerImpl::ProcessMessage(
|
|||||||
LOCK(pfrom.cs_SubVer);
|
LOCK(pfrom.cs_SubVer);
|
||||||
pfrom.cleanSubVer = cleanSubVer;
|
pfrom.cleanSubVer = cleanSubVer;
|
||||||
}
|
}
|
||||||
pfrom.nStartingHeight = nStartingHeight;
|
peer->m_starting_height = starting_height;
|
||||||
|
|
||||||
// set nodes not relaying blocks and tx and not serving (parts) of the historical blockchain as "clients"
|
// set nodes not relaying blocks and tx and not serving (parts) of the historical blockchain as "clients"
|
||||||
pfrom.fClient = (!(nServices & NODE_NETWORK) && !(nServices & NODE_NETWORK_LIMITED));
|
pfrom.fClient = (!(nServices & NODE_NETWORK) && !(nServices & NODE_NETWORK_LIMITED));
|
||||||
@ -3095,7 +3135,7 @@ void PeerManagerImpl::ProcessMessage(
|
|||||||
|
|
||||||
LogPrint(BCLog::NET, "receive version message: %s: version %d, blocks=%d, us=%s, peer=%d%s\n",
|
LogPrint(BCLog::NET, "receive version message: %s: version %d, blocks=%d, us=%s, peer=%d%s\n",
|
||||||
cleanSubVer, pfrom.nVersion,
|
cleanSubVer, pfrom.nVersion,
|
||||||
pfrom.nStartingHeight, addrMe.ToString(), pfrom.GetId(),
|
peer->m_starting_height, addrMe.ToString(), pfrom.GetId(),
|
||||||
remoteAddr);
|
remoteAddr);
|
||||||
|
|
||||||
int64_t nTimeOffset = nTime - GetTime();
|
int64_t nTimeOffset = nTime - GetTime();
|
||||||
@ -3125,7 +3165,7 @@ void PeerManagerImpl::ProcessMessage(
|
|||||||
|
|
||||||
if (!pfrom.IsInboundConn()) {
|
if (!pfrom.IsInboundConn()) {
|
||||||
LogPrintf("New outbound peer connected: version: %d, blocks=%d, peer=%d%s (%s)\n",
|
LogPrintf("New outbound peer connected: version: %d, blocks=%d, peer=%d%s (%s)\n",
|
||||||
pfrom.nVersion.load(), pfrom.nStartingHeight,
|
pfrom.nVersion.load(), peer->m_starting_height,
|
||||||
pfrom.GetId(), (fLogIPs ? strprintf(", peeraddr=%s", pfrom.addr.ToString()) : ""),
|
pfrom.GetId(), (fLogIPs ? strprintf(", peeraddr=%s", pfrom.addr.ToString()) : ""),
|
||||||
pfrom.IsBlockOnlyConn()? "block-relay" : "full-relay");
|
pfrom.IsBlockOnlyConn()? "block-relay" : "full-relay");
|
||||||
}
|
}
|
||||||
@ -3482,14 +3522,13 @@ void PeerManagerImpl::ProcessMessage(
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (pfrom.CanRelay()) {
|
if (pfrom.CanRelay()) {
|
||||||
WITH_LOCK(pfrom.cs_inventory, pfrom.vInventoryBlockToSend.push_back(pindex->GetBlockHash()));
|
WITH_LOCK(peer->m_block_inv_mutex, peer->m_blocks_for_inv_relay.push_back(pindex->GetBlockHash()));
|
||||||
}
|
}
|
||||||
if (--nLimit <= 0)
|
if (--nLimit <= 0) {
|
||||||
{
|
|
||||||
// When this block is requested, we'll send an inv that'll
|
// When this block is requested, we'll send an inv that'll
|
||||||
// trigger the peer to getblocks the next batch of inventory.
|
// trigger the peer to getblocks the next batch of inventory.
|
||||||
LogPrint(BCLog::NET, " getblocks stopping at limit %d %s\n", pindex->nHeight, pindex->GetBlockHash().ToString());
|
LogPrint(BCLog::NET, " getblocks stopping at limit %d %s\n", pindex->nHeight, pindex->GetBlockHash().ToString());
|
||||||
pfrom.hashContinue = pindex->GetBlockHash();
|
WITH_LOCK(peer->m_block_inv_mutex, {peer->m_continuation_block = pindex->GetBlockHash();});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3972,7 +4011,7 @@ void PeerManagerImpl::ProcessMessage(
|
|||||||
// the peer if the header turns out to be for an invalid block.
|
// the peer if the header turns out to be for an invalid block.
|
||||||
// Note that if a peer tries to build on an invalid chain, that
|
// Note that if a peer tries to build on an invalid chain, that
|
||||||
// will be detected and the peer will be disconnected/discouraged.
|
// will be detected and the peer will be disconnected/discouraged.
|
||||||
return ProcessHeadersMessage(pfrom, {cmpctblock.header}, /*punish_duplicate_invalid=*/true);
|
return ProcessHeadersMessage(pfrom, *peer, {cmpctblock.header}, /*punish_duplicate_invalid=*/true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fBlockReconstructed) {
|
if (fBlockReconstructed) {
|
||||||
@ -4111,7 +4150,7 @@ void PeerManagerImpl::ProcessMessage(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ProcessHeadersMessage(pfrom, headers, /*via_compact_block=*/false);
|
return ProcessHeadersMessage(pfrom, *peer, headers, /*via_compact_block=*/false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (msg_type == NetMsgType::BLOCK)
|
if (msg_type == NetMsgType::BLOCK)
|
||||||
@ -4798,6 +4837,7 @@ bool PeerManagerImpl::SendMessages(CNode* pto)
|
|||||||
{
|
{
|
||||||
assert(m_llmq_ctx);
|
assert(m_llmq_ctx);
|
||||||
|
|
||||||
|
PeerRef peer = GetPeerRef(pto->GetId());
|
||||||
const Consensus::Params& consensusParams = m_chainparams.GetConsensus();
|
const Consensus::Params& consensusParams = m_chainparams.GetConsensus();
|
||||||
|
|
||||||
// We must call MaybeDiscourageAndDisconnect first, to ensure that we'll
|
// We must call MaybeDiscourageAndDisconnect first, to ensure that we'll
|
||||||
@ -4923,7 +4963,7 @@ bool PeerManagerImpl::SendMessages(CNode* pto)
|
|||||||
if (pindexStart->pprev)
|
if (pindexStart->pprev)
|
||||||
pindexStart = pindexStart->pprev;
|
pindexStart = pindexStart->pprev;
|
||||||
std::string msg_type = (pto->nServices & NODE_HEADERS_COMPRESSED) ? NetMsgType::GETHEADERS2 : NetMsgType::GETHEADERS;
|
std::string msg_type = (pto->nServices & NODE_HEADERS_COMPRESSED) ? NetMsgType::GETHEADERS2 : NetMsgType::GETHEADERS;
|
||||||
LogPrint(BCLog::NET, "initial %s (%d) to peer=%d (startheight:%d)\n", msg_type, pindexStart->nHeight, pto->GetId(), pto->nStartingHeight);
|
LogPrint(BCLog::NET, "initial %s (%d) to peer=%d (startheight:%d)\n", msg_type, pindexStart->nHeight, pto->GetId(), peer->m_starting_height);
|
||||||
m_connman.PushMessage(pto, msgMaker.Make(msg_type, m_chainman.ActiveChain().GetLocator(pindexStart), uint256()));
|
m_connman.PushMessage(pto, msgMaker.Make(msg_type, m_chainman.ActiveChain().GetLocator(pindexStart), uint256()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -4939,11 +4979,11 @@ bool PeerManagerImpl::SendMessages(CNode* pto)
|
|||||||
// If no header would connect, or if we have too many
|
// If no header would connect, or if we have too many
|
||||||
// blocks, or if the peer doesn't want headers, just
|
// blocks, or if the peer doesn't want headers, just
|
||||||
// add all to the inv queue.
|
// add all to the inv queue.
|
||||||
LOCK(pto->cs_inventory);
|
LOCK(peer->m_block_inv_mutex);
|
||||||
std::vector<CBlock> vHeaders;
|
std::vector<CBlock> vHeaders;
|
||||||
bool fRevertToInv = ((!state.fPreferHeaders && !state.fPreferHeadersCompressed &&
|
bool fRevertToInv = ((!state.fPreferHeaders && !state.fPreferHeadersCompressed &&
|
||||||
(!state.fPreferHeaderAndIDs || pto->vBlockHashesToAnnounce.size() > 1)) ||
|
(!state.fPreferHeaderAndIDs || peer->m_blocks_for_headers_relay.size() > 1)) ||
|
||||||
pto->vBlockHashesToAnnounce.size() > MAX_BLOCKS_TO_ANNOUNCE);
|
peer->m_blocks_for_headers_relay.size() > MAX_BLOCKS_TO_ANNOUNCE);
|
||||||
const CBlockIndex *pBestIndex = nullptr; // last header queued for delivery
|
const CBlockIndex *pBestIndex = nullptr; // last header queued for delivery
|
||||||
ProcessBlockAvailability(pto->GetId()); // ensure pindexBestKnownBlock is up-to-date
|
ProcessBlockAvailability(pto->GetId()); // ensure pindexBestKnownBlock is up-to-date
|
||||||
|
|
||||||
@ -4952,7 +4992,7 @@ bool PeerManagerImpl::SendMessages(CNode* pto)
|
|||||||
// Try to find first header that our peer doesn't have, and
|
// Try to find first header that our peer doesn't have, and
|
||||||
// then send all headers past that one. If we come across any
|
// then send all headers past that one. If we come across any
|
||||||
// headers that aren't on m_chainman.ActiveChain(), give up.
|
// headers that aren't on m_chainman.ActiveChain(), give up.
|
||||||
for (const uint256 &hash : pto->vBlockHashesToAnnounce) {
|
for (const uint256& hash : peer->m_blocks_for_headers_relay) {
|
||||||
const CBlockIndex* pindex = m_chainman.m_blockman.LookupBlockIndex(hash);
|
const CBlockIndex* pindex = m_chainman.m_blockman.LookupBlockIndex(hash);
|
||||||
assert(pindex);
|
assert(pindex);
|
||||||
if (m_chainman.ActiveChain()[pindex->nHeight] != pindex) {
|
if (m_chainman.ActiveChain()[pindex->nHeight] != pindex) {
|
||||||
@ -4969,7 +5009,7 @@ bool PeerManagerImpl::SendMessages(CNode* pto)
|
|||||||
// which should be caught by the prior check), but one
|
// which should be caught by the prior check), but one
|
||||||
// way this could happen is by using invalidateblock /
|
// way this could happen is by using invalidateblock /
|
||||||
// reconsiderblock repeatedly on the tip, causing it to
|
// reconsiderblock repeatedly on the tip, causing it to
|
||||||
// be added multiple times to vBlockHashesToAnnounce.
|
// be added multiple times to m_blocks_for_headers_relay.
|
||||||
// Robustly deal with this rare situation by reverting
|
// Robustly deal with this rare situation by reverting
|
||||||
// to an inv.
|
// to an inv.
|
||||||
fRevertToInv = true;
|
fRevertToInv = true;
|
||||||
@ -5057,10 +5097,10 @@ bool PeerManagerImpl::SendMessages(CNode* pto)
|
|||||||
}
|
}
|
||||||
if (fRevertToInv) {
|
if (fRevertToInv) {
|
||||||
// If falling back to using an inv, just try to inv the tip.
|
// If falling back to using an inv, just try to inv the tip.
|
||||||
// The last entry in vBlockHashesToAnnounce was our tip at some point
|
// The last entry in m_blocks_for_headers_relay was our tip at some point
|
||||||
// in the past.
|
// in the past.
|
||||||
if (!pto->vBlockHashesToAnnounce.empty()) {
|
if (!peer->m_blocks_for_headers_relay.empty()) {
|
||||||
const uint256 &hashToAnnounce = pto->vBlockHashesToAnnounce.back();
|
const uint256& hashToAnnounce = peer->m_blocks_for_headers_relay.back();
|
||||||
const CBlockIndex* pindex = m_chainman.m_blockman.LookupBlockIndex(hashToAnnounce);
|
const CBlockIndex* pindex = m_chainman.m_blockman.LookupBlockIndex(hashToAnnounce);
|
||||||
assert(pindex);
|
assert(pindex);
|
||||||
|
|
||||||
@ -5074,13 +5114,13 @@ bool PeerManagerImpl::SendMessages(CNode* pto)
|
|||||||
|
|
||||||
// If the peer's chain has this block, don't inv it back.
|
// If the peer's chain has this block, don't inv it back.
|
||||||
if (!PeerHasHeader(&state, pindex)) {
|
if (!PeerHasHeader(&state, pindex)) {
|
||||||
pto->vInventoryBlockToSend.push_back(hashToAnnounce);
|
peer->m_blocks_for_inv_relay.push_back(hashToAnnounce);
|
||||||
LogPrint(BCLog::NET, "%s: sending inv peer=%d hash=%s\n", __func__,
|
LogPrint(BCLog::NET, "%s: sending inv peer=%d hash=%s\n", __func__,
|
||||||
pto->GetId(), hashToAnnounce.ToString());
|
pto->GetId(), hashToAnnounce.ToString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pto->vBlockHashesToAnnounce.clear();
|
peer->m_blocks_for_headers_relay.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
@ -5088,26 +5128,26 @@ bool PeerManagerImpl::SendMessages(CNode* pto)
|
|||||||
//
|
//
|
||||||
std::vector<CInv> vInv;
|
std::vector<CInv> vInv;
|
||||||
{
|
{
|
||||||
LOCK2(m_mempool.cs, pto->cs_inventory);
|
LOCK2(m_mempool.cs, peer->m_block_inv_mutex);
|
||||||
|
|
||||||
size_t reserve = INVENTORY_BROADCAST_MAX_PER_1MB_BLOCK * MaxBlockSize() / 1000000;
|
size_t reserve = INVENTORY_BROADCAST_MAX_PER_1MB_BLOCK * MaxBlockSize() / 1000000;
|
||||||
if (pto->RelayAddrsWithConn()) {
|
if (pto->RelayAddrsWithConn()) {
|
||||||
LOCK(pto->m_tx_relay->cs_tx_inventory);
|
LOCK(pto->m_tx_relay->cs_tx_inventory);
|
||||||
reserve = std::min<size_t>(pto->m_tx_relay->setInventoryTxToSend.size(), reserve);
|
reserve = std::min<size_t>(pto->m_tx_relay->setInventoryTxToSend.size(), reserve);
|
||||||
}
|
}
|
||||||
reserve = std::max<size_t>(reserve, pto->vInventoryBlockToSend.size());
|
reserve = std::max<size_t>(reserve, peer->m_blocks_for_inv_relay.size());
|
||||||
reserve = std::min<size_t>(reserve, MAX_INV_SZ);
|
reserve = std::min<size_t>(reserve, MAX_INV_SZ);
|
||||||
vInv.reserve(reserve);
|
vInv.reserve(reserve);
|
||||||
|
|
||||||
// Add blocks
|
// Add blocks
|
||||||
for (const uint256& hash : pto->vInventoryBlockToSend) {
|
for (const uint256& hash : peer->m_blocks_for_inv_relay) {
|
||||||
vInv.push_back(CInv(MSG_BLOCK, hash));
|
vInv.push_back(CInv(MSG_BLOCK, hash));
|
||||||
if (vInv.size() == MAX_INV_SZ) {
|
if (vInv.size() == MAX_INV_SZ) {
|
||||||
m_connman.PushMessage(pto, msgMaker.Make(NetMsgType::INV, vInv));
|
m_connman.PushMessage(pto, msgMaker.Make(NetMsgType::INV, vInv));
|
||||||
vInv.clear();
|
vInv.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pto->vInventoryBlockToSend.clear();
|
peer->m_blocks_for_inv_relay.clear();
|
||||||
|
|
||||||
auto queueAndMaybePushInv = [this, pto, &vInv, &msgMaker](const CInv& invIn) {
|
auto queueAndMaybePushInv = [this, pto, &vInv, &msgMaker](const CInv& invIn) {
|
||||||
AssertLockHeld(pto->m_tx_relay->cs_tx_inventory);
|
AssertLockHeld(pto->m_tx_relay->cs_tx_inventory);
|
||||||
|
@ -38,6 +38,7 @@ struct CNodeStateStats {
|
|||||||
int m_misbehavior_score = 0;
|
int m_misbehavior_score = 0;
|
||||||
int nSyncHeight = -1;
|
int nSyncHeight = -1;
|
||||||
int nCommonHeight = -1;
|
int nCommonHeight = -1;
|
||||||
|
int m_starting_height = -1;
|
||||||
std::vector<int> vHeightInFlight;
|
std::vector<int> vHeightInFlight;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1259,7 +1259,6 @@ void RPCConsole::updateNodeDetail(const CNodeCombinedStats *stats)
|
|||||||
: stats->nodeStats.fRelayTxes
|
: stats->nodeStats.fRelayTxes
|
||||||
? tr("Outbound")
|
? tr("Outbound")
|
||||||
: tr("Outbound block-relay"));
|
: tr("Outbound block-relay"));
|
||||||
ui->peerHeight->setText(QString::number(stats->nodeStats.nStartingHeight));
|
|
||||||
ui->peerNetwork->setText(GUIUtil::NetworkToQString(stats->nodeStats.m_network));
|
ui->peerNetwork->setText(GUIUtil::NetworkToQString(stats->nodeStats.m_network));
|
||||||
if (stats->nodeStats.m_permissionFlags == PF_NONE) {
|
if (stats->nodeStats.m_permissionFlags == PF_NONE) {
|
||||||
ui->peerPermissions->setText(tr("N/A"));
|
ui->peerPermissions->setText(tr("N/A"));
|
||||||
@ -1298,6 +1297,8 @@ void RPCConsole::updateNodeDetail(const CNodeCombinedStats *stats)
|
|||||||
ui->peerCommonHeight->setText(QString("%1").arg(stats->nodeStateStats.nCommonHeight));
|
ui->peerCommonHeight->setText(QString("%1").arg(stats->nodeStateStats.nCommonHeight));
|
||||||
else
|
else
|
||||||
ui->peerCommonHeight->setText(tr("Unknown"));
|
ui->peerCommonHeight->setText(tr("Unknown"));
|
||||||
|
|
||||||
|
ui->peerHeight->setText(QString::number(stats->nodeStateStats.m_starting_height));
|
||||||
}
|
}
|
||||||
|
|
||||||
ui->detailWidget->show();
|
ui->detailWidget->show();
|
||||||
|
@ -137,8 +137,8 @@ static RPCHelpMan getpeerinfo()
|
|||||||
"Please note this output is unlikely to be stable in upcoming releases as we iterate to\n"
|
"Please note this output is unlikely to be stable in upcoming releases as we iterate to\n"
|
||||||
"best capture connection behaviors."},
|
"best capture connection behaviors."},
|
||||||
{RPCResult::Type::BOOL, "masternode", "Whether connection was due to masternode connection attempt"},
|
{RPCResult::Type::BOOL, "masternode", "Whether connection was due to masternode connection attempt"},
|
||||||
{RPCResult::Type::NUM, "startingheight", "The starting height (block) of the peer"},
|
|
||||||
{RPCResult::Type::NUM, "banscore", "The ban score (DEPRECATED, returned only if config option -deprecatedrpc=banscore is passed)"},
|
{RPCResult::Type::NUM, "banscore", "The ban score (DEPRECATED, returned only if config option -deprecatedrpc=banscore is passed)"},
|
||||||
|
{RPCResult::Type::NUM, "startingheight", "The starting height (block) of the peer"},
|
||||||
{RPCResult::Type::NUM, "synced_headers", "The last header we have in common with this peer"},
|
{RPCResult::Type::NUM, "synced_headers", "The last header we have in common with this peer"},
|
||||||
{RPCResult::Type::NUM, "synced_blocks", "The last block we have in common with this peer"},
|
{RPCResult::Type::NUM, "synced_blocks", "The last block we have in common with this peer"},
|
||||||
{RPCResult::Type::ARR, "inflight", "",
|
{RPCResult::Type::ARR, "inflight", "",
|
||||||
@ -226,12 +226,12 @@ static RPCHelpMan getpeerinfo()
|
|||||||
obj.pushKV("inbound", stats.fInbound);
|
obj.pushKV("inbound", stats.fInbound);
|
||||||
obj.pushKV("addnode", stats.m_manual_connection);
|
obj.pushKV("addnode", stats.m_manual_connection);
|
||||||
obj.pushKV("masternode", stats.m_masternode_connection);
|
obj.pushKV("masternode", stats.m_masternode_connection);
|
||||||
obj.pushKV("startingheight", stats.nStartingHeight);
|
|
||||||
if (fStateStats) {
|
if (fStateStats) {
|
||||||
if (IsDeprecatedRPCEnabled("banscore")) {
|
if (IsDeprecatedRPCEnabled("banscore")) {
|
||||||
// banscore is deprecated in v21 for removal in v22
|
// banscore is deprecated in v21 for removal in v22
|
||||||
obj.pushKV("banscore", statestats.m_misbehavior_score);
|
obj.pushKV("banscore", statestats.m_misbehavior_score);
|
||||||
}
|
}
|
||||||
|
obj.pushKV("startingheight", statestats.m_starting_height);
|
||||||
obj.pushKV("synced_headers", statestats.nSyncHeight);
|
obj.pushKV("synced_headers", statestats.nSyncHeight);
|
||||||
obj.pushKV("synced_blocks", statestats.nCommonHeight);
|
obj.pushKV("synced_blocks", statestats.nCommonHeight);
|
||||||
UniValue heights(UniValue::VARR);
|
UniValue heights(UniValue::VARR);
|
||||||
|
Loading…
Reference in New Issue
Block a user