@@ -129,6 +129,8 @@ static constexpr unsigned int INVENTORY_BROADCAST_MAX = 7 * INVENTORY_BROADCAST_
129
129
static constexpr unsigned int AVG_FEEFILTER_BROADCAST_INTERVAL = 10 * 60 ;
130
130
/* * Maximum feefilter broadcast delay after significant change. */
131
131
static constexpr unsigned int MAX_FEEFILTER_CHANGE_DELAY = 5 * 60 ;
132
+ /* * Maximum number of compact filters that may be requested with one getcfilters. See BIP 157. */
133
+ static constexpr uint32_t MAX_GETCFILTERS_SIZE = 1000 ;
132
134
/* * Maximum number of cf hashes that may be requested with one getcfheaders. See BIP 157. */
133
135
static constexpr uint32_t MAX_GETCFHEADERS_SIZE = 2000 ;
134
136
@@ -2051,6 +2053,49 @@ static bool PrepareBlockFilterRequest(CNode& pfrom, const CChainParams& chain_pa
2051
2053
return true ;
2052
2054
}
2053
2055
2056
+ /* *
2057
+ * Handle a cfilters request.
2058
+ *
2059
+ * May disconnect from the peer in the case of a bad request.
2060
+ *
2061
+ * @param[in] pfrom The peer that we received the request from
2062
+ * @param[in] vRecv The raw message received
2063
+ * @param[in] chain_params Chain parameters
2064
+ * @param[in] connman Pointer to the connection manager
2065
+ */
2066
+ static void ProcessGetCFilters (CNode& pfrom, CDataStream& vRecv, const CChainParams& chain_params,
2067
+ CConnman& connman)
2068
+ {
2069
+ uint8_t filter_type_ser;
2070
+ uint32_t start_height;
2071
+ uint256 stop_hash;
2072
+
2073
+ vRecv >> filter_type_ser >> start_height >> stop_hash;
2074
+
2075
+ const BlockFilterType filter_type = static_cast <BlockFilterType>(filter_type_ser);
2076
+
2077
+ const CBlockIndex* stop_index;
2078
+ BlockFilterIndex* filter_index;
2079
+ if (!PrepareBlockFilterRequest (pfrom, chain_params, filter_type, start_height, stop_hash,
2080
+ MAX_GETCFILTERS_SIZE, stop_index, filter_index)) {
2081
+ return ;
2082
+ }
2083
+
2084
+ std::vector<BlockFilter> filters;
2085
+
2086
+ if (!filter_index->LookupFilterRange (start_height, stop_index, filters)) {
2087
+ LogPrint (BCLog::NET, " Failed to find block filter in index: filter_type=%s, start_height=%d, stop_hash=%s\n " ,
2088
+ BlockFilterTypeName (filter_type), start_height, stop_hash.ToString ());
2089
+ return ;
2090
+ }
2091
+
2092
+ for (const auto & filter : filters) {
2093
+ CSerializedNetMsg msg = CNetMsgMaker (pfrom.GetSendVersion ())
2094
+ .Make (NetMsgType::CFILTER, filter);
2095
+ connman.PushMessage (&pfrom, std::move (msg));
2096
+ }
2097
+ }
2098
+
2054
2099
/* *
2055
2100
* Handle a cfheaders request.
2056
2101
*
@@ -3466,6 +3511,11 @@ bool ProcessMessage(CNode* pfrom, const std::string& msg_type, CDataStream& vRec
3466
3511
return true ;
3467
3512
}
3468
3513
3514
+ if (msg_type == NetMsgType::GETCFILTERS) {
3515
+ ProcessGetCFilters (*pfrom, vRecv, chainparams, *connman);
3516
+ return true ;
3517
+ }
3518
+
3469
3519
if (msg_type == NetMsgType::GETCFHEADERS) {
3470
3520
ProcessGetCFHeaders (*pfrom, vRecv, chainparams, *connman);
3471
3521
return true ;
0 commit comments