Changeset View
Changeset View
Standalone View
Standalone View
src/net_processing.cpp
- This file is larger than 256 KB, so syntax highlighting is disabled by default.
Show First 20 Lines • Show All 348 Lines • ▼ Show 20 Lines | struct Peer { | ||||
* not change after initialization. | * not change after initialization. | ||||
* | * | ||||
* An interesting example of this is NODE_NETWORK and initial block | * An interesting example of this is NODE_NETWORK and initial block | ||||
* download: a node which starts up from scratch doesn't have any blocks | * download: a node which starts up from scratch doesn't have any blocks | ||||
* to serve, but still advertises NODE_NETWORK because it will eventually | * to serve, but still advertises NODE_NETWORK because it will eventually | ||||
* fulfill this role after IBD completes. P2P code is written in such a | * fulfill this role after IBD completes. P2P code is written in such a | ||||
* way that it can gracefully handle peers who don't make good on their | * way that it can gracefully handle peers who don't make good on their | ||||
* service advertisements. | * service advertisements. | ||||
* | |||||
* TODO: remove redundant CNode::nLocalServices | |||||
*/ | */ | ||||
const ServiceFlags m_our_services; | const ServiceFlags m_our_services; | ||||
/** Services this peer offered to us. */ | /** Services this peer offered to us. */ | ||||
std::atomic<ServiceFlags> m_their_services{NODE_NONE}; | std::atomic<ServiceFlags> m_their_services{NODE_NONE}; | ||||
/** Protects misbehavior data members */ | /** Protects misbehavior data members */ | ||||
Mutex m_misbehavior_mutex; | Mutex m_misbehavior_mutex; | ||||
▲ Show 20 Lines • Show All 649 Lines • ▼ Show 20 Lines | private: | ||||
void ProcessGetBlockData(const Config &config, CNode &pfrom, Peer &peer, | void ProcessGetBlockData(const Config &config, CNode &pfrom, Peer &peer, | ||||
const CInv &inv); | const CInv &inv); | ||||
/** | /** | ||||
* Validation logic for compact filters request handling. | * Validation logic for compact filters request handling. | ||||
* | * | ||||
* May disconnect from the peer in the case of a bad request. | * May disconnect from the peer in the case of a bad request. | ||||
* | * | ||||
* @param[in] node The node that we received the request from | |||||
* @param[in] peer The peer that we received the request from | * @param[in] peer The peer that we received the request from | ||||
* @param[in] filter_type The filter type the request is for. Must be | * @param[in] filter_type The filter type the request is for. Must be | ||||
* basic filters. | * basic filters. | ||||
* @param[in] start_height The start height for the request | * @param[in] start_height The start height for the request | ||||
* @param[in] stop_hash The stop_hash for the request | * @param[in] stop_hash The stop_hash for the request | ||||
* @param[in] max_height_diff The maximum number of items permitted to | * @param[in] max_height_diff The maximum number of items permitted to | ||||
* request, as specified in BIP 157 | * request, as specified in BIP 157 | ||||
* @param[out] stop_index The CBlockIndex for the stop_hash block, if | * @param[out] stop_index The CBlockIndex for the stop_hash block, if | ||||
* the request can be serviced. | * the request can be serviced. | ||||
* @param[out] filter_index The filter index, if the request can be | * @param[out] filter_index The filter index, if the request can be | ||||
* serviced. | * serviced. | ||||
* @return True if the request can be serviced. | * @return True if the request can be serviced. | ||||
*/ | */ | ||||
bool PrepareBlockFilterRequest(CNode &peer, BlockFilterType filter_type, | bool PrepareBlockFilterRequest(CNode &node, Peer &peer, | ||||
BlockFilterType filter_type, | |||||
uint32_t start_height, | uint32_t start_height, | ||||
const BlockHash &stop_hash, | const BlockHash &stop_hash, | ||||
uint32_t max_height_diff, | uint32_t max_height_diff, | ||||
const CBlockIndex *&stop_index, | const CBlockIndex *&stop_index, | ||||
BlockFilterIndex *&filter_index); | BlockFilterIndex *&filter_index); | ||||
/** | /** | ||||
* Handle a cfilters request. | * Handle a cfilters request. | ||||
* | * | ||||
* May disconnect from the peer in the case of a bad request. | * May disconnect from the peer in the case of a bad request. | ||||
* | * | ||||
* @param[in] node The node that we received the request from | |||||
* @param[in] peer The peer that we received the request from | * @param[in] peer The peer that we received the request from | ||||
* @param[in] vRecv The raw message received | * @param[in] vRecv The raw message received | ||||
*/ | */ | ||||
void ProcessGetCFilters(CNode &peer, CDataStream &vRecv); | void ProcessGetCFilters(CNode &node, Peer &peer, CDataStream &vRecv); | ||||
/** | /** | ||||
* Handle a cfheaders request. | * Handle a cfheaders request. | ||||
* | |||||
* May disconnect from the peer in the case of a bad request. | * May disconnect from the peer in the case of a bad request. | ||||
* | |||||
* @param[in] peer The peer that we received the request from | |||||
* @param[in] vRecv The raw message received | |||||
*/ | */ | ||||
void ProcessGetCFHeaders(CNode &peer, CDataStream &vRecv); | void ProcessGetCFHeaders(CNode &node, Peer &peer, CDataStream &vRecv); | ||||
/** | /** | ||||
* Handle a getcfcheckpt request. | |||||
* | |||||
* May disconnect from the peer in the case of a bad request. | |||||
* | * | ||||
* @param[in] node The node that we received the request from | |||||
* @param[in] peer The peer that we received the request from | * @param[in] peer The peer that we received the request from | ||||
* @param[in] vRecv The raw message received | * @param[in] vRecv The raw message received | ||||
*/ | */ | ||||
void ProcessGetCFCheckPt(CNode &peer, CDataStream &vRecv); | void ProcessGetCFCheckPt(CNode &node, Peer &peer, CDataStream &vRecv); | ||||
/** | /** | ||||
* Decide a response for an Avalanche poll about the given block. | * Decide a response for an Avalanche poll about the given block. | ||||
* | * | ||||
* @param[in] hash The hash of the block being polled for | * @param[in] hash The hash of the block being polled for | ||||
* @return Our current vote for the block | * @return Our current vote for the block | ||||
*/ | */ | ||||
uint32_t GetAvalancheVoteForBlock(const BlockHash &hash) const | uint32_t GetAvalancheVoteForBlock(const BlockHash &hash) const | ||||
▲ Show 20 Lines • Show All 582 Lines • ▼ Show 20 Lines | if (!node.HasPermission(requestParams.bypass_request_limits_permissions) && | ||||
delay += requestParams.overloaded_peer_delay; | delay += requestParams.overloaded_peer_delay; | ||||
} | } | ||||
return current_time + delay; | return current_time + delay; | ||||
} | } | ||||
void PeerManagerImpl::PushNodeVersion(const Config &config, CNode &pnode, | void PeerManagerImpl::PushNodeVersion(const Config &config, CNode &pnode, | ||||
const Peer &peer) { | const Peer &peer) { | ||||
// Note that pnode.GetLocalServices() is a reflection of the local | ServiceFlags nLocalNodeServices{peer.m_our_services}; | ||||
// services we were offering when the CNode object was created for this | |||||
// peer. | |||||
ServiceFlags nLocalNodeServices = pnode.GetLocalServices(); | |||||
const int64_t nTime{count_seconds(GetTime<std::chrono::seconds>())}; | const int64_t nTime{count_seconds(GetTime<std::chrono::seconds>())}; | ||||
uint64_t nonce = pnode.GetLocalNonce(); | uint64_t nonce = pnode.GetLocalNonce(); | ||||
const int nNodeStartingHeight{m_best_height}; | const int nNodeStartingHeight{m_best_height}; | ||||
NodeId nodeid = pnode.GetId(); | NodeId nodeid = pnode.GetId(); | ||||
CAddress addr = pnode.addr; | CAddress addr = pnode.addr; | ||||
uint64_t extraEntropy = pnode.GetLocalExtraEntropy(); | uint64_t extraEntropy = pnode.GetLocalExtraEntropy(); | ||||
CAddress addrYou = | CAddress addrYou = | ||||
▲ Show 20 Lines • Show All 1,023 Lines • ▼ Show 20 Lines | if (m_connman.OutboundTargetReached(true) && | ||||
!pfrom.HasPermission(NetPermissionFlags::Download)) { | !pfrom.HasPermission(NetPermissionFlags::Download)) { | ||||
LogPrint(BCLog::NET, | LogPrint(BCLog::NET, | ||||
"historical block serving limit reached, disconnect peer=%d\n", | "historical block serving limit reached, disconnect peer=%d\n", | ||||
pfrom.GetId()); | pfrom.GetId()); | ||||
pfrom.fDisconnect = true; | pfrom.fDisconnect = true; | ||||
return; | return; | ||||
} | } | ||||
// Avoid leaking prune-height by never sending blocks below the | // Avoid leaking prune-height by never sending blocks below the | ||||
// NODE_NETWORK_LIMITED threshold. | // NODE_NETWORK_LIMITED threshold Add two blocks buffer extension for | ||||
// Add two blocks buffer extension for possible races | // possible races | ||||
if (!pfrom.HasPermission(NetPermissionFlags::NoBan) && | if (!pfrom.HasPermission(NetPermissionFlags::NoBan) && | ||||
((((pfrom.GetLocalServices() & NODE_NETWORK_LIMITED) == | ((((peer.m_our_services & NODE_NETWORK_LIMITED) == | ||||
NODE_NETWORK_LIMITED) && | NODE_NETWORK_LIMITED) && | ||||
((pfrom.GetLocalServices() & NODE_NETWORK) != NODE_NETWORK) && | ((peer.m_our_services & NODE_NETWORK) != NODE_NETWORK) && | ||||
(m_chainman.ActiveChain().Tip()->nHeight - pindex->nHeight > | (m_chainman.ActiveChain().Tip()->nHeight - pindex->nHeight > | ||||
(int)NODE_NETWORK_LIMITED_MIN_BLOCKS + 2)))) { | (int)NODE_NETWORK_LIMITED_MIN_BLOCKS + 2)))) { | ||||
LogPrint(BCLog::NET, | LogPrint(BCLog::NET, | ||||
"Ignore block request below NODE_NETWORK_LIMITED " | "Ignore block request below NODE_NETWORK_LIMITED threshold, " | ||||
"threshold, disconnect peer=%d\n", | "disconnect peer=%d\n", | ||||
pfrom.GetId()); | pfrom.GetId()); | ||||
// disconnect node and prevent it from stalling (would otherwise wait | // disconnect node and prevent it from stalling (would otherwise wait | ||||
// for the missing block) | // for the missing block) | ||||
pfrom.fDisconnect = true; | pfrom.fDisconnect = true; | ||||
return; | return; | ||||
} | } | ||||
// Pruned nodes may have deleted the block, so check whether it's available | // Pruned nodes may have deleted the block, so check whether it's available | ||||
// before trying to send. | // before trying to send. | ||||
if (!pindex->nStatus.hasData()) { | if (!pindex->nStatus.hasData()) { | ||||
▲ Show 20 Lines • Show All 600 Lines • ▼ Show 20 Lines | while (!orphan_work_set.empty()) { | ||||
m_orphanage.EraseTx(orphanTxId); | m_orphanage.EraseTx(orphanTxId); | ||||
break; | break; | ||||
} | } | ||||
} | } | ||||
} | } | ||||
bool PeerManagerImpl::PrepareBlockFilterRequest( | bool PeerManagerImpl::PrepareBlockFilterRequest( | ||||
CNode &peer, BlockFilterType filter_type, uint32_t start_height, | CNode &node, Peer &peer, BlockFilterType filter_type, uint32_t start_height, | ||||
const BlockHash &stop_hash, uint32_t max_height_diff, | const BlockHash &stop_hash, uint32_t max_height_diff, | ||||
const CBlockIndex *&stop_index, BlockFilterIndex *&filter_index) { | const CBlockIndex *&stop_index, BlockFilterIndex *&filter_index) { | ||||
const bool supported_filter_type = | const bool supported_filter_type = | ||||
(filter_type == BlockFilterType::BASIC && | (filter_type == BlockFilterType::BASIC && | ||||
(peer.GetLocalServices() & NODE_COMPACT_FILTERS)); | (peer.m_our_services & NODE_COMPACT_FILTERS)); | ||||
if (!supported_filter_type) { | if (!supported_filter_type) { | ||||
LogPrint(BCLog::NET, | LogPrint(BCLog::NET, | ||||
"peer %d requested unsupported block filter type: %d\n", | "peer %d requested unsupported block filter type: %d\n", | ||||
peer.GetId(), static_cast<uint8_t>(filter_type)); | node.GetId(), static_cast<uint8_t>(filter_type)); | ||||
peer.fDisconnect = true; | node.fDisconnect = true; | ||||
return false; | return false; | ||||
} | } | ||||
{ | { | ||||
LOCK(cs_main); | LOCK(cs_main); | ||||
stop_index = m_chainman.m_blockman.LookupBlockIndex(stop_hash); | stop_index = m_chainman.m_blockman.LookupBlockIndex(stop_hash); | ||||
// Check that the stop block exists and the peer would be allowed to | // Check that the stop block exists and the peer would be allowed to | ||||
// fetch it. | // fetch it. | ||||
if (!stop_index || !BlockRequestAllowed(stop_index)) { | if (!stop_index || !BlockRequestAllowed(stop_index)) { | ||||
LogPrint(BCLog::NET, "peer %d requested invalid block hash: %s\n", | LogPrint(BCLog::NET, "peer %d requested invalid block hash: %s\n", | ||||
peer.GetId(), stop_hash.ToString()); | node.GetId(), stop_hash.ToString()); | ||||
peer.fDisconnect = true; | node.fDisconnect = true; | ||||
return false; | return false; | ||||
} | } | ||||
} | } | ||||
uint32_t stop_height = stop_index->nHeight; | uint32_t stop_height = stop_index->nHeight; | ||||
if (start_height > stop_height) { | if (start_height > stop_height) { | ||||
LogPrint( | LogPrint( | ||||
BCLog::NET, | BCLog::NET, | ||||
"peer %d sent invalid getcfilters/getcfheaders with " /* Continued | "peer %d sent invalid getcfilters/getcfheaders with " /* Continued | ||||
*/ | */ | ||||
"start height %d and stop height %d\n", | "start height %d and stop height %d\n", | ||||
peer.GetId(), start_height, stop_height); | node.GetId(), start_height, stop_height); | ||||
peer.fDisconnect = true; | node.fDisconnect = true; | ||||
return false; | return false; | ||||
} | } | ||||
if (stop_height - start_height >= max_height_diff) { | if (stop_height - start_height >= max_height_diff) { | ||||
LogPrint(BCLog::NET, | LogPrint(BCLog::NET, | ||||
"peer %d requested too many cfilters/cfheaders: %d / %d\n", | "peer %d requested too many cfilters/cfheaders: %d / %d\n", | ||||
peer.GetId(), stop_height - start_height + 1, max_height_diff); | node.GetId(), stop_height - start_height + 1, max_height_diff); | ||||
peer.fDisconnect = true; | node.fDisconnect = true; | ||||
return false; | return false; | ||||
} | } | ||||
filter_index = GetBlockFilterIndex(filter_type); | filter_index = GetBlockFilterIndex(filter_type); | ||||
if (!filter_index) { | if (!filter_index) { | ||||
LogPrint(BCLog::NET, "Filter index for supported type %s not found\n", | LogPrint(BCLog::NET, "Filter index for supported type %s not found\n", | ||||
BlockFilterTypeName(filter_type)); | BlockFilterTypeName(filter_type)); | ||||
return false; | return false; | ||||
} | } | ||||
return true; | return true; | ||||
} | } | ||||
void PeerManagerImpl::ProcessGetCFilters(CNode &peer, CDataStream &vRecv) { | void PeerManagerImpl::ProcessGetCFilters(CNode &node, Peer &peer, | ||||
CDataStream &vRecv) { | |||||
uint8_t filter_type_ser; | uint8_t filter_type_ser; | ||||
uint32_t start_height; | uint32_t start_height; | ||||
BlockHash stop_hash; | BlockHash stop_hash; | ||||
vRecv >> filter_type_ser >> start_height >> stop_hash; | vRecv >> filter_type_ser >> start_height >> stop_hash; | ||||
const BlockFilterType filter_type = | const BlockFilterType filter_type = | ||||
static_cast<BlockFilterType>(filter_type_ser); | static_cast<BlockFilterType>(filter_type_ser); | ||||
const CBlockIndex *stop_index; | const CBlockIndex *stop_index; | ||||
BlockFilterIndex *filter_index; | BlockFilterIndex *filter_index; | ||||
if (!PrepareBlockFilterRequest(peer, filter_type, start_height, stop_hash, | if (!PrepareBlockFilterRequest(node, peer, filter_type, start_height, | ||||
MAX_GETCFILTERS_SIZE, stop_index, | stop_hash, MAX_GETCFILTERS_SIZE, stop_index, | ||||
filter_index)) { | filter_index)) { | ||||
return; | return; | ||||
} | } | ||||
std::vector<BlockFilter> filters; | std::vector<BlockFilter> filters; | ||||
if (!filter_index->LookupFilterRange(start_height, stop_index, filters)) { | if (!filter_index->LookupFilterRange(start_height, stop_index, filters)) { | ||||
LogPrint(BCLog::NET, | LogPrint(BCLog::NET, | ||||
"Failed to find block filter in index: filter_type=%s, " | "Failed to find block filter in index: filter_type=%s, " | ||||
"start_height=%d, stop_hash=%s\n", | "start_height=%d, stop_hash=%s\n", | ||||
BlockFilterTypeName(filter_type), start_height, | BlockFilterTypeName(filter_type), start_height, | ||||
stop_hash.ToString()); | stop_hash.ToString()); | ||||
return; | return; | ||||
} | } | ||||
for (const auto &filter : filters) { | for (const auto &filter : filters) { | ||||
CSerializedNetMsg msg = CNetMsgMaker(peer.GetCommonVersion()) | CSerializedNetMsg msg = CNetMsgMaker(node.GetCommonVersion()) | ||||
.Make(NetMsgType::CFILTER, filter); | .Make(NetMsgType::CFILTER, filter); | ||||
m_connman.PushMessage(&peer, std::move(msg)); | m_connman.PushMessage(&node, std::move(msg)); | ||||
} | } | ||||
} | } | ||||
void PeerManagerImpl::ProcessGetCFHeaders(CNode &peer, CDataStream &vRecv) { | void PeerManagerImpl::ProcessGetCFHeaders(CNode &node, Peer &peer, | ||||
CDataStream &vRecv) { | |||||
uint8_t filter_type_ser; | uint8_t filter_type_ser; | ||||
uint32_t start_height; | uint32_t start_height; | ||||
BlockHash stop_hash; | BlockHash stop_hash; | ||||
vRecv >> filter_type_ser >> start_height >> stop_hash; | vRecv >> filter_type_ser >> start_height >> stop_hash; | ||||
const BlockFilterType filter_type = | const BlockFilterType filter_type = | ||||
static_cast<BlockFilterType>(filter_type_ser); | static_cast<BlockFilterType>(filter_type_ser); | ||||
const CBlockIndex *stop_index; | const CBlockIndex *stop_index; | ||||
BlockFilterIndex *filter_index; | BlockFilterIndex *filter_index; | ||||
if (!PrepareBlockFilterRequest(peer, filter_type, start_height, stop_hash, | if (!PrepareBlockFilterRequest(node, peer, filter_type, start_height, | ||||
MAX_GETCFHEADERS_SIZE, stop_index, | stop_hash, MAX_GETCFHEADERS_SIZE, stop_index, | ||||
filter_index)) { | filter_index)) { | ||||
return; | return; | ||||
} | } | ||||
uint256 prev_header; | uint256 prev_header; | ||||
if (start_height > 0) { | if (start_height > 0) { | ||||
const CBlockIndex *const prev_block = | const CBlockIndex *const prev_block = | ||||
stop_index->GetAncestor(static_cast<int>(start_height - 1)); | stop_index->GetAncestor(static_cast<int>(start_height - 1)); | ||||
Show All 14 Lines | if (!filter_index->LookupFilterHashRange(start_height, stop_index, | ||||
"Failed to find block filter hashes in index: filter_type=%s, " | "Failed to find block filter hashes in index: filter_type=%s, " | ||||
"start_height=%d, stop_hash=%s\n", | "start_height=%d, stop_hash=%s\n", | ||||
BlockFilterTypeName(filter_type), start_height, | BlockFilterTypeName(filter_type), start_height, | ||||
stop_hash.ToString()); | stop_hash.ToString()); | ||||
return; | return; | ||||
} | } | ||||
CSerializedNetMsg msg = | CSerializedNetMsg msg = | ||||
CNetMsgMaker(peer.GetCommonVersion()) | CNetMsgMaker(node.GetCommonVersion()) | ||||
.Make(NetMsgType::CFHEADERS, filter_type_ser, | .Make(NetMsgType::CFHEADERS, filter_type_ser, | ||||
stop_index->GetBlockHash(), prev_header, filter_hashes); | stop_index->GetBlockHash(), prev_header, filter_hashes); | ||||
m_connman.PushMessage(&peer, std::move(msg)); | m_connman.PushMessage(&node, std::move(msg)); | ||||
} | } | ||||
void PeerManagerImpl::ProcessGetCFCheckPt(CNode &peer, CDataStream &vRecv) { | void PeerManagerImpl::ProcessGetCFCheckPt(CNode &node, Peer &peer, | ||||
CDataStream &vRecv) { | |||||
uint8_t filter_type_ser; | uint8_t filter_type_ser; | ||||
BlockHash stop_hash; | BlockHash stop_hash; | ||||
vRecv >> filter_type_ser >> stop_hash; | vRecv >> filter_type_ser >> stop_hash; | ||||
const BlockFilterType filter_type = | const BlockFilterType filter_type = | ||||
static_cast<BlockFilterType>(filter_type_ser); | static_cast<BlockFilterType>(filter_type_ser); | ||||
const CBlockIndex *stop_index; | const CBlockIndex *stop_index; | ||||
BlockFilterIndex *filter_index; | BlockFilterIndex *filter_index; | ||||
if (!PrepareBlockFilterRequest( | if (!PrepareBlockFilterRequest( | ||||
peer, filter_type, /*start_height=*/0, stop_hash, | node, peer, filter_type, /*start_height=*/0, stop_hash, | ||||
/*max_height_diff=*/std::numeric_limits<uint32_t>::max(), | /*max_height_diff=*/std::numeric_limits<uint32_t>::max(), | ||||
stop_index, filter_index)) { | stop_index, filter_index)) { | ||||
return; | return; | ||||
} | } | ||||
std::vector<uint256> headers(stop_index->nHeight / CFCHECKPT_INTERVAL); | std::vector<uint256> headers(stop_index->nHeight / CFCHECKPT_INTERVAL); | ||||
// Populate headers. | // Populate headers. | ||||
const CBlockIndex *block_index = stop_index; | const CBlockIndex *block_index = stop_index; | ||||
for (int i = headers.size() - 1; i >= 0; i--) { | for (int i = headers.size() - 1; i >= 0; i--) { | ||||
int height = (i + 1) * CFCHECKPT_INTERVAL; | int height = (i + 1) * CFCHECKPT_INTERVAL; | ||||
block_index = block_index->GetAncestor(height); | block_index = block_index->GetAncestor(height); | ||||
if (!filter_index->LookupFilterHeader(block_index, headers[i])) { | if (!filter_index->LookupFilterHeader(block_index, headers[i])) { | ||||
LogPrint(BCLog::NET, | LogPrint(BCLog::NET, | ||||
"Failed to find block filter header in index: " | "Failed to find block filter header in index: " | ||||
"filter_type=%s, block_hash=%s\n", | "filter_type=%s, block_hash=%s\n", | ||||
BlockFilterTypeName(filter_type), | BlockFilterTypeName(filter_type), | ||||
block_index->GetBlockHash().ToString()); | block_index->GetBlockHash().ToString()); | ||||
return; | return; | ||||
} | } | ||||
} | } | ||||
CSerializedNetMsg msg = CNetMsgMaker(peer.GetCommonVersion()) | CSerializedNetMsg msg = CNetMsgMaker(node.GetCommonVersion()) | ||||
.Make(NetMsgType::CFCHECKPT, filter_type_ser, | .Make(NetMsgType::CFCHECKPT, filter_type_ser, | ||||
stop_index->GetBlockHash(), headers); | stop_index->GetBlockHash(), headers); | ||||
m_connman.PushMessage(&peer, std::move(msg)); | m_connman.PushMessage(&node, std::move(msg)); | ||||
} | } | ||||
bool IsAvalancheMessageType(const std::string &msg_type) { | bool IsAvalancheMessageType(const std::string &msg_type) { | ||||
return msg_type == NetMsgType::AVAHELLO || | return msg_type == NetMsgType::AVAHELLO || | ||||
msg_type == NetMsgType::AVAPOLL || | msg_type == NetMsgType::AVAPOLL || | ||||
msg_type == NetMsgType::AVARESPONSE || | msg_type == NetMsgType::AVARESPONSE || | ||||
msg_type == NetMsgType::AVAPROOF || | msg_type == NetMsgType::AVAPROOF || | ||||
msg_type == NetMsgType::GETAVAADDR || | msg_type == NetMsgType::GETAVAADDR || | ||||
▲ Show 20 Lines • Show All 264 Lines • ▼ Show 20 Lines | if (msg_type == NetMsgType::VERSION) { | ||||
} | } | ||||
peer->m_starting_height = starting_height; | peer->m_starting_height = starting_height; | ||||
// We only initialize the m_tx_relay data structure if: | // We only initialize the m_tx_relay data structure if: | ||||
// - this isn't an outbound block-relay-only connection; and | // - this isn't an outbound block-relay-only connection; and | ||||
// - fRelay=true or we're offering NODE_BLOOM to this peer | // - fRelay=true or we're offering NODE_BLOOM to this peer | ||||
// (NODE_BLOOM means that the peer may turn on tx relay later) | // (NODE_BLOOM means that the peer may turn on tx relay later) | ||||
if (!pfrom.IsBlockOnlyConn() && | if (!pfrom.IsBlockOnlyConn() && | ||||
(fRelay || (pfrom.GetLocalServices() & NODE_BLOOM))) { | (fRelay || (peer->m_our_services & NODE_BLOOM))) { | ||||
auto *const tx_relay = peer->SetTxRelay(); | auto *const tx_relay = peer->SetTxRelay(); | ||||
{ | { | ||||
LOCK(tx_relay->m_bloom_filter_mutex); | LOCK(tx_relay->m_bloom_filter_mutex); | ||||
// set to true after we get the first filter* message | // set to true after we get the first filter* message | ||||
tx_relay->m_relay_txs = fRelay; | tx_relay->m_relay_txs = fRelay; | ||||
} | } | ||||
if (fRelay) { | if (fRelay) { | ||||
pfrom.m_relays_txs = true; | pfrom.m_relays_txs = true; | ||||
▲ Show 20 Lines • Show All 1,976 Lines • ▼ Show 20 Lines | if (msg_type == NetMsgType::GETAVAADDR) { | ||||
for (const CNode *pnode : avaNodes) { | for (const CNode *pnode : avaNodes) { | ||||
PushAddress(*peer, pnode->addr, insecure_rand); | PushAddress(*peer, pnode->addr, insecure_rand); | ||||
} | } | ||||
return; | return; | ||||
} | } | ||||
if (msg_type == NetMsgType::MEMPOOL) { | if (msg_type == NetMsgType::MEMPOOL) { | ||||
if (!(pfrom.GetLocalServices() & NODE_BLOOM) && | if (!(peer->m_our_services & NODE_BLOOM) && | ||||
!pfrom.HasPermission(NetPermissionFlags::Mempool)) { | !pfrom.HasPermission(NetPermissionFlags::Mempool)) { | ||||
if (!pfrom.HasPermission(NetPermissionFlags::NoBan)) { | if (!pfrom.HasPermission(NetPermissionFlags::NoBan)) { | ||||
LogPrint(BCLog::NET, | LogPrint(BCLog::NET, | ||||
"mempool request with bloom filters disabled, " | "mempool request with bloom filters disabled, " | ||||
"disconnect peer=%d\n", | "disconnect peer=%d\n", | ||||
pfrom.GetId()); | pfrom.GetId()); | ||||
pfrom.fDisconnect = true; | pfrom.fDisconnect = true; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 96 Lines • ▼ Show 20 Lines | if (msg_type == NetMsgType::PONG) { | ||||
} | } | ||||
if (bPingFinished) { | if (bPingFinished) { | ||||
peer->m_ping_nonce_sent = 0; | peer->m_ping_nonce_sent = 0; | ||||
} | } | ||||
return; | return; | ||||
} | } | ||||
if (msg_type == NetMsgType::FILTERLOAD) { | if (msg_type == NetMsgType::FILTERLOAD) { | ||||
if (!(pfrom.GetLocalServices() & NODE_BLOOM)) { | if (!(peer->m_our_services & NODE_BLOOM)) { | ||||
LogPrint(BCLog::NET, | LogPrint(BCLog::NET, | ||||
"filterload received despite not offering bloom services " | "filterload received despite not offering bloom services " | ||||
"from peer=%d; disconnecting\n", | "from peer=%d; disconnecting\n", | ||||
pfrom.GetId()); | pfrom.GetId()); | ||||
pfrom.fDisconnect = true; | pfrom.fDisconnect = true; | ||||
return; | return; | ||||
} | } | ||||
CBloomFilter filter; | CBloomFilter filter; | ||||
Show All 9 Lines | if (msg_type == NetMsgType::FILTERLOAD) { | ||||
tx_relay->m_relay_txs = true; | tx_relay->m_relay_txs = true; | ||||
} | } | ||||
pfrom.m_bloom_filter_loaded = true; | pfrom.m_bloom_filter_loaded = true; | ||||
} | } | ||||
return; | return; | ||||
} | } | ||||
if (msg_type == NetMsgType::FILTERADD) { | if (msg_type == NetMsgType::FILTERADD) { | ||||
if (!(pfrom.GetLocalServices() & NODE_BLOOM)) { | if (!(peer->m_our_services & NODE_BLOOM)) { | ||||
LogPrint(BCLog::NET, | LogPrint(BCLog::NET, | ||||
"filteradd received despite not offering bloom services " | "filteradd received despite not offering bloom services " | ||||
"from peer=%d; disconnecting\n", | "from peer=%d; disconnecting\n", | ||||
pfrom.GetId()); | pfrom.GetId()); | ||||
pfrom.fDisconnect = true; | pfrom.fDisconnect = true; | ||||
return; | return; | ||||
} | } | ||||
std::vector<uint8_t> vData; | std::vector<uint8_t> vData; | ||||
Show All 17 Lines | if (msg_type == NetMsgType::FILTERADD) { | ||||
// The structure of this code doesn't really allow for a good error | // The structure of this code doesn't really allow for a good error | ||||
// code. We'll go generic. | // code. We'll go generic. | ||||
Misbehaving(pfrom, 100, "bad filteradd message"); | Misbehaving(pfrom, 100, "bad filteradd message"); | ||||
} | } | ||||
return; | return; | ||||
} | } | ||||
if (msg_type == NetMsgType::FILTERCLEAR) { | if (msg_type == NetMsgType::FILTERCLEAR) { | ||||
if (!(pfrom.GetLocalServices() & NODE_BLOOM)) { | if (!(peer->m_our_services & NODE_BLOOM)) { | ||||
LogPrint(BCLog::NET, | LogPrint(BCLog::NET, | ||||
"filterclear received despite not offering bloom services " | "filterclear received despite not offering bloom services " | ||||
"from peer=%d; disconnecting\n", | "from peer=%d; disconnecting\n", | ||||
pfrom.GetId()); | pfrom.GetId()); | ||||
pfrom.fDisconnect = true; | pfrom.fDisconnect = true; | ||||
return; | return; | ||||
} | } | ||||
auto tx_relay = peer->GetTxRelay(); | auto tx_relay = peer->GetTxRelay(); | ||||
Show All 20 Lines | if (msg_type == NetMsgType::FEEFILTER) { | ||||
} | } | ||||
LogPrint(BCLog::NET, "received: feefilter of %s from peer=%d\n", | LogPrint(BCLog::NET, "received: feefilter of %s from peer=%d\n", | ||||
CFeeRate(newFeeFilter).ToString(), pfrom.GetId()); | CFeeRate(newFeeFilter).ToString(), pfrom.GetId()); | ||||
} | } | ||||
return; | return; | ||||
} | } | ||||
if (msg_type == NetMsgType::GETCFILTERS) { | if (msg_type == NetMsgType::GETCFILTERS) { | ||||
ProcessGetCFilters(pfrom, vRecv); | ProcessGetCFilters(pfrom, *peer, vRecv); | ||||
return; | return; | ||||
} | } | ||||
if (msg_type == NetMsgType::GETCFHEADERS) { | if (msg_type == NetMsgType::GETCFHEADERS) { | ||||
ProcessGetCFHeaders(pfrom, vRecv); | ProcessGetCFHeaders(pfrom, *peer, vRecv); | ||||
return; | return; | ||||
} | } | ||||
if (msg_type == NetMsgType::GETCFCHECKPT) { | if (msg_type == NetMsgType::GETCFCHECKPT) { | ||||
ProcessGetCFCheckPt(pfrom, vRecv); | ProcessGetCFCheckPt(pfrom, *peer, vRecv); | ||||
return; | return; | ||||
} | } | ||||
if (msg_type == NetMsgType::NOTFOUND) { | if (msg_type == NetMsgType::NOTFOUND) { | ||||
std::vector<CInv> vInv; | std::vector<CInv> vInv; | ||||
vRecv >> vInv; | vRecv >> vInv; | ||||
// A peer might send up to 1 notfound per getdata request, but no more | // A peer might send up to 1 notfound per getdata request, but no more | ||||
if (vInv.size() <= PROOF_REQUEST_PARAMS.max_peer_announcements + | if (vInv.size() <= PROOF_REQUEST_PARAMS.max_peer_announcements + | ||||
▲ Show 20 Lines • Show All 1,480 Lines • Show Last 20 Lines |