|
|
|
@ -472,6 +472,24 @@ private:
|
|
|
|
|
std::vector<std::pair<uint256, CTransactionRef>> vExtraTxnForCompact GUARDED_BY(g_cs_orphans);
|
|
|
|
|
/** Offset into vExtraTxnForCompact to insert the next tx */
|
|
|
|
|
size_t vExtraTxnForCompactIt GUARDED_BY(g_cs_orphans) = 0;
|
|
|
|
|
|
|
|
|
|
void ProcessBlockAvailability(NodeId nodeid) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
|
|
|
|
|
void UpdateBlockAvailability(NodeId nodeid, const uint256 &hash) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
|
|
|
|
|
bool CanDirectFetch(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);
|
|
|
|
|
void ProcessGetBlockData(CNode& pfrom, Peer& peer, const CChainParams& chainparams, const CInv& inv, CConnman& connman);
|
|
|
|
|
bool PrepareBlockFilterRequest(CNode& peer, const CChainParams& chain_params,
|
|
|
|
|
BlockFilterType filter_type, uint32_t start_height,
|
|
|
|
|
const uint256& stop_hash, uint32_t max_height_diff,
|
|
|
|
|
const CBlockIndex*& stop_index,
|
|
|
|
|
BlockFilterIndex*& filter_index);
|
|
|
|
|
void ProcessGetCFilters(CNode& peer, CDataStream& vRecv, const CChainParams& chain_params,
|
|
|
|
|
CConnman& connman);
|
|
|
|
|
void ProcessGetCFHeaders(CNode& peer, CDataStream& vRecv, const CChainParams& chain_params,
|
|
|
|
|
CConnman& connman);
|
|
|
|
|
void ProcessGetCFCheckPt(CNode& peer, CDataStream& vRecv, const CChainParams& chain_params,
|
|
|
|
|
CConnman& connman);
|
|
|
|
|
};
|
|
|
|
|
} // namespace
|
|
|
|
|
|
|
|
|
@ -684,41 +702,6 @@ bool PeerManagerImpl::MarkBlockAsInFlight(NodeId nodeid, const uint256& hash, co
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** Check whether the last unknown block a peer advertised is not yet known. */
|
|
|
|
|
static void ProcessBlockAvailability(NodeId nodeid) EXCLUSIVE_LOCKS_REQUIRED(cs_main) {
|
|
|
|
|
CNodeState *state = State(nodeid);
|
|
|
|
|
assert(state != nullptr);
|
|
|
|
|
|
|
|
|
|
if (!state->hashLastUnknownBlock.IsNull()) {
|
|
|
|
|
const CBlockIndex* pindex = g_chainman.m_blockman.LookupBlockIndex(state->hashLastUnknownBlock);
|
|
|
|
|
if (pindex && pindex->nChainWork > 0) {
|
|
|
|
|
if (state->pindexBestKnownBlock == nullptr || pindex->nChainWork >= state->pindexBestKnownBlock->nChainWork) {
|
|
|
|
|
state->pindexBestKnownBlock = pindex;
|
|
|
|
|
}
|
|
|
|
|
state->hashLastUnknownBlock.SetNull();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** Update tracking information about which blocks a peer is assumed to have. */
|
|
|
|
|
static void UpdateBlockAvailability(NodeId nodeid, const uint256 &hash) EXCLUSIVE_LOCKS_REQUIRED(cs_main) {
|
|
|
|
|
CNodeState *state = State(nodeid);
|
|
|
|
|
assert(state != nullptr);
|
|
|
|
|
|
|
|
|
|
ProcessBlockAvailability(nodeid);
|
|
|
|
|
|
|
|
|
|
const CBlockIndex* pindex = g_chainman.m_blockman.LookupBlockIndex(hash);
|
|
|
|
|
if (pindex && pindex->nChainWork > 0) {
|
|
|
|
|
// An actually better block was announced.
|
|
|
|
|
if (state->pindexBestKnownBlock == nullptr || pindex->nChainWork >= state->pindexBestKnownBlock->nChainWork) {
|
|
|
|
|
state->pindexBestKnownBlock = pindex;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
// An unknown block was announced; just assume that the latest one is the best one.
|
|
|
|
|
state->hashLastUnknownBlock = hash;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void PeerManagerImpl::MaybeSetPeerAsAnnouncingHeaderAndIDs(NodeId nodeid)
|
|
|
|
|
{
|
|
|
|
|
AssertLockHeld(cs_main);
|
|
|
|
@ -768,7 +751,7 @@ bool PeerManagerImpl::TipMayBeStale()
|
|
|
|
|
return m_last_tip_update < GetTime() - consensusParams.nPowTargetSpacing * 3 && mapBlocksInFlight.empty();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static bool CanDirectFetch(const Consensus::Params &consensusParams) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
|
|
|
|
|
bool PeerManagerImpl::CanDirectFetch(const Consensus::Params &consensusParams)
|
|
|
|
|
{
|
|
|
|
|
return ::ChainActive().Tip()->GetBlockTime() > GetAdjustedTime() - consensusParams.nPowTargetSpacing * 20;
|
|
|
|
|
}
|
|
|
|
@ -782,6 +765,41 @@ static bool PeerHasHeader(CNodeState *state, const CBlockIndex *pindex) EXCLUSIV
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** Check whether the last unknown block a peer advertised is not yet known. */
|
|
|
|
|
void PeerManagerImpl::ProcessBlockAvailability(NodeId nodeid) {
|
|
|
|
|
CNodeState *state = State(nodeid);
|
|
|
|
|
assert(state != nullptr);
|
|
|
|
|
|
|
|
|
|
if (!state->hashLastUnknownBlock.IsNull()) {
|
|
|
|
|
const CBlockIndex* pindex = g_chainman.m_blockman.LookupBlockIndex(state->hashLastUnknownBlock);
|
|
|
|
|
if (pindex && pindex->nChainWork > 0) {
|
|
|
|
|
if (state->pindexBestKnownBlock == nullptr || pindex->nChainWork >= state->pindexBestKnownBlock->nChainWork) {
|
|
|
|
|
state->pindexBestKnownBlock = pindex;
|
|
|
|
|
}
|
|
|
|
|
state->hashLastUnknownBlock.SetNull();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** Update tracking information about which blocks a peer is assumed to have. */
|
|
|
|
|
void PeerManagerImpl::UpdateBlockAvailability(NodeId nodeid, const uint256 &hash) {
|
|
|
|
|
CNodeState *state = State(nodeid);
|
|
|
|
|
assert(state != nullptr);
|
|
|
|
|
|
|
|
|
|
ProcessBlockAvailability(nodeid);
|
|
|
|
|
|
|
|
|
|
const CBlockIndex* pindex = g_chainman.m_blockman.LookupBlockIndex(hash);
|
|
|
|
|
if (pindex && pindex->nChainWork > 0) {
|
|
|
|
|
// An actually better block was announced.
|
|
|
|
|
if (state->pindexBestKnownBlock == nullptr || pindex->nChainWork >= state->pindexBestKnownBlock->nChainWork) {
|
|
|
|
|
state->pindexBestKnownBlock = pindex;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
// An unknown block was announced; just assume that the latest one is the best one.
|
|
|
|
|
state->hashLastUnknownBlock = hash;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void PeerManagerImpl::FindNextBlocksToDownload(NodeId nodeid, unsigned int count, std::vector<const CBlockIndex*>& vBlocks, NodeId& nodeStaller)
|
|
|
|
|
{
|
|
|
|
|
if (count == 0)
|
|
|
|
@ -1200,7 +1218,7 @@ bool PeerManagerImpl::MaybePunishNodeForTx(NodeId nodeid, const TxValidationStat
|
|
|
|
|
// active chain if they are no more than a month older (both in time, and in
|
|
|
|
|
// best equivalent proof of work) than the best header chain we know about and
|
|
|
|
|
// we fully-validated them at some point.
|
|
|
|
|
static bool BlockRequestAllowed(const CBlockIndex* pindex, const Consensus::Params& consensusParams) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
|
|
|
|
|
bool PeerManagerImpl::BlockRequestAllowed(const CBlockIndex* pindex, const Consensus::Params& consensusParams)
|
|
|
|
|
{
|
|
|
|
|
AssertLockHeld(cs_main);
|
|
|
|
|
if (::ChainActive().Contains(pindex)) return true;
|
|
|
|
@ -1454,7 +1472,7 @@ bool PeerManagerImpl::AlreadyHaveTx(const GenTxid& gtxid)
|
|
|
|
|
return recentRejects->contains(hash) || m_mempool.exists(gtxid);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool static AlreadyHaveBlock(const uint256& block_hash) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
|
|
|
|
|
bool PeerManagerImpl::AlreadyHaveBlock(const uint256& block_hash)
|
|
|
|
|
{
|
|
|
|
|
return g_chainman.m_blockman.LookupBlockIndex(block_hash) != nullptr;
|
|
|
|
|
}
|
|
|
|
@ -1535,7 +1553,7 @@ static void RelayAddress(const CNode& originator,
|
|
|
|
|
connman.ForEachNodeThen(std::move(sortfunc), std::move(pushfunc));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void static ProcessGetBlockData(CNode& pfrom, Peer& peer, const CChainParams& chainparams, const CInv& inv, CConnman& connman)
|
|
|
|
|
void PeerManagerImpl::ProcessGetBlockData(CNode& pfrom, Peer& peer, const CChainParams& chainparams, const CInv& inv, CConnman& connman)
|
|
|
|
|
{
|
|
|
|
|
bool send = false;
|
|
|
|
|
std::shared_ptr<const CBlock> a_recent_block;
|
|
|
|
@ -2118,7 +2136,7 @@ void PeerManagerImpl::ProcessOrphanTx(std::set<uint256>& orphan_work_set)
|
|
|
|
|
* @param[out] filter_index The filter index, if the request can be serviced.
|
|
|
|
|
* @return True if the request can be serviced.
|
|
|
|
|
*/
|
|
|
|
|
static bool PrepareBlockFilterRequest(CNode& peer, const CChainParams& chain_params,
|
|
|
|
|
bool PeerManagerImpl::PrepareBlockFilterRequest(CNode& peer, const CChainParams& chain_params,
|
|
|
|
|
BlockFilterType filter_type, uint32_t start_height,
|
|
|
|
|
const uint256& stop_hash, uint32_t max_height_diff,
|
|
|
|
|
const CBlockIndex*& stop_index,
|
|
|
|
@ -2181,7 +2199,7 @@ static bool PrepareBlockFilterRequest(CNode& peer, const CChainParams& chain_par
|
|
|
|
|
* @param[in] chain_params Chain parameters
|
|
|
|
|
* @param[in] connman Pointer to the connection manager
|
|
|
|
|
*/
|
|
|
|
|
static void ProcessGetCFilters(CNode& peer, CDataStream& vRecv, const CChainParams& chain_params,
|
|
|
|
|
void PeerManagerImpl::ProcessGetCFilters(CNode& peer, CDataStream& vRecv, const CChainParams& chain_params,
|
|
|
|
|
CConnman& connman)
|
|
|
|
|
{
|
|
|
|
|
uint8_t filter_type_ser;
|
|
|
|
@ -2223,7 +2241,7 @@ static void ProcessGetCFilters(CNode& peer, CDataStream& vRecv, const CChainPara
|
|
|
|
|
* @param[in] chain_params Chain parameters
|
|
|
|
|
* @param[in] connman Pointer to the connection manager
|
|
|
|
|
*/
|
|
|
|
|
static void ProcessGetCFHeaders(CNode& peer, CDataStream& vRecv, const CChainParams& chain_params,
|
|
|
|
|
void PeerManagerImpl::ProcessGetCFHeaders(CNode& peer, CDataStream& vRecv, const CChainParams& chain_params,
|
|
|
|
|
CConnman& connman)
|
|
|
|
|
{
|
|
|
|
|
uint8_t filter_type_ser;
|
|
|
|
@ -2278,7 +2296,7 @@ static void ProcessGetCFHeaders(CNode& peer, CDataStream& vRecv, const CChainPar
|
|
|
|
|
* @param[in] chain_params Chain parameters
|
|
|
|
|
* @param[in] connman Pointer to the connection manager
|
|
|
|
|
*/
|
|
|
|
|
static void ProcessGetCFCheckPt(CNode& peer, CDataStream& vRecv, const CChainParams& chain_params,
|
|
|
|
|
void PeerManagerImpl::ProcessGetCFCheckPt(CNode& peer, CDataStream& vRecv, const CChainParams& chain_params,
|
|
|
|
|
CConnman& connman)
|
|
|
|
|
{
|
|
|
|
|
uint8_t filter_type_ser;
|
|
|
|
@ -4747,4 +4765,3 @@ bool PeerManagerImpl::SendMessages(CNode* pto)
|
|
|
|
|
} // release cs_main
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|