aboutsummaryrefslogtreecommitdiff
path: root/src/net_processing.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/net_processing.cpp')
-rw-r--r--src/net_processing.cpp275
1 files changed, 122 insertions, 153 deletions
diff --git a/src/net_processing.cpp b/src/net_processing.cpp
index cb0e8c88f8..349d7fd8fb 100644
--- a/src/net_processing.cpp
+++ b/src/net_processing.cpp
@@ -175,6 +175,8 @@ static constexpr double MAX_ADDR_RATE_PER_SECOND{0.1};
* based increments won't go above this, but the MAX_ADDR_TO_SEND increment following GETADDR
* is exempt from this limit). */
static constexpr size_t MAX_ADDR_PROCESSING_TOKEN_BUCKET{MAX_ADDR_TO_SEND};
+/** The compactblocks version we support. See BIP 152. */
+static constexpr uint64_t CMPCTBLOCKS_VERSION{2};
// Internal stuff
namespace {
@@ -365,23 +367,12 @@ struct CNodeState {
bool fPreferredDownload{false};
//! Whether this peer wants invs or headers (when possible) for block announcements.
bool fPreferHeaders{false};
- //! Whether this peer wants invs or cmpctblocks (when possible) for block announcements.
- bool fPreferHeaderAndIDs{false};
- /**
- * Whether this peer will send us cmpctblocks if we request them.
- * This is not used to gate request logic, as we really only care about fSupportsDesiredCmpctVersion,
- * but is used as a flag to "lock in" the version of compact blocks (fWantsCmpctWitness) we send.
- */
- bool fProvidesHeaderAndIDs{false};
+ /** Whether this peer wants invs or cmpctblocks (when possible) for block announcements. */
+ bool m_requested_hb_cmpctblocks{false};
+ /** Whether this peer will send us cmpctblocks if we request them. */
+ bool m_provides_cmpctblocks{false};
//! Whether this peer can give us witnesses
bool fHaveWitness{false};
- //! Whether this peer wants witnesses in cmpctblocks/blocktxns
- bool fWantsCmpctWitness{false};
- /**
- * If we've announced NODE_WITNESS to this peer: whether the peer sends witnesses in cmpctblocks/blocktxns,
- * otherwise: whether this peer sends non-witnesses in cmpctblocks/blocktxns.
- */
- bool fSupportsDesiredCmpctVersion{false};
/** State used to enforce CHAIN_SYNC_TIMEOUT and EXTRA_PEER_CHECK_INTERVAL logic.
*
@@ -440,30 +431,37 @@ public:
CTxMemPool& pool, bool ignore_incoming_txs);
/** Overridden from CValidationInterface. */
- void BlockConnected(const std::shared_ptr<const CBlock>& pblock, const CBlockIndex* pindexConnected) override;
- void BlockDisconnected(const std::shared_ptr<const CBlock> &block, const CBlockIndex* pindex) override;
- void UpdatedBlockTip(const CBlockIndex *pindexNew, const CBlockIndex *pindexFork, bool fInitialDownload) override;
- void BlockChecked(const CBlock& block, const BlockValidationState& state) override;
+ void BlockConnected(const std::shared_ptr<const CBlock>& pblock, const CBlockIndex* pindexConnected) override
+ EXCLUSIVE_LOCKS_REQUIRED(!m_recent_confirmed_transactions_mutex);
+ void BlockDisconnected(const std::shared_ptr<const CBlock> &block, const CBlockIndex* pindex) override
+ EXCLUSIVE_LOCKS_REQUIRED(!m_recent_confirmed_transactions_mutex);
+ void UpdatedBlockTip(const CBlockIndex *pindexNew, const CBlockIndex *pindexFork, bool fInitialDownload) override
+ EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex);
+ void BlockChecked(const CBlock& block, const BlockValidationState& state) override
+ EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex);
void NewPoWValidBlock(const CBlockIndex *pindex, const std::shared_ptr<const CBlock>& pblock) override;
/** Implement NetEventsInterface */
- void InitializeNode(CNode* pnode) override;
- void FinalizeNode(const CNode& node) override;
- bool ProcessMessages(CNode* pfrom, std::atomic<bool>& interrupt) override;
- bool SendMessages(CNode* pto) override EXCLUSIVE_LOCKS_REQUIRED(pto->cs_sendProcessing);
+ void InitializeNode(CNode* pnode) override EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex);
+ void FinalizeNode(const CNode& node) override EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex);
+ bool ProcessMessages(CNode* pfrom, std::atomic<bool>& interrupt) override
+ EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex, !m_recent_confirmed_transactions_mutex);
+ bool SendMessages(CNode* pto) override EXCLUSIVE_LOCKS_REQUIRED(pto->cs_sendProcessing)
+ EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex, !m_recent_confirmed_transactions_mutex);
/** Implement PeerManager */
void StartScheduledTasks(CScheduler& scheduler) override;
void CheckForStaleTipAndEvictPeers() override;
std::optional<std::string> FetchBlock(NodeId peer_id, const CBlockIndex& block_index) override;
- bool GetNodeStateStats(NodeId nodeid, CNodeStateStats& stats) const override;
+ bool GetNodeStateStats(NodeId nodeid, CNodeStateStats& stats) const override EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex);
bool IgnoresIncomingTxs() override { return m_ignore_incoming_txs; }
- void SendPings() override;
- void RelayTransaction(const uint256& txid, const uint256& wtxid) override;
+ void SendPings() override EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex);
+ void RelayTransaction(const uint256& txid, const uint256& wtxid) override EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex);
void SetBestHeight(int height) override { m_best_height = height; };
- void Misbehaving(const NodeId pnode, const int howmuch, const std::string& message) override;
+ void Misbehaving(const NodeId pnode, const int howmuch, const std::string& message) override EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex);
void ProcessMessage(CNode& pfrom, const std::string& msg_type, CDataStream& vRecv,
- const std::chrono::microseconds time_received, const std::atomic<bool>& interruptMsgProc) override;
+ const std::chrono::microseconds time_received, const std::atomic<bool>& interruptMsgProc) override
+ EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex, !m_recent_confirmed_transactions_mutex);
void UpdateLastBlockAnnounceTime(NodeId node, int64_t time_in_seconds) override;
private:
@@ -474,15 +472,15 @@ private:
void EvictExtraOutboundPeers(std::chrono::seconds now) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
/** Retrieve unbroadcast transactions from the mempool and reattempt sending to peers */
- void ReattemptInitialBroadcast(CScheduler& scheduler);
+ void ReattemptInitialBroadcast(CScheduler& scheduler) EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex);
/** Get a shared pointer to the Peer object.
* May return an empty shared_ptr if the Peer object can't be found. */
- PeerRef GetPeerRef(NodeId id) const;
+ PeerRef GetPeerRef(NodeId id) const EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex);
/** Get a shared pointer to the Peer object and remove it from m_peer_map.
* May return an empty shared_ptr if the Peer object can't be found. */
- PeerRef RemovePeer(NodeId id);
+ PeerRef RemovePeer(NodeId id) EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex);
/**
* Potentially mark a node discouraged based on the contents of a BlockValidationState object
@@ -495,14 +493,16 @@ private:
* @return Returns true if the peer was punished (probably disconnected)
*/
bool MaybePunishNodeForBlock(NodeId nodeid, const BlockValidationState& state,
- bool via_compact_block, const std::string& message = "");
+ bool via_compact_block, const std::string& message = "")
+ EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex);
/**
* Potentially disconnect and discourage a node based on the contents of a TxValidationState object
*
* @return Returns true if the peer was punished (probably disconnected)
*/
- bool MaybePunishNodeForTx(NodeId nodeid, const TxValidationState& state, const std::string& message = "");
+ bool MaybePunishNodeForTx(NodeId nodeid, const TxValidationState& state, const std::string& message = "")
+ EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex);
/** Maybe disconnect a peer and discourage future connections from its address.
*
@@ -512,13 +512,16 @@ private:
*/
bool MaybeDiscourageAndDisconnect(CNode& pnode, Peer& peer);
- void ProcessOrphanTx(std::set<uint256>& orphan_work_set) EXCLUSIVE_LOCKS_REQUIRED(cs_main, g_cs_orphans);
+ void ProcessOrphanTx(std::set<uint256>& orphan_work_set) EXCLUSIVE_LOCKS_REQUIRED(cs_main, g_cs_orphans)
+ EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex);
/** Process a single headers message from a peer. */
void ProcessHeadersMessage(CNode& pfrom, const Peer& peer,
const std::vector<CBlockHeader>& headers,
- bool via_compact_block);
+ bool via_compact_block)
+ EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex);
- void SendBlockTransactions(CNode& pfrom, const CBlock& block, const BlockTransactionsRequest& req);
+ void SendBlockTransactions(CNode& pfrom, const CBlock& block, const BlockTransactionsRequest& req)
+ EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex);
/** Register with TxRequestTracker that an INV has been received from a
* peer. The announcement parameters are decided in PeerManager and then
@@ -545,7 +548,7 @@ private:
* @param[in] fReachable Whether the address' network is reachable. We relay unreachable
* addresses less.
*/
- void RelayAddress(NodeId originator, const CAddress& addr, bool fReachable);
+ void RelayAddress(NodeId originator, const CAddress& addr, bool fReachable) EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex);
/** Send `feefilter` message. */
void MaybeSendFeefilter(CNode& node, Peer& peer, std::chrono::microseconds current_time);
@@ -615,7 +618,8 @@ private:
/** Number of preferable block download peers. */
int m_num_preferred_download_peers GUARDED_BY(cs_main){0};
- bool AlreadyHaveTx(const GenTxid& gtxid) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
+ bool AlreadyHaveTx(const GenTxid& gtxid)
+ EXCLUSIVE_LOCKS_REQUIRED(cs_main, !m_recent_confirmed_transactions_mutex);
/**
* Filter for transactions that were recently rejected by the mempool.
@@ -687,7 +691,6 @@ private:
std::shared_ptr<const CBlock> m_most_recent_block GUARDED_BY(m_most_recent_block_mutex);
std::shared_ptr<const CBlockHeaderAndShortTxIDs> m_most_recent_compact_block GUARDED_BY(m_most_recent_block_mutex);
uint256 m_most_recent_block_hash GUARDED_BY(m_most_recent_block_mutex);
- bool m_most_recent_compact_block_has_witnesses GUARDED_BY(m_most_recent_block_mutex){false};
/** Height of the highest block announced using BIP 152 high-bandwidth mode. */
int m_highest_fast_announce{0};
@@ -974,54 +977,52 @@ void PeerManagerImpl::MaybeSetPeerAsAnnouncingHeaderAndIDs(NodeId nodeid)
if (m_ignore_incoming_txs) return;
CNodeState* nodestate = State(nodeid);
- if (!nodestate || !nodestate->fSupportsDesiredCmpctVersion) {
- // Never ask from peers who can't provide witnesses.
+ if (!nodestate || !nodestate->m_provides_cmpctblocks) {
+ // Don't request compact blocks if the peer has not signalled support
return;
}
- if (nodestate->fProvidesHeaderAndIDs) {
- int num_outbound_hb_peers = 0;
- for (std::list<NodeId>::iterator it = lNodesAnnouncingHeaderAndIDs.begin(); it != lNodesAnnouncingHeaderAndIDs.end(); it++) {
- if (*it == nodeid) {
- lNodesAnnouncingHeaderAndIDs.erase(it);
- lNodesAnnouncingHeaderAndIDs.push_back(nodeid);
- return;
- }
- CNodeState *state = State(*it);
- if (state != nullptr && !state->m_is_inbound) ++num_outbound_hb_peers;
- }
- if (nodestate->m_is_inbound) {
- // If we're adding an inbound HB peer, make sure we're not removing
- // our last outbound HB peer in the process.
- if (lNodesAnnouncingHeaderAndIDs.size() >= 3 && num_outbound_hb_peers == 1) {
- CNodeState *remove_node = State(lNodesAnnouncingHeaderAndIDs.front());
- if (remove_node != nullptr && !remove_node->m_is_inbound) {
- // Put the HB outbound peer in the second slot, so that it
- // doesn't get removed.
- std::swap(lNodesAnnouncingHeaderAndIDs.front(), *std::next(lNodesAnnouncingHeaderAndIDs.begin()));
- }
- }
+
+ int num_outbound_hb_peers = 0;
+ for (std::list<NodeId>::iterator it = lNodesAnnouncingHeaderAndIDs.begin(); it != lNodesAnnouncingHeaderAndIDs.end(); it++) {
+ if (*it == nodeid) {
+ lNodesAnnouncingHeaderAndIDs.erase(it);
+ lNodesAnnouncingHeaderAndIDs.push_back(nodeid);
+ return;
}
- m_connman.ForNode(nodeid, [this](CNode* pfrom) EXCLUSIVE_LOCKS_REQUIRED(::cs_main) {
- AssertLockHeld(::cs_main);
- uint64_t nCMPCTBLOCKVersion = 2;
- if (lNodesAnnouncingHeaderAndIDs.size() >= 3) {
- // As per BIP152, we only get 3 of our peers to announce
- // blocks using compact encodings.
- m_connman.ForNode(lNodesAnnouncingHeaderAndIDs.front(), [this, nCMPCTBLOCKVersion](CNode* pnodeStop){
- m_connman.PushMessage(pnodeStop, CNetMsgMaker(pnodeStop->GetCommonVersion()).Make(NetMsgType::SENDCMPCT, /*fAnnounceUsingCMPCTBLOCK=*/false, nCMPCTBLOCKVersion));
- // save BIP152 bandwidth state: we select peer to be low-bandwidth
- pnodeStop->m_bip152_highbandwidth_to = false;
- return true;
- });
- lNodesAnnouncingHeaderAndIDs.pop_front();
+ CNodeState *state = State(*it);
+ if (state != nullptr && !state->m_is_inbound) ++num_outbound_hb_peers;
+ }
+ if (nodestate->m_is_inbound) {
+ // If we're adding an inbound HB peer, make sure we're not removing
+ // our last outbound HB peer in the process.
+ if (lNodesAnnouncingHeaderAndIDs.size() >= 3 && num_outbound_hb_peers == 1) {
+ CNodeState *remove_node = State(lNodesAnnouncingHeaderAndIDs.front());
+ if (remove_node != nullptr && !remove_node->m_is_inbound) {
+ // Put the HB outbound peer in the second slot, so that it
+ // doesn't get removed.
+ std::swap(lNodesAnnouncingHeaderAndIDs.front(), *std::next(lNodesAnnouncingHeaderAndIDs.begin()));
}
- m_connman.PushMessage(pfrom, CNetMsgMaker(pfrom->GetCommonVersion()).Make(NetMsgType::SENDCMPCT, /*fAnnounceUsingCMPCTBLOCK=*/true, nCMPCTBLOCKVersion));
- // save BIP152 bandwidth state: we select peer to be high-bandwidth
- pfrom->m_bip152_highbandwidth_to = true;
- lNodesAnnouncingHeaderAndIDs.push_back(pfrom->GetId());
- return true;
- });
+ }
}
+ m_connman.ForNode(nodeid, [this](CNode* pfrom) EXCLUSIVE_LOCKS_REQUIRED(::cs_main) {
+ AssertLockHeld(::cs_main);
+ if (lNodesAnnouncingHeaderAndIDs.size() >= 3) {
+ // As per BIP152, we only get 3 of our peers to announce
+ // blocks using compact encodings.
+ m_connman.ForNode(lNodesAnnouncingHeaderAndIDs.front(), [this](CNode* pnodeStop){
+ m_connman.PushMessage(pnodeStop, CNetMsgMaker(pnodeStop->GetCommonVersion()).Make(NetMsgType::SENDCMPCT, /*high_bandwidth=*/false, /*version=*/CMPCTBLOCKS_VERSION));
+ // save BIP152 bandwidth state: we select peer to be low-bandwidth
+ pnodeStop->m_bip152_highbandwidth_to = false;
+ return true;
+ });
+ lNodesAnnouncingHeaderAndIDs.pop_front();
+ }
+ m_connman.PushMessage(pfrom, CNetMsgMaker(pfrom->GetCommonVersion()).Make(NetMsgType::SENDCMPCT, /*high_bandwidth=*/true, /*version=*/CMPCTBLOCKS_VERSION));
+ // save BIP152 bandwidth state: we select peer to be high-bandwidth
+ pfrom->m_bip152_highbandwidth_to = true;
+ lNodesAnnouncingHeaderAndIDs.push_back(pfrom->GetId());
+ return true;
+ });
}
bool PeerManagerImpl::TipMayBeStale()
@@ -1110,7 +1111,6 @@ void PeerManagerImpl::FindNextBlocksToDownload(NodeId nodeid, unsigned int count
if (state->pindexLastCommonBlock == state->pindexBestKnownBlock)
return;
- const Consensus::Params& consensusParams = m_chainparams.GetConsensus();
std::vector<const CBlockIndex*> vToFetch;
const CBlockIndex *pindexWalk = state->pindexLastCommonBlock;
// Never fetch further than the best block we know the peer has, or more than BLOCK_DOWNLOAD_WINDOW + 1 beyond the last
@@ -1140,7 +1140,7 @@ void PeerManagerImpl::FindNextBlocksToDownload(NodeId nodeid, unsigned int count
// We consider the chain that this peer is on invalid.
return;
}
- if (!State(nodeid)->fHaveWitness && DeploymentActiveAt(*pindex, consensusParams, Consensus::DEPLOYMENT_SEGWIT)) {
+ if (!State(nodeid)->fHaveWitness && DeploymentActiveAt(*pindex, m_chainman, Consensus::DEPLOYMENT_SEGWIT)) {
// We wouldn't download this block or its descendants from this peer.
return;
}
@@ -1641,7 +1641,8 @@ void PeerManagerImpl::NewPoWValidBlock(const CBlockIndex *pindex, const std::sha
return;
m_highest_fast_announce = pindex->nHeight;
- bool fWitnessEnabled = DeploymentActiveAt(*pindex, m_chainparams.GetConsensus(), Consensus::DEPLOYMENT_SEGWIT);
+ if (!DeploymentActiveAt(*pindex, m_chainman, Consensus::DEPLOYMENT_SEGWIT)) return;
+
uint256 hashBlock(pblock->GetHash());
const std::shared_future<CSerializedNetMsg> lazy_ser{
std::async(std::launch::deferred, [&] { return msgMaker.Make(NetMsgType::CMPCTBLOCK, *pcmpctblock); })};
@@ -1651,10 +1652,9 @@ void PeerManagerImpl::NewPoWValidBlock(const CBlockIndex *pindex, const std::sha
m_most_recent_block_hash = hashBlock;
m_most_recent_block = pblock;
m_most_recent_compact_block = pcmpctblock;
- m_most_recent_compact_block_has_witnesses = fWitnessEnabled;
}
- m_connman.ForEachNode([this, pindex, fWitnessEnabled, &lazy_ser, &hashBlock](CNode* pnode) EXCLUSIVE_LOCKS_REQUIRED(::cs_main) {
+ m_connman.ForEachNode([this, pindex, &lazy_ser, &hashBlock](CNode* pnode) EXCLUSIVE_LOCKS_REQUIRED(::cs_main) {
AssertLockHeld(::cs_main);
if (pnode->GetCommonVersion() < INVALID_CB_NO_BAN_VERSION || pnode->fDisconnect)
@@ -1663,8 +1663,7 @@ void PeerManagerImpl::NewPoWValidBlock(const CBlockIndex *pindex, const std::sha
CNodeState &state = *State(pnode->GetId());
// If the peer has, or we announced to them the previous block already,
// but we don't think they have this one, go ahead and announce it
- if (state.fPreferHeaderAndIDs && (!fWitnessEnabled || state.fWantsCmpctWitness) &&
- !PeerHasHeader(&state, pindex) && PeerHasHeader(&state, pindex->pprev)) {
+ if (state.m_requested_hb_cmpctblocks && !PeerHasHeader(&state, pindex) && PeerHasHeader(&state, pindex->pprev)) {
LogPrint(BCLog::NET, "%s sending header-and-ids %s to peer=%d\n", "PeerManager::NewPoWValidBlock",
hashBlock.ToString(), pnode->GetId());
@@ -1859,12 +1858,10 @@ void PeerManagerImpl::ProcessGetBlockData(CNode& pfrom, Peer& peer, const CInv&
{
std::shared_ptr<const CBlock> a_recent_block;
std::shared_ptr<const CBlockHeaderAndShortTxIDs> a_recent_compact_block;
- bool fWitnessesPresentInARecentCompactBlock;
{
LOCK(m_most_recent_block_mutex);
a_recent_block = m_most_recent_block;
a_recent_compact_block = m_most_recent_compact_block;
- fWitnessesPresentInARecentCompactBlock = m_most_recent_compact_block_has_witnesses;
}
bool need_activate_chain = false;
@@ -1977,17 +1974,15 @@ void PeerManagerImpl::ProcessGetBlockData(CNode& pfrom, Peer& peer, const CInv&
// they won't have a useful mempool to match against a compact block,
// and we don't feel like constructing the object for them, so
// instead we respond with the full, non-compact block.
- bool fPeerWantsWitness = State(pfrom.GetId())->fWantsCmpctWitness;
- int nSendFlags = fPeerWantsWitness ? 0 : SERIALIZE_TRANSACTION_NO_WITNESS;
if (CanDirectFetch() && pindex->nHeight >= m_chainman.ActiveChain().Height() - MAX_CMPCTBLOCK_DEPTH) {
- if ((fPeerWantsWitness || !fWitnessesPresentInARecentCompactBlock) && a_recent_compact_block && a_recent_compact_block->header.GetHash() == pindex->GetBlockHash()) {
- m_connman.PushMessage(&pfrom, msgMaker.Make(nSendFlags, NetMsgType::CMPCTBLOCK, *a_recent_compact_block));
+ if (a_recent_compact_block && a_recent_compact_block->header.GetHash() == pindex->GetBlockHash()) {
+ m_connman.PushMessage(&pfrom, msgMaker.Make(NetMsgType::CMPCTBLOCK, *a_recent_compact_block));
} else {
- CBlockHeaderAndShortTxIDs cmpctblock(*pblock, fPeerWantsWitness);
- m_connman.PushMessage(&pfrom, msgMaker.Make(nSendFlags, NetMsgType::CMPCTBLOCK, cmpctblock));
+ CBlockHeaderAndShortTxIDs cmpctblock(*pblock, true);
+ m_connman.PushMessage(&pfrom, msgMaker.Make(NetMsgType::CMPCTBLOCK, cmpctblock));
}
} else {
- m_connman.PushMessage(&pfrom, msgMaker.Make(nSendFlags, NetMsgType::BLOCK, *pblock));
+ m_connman.PushMessage(&pfrom, msgMaker.Make(NetMsgType::BLOCK, *pblock));
}
}
}
@@ -2146,10 +2141,9 @@ void PeerManagerImpl::SendBlockTransactions(CNode& pfrom, const CBlock& block, c
}
resp.txn[i] = block.vtx[req.indexes[i]];
}
- LOCK(cs_main);
+
const CNetMsgMaker msgMaker(pfrom.GetCommonVersion());
- int nSendFlags = State(pfrom.GetId())->fWantsCmpctWitness ? 0 : SERIALIZE_TRANSACTION_NO_WITNESS;
- m_connman.PushMessage(&pfrom, msgMaker.Make(nSendFlags, NetMsgType::BLOCKTXN, resp));
+ m_connman.PushMessage(&pfrom, msgMaker.Make(NetMsgType::BLOCKTXN, resp));
}
void PeerManagerImpl::ProcessHeadersMessage(CNode& pfrom, const Peer& peer,
@@ -2214,7 +2208,7 @@ void PeerManagerImpl::ProcessHeadersMessage(CNode& pfrom, const Peer& peer,
}
BlockValidationState state;
- if (!m_chainman.ProcessNewBlockHeaders(headers, state, m_chainparams, &pindexLast)) {
+ if (!m_chainman.ProcessNewBlockHeaders(headers, state, &pindexLast)) {
if (state.IsInvalid()) {
MaybePunishNodeForBlock(pfrom.GetId(), state, via_compact_block, "invalid header received");
return;
@@ -2258,7 +2252,7 @@ void PeerManagerImpl::ProcessHeadersMessage(CNode& pfrom, const Peer& peer,
while (pindexWalk && !m_chainman.ActiveChain().Contains(pindexWalk) && vToFetch.size() <= MAX_BLOCKS_IN_TRANSIT_PER_PEER) {
if (!(pindexWalk->nStatus & BLOCK_HAVE_DATA) &&
!IsBlockRequested(pindexWalk->GetBlockHash()) &&
- (!DeploymentActiveAt(*pindexWalk, m_chainparams.GetConsensus(), Consensus::DEPLOYMENT_SEGWIT) || State(pfrom.GetId())->fHaveWitness)) {
+ (!DeploymentActiveAt(*pindexWalk, m_chainman, Consensus::DEPLOYMENT_SEGWIT) || State(pfrom.GetId())->fHaveWitness)) {
// We don't have this block, and it's not yet in flight.
vToFetch.push_back(pindexWalk);
}
@@ -2292,7 +2286,7 @@ void PeerManagerImpl::ProcessHeadersMessage(CNode& pfrom, const Peer& peer,
}
if (vGetData.size() > 0) {
if (!m_ignore_incoming_txs &&
- nodestate->fSupportsDesiredCmpctVersion &&
+ nodestate->m_provides_cmpctblocks &&
vGetData.size() == 1 &&
mapBlocksInFlight.size() == 1 &&
pindexLast->pprev->IsValid(BLOCK_VALID_CHAIN)) {
@@ -2591,7 +2585,7 @@ void PeerManagerImpl::ProcessGetCFCheckPt(CNode& peer, CDataStream& vRecv)
void PeerManagerImpl::ProcessBlock(CNode& node, const std::shared_ptr<const CBlock>& block, bool force_processing)
{
bool new_block{false};
- m_chainman.ProcessNewBlock(m_chainparams, block, force_processing, &new_block);
+ m_chainman.ProcessNewBlock(block, force_processing, &new_block);
if (new_block) {
node.m_last_block_time = GetTime<std::chrono::seconds>();
} else {
@@ -2862,16 +2856,12 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
m_connman.PushMessage(&pfrom, msgMaker.Make(NetMsgType::SENDHEADERS));
}
if (pfrom.GetCommonVersion() >= SHORT_IDS_BLOCKS_VERSION) {
- // Tell our peer we are willing to provide version 1 or 2 cmpctblocks
+ // Tell our peer we are willing to provide version 2 cmpctblocks.
// However, we do not request new block announcements using
// cmpctblock messages.
// We send this to non-NODE NETWORK peers as well, because
// they may wish to request compact blocks from us
- bool fAnnounceUsingCMPCTBLOCK = false;
- uint64_t nCMPCTBLOCKVersion = 2;
- m_connman.PushMessage(&pfrom, msgMaker.Make(NetMsgType::SENDCMPCT, fAnnounceUsingCMPCTBLOCK, nCMPCTBLOCKVersion));
- nCMPCTBLOCKVersion = 1;
- m_connman.PushMessage(&pfrom, msgMaker.Make(NetMsgType::SENDCMPCT, fAnnounceUsingCMPCTBLOCK, nCMPCTBLOCKVersion));
+ m_connman.PushMessage(&pfrom, msgMaker.Make(NetMsgType::SENDCMPCT, /*high_bandwidth=*/false, /*version=*/CMPCTBLOCKS_VERSION));
}
pfrom.fSuccessfullyConnected = true;
return;
@@ -2884,26 +2874,20 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
}
if (msg_type == NetMsgType::SENDCMPCT) {
- bool fAnnounceUsingCMPCTBLOCK = false;
- uint64_t nCMPCTBLOCKVersion = 0;
- vRecv >> fAnnounceUsingCMPCTBLOCK >> nCMPCTBLOCKVersion;
- if (nCMPCTBLOCKVersion == 1 || nCMPCTBLOCKVersion == 2) {
- LOCK(cs_main);
- // fProvidesHeaderAndIDs is used to "lock in" version of compact blocks we send (fWantsCmpctWitness)
- if (!State(pfrom.GetId())->fProvidesHeaderAndIDs) {
- State(pfrom.GetId())->fProvidesHeaderAndIDs = true;
- State(pfrom.GetId())->fWantsCmpctWitness = nCMPCTBLOCKVersion == 2;
- }
- if (State(pfrom.GetId())->fWantsCmpctWitness == (nCMPCTBLOCKVersion == 2)) { // ignore later version announces
- State(pfrom.GetId())->fPreferHeaderAndIDs = fAnnounceUsingCMPCTBLOCK;
- // save whether peer selects us as BIP152 high-bandwidth peer
- // (receiving sendcmpct(1) signals high-bandwidth, sendcmpct(0) low-bandwidth)
- pfrom.m_bip152_highbandwidth_from = fAnnounceUsingCMPCTBLOCK;
- }
- if (!State(pfrom.GetId())->fSupportsDesiredCmpctVersion) {
- State(pfrom.GetId())->fSupportsDesiredCmpctVersion = (nCMPCTBLOCKVersion == 2);
- }
- }
+ bool sendcmpct_hb{false};
+ uint64_t sendcmpct_version{0};
+ vRecv >> sendcmpct_hb >> sendcmpct_version;
+
+ // Only support compact block relay with witnesses
+ if (sendcmpct_version != CMPCTBLOCKS_VERSION) return;
+
+ LOCK(cs_main);
+ CNodeState* nodestate = State(pfrom.GetId());
+ nodestate->m_provides_cmpctblocks = true;
+ nodestate->m_requested_hb_cmpctblocks = sendcmpct_hb;
+ // save whether peer selects us as BIP152 high-bandwidth peer
+ // (receiving sendcmpct(1) signals high-bandwidth, sendcmpct(0) low-bandwidth)
+ pfrom.m_bip152_highbandwidth_from = sendcmpct_hb;
return;
}
@@ -3252,9 +3236,7 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
// expensive disk reads, because it will require the peer to
// actually receive all the data read from disk over the network.
LogPrint(BCLog::NET, "Peer %d sent us a getblocktxn for a block > %i deep\n", pfrom.GetId(), MAX_BLOCKTXN_DEPTH);
- CInv inv;
- WITH_LOCK(cs_main, inv.type = State(pfrom.GetId())->fWantsCmpctWitness ? MSG_WITNESS_BLOCK : MSG_BLOCK);
- inv.hash = req.blockhash;
+ CInv inv{MSG_WITNESS_BLOCK, req.blockhash};
WITH_LOCK(peer->m_getdata_requests_mutex, peer->m_getdata_requests.push_back(inv));
// The message processing loop will go around again (without pausing) and we'll respond then
return;
@@ -3569,7 +3551,7 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
const CBlockIndex *pindex = nullptr;
BlockValidationState state;
- if (!m_chainman.ProcessNewBlockHeaders({cmpctblock.header}, state, m_chainparams, &pindex)) {
+ if (!m_chainman.ProcessNewBlockHeaders({cmpctblock.header}, state, &pindex)) {
if (state.IsInvalid()) {
MaybePunishNodeForBlock(pfrom.GetId(), state, /*via_compact_block=*/true, "invalid header via cmpctblock");
return;
@@ -3629,12 +3611,6 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
return;
}
- if (DeploymentActiveAt(*pindex, m_chainparams.GetConsensus(), Consensus::DEPLOYMENT_SEGWIT) && !nodestate->fSupportsDesiredCmpctVersion) {
- // Don't bother trying to process compact blocks from v1 peers
- // after segwit activates.
- return;
- }
-
// We want to be a bit conservative just to be extra careful about DoS
// possibilities in compact block processing...
if (pindex->nHeight <= m_chainman.ActiveChain().Height() + 2) {
@@ -4724,7 +4700,7 @@ bool PeerManagerImpl::SendMessages(CNode* pto)
LOCK(peer->m_block_inv_mutex);
std::vector<CBlock> vHeaders;
bool fRevertToInv = ((!state.fPreferHeaders &&
- (!state.fPreferHeaderAndIDs || peer->m_blocks_for_headers_relay.size() > 1)) ||
+ (!state.m_requested_hb_cmpctblocks || peer->m_blocks_for_headers_relay.size() > 1)) ||
peer->m_blocks_for_headers_relay.size() > MAX_BLOCKS_TO_ANNOUNCE);
const CBlockIndex *pBestIndex = nullptr; // last header queued for delivery
ProcessBlockAvailability(pto->GetId()); // ensure pindexBestKnownBlock is up-to-date
@@ -4777,24 +4753,17 @@ bool PeerManagerImpl::SendMessages(CNode* pto)
}
}
if (!fRevertToInv && !vHeaders.empty()) {
- if (vHeaders.size() == 1 && state.fPreferHeaderAndIDs) {
+ if (vHeaders.size() == 1 && state.m_requested_hb_cmpctblocks) {
// We only send up to 1 block as header-and-ids, as otherwise
// probably means we're doing an initial-ish-sync or they're slow
LogPrint(BCLog::NET, "%s sending header-and-ids %s to peer=%d\n", __func__,
vHeaders.front().GetHash().ToString(), pto->GetId());
- int nSendFlags = state.fWantsCmpctWitness ? 0 : SERIALIZE_TRANSACTION_NO_WITNESS;
-
bool fGotBlockFromCache = false;
{
LOCK(m_most_recent_block_mutex);
if (m_most_recent_block_hash == pBestIndex->GetBlockHash()) {
- if (state.fWantsCmpctWitness || !m_most_recent_compact_block_has_witnesses)
- m_connman.PushMessage(pto, msgMaker.Make(nSendFlags, NetMsgType::CMPCTBLOCK, *m_most_recent_compact_block));
- else {
- CBlockHeaderAndShortTxIDs cmpctblock(*m_most_recent_block, state.fWantsCmpctWitness);
- m_connman.PushMessage(pto, msgMaker.Make(nSendFlags, NetMsgType::CMPCTBLOCK, cmpctblock));
- }
+ m_connman.PushMessage(pto, msgMaker.Make(NetMsgType::CMPCTBLOCK, *m_most_recent_compact_block));
fGotBlockFromCache = true;
}
}
@@ -4802,8 +4771,8 @@ bool PeerManagerImpl::SendMessages(CNode* pto)
CBlock block;
bool ret = ReadBlockFromDisk(block, pBestIndex, consensusParams);
assert(ret);
- CBlockHeaderAndShortTxIDs cmpctblock(block, state.fWantsCmpctWitness);
- m_connman.PushMessage(pto, msgMaker.Make(nSendFlags, NetMsgType::CMPCTBLOCK, cmpctblock));
+ CBlockHeaderAndShortTxIDs cmpctblock(block, true);
+ m_connman.PushMessage(pto, msgMaker.Make(NetMsgType::CMPCTBLOCK, cmpctblock));
}
state.pindexBestHeaderSent = pBestIndex;
} else if (state.fPreferHeaders) {