mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-01-25 10:43:19 -03:00
[net processing] Replace fHaveWitness with CanServeWitnesses()
This commit is contained in:
parent
f65e83d51b
commit
7d1c036934
1 changed files with 35 additions and 34 deletions
|
@ -432,8 +432,6 @@ struct CNodeState {
|
|||
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};
|
||||
|
||||
/** State used to enforce CHAIN_SYNC_TIMEOUT and EXTRA_PEER_CHECK_INTERVAL logic.
|
||||
*
|
||||
|
@ -514,7 +512,8 @@ public:
|
|||
/** Implement PeerManager */
|
||||
void StartScheduledTasks(CScheduler& scheduler) override;
|
||||
void CheckForStaleTipAndEvictPeers() override;
|
||||
std::optional<std::string> FetchBlock(NodeId peer_id, const CBlockIndex& block_index) override;
|
||||
std::optional<std::string> FetchBlock(NodeId peer_id, const CBlockIndex& block_index) override
|
||||
EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex);
|
||||
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 EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex);
|
||||
|
@ -600,7 +599,7 @@ private:
|
|||
*/
|
||||
bool MaybeSendGetHeaders(CNode& pfrom, const CBlockLocator& locator, Peer& peer);
|
||||
/** Potentially fetch blocks from this peer upon receipt of a new headers tip */
|
||||
void HeadersDirectFetchBlocks(CNode& pfrom, const CBlockIndex* pindexLast);
|
||||
void HeadersDirectFetchBlocks(CNode& pfrom, const Peer& peer, const CBlockIndex* pindexLast);
|
||||
/** Update peer state based on received headers message */
|
||||
void UpdatePeerStateForReceivedHeaders(CNode& pfrom, const CBlockIndex *pindexLast, bool received_new_header, bool may_have_more_headers);
|
||||
|
||||
|
@ -679,7 +678,7 @@ private:
|
|||
/** Get a pointer to a mutable CNodeState. */
|
||||
CNodeState* State(NodeId pnode) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
|
||||
|
||||
uint32_t GetFetchFlags(const CNode& pfrom) const EXCLUSIVE_LOCKS_REQUIRED(cs_main);
|
||||
uint32_t GetFetchFlags(const Peer& peer) const;
|
||||
|
||||
std::atomic<std::chrono::microseconds> m_next_inv_to_inbounds{0us};
|
||||
|
||||
|
@ -800,7 +799,7 @@ private:
|
|||
/** Update pindexLastCommonBlock and add not-in-flight missing successors to vBlocks, until it has
|
||||
* at most count entries.
|
||||
*/
|
||||
void FindNextBlocksToDownload(NodeId nodeid, unsigned int count, std::vector<const CBlockIndex*>& vBlocks, NodeId& nodeStaller) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
|
||||
void FindNextBlocksToDownload(const Peer& peer, unsigned int count, std::vector<const CBlockIndex*>& vBlocks, NodeId& nodeStaller) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
|
||||
|
||||
std::map<uint256, std::pair<NodeId, std::list<QueuedBlock>::iterator> > mapBlocksInFlight GUARDED_BY(cs_main);
|
||||
|
||||
|
@ -991,6 +990,12 @@ static bool IsLimitedPeer(const Peer& peer)
|
|||
(peer.m_their_services & NODE_NETWORK_LIMITED));
|
||||
}
|
||||
|
||||
/** Whether this peer can serve us witness data */
|
||||
static bool CanServeWitnesses(const Peer& peer)
|
||||
{
|
||||
return peer.m_their_services & NODE_WITNESS;
|
||||
}
|
||||
|
||||
std::chrono::microseconds PeerManagerImpl::NextInvToInbounds(std::chrono::microseconds now,
|
||||
std::chrono::seconds average_interval)
|
||||
{
|
||||
|
@ -1184,17 +1189,17 @@ void PeerManagerImpl::UpdateBlockAvailability(NodeId nodeid, const uint256 &hash
|
|||
}
|
||||
}
|
||||
|
||||
void PeerManagerImpl::FindNextBlocksToDownload(NodeId nodeid, unsigned int count, std::vector<const CBlockIndex*>& vBlocks, NodeId& nodeStaller)
|
||||
void PeerManagerImpl::FindNextBlocksToDownload(const Peer& peer, unsigned int count, std::vector<const CBlockIndex*>& vBlocks, NodeId& nodeStaller)
|
||||
{
|
||||
if (count == 0)
|
||||
return;
|
||||
|
||||
vBlocks.reserve(vBlocks.size() + count);
|
||||
CNodeState *state = State(nodeid);
|
||||
CNodeState *state = State(peer.m_id);
|
||||
assert(state != nullptr);
|
||||
|
||||
// Make sure pindexBestKnownBlock is up to date, we'll need it.
|
||||
ProcessBlockAvailability(nodeid);
|
||||
ProcessBlockAvailability(peer.m_id);
|
||||
|
||||
if (state->pindexBestKnownBlock == nullptr || state->pindexBestKnownBlock->nChainWork < m_chainman.ActiveChain().Tip()->nChainWork || state->pindexBestKnownBlock->nChainWork < nMinimumChainWork) {
|
||||
// This peer has nothing interesting.
|
||||
|
@ -1242,7 +1247,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, m_chainman, Consensus::DEPLOYMENT_SEGWIT)) {
|
||||
if (!CanServeWitnesses(peer) && DeploymentActiveAt(*pindex, m_chainman, Consensus::DEPLOYMENT_SEGWIT)) {
|
||||
// We wouldn't download this block or its descendants from this peer.
|
||||
return;
|
||||
}
|
||||
|
@ -1253,7 +1258,7 @@ void PeerManagerImpl::FindNextBlocksToDownload(NodeId nodeid, unsigned int count
|
|||
// The block is not already downloaded, and not yet in flight.
|
||||
if (pindex->nHeight > nWindowEnd) {
|
||||
// We reached the end of the window.
|
||||
if (vBlocks.size() == 0 && waitingfor != nodeid) {
|
||||
if (vBlocks.size() == 0 && waitingfor != peer.m_id) {
|
||||
// We aren't able to fetch anything, but we would be if the download window was one larger.
|
||||
nodeStaller = waitingfor;
|
||||
}
|
||||
|
@ -1621,12 +1626,14 @@ std::optional<std::string> PeerManagerImpl::FetchBlock(NodeId peer_id, const CBl
|
|||
if (fImporting) return "Importing...";
|
||||
if (fReindex) return "Reindexing...";
|
||||
|
||||
LOCK(cs_main);
|
||||
// Ensure this peer exists and hasn't been disconnected
|
||||
CNodeState* state = State(peer_id);
|
||||
if (state == nullptr) return "Peer does not exist";
|
||||
PeerRef peer = GetPeerRef(peer_id);
|
||||
if (peer == nullptr) return "Peer does not exist";
|
||||
|
||||
// Ignore pre-segwit peers
|
||||
if (!state->fHaveWitness) return "Pre-SegWit peer";
|
||||
if (!CanServeWitnesses(*peer)) return "Pre-SegWit peer";
|
||||
|
||||
LOCK(cs_main);
|
||||
|
||||
// Mark block as in-flight unless it already is (for this peer).
|
||||
// If a block was already in-flight for a different peer, its BLOCKTXN
|
||||
|
@ -2227,10 +2234,10 @@ void PeerManagerImpl::ProcessGetData(CNode& pfrom, Peer& peer, const std::atomic
|
|||
}
|
||||
}
|
||||
|
||||
uint32_t PeerManagerImpl::GetFetchFlags(const CNode& pfrom) const EXCLUSIVE_LOCKS_REQUIRED(cs_main)
|
||||
uint32_t PeerManagerImpl::GetFetchFlags(const Peer& peer) const
|
||||
{
|
||||
uint32_t nFetchFlags = 0;
|
||||
if (State(pfrom.GetId())->fHaveWitness) {
|
||||
if (CanServeWitnesses(peer)) {
|
||||
nFetchFlags |= MSG_WITNESS_FLAG;
|
||||
}
|
||||
return nFetchFlags;
|
||||
|
@ -2325,7 +2332,7 @@ bool PeerManagerImpl::MaybeSendGetHeaders(CNode& pfrom, const CBlockLocator& loc
|
|||
* We require that the given tip have at least as much work as our tip, and for
|
||||
* our current tip to be "close to synced" (see CanDirectFetch()).
|
||||
*/
|
||||
void PeerManagerImpl::HeadersDirectFetchBlocks(CNode& pfrom, const CBlockIndex* pindexLast)
|
||||
void PeerManagerImpl::HeadersDirectFetchBlocks(CNode& pfrom, const Peer& peer, const CBlockIndex* pindexLast)
|
||||
{
|
||||
const CNetMsgMaker msgMaker(pfrom.GetCommonVersion());
|
||||
|
||||
|
@ -2340,7 +2347,7 @@ void PeerManagerImpl::HeadersDirectFetchBlocks(CNode& pfrom, const CBlockIndex*
|
|||
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_chainman, Consensus::DEPLOYMENT_SEGWIT) || State(pfrom.GetId())->fHaveWitness)) {
|
||||
(!DeploymentActiveAt(*pindexWalk, m_chainman, Consensus::DEPLOYMENT_SEGWIT) || CanServeWitnesses(peer))) {
|
||||
// We don't have this block, and it's not yet in flight.
|
||||
vToFetch.push_back(pindexWalk);
|
||||
}
|
||||
|
@ -2362,7 +2369,7 @@ void PeerManagerImpl::HeadersDirectFetchBlocks(CNode& pfrom, const CBlockIndex*
|
|||
// Can't download any more from this peer
|
||||
break;
|
||||
}
|
||||
uint32_t nFetchFlags = GetFetchFlags(pfrom);
|
||||
uint32_t nFetchFlags = GetFetchFlags(peer);
|
||||
vGetData.push_back(CInv(MSG_BLOCK | nFetchFlags, pindex->GetBlockHash()));
|
||||
BlockRequested(pfrom.GetId(), *pindex);
|
||||
LogPrint(BCLog::NET, "Requesting block %s from peer=%d\n",
|
||||
|
@ -2507,7 +2514,7 @@ void PeerManagerImpl::ProcessHeadersMessage(CNode& pfrom, Peer& peer,
|
|||
UpdatePeerStateForReceivedHeaders(pfrom, pindexLast, received_new_header, nCount == MAX_HEADERS_RESULTS);
|
||||
|
||||
// Consider immediately downloading blocks.
|
||||
HeadersDirectFetchBlocks(pfrom, pindexLast);
|
||||
HeadersDirectFetchBlocks(pfrom, peer, pindexLast);
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -2901,12 +2908,6 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
|
|||
if (fRelay) pfrom.m_relays_txs = true;
|
||||
}
|
||||
|
||||
if((nServices & NODE_WITNESS))
|
||||
{
|
||||
LOCK(cs_main);
|
||||
State(pfrom.GetId())->fHaveWitness = true;
|
||||
}
|
||||
|
||||
// Potentially mark this peer as a preferred download peer.
|
||||
{
|
||||
LOCK(cs_main);
|
||||
|
@ -3789,7 +3790,7 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
|
|||
// We requested this block for some reason, but our mempool will probably be useless
|
||||
// so we just grab the block via normal getdata
|
||||
std::vector<CInv> vInv(1);
|
||||
vInv[0] = CInv(MSG_BLOCK | GetFetchFlags(pfrom), cmpctblock.header.GetHash());
|
||||
vInv[0] = CInv(MSG_BLOCK | GetFetchFlags(*peer), cmpctblock.header.GetHash());
|
||||
m_connman.PushMessage(&pfrom, msgMaker.Make(NetMsgType::GETDATA, vInv));
|
||||
}
|
||||
return;
|
||||
|
@ -3825,7 +3826,7 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
|
|||
} else if (status == READ_STATUS_FAILED) {
|
||||
// Duplicate txindexes, the block is now in-flight, so just request it
|
||||
std::vector<CInv> vInv(1);
|
||||
vInv[0] = CInv(MSG_BLOCK | GetFetchFlags(pfrom), cmpctblock.header.GetHash());
|
||||
vInv[0] = CInv(MSG_BLOCK | GetFetchFlags(*peer), cmpctblock.header.GetHash());
|
||||
m_connman.PushMessage(&pfrom, msgMaker.Make(NetMsgType::GETDATA, vInv));
|
||||
return;
|
||||
}
|
||||
|
@ -3868,7 +3869,7 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
|
|||
// We requested this block, but its far into the future, so our
|
||||
// mempool will probably be useless - request the block normally
|
||||
std::vector<CInv> vInv(1);
|
||||
vInv[0] = CInv(MSG_BLOCK | GetFetchFlags(pfrom), cmpctblock.header.GetHash());
|
||||
vInv[0] = CInv(MSG_BLOCK | GetFetchFlags(*peer), cmpctblock.header.GetHash());
|
||||
m_connman.PushMessage(&pfrom, msgMaker.Make(NetMsgType::GETDATA, vInv));
|
||||
return;
|
||||
} else {
|
||||
|
@ -3952,7 +3953,7 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
|
|||
} else if (status == READ_STATUS_FAILED) {
|
||||
// Might have collided, fall back to getdata now :(
|
||||
std::vector<CInv> invs;
|
||||
invs.push_back(CInv(MSG_BLOCK | GetFetchFlags(pfrom), resp.blockhash));
|
||||
invs.push_back(CInv(MSG_BLOCK | GetFetchFlags(*peer), resp.blockhash));
|
||||
m_connman.PushMessage(&pfrom, msgMaker.Make(NetMsgType::GETDATA, invs));
|
||||
} else {
|
||||
// Block is either okay, or possibly we received
|
||||
|
@ -5266,9 +5267,9 @@ bool PeerManagerImpl::SendMessages(CNode* pto)
|
|||
if (CanServeBlocks(*peer) && ((sync_blocks_and_headers_from_peer && !IsLimitedPeer(*peer)) || !m_chainman.ActiveChainstate().IsInitialBlockDownload()) && state.nBlocksInFlight < MAX_BLOCKS_IN_TRANSIT_PER_PEER) {
|
||||
std::vector<const CBlockIndex*> vToDownload;
|
||||
NodeId staller = -1;
|
||||
FindNextBlocksToDownload(pto->GetId(), MAX_BLOCKS_IN_TRANSIT_PER_PEER - state.nBlocksInFlight, vToDownload, staller);
|
||||
FindNextBlocksToDownload(*peer, MAX_BLOCKS_IN_TRANSIT_PER_PEER - state.nBlocksInFlight, vToDownload, staller);
|
||||
for (const CBlockIndex *pindex : vToDownload) {
|
||||
uint32_t nFetchFlags = GetFetchFlags(*pto);
|
||||
uint32_t nFetchFlags = GetFetchFlags(*peer);
|
||||
vGetData.push_back(CInv(MSG_BLOCK | nFetchFlags, pindex->GetBlockHash()));
|
||||
BlockRequested(pto->GetId(), *pindex);
|
||||
LogPrint(BCLog::NET, "Requesting block %s (%d) peer=%d\n", pindex->GetBlockHash().ToString(),
|
||||
|
@ -5295,7 +5296,7 @@ bool PeerManagerImpl::SendMessages(CNode* pto)
|
|||
if (!AlreadyHaveTx(gtxid)) {
|
||||
LogPrint(BCLog::NET, "Requesting %s %s peer=%d\n", gtxid.IsWtxid() ? "wtx" : "tx",
|
||||
gtxid.GetHash().ToString(), pto->GetId());
|
||||
vGetData.emplace_back(gtxid.IsWtxid() ? MSG_WTX : (MSG_TX | GetFetchFlags(*pto)), gtxid.GetHash());
|
||||
vGetData.emplace_back(gtxid.IsWtxid() ? MSG_WTX : (MSG_TX | GetFetchFlags(*peer)), gtxid.GetHash());
|
||||
if (vGetData.size() >= MAX_GETDATA_SZ) {
|
||||
m_connman.PushMessage(pto, msgMaker.Make(NetMsgType::GETDATA, vGetData));
|
||||
vGetData.clear();
|
||||
|
|
Loading…
Add table
Reference in a new issue