Skip to content

Conversation

jamesob
Copy link
Contributor

@jamesob jamesob commented Nov 18, 2021

Revives #20664. All feedback from the previous PR has either been responded to inline or incorporated here.


Major changes from Jonas' PR:

  • consolidated arguments for scantxoutset/scanblocks
  • substantial cleanup of the functional test

Here's the range-diff (git range-diff master jonasschnelli/2020/12/filterblocks_rpc jamesob/2021-11-scanblocks): https://gist.github.com/jamesob/aa4a975344209f0316444b8de2ec1d18

Original PR description

The scanblocks RPC call allows one to get relevant blockhashes from a set of descriptors by scanning all blockfilters in a given range.

Example:

scanblocks start '["addr(<bitcoin_address>)"]' 661000 (returns relevant blockhashes for <bitcoin_address> from blockrange 661000->tip)

Why is this useful?

Fast wallet rescans: get the relevant blocks and only rescan those via rescanblockchain getblockheader(<hash>)[height] getblockheader(<hash>)[height]). A future PR may add an option to allow to provide an array of blockhashes to rescanblockchain.

prune wallet rescans: (needs additional changes): together with a call to fetch blocks from the p2p network if they have been pruned, it would allow to rescan wallets back to the genesis block in pruned mode (relevant #15946).

SPV mode (needs additional changes): it would be possible to build the blockfilterindex from the p2p network (rather then deriving them from the blocks) and thus allow some sort of hybrid-SPV mode with moderate bandwidth consumption (related #9483)

@jamesob
Copy link
Contributor Author

jamesob commented Nov 18, 2021

Previously involved:

@ghost
Copy link

ghost commented Nov 18, 2021

Thanks for reviving 20664. There are many interesting PRs by jonasschnelli which never got merged for different reasons.

Will test it this weekend.

@DrahtBot
Copy link
Contributor

DrahtBot commented Nov 18, 2021

The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.

Conflicts

Reviewers, this pull request conflicts with the following ones:

  • #26283 (p2p: Fill reconciliation sets and request reconciliation (Erlay) by naumenkogs)
  • #25366 (util, rpc: Add parameter to deriveaddresses to display address information by w0xlt)
  • #24162 (rpc: add require_checksum flag to deriveaddresses by kallewoof)
  • #23443 (p2p: Erlay support signaling by naumenkogs)

If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first.

@ghost
Copy link

ghost commented Nov 21, 2021

I tried the syntax based on example mentioned in PR description and it gives me an error:

$ bitcoin-cli scanblocks start '["addr(mzrj4QmPhk98vc2yQw42uCsgwfBjVzPPLM)"]' 1000000
error code: -1
error message:
Index is not enabled for filtertype basic

I checked the code for RPC help but don't understand what exactly should be enabled and how are filters used in this RPC

@fjahr
Copy link
Contributor

fjahr commented Nov 21, 2021

I tried the syntax based on example mentioned in PR description and it gives me an error:

$ bitcoin-cli scanblocks start '["addr(mzrj4QmPhk98vc2yQw42uCsgwfBjVzPPLM)"]' 1000000
error code: -1
error message:
Index is not enabled for filtertype basic

I checked the code for RPC help but don't understand what exactly should be enabled and how are filters used in this RPC

You probably did not run bitcoind with -blockfilterindex=1?

I guess that issue could be caught earlier and use a better error message :)

@ghost
Copy link

ghost commented Nov 22, 2021

You probably did not run bitcoind with -blockfilterindex=1?

Thanks for the help @fjahr. Tried running bitcoind with -blockfilterindex=1:

2021-11-22T01:44:23Z basic block filter index is enabled at height 2104934
2021-11-22T01:44:23Z basic block filter index thread exit
$ bitcoin-cli scanblocks start '["addr(mzrj4QmPhk98vc2yQw42uCsgwfBjVzPPLM)"]' 1000000

Got response after few minutes with lot of block hashes. I was expecting a quick response based on concept of this PR and time it took for -blockfilterindex=1 so not sure what exactly did we achieve but will check others things later. Will sleep now as its morning here already.

@benthecarman
Copy link
Contributor

Concept ACK

Is there plans to add functionality similiar to rescanblockchain so it does it for your wallets, without having to enter in the descriptors manually?

Copy link
Contributor

@theStack theStack left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Concept re-ACK. Thanks for picking this up! 👍

Did a first quick test on signet with a coinbase tx address from an arbitrary block (height 1337) that is spent about 1000 blocks later (https://explorer.bc-2.jp/address/tb1q6tnc9k7a3pdufryr9tpttjulh97g838vljyrgx):

$ ./src/bitcoind -signet -blockfilterindex=1 &
$ ./src/bitcoin-cli -signet scanblocks start '["addr(tb1q6tnc9k7a3pdufryr9tpttjulh97g838vljyrgx)"]'
{
  "from_height": 0,
  "to_height": 66345,
  "relevant_blocks": [
    "00000109e0671e4b8bc44ae1f08a6a87d656968d08e264f20631ed32f69fbea8",
    "00000030b26a4a94272999a68068adf0b617beef9caac51d6ff003dbf4bd8223"
  ]
}

On a quick glance over the second commit, I saw that the help examples are not working, see comment below. Will review more in-depth within the next days.

@jamesob jamesob force-pushed the 2021-11-scanblocks branch from c1e71fb to e1c8918 Compare December 2, 2021 21:51
@jamesob
Copy link
Contributor Author

jamesob commented Dec 2, 2021

On a quick glance over the second commit, I saw that the help examples are not working, see comment below. Will review more in-depth within the next days.

@theStack fixed, thanks!

Copy link

@ghost ghost left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

.

Copy link

@ghost ghost left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NACK

Based on my testing I was not able to do fast scan as mentioned in OP:

Why is this useful?
Fast wallet rescans: get the relevant blocks and only rescan those via rescanblockchain getblockheader()[height] getblockheader()[height]). A future PR may add an option to allow to provide an array of blockhashes to rescanblockchain.

@sipa
Copy link
Member

sipa commented Dec 4, 2021

@prayank23 Without blockfilters it would take many times longer, and without this PR the functionality to scan blocks doesn't exist at all.

@ghost
Copy link

ghost commented Dec 4, 2021

@sipa is that considering the time it takes for -blockfilterindex=1 ? PR does not achieve any fast scans IMO. Maybe description should be changed or PR author can take some time to respond with comments when reviewers waste their nights to review the PR

@sipa
Copy link
Member

sipa commented Dec 4, 2021

@prayank23 You only need to build the filters once, and you need them too for -peerblockfilters (if you want to support BIP157 protocol).

Comment on lines 2318 to 2321
static const auto scan_result_abort = RPCResult{"When action=='abort'", RPCResult::Type::BOOL, "", ""};
static const auto scan_result_status_none = RPCResult{"When action=='status' and no scan is in progress", RPCResult::Type::NONE, "", ""};
static const auto scan_result_status_some = RPCResult{
"When action=='status' and scan is in progress", RPCResult::Type::OBJ, "", "",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Other RPC docs use plain English "if verbose is not set or set to false"

Suggest adopting the language used in prior revisions of this feature

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure what you mean here.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mean we should stick to either plain English or pseudo-code for docs, but avoid mixing the two.

}
}
if (!request.params[3].isNull()) {
stop_block = active_chain[request.params[3].get_int()];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's possible this block could be reorg'd out during the scan, and then it won't stop until it reaches the new best block?

I guess if it was reorg'd out, it probably doesn't matter, but might be nice to fix.

@luke-jr
Copy link
Member

luke-jr commented Mar 24, 2022

Proposed changes (feel free to squash): jamesob/bitcoin@2021-11-scanblocks...luke-jr:rpc_scanblocks

jonasschnelli and others added 2 commits October 4, 2022 13:51
@jamesob jamesob force-pushed the 2021-11-scanblocks branch from b770100 to 626b7c8 Compare October 4, 2022 17:51
@jamesob
Copy link
Contributor Author

jamesob commented Oct 4, 2022

Trivial rebase pushed.

Given the number of (tested) ACKs here it would be nice to get this merged sooner rather than later; it's been open almost a year.

@Sjors
Copy link
Member

Sjors commented Oct 4, 2022

On my list to reACK soon(tm)

Copy link
Member

@maflcko maflcko left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

left some nits, feel free to ignore

while (block) {
node.rpc_interruption_point(); // allow a clean shutdown
if (g_scanfilter_should_abort_scan) {
LogPrintf("scanblocks RPC aborted at height %d.\n", block->nHeight);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not sure about unconditional logging here. This will fill the disk and there is no way for a user to disable it, unless they turn off all logging.

Is there a reason to log as opposed to return something to the rpc user?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, wouldn't be bad to return a "completed" flag inside the return object.

// compare the elements-set with each filter
if (filter.GetFilter().MatchAny(needle_set)) {
blocks.push_back(filter.GetBlockHash().GetHex());
LogPrint(BCLog::RPC, "scanblocks: found match in %s\n", filter.GetBlockHash().GetHex());
Copy link
Member

@maflcko maflcko Oct 4, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: If this logging is for debugging, maybe put this in the debug category?

Though, I wonder what the use is, given that this will be returned to the RPC user anyway, so there would be no need to persist this in the debug log?

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);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same?

@jamesob
Copy link
Contributor Author

jamesob commented Oct 12, 2022

Unless there are any correctness problems I'm going to leave this PR as-is; 3 solid ACKs, so would be nice to get this merged.

Copy link
Member

@furszy furszy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

diff re-ACK 626b7c8

I can tackle all the remaining nits on the follow-up PR that I'm planning to do (#23549 (review))

@achow101 achow101 merged commit bc2b1f0 into bitcoin:master Oct 13, 2022
@kouloumos
Copy link
Contributor

kouloumos commented Oct 13, 2022

Does this also need release notes?
edit: https://github.com/bitcoin-core/bitcoin-devwiki/wiki/scanblocks-RPC-release-notes

maflcko pushed a commit to maflcko/bitcoin-core that referenced this pull request Oct 14, 2022
ae3626e test: use MiniWallet for rpc_scanblocks.py (Sebastian Falbesoner)

Pull request description:

  This is a small follow-up for bitcoin#23549 which introduced `scanblocks`. Since that RPC doesn't need the wallet, we can switch the functional test to use MiniWallet.

ACKs for top commit:
  MarcoFalke:
    review ACK ae3626e

Tree-SHA512: e0b0088103e059b29719299c58fd5173b1cff58cb73025a9a33ad493cd0ac50ba25a5f790e471c00a09b4dca80f3c011174ca4e0c8f34746c39831f5823dc8ba
maflcko pushed a commit that referenced this pull request Oct 21, 2022
ff138f9 doc: add `scanblocks` to list of descriptor RPCs (Sebastian Falbesoner)

Pull request description:

  This is a tiny documentation follow-up to #23549.

ACKs for top commit:
  aureleoules:
    ACK ff138f9
  shaavan:
    ACK ff138f9

Tree-SHA512: cc45b78c13ec4aa5bac688648f8e83f04a9ae54376e67371b280428f0253e2585cf0575fa51e3835d4c13c940559bfcdd88d7504bf97a81b2a73bb34a0db7577
sidhujag pushed a commit to syscoin/syscoin that referenced this pull request Oct 23, 2022
626b7c8 fuzz: add scanblocks as safe for fuzzing (James O'Beirne)
94fe545 test: rpc: add scanblocks functional test (Jonas Schnelli)
6ef2566 rpc: add scanblocks - scan for relevant blocks with descriptors (Jonas Schnelli)
a4258f6 rpc: move-only: consolidate blockchain scan args (James O'Beirne)

Pull request description:

  Revives bitcoin#20664. All feedback from the previous PR has either been responded to inline or incorporated here.

  ---

  Major changes from Jonas' PR:
  - consolidated arguments for scantxoutset/scanblocks
  - substantial cleanup of the functional test

  Here's the range-diff (`git range-diff master jonasschnelli/2020/12/filterblocks_rpc jamesob/2021-11-scanblocks`): https://gist.github.com/jamesob/aa4a975344209f0316444b8de2ec1d18

  ### Original PR description

  > The `scanblocks` RPC call allows one to get relevant blockhashes from a set of descriptors by scanning all blockfilters in a given range.
  >
  > **Example:**
  >
  > `scanblocks start '["addr(<bitcoin_address>)"]' 661000` (returns relevant blockhashes for `<bitcoin_address>` from blockrange 661000->tip)
  >
  > ## Why is this useful?
  > **Fast wallet rescans**: get the relevant blocks and only rescan those via `rescanblockchain getblockheader(<hash>)[height] getblockheader(<hash>)[height])`. A future PR may add an option to allow to provide an array of blockhashes to `rescanblockchain`.
  >
  > **prune wallet rescans**: (_needs additional changes_): together with a call to fetch blocks from the p2p network if they have been pruned, it would allow to rescan wallets back to the genesis block in pruned mode (relevant bitcoin#15946).
  >
  > **SPV mode** (_needs additional changes_): it would be possible to build the blockfilterindex from the p2p network (rather then deriving them from the blocks) and thus allow some sort of hybrid-SPV mode with moderate bandwidth consumption (related bitcoin#9483)

ACKs for top commit:
  furszy:
    diff re-ACK 626b7c8

Tree-SHA512: f84e4dcb851b122b39e9700c58fbc31e899cdcf9b587df9505eaf1f45578cc4253e89ce2a45d1ff21bd213e31ddeedbbcad2c80810f46755b30acc17b07e2873
sidhujag pushed a commit to syscoin/syscoin that referenced this pull request Oct 23, 2022
ae3626e test: use MiniWallet for rpc_scanblocks.py (Sebastian Falbesoner)

Pull request description:

  This is a small follow-up for bitcoin#23549 which introduced `scanblocks`. Since that RPC doesn't need the wallet, we can switch the functional test to use MiniWallet.

ACKs for top commit:
  MarcoFalke:
    review ACK ae3626e

Tree-SHA512: e0b0088103e059b29719299c58fd5173b1cff58cb73025a9a33ad493cd0ac50ba25a5f790e471c00a09b4dca80f3c011174ca4e0c8f34746c39831f5823dc8ba
sidhujag pushed a commit to syscoin/syscoin that referenced this pull request Oct 23, 2022
ff138f9 doc: add `scanblocks` to list of descriptor RPCs (Sebastian Falbesoner)

Pull request description:

  This is a tiny documentation follow-up to bitcoin#23549.

ACKs for top commit:
  aureleoules:
    ACK ff138f9
  shaavan:
    ACK ff138f9

Tree-SHA512: cc45b78c13ec4aa5bac688648f8e83f04a9ae54376e67371b280428f0253e2585cf0575fa51e3835d4c13c940559bfcdd88d7504bf97a81b2a73bb34a0db7577
achow101 added a commit to bitcoin-core/gui that referenced this pull request May 1, 2023
b922f6b rpc: scanblocks, add "completed" flag to the result obj (furszy)
ce50acc rpc: scanblocks, do not traverse the whole chain block by block (furszy)

Pull request description:

  Coming from bitcoin/bitcoin#23549 (review)

  The current `scanblocks` flow walks-through every block in the active chain
  until hits the chain tip or processes 10k blocks, then calls `lookupFilterRange`
  function to obtain all filters from that particular range.

  This is only done to obtain the heights range to look up the block
  filters. Which is unneeded.

  As `scanblocks` only lookup block filters in the active chain, we can
  directly calculate the lookup range heights, by using the chain tip,
  without requiring to traverse the chain block by block.

ACKs for top commit:
  achow101:
    ACK b922f6b
  TheCharlatan:
    ACK b922f6b

Tree-SHA512: 0587e6d9cf87a59184adb2dbc26a4e2bce3a16233594c6c330f69feb49bf7dc63fdacf44fc20308e93441159ebc604c63eb7de19204d3e745a2ff16004892b45
sidhujag pushed a commit to syscoin/syscoin that referenced this pull request May 1, 2023
b922f6b rpc: scanblocks, add "completed" flag to the result obj (furszy)
ce50acc rpc: scanblocks, do not traverse the whole chain block by block (furszy)

Pull request description:

  Coming from bitcoin#23549 (review)

  The current `scanblocks` flow walks-through every block in the active chain
  until hits the chain tip or processes 10k blocks, then calls `lookupFilterRange`
  function to obtain all filters from that particular range.

  This is only done to obtain the heights range to look up the block
  filters. Which is unneeded.

  As `scanblocks` only lookup block filters in the active chain, we can
  directly calculate the lookup range heights, by using the chain tip,
  without requiring to traverse the chain block by block.

ACKs for top commit:
  achow101:
    ACK b922f6b
  TheCharlatan:
    ACK b922f6b

Tree-SHA512: 0587e6d9cf87a59184adb2dbc26a4e2bce3a16233594c6c330f69feb49bf7dc63fdacf44fc20308e93441159ebc604c63eb7de19204d3e745a2ff16004892b45
This was referenced May 24, 2023
luke-jr pushed a commit to luke-jr/bitcoin that referenced this pull request Jul 19, 2023
For later reuse in `scanblocks`.

Github-Pull: bitcoin#23549
Rebased-From: a4258f6
luke-jr pushed a commit to luke-jr/bitcoin that referenced this pull request Jul 19, 2023
Co-authored-by: James O'Beirne <james.obeirne@gmail.com>

Github-Pull: bitcoin#23549
Rebased-From: 6ef2566
luke-jr pushed a commit to luke-jr/bitcoin that referenced this pull request Jul 19, 2023
Co-authored-by: James O'Beirne <james.obeirne@gmail.com>

Github-Pull: bitcoin#23549
Rebased-From: 94fe545
luke-jr pushed a commit to luke-jr/bitcoin that referenced this pull request Jul 19, 2023
@bitcoin bitcoin locked and limited conversation to collaborators Oct 13, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.