Changeset View
Changeset View
Standalone View
Standalone View
src/net_processing.cpp
Show First 20 Lines • Show All 2,236 Lines • ▼ Show 20 Lines | void static ProcessOrphanTx(const Config &config, CConnman &connman, | ||||
} | } | ||||
} | } | ||||
/** | /** | ||||
* 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] pfrom The peer that we received the request from | * @param[in] peer The peer that we received the request from | ||||
* @param[in] chain_params Chain parameters | * @param[in] chain_params Chain parameters | ||||
* @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 the | * @param[out] stop_index The CBlockIndex for the stop_hash block, if the | ||||
* request can be serviced. | * 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. | ||||
*/ | */ | ||||
static bool PrepareBlockFilterRequest( | static bool PrepareBlockFilterRequest( | ||||
CNode &pfrom, const CChainParams &chain_params, BlockFilterType filter_type, | CNode &peer, const CChainParams &chain_params, BlockFilterType filter_type, | ||||
uint32_t start_height, const BlockHash &stop_hash, uint32_t max_height_diff, | uint32_t start_height, 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 && | ||||
gArgs.GetBoolArg("-peerblockfilters", DEFAULT_PEERBLOCKFILTERS)); | gArgs.GetBoolArg("-peerblockfilters", DEFAULT_PEERBLOCKFILTERS)); | ||||
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", | ||||
pfrom.GetId(), static_cast<uint8_t>(filter_type)); | peer.GetId(), static_cast<uint8_t>(filter_type)); | ||||
pfrom.fDisconnect = true; | peer.fDisconnect = true; | ||||
return false; | return false; | ||||
} | } | ||||
{ | { | ||||
LOCK(cs_main); | LOCK(cs_main); | ||||
stop_index = LookupBlockIndex(stop_hash); | stop_index = 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 || | if (!stop_index || | ||||
!BlockRequestAllowed(stop_index, chain_params.GetConsensus())) { | !BlockRequestAllowed(stop_index, chain_params.GetConsensus())) { | ||||
LogPrint(BCLog::NET, "peer %d requested invalid block hash: %s\n", | LogPrint(BCLog::NET, "peer %d requested invalid block hash: %s\n", | ||||
pfrom.GetId(), stop_hash.ToString()); | peer.GetId(), stop_hash.ToString()); | ||||
pfrom.fDisconnect = true; | peer.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", | ||||
pfrom.GetId(), start_height, stop_height); | peer.GetId(), start_height, stop_height); | ||||
pfrom.fDisconnect = true; | peer.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", | ||||
pfrom.GetId(), stop_height - start_height + 1, | peer.GetId(), stop_height - start_height + 1, max_height_diff); | ||||
max_height_diff); | peer.fDisconnect = true; | ||||
pfrom.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; | ||||
} | } | ||||
/** | /** | ||||
* 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] pfrom 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 | ||||
* @param[in] chain_params Chain parameters | * @param[in] chain_params Chain parameters | ||||
* @param[in] connman Pointer to the connection manager | * @param[in] connman Pointer to the connection manager | ||||
*/ | */ | ||||
static void ProcessGetCFilters(CNode &pfrom, CDataStream &vRecv, | static void ProcessGetCFilters(CNode &peer, CDataStream &vRecv, | ||||
const CChainParams &chain_params, | const CChainParams &chain_params, | ||||
CConnman &connman) { | CConnman &connman) { | ||||
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( | if (!PrepareBlockFilterRequest( | ||||
pfrom, chain_params, filter_type, start_height, stop_hash, | peer, chain_params, filter_type, start_height, stop_hash, | ||||
MAX_GETCFILTERS_SIZE, stop_index, filter_index)) { | MAX_GETCFILTERS_SIZE, stop_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(pfrom.GetSendVersion()) | CSerializedNetMsg msg = CNetMsgMaker(peer.GetSendVersion()) | ||||
.Make(NetMsgType::CFILTER, filter); | .Make(NetMsgType::CFILTER, filter); | ||||
connman.PushMessage(&pfrom, std::move(msg)); | connman.PushMessage(&peer, std::move(msg)); | ||||
} | } | ||||
} | } | ||||
/** | /** | ||||
* 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] pfrom 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 | ||||
* @param[in] chain_params Chain parameters | * @param[in] chain_params Chain parameters | ||||
* @param[in] connman Pointer to the connection manager | * @param[in] connman Pointer to the connection manager | ||||
*/ | */ | ||||
static void ProcessGetCFHeaders(CNode &pfrom, CDataStream &vRecv, | static void ProcessGetCFHeaders(CNode &peer, CDataStream &vRecv, | ||||
const CChainParams &chain_params, | const CChainParams &chain_params, | ||||
CConnman &connman) { | CConnman &connman) { | ||||
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( | if (!PrepareBlockFilterRequest( | ||||
pfrom, chain_params, filter_type, start_height, stop_hash, | peer, chain_params, filter_type, start_height, stop_hash, | ||||
MAX_GETCFHEADERS_SIZE, stop_index, filter_index)) { | MAX_GETCFHEADERS_SIZE, stop_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(pfrom.GetSendVersion()) | CNetMsgMaker(peer.GetSendVersion()) | ||||
.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); | ||||
connman.PushMessage(&pfrom, std::move(msg)); | connman.PushMessage(&peer, std::move(msg)); | ||||
} | } | ||||
/** | /** | ||||
* Handle a getcfcheckpt request. | * Handle a getcfcheckpt 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] pfrom 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 | ||||
* @param[in] chain_params Chain parameters | * @param[in] chain_params Chain parameters | ||||
* @param[in] connman Pointer to the connection manager | * @param[in] connman Pointer to the connection manager | ||||
*/ | */ | ||||
static void ProcessGetCFCheckPt(CNode &pfrom, CDataStream &vRecv, | static void ProcessGetCFCheckPt(CNode &peer, CDataStream &vRecv, | ||||
const CChainParams &chain_params, | const CChainParams &chain_params, | ||||
CConnman &connman) { | CConnman &connman) { | ||||
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( | ||||
pfrom, chain_params, filter_type, /*start_height=*/0, stop_hash, | peer, chain_params, 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(pfrom.GetSendVersion()) | CSerializedNetMsg msg = CNetMsgMaker(peer.GetSendVersion()) | ||||
.Make(NetMsgType::CFCHECKPT, filter_type_ser, | .Make(NetMsgType::CFCHECKPT, filter_type_ser, | ||||
stop_index->GetBlockHash(), headers); | stop_index->GetBlockHash(), headers); | ||||
connman.PushMessage(&pfrom, std::move(msg)); | connman.PushMessage(&peer, std::move(msg)); | ||||
} | } | ||||
bool ProcessMessage(const Config &config, CNode &pfrom, | bool ProcessMessage(const Config &config, CNode &pfrom, | ||||
const std::string &msg_type, CDataStream &vRecv, | const std::string &msg_type, CDataStream &vRecv, | ||||
int64_t nTimeReceived, ChainstateManager &chainman, | int64_t nTimeReceived, ChainstateManager &chainman, | ||||
CConnman &connman, BanMan *banman, | CConnman &connman, BanMan *banman, | ||||
const std::atomic<bool> &interruptMsgProc) { | const std::atomic<bool> &interruptMsgProc) { | ||||
const CChainParams &chainparams = config.GetChainParams(); | const CChainParams &chainparams = config.GetChainParams(); | ||||
▲ Show 20 Lines • Show All 2,792 Lines • Show Last 20 Lines |