@ -2383,27 +2383,28 @@ static RPCHelpMan scanblocks()
ChainstateManager & chainman = EnsureChainman ( node ) ;
// set the start-height
const CBlockIndex * block = nullptr ;
const CBlockIndex * start_index = nullptr ;
const CBlockIndex * stop_block = nullptr ;
{
LOCK ( cs_main ) ;
CChain & active_chain = chainman . ActiveChain ( ) ;
block = active_chain . Genesis ( ) ;
stop_block = active_chain . Tip ( ) ;
start_index = active_chain . Genesis ( ) ;
stop_block = active_chain . Tip ( ) ; // If no stop block is provided, stop at the chain tip.
if ( ! request . params [ 2 ] . isNull ( ) ) {
block = active_chain [ request . params [ 2 ] . getInt < int > ( ) ] ;
if ( ! block ) {
start_index = active_chain [ request . params [ 2 ] . getInt < int > ( ) ] ;
if ( ! start_index ) {
throw JSONRPCError ( RPC_MISC_ERROR , " Invalid start_height " ) ;
}
}
if ( ! request . params [ 3 ] . isNull ( ) ) {
stop_block = active_chain [ request . params [ 3 ] . getInt < int > ( ) ] ;
if ( ! stop_block | | stop_block - > nHeight < block - > nHeight ) {
if ( ! stop_block | | stop_block - > nHeight < start_index - > nHeight ) {
throw JSONRPCError ( RPC_MISC_ERROR , " Invalid stop_height " ) ;
}
}
}
CHECK_NONFATAL ( block ) ;
CHECK_NONFATAL ( start_index ) ;
CHECK_NONFATAL ( stop_block ) ;
// loop through the scan objects, add scripts to the needle_set
GCSFilter : : ElementSet needle_set ;
@ -2416,63 +2417,62 @@ static RPCHelpMan scanblocks()
}
UniValue blocks ( UniValue : : VARR ) ;
const int amount_per_chunk = 10000 ;
const CBlockIndex * start_index = block ; // for remembering the start of a blockfilter range
std : : vector < BlockFilter > filters ;
const CBlockIndex * start_block = block ; // for progress reporting
const int total_blocks_to_process = stop_block - > nHeight - start_block - > nH eight;
int start_block_height = start_index - > nHeight ; // for progress reporting
const int total_blocks_to_process = stop_block - > nHeight - start_block _h eight;
g_scanfilter_should_abort_scan = false ;
g_scanfilter_progress = 0 ;
g_scanfilter_progress_height = start_block - > nH eight;
g_scanfilter_progress_height = start_block _h eight;
while ( block ) {
const CBlockIndex * end_range = nullptr ;
do {
node . rpc_interruption_point ( ) ; // allow a clean shutdown
if ( g_scanfilter_should_abort_scan ) {
LogPrintf ( " scanblocks RPC aborted at height %d. \n " , block - > nHeight ) ;
LogPrintf ( " scanblocks RPC aborted at height %d. \n " , end_range - > nHeight ) ;
break ;
}
const CBlockIndex * next = nullptr ;
{
LOCK ( cs_main ) ;
CChain & active_chain = chainman . ActiveChain ( ) ;
next = active_chain . Next ( block ) ;
if ( block = = stop_block ) next = nullptr ;
}
if ( start_index - > nHeight + amount_per_chunk = = block - > nHeight | | next = = nullptr ) {
LogPrint ( BCLog : : RPC , " Fetching blockfilters from height %d to height %d. \n " , start_index - > nHeight , block - > nHeight ) ;
if ( index - > LookupFilterRange ( start_index - > nHeight , block , filters ) ) {
for ( const BlockFilter & filter : filters ) {
// compare the elements-set with each filter
if ( filter . GetFilter ( ) . MatchAny ( needle_set ) ) {
if ( filter_false_positives ) {
// Double check the filter matches by scanning the block
const CBlockIndex & blockindex = * CHECK_NONFATAL ( WITH_LOCK ( cs_main , return chainman . m_blockman . LookupBlockIndex ( filter . GetBlockHash ( ) ) ) ) ;
if ( ! CheckBlockFilterMatches ( chainman . m_blockman , blockindex , needle_set ) ) {
continue ;
}
}
blocks . push_back ( filter . GetBlockHash ( ) . GetHex ( ) ) ;
LogPrint ( BCLog : : RPC , " scanblocks: found match in %s \n " , filter . GetBlockHash ( ) . GetHex ( ) ) ;
// split the lookup range in chunks if we are deeper than 'amount_per_chunk' blocks from the stopping block
int start_block = ! end_range ? start_index - > nHeight : start_index - > nHeight + 1 ; // to not include the previous round 'end_range' block
end_range = ( start_block + amount_per_chunk < stop_block - > nHeight ) ?
WITH_LOCK ( : : cs_main , return chainman . ActiveChain ( ) [ start_block + amount_per_chunk ] ) :
stop_block ;
if ( index - > LookupFilterRange ( start_block , end_range , filters ) ) {
for ( const BlockFilter & filter : filters ) {
// compare the elements-set with each filter
if ( filter . GetFilter ( ) . MatchAny ( needle_set ) ) {
if ( filter_false_positives ) {
// Double check the filter matches by scanning the block
const CBlockIndex & blockindex = * CHECK_NONFATAL ( WITH_LOCK ( cs_main , return chainman . m_blockman . LookupBlockIndex ( filter . GetBlockHash ( ) ) ) ) ;
if ( ! CheckBlockFilterMatches ( chainman . m_blockman , blockindex , needle_set ) ) {
continue ;
}
}
blocks . push_back ( filter . GetBlockHash ( ) . GetHex ( ) ) ;
LogPrint ( BCLog : : RPC , " scanblocks: found match in %s \n " , filter . GetBlockHash ( ) . GetHex ( ) ) ;
}
}
start_index = block ;
// update progress
int blocks_processed = block - > nHeight - start_block - > nHeight ;
if ( total_blocks_to_process > 0 ) { // avoid division by zero
g_scanfilter_progress = ( int ) ( 100.0 / total_blocks_to_process * blocks_processed ) ;
} else {
g_scanfilter_progress = 100 ;
}
g_scanfilter_progress_height = block - > nHeight ;
}
block = next ;
}
ret . pushKV ( " from_height " , start_block - > nHeight ) ;
ret . pushKV ( " to_height " , g_scanfilter_progress_height . load ( ) ) ;
start_index = end_range ;
// update progress
int blocks_processed = end_range - > nHeight - start_block_height ;
if ( total_blocks_to_process > 0 ) { // avoid division by zero
g_scanfilter_progress = ( int ) ( 100.0 / total_blocks_to_process * blocks_processed ) ;
} else {
g_scanfilter_progress = 100 ;
}
g_scanfilter_progress_height = end_range - > nHeight ;
// Finish if we reached the stop block
} while ( start_index ! = stop_block ) ;
ret . pushKV ( " from_height " , start_block_height ) ;
ret . pushKV ( " to_height " , stop_block - > nHeight ) ;
ret . pushKV ( " relevant_blocks " , blocks ) ;
}
else {