-
Notifications
You must be signed in to change notification settings - Fork 38.8k
rpc: add relevant_blocks to scanblocks status
#30713
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
The following sections might be updated with supplementary metadata relevant to reviewers and maintainers. Code Coverage & BenchmarksFor details see: https://corecheck.dev/bitcoin/bitcoin/pulls/30713. ReviewsSee the guideline for information on the review process.
If your review is incorrectly listed, please react with 👎 to this comment and the bot will ignore it on the next update. ConflictsNo conflicts as of last run. |
revelant_blocks to scanblocks status
|
🚧 At least one of the CI tasks failed. HintsMake sure to run all tests locally, according to the documentation. The failure may happen due to a number of reasons, for example:
Leave a comment here, if you need help tracking down a confusing failure. |
|
Concept ACK. This'd be useful, especially in conjunction with #30708. |
src/rpc/blockchain.cpp
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since status stops working when the scan completes, it seems like we should clear g_relevant_blocks here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, thank you. Will update.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That'd introduce a race, where the relevant blocks are cleared before the reserver is destructed (and thus the status call may return an empty list where previously it didn't for the same call)
Not sure if it matters, or worthy to address.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While leaving scanblocks() without resetting g_relevant_blocks isn't ideal, resetting g_relevant_blocks just before BlockFiltersScanReserver in the start branch seemed to be a good way to prevent status from accidentally seeing an empty g_relevant_blocks (at least in common cases). Please let me know if I'm overlooking a likely concurrency case, and it can be adjusted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems trivial to fix properly? luke-jr@5698131
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
included, thanks
pablomartin4btc
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Concept ACK (coming from #30708).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
tACK 39ee30c31f5b33a084f420ed49170e669a8f6440
Release notes has been added and g_relevant_blocks reset has been placed into the start conditional section since my last review.
Tested on mainnet.
/build/src/bitcoin-cli scanblocks start '["addr(bc1p0cp0vyag6snlta2l7c4am3rue7eef9f72l7uhx52m4v27vfydx9s8tfs7t)"]' 850263
{
"from_height": 850263,
"to_height": 860861,
"relevant_blocks": [
"00000000000000000002b3c2a395905df9d12ce30d2237f064cdafacb81eb33d",
"00000000000000000002bc5cc78f5b0913a5230a8f4b0d5060bc9a60900a5a88",
"00000000000000000001c5291ed6a40c06d3db5c8fb738567654b24a14b24ecb"
],
"completed": true
}
./build/src/bitcoin-cli scanblocks status
{
"progress": 0,
"current_height": 850263,
"relevant_blocks": [
"00000000000000000002b3c2a395905df9d12ce30d2237f064cdafacb81eb33d"
]
}
For those not used to scanblocks I'd add a little note somewhere in the description that in order to testing this change the block filter index feature should be enabled, by either passing -blockfilterindex as an argument on the node start up or putting it in the bitcoin.conf file (same for #30708), even it's specified in the help or an error would lead to that, it'd make it easier and straightforward. Also that if the feature was not enabled before it could take up to a few hours to create the indexes.
Out of the scope of this PR, having played around start, status, abort subcommands, I'd add some more context in the results of the first 2. Perhaps as "good first issue".
-
for
statussubcommand, instead of returning no results when there are no scans in progress:./build/src/bitcoin-cli -datadir=${AU_DATADIR} scanblocks status { "status": "No scan in progress" } -
for
startsubcommand, when theaborthas been triggered and was no completion:/build/src/bitcoin-cli -datadir=${AU_DATADIR} scanblocks start '["addr(bc1p0cp0vyag6snlta2l7c4am3rue7eef9f72l7uhx52m4v27vfydx9s8tfs7t)"]' 750000 { "from_height": 750000, "to_height": 780002, "relevant_blocks": [ ], "completed": false, "status": "Abort call performed" }
|
Thanks for reviewing.
These are good ideas for follow-up PRs.
Good idea. Description updated. |
Thanks! It looks good. Forgot to mention that it would be nice to add some test checking |
It would be. I took a look at bitcoin/test/functional/rpc_scanblocks.py Lines 128 to 129 in 0725a37
Any ideas on how to slow down |
Exactly.
I've been playing a bit around the |
naiyoma
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tested changes on mainnet
Started scanning
./build/src/bitcoin-cli scanblocks start '["addr(bc1qgqrn8gratlc59gn5v02nrz0rg8anjjaxt3efh8)"]'
status check
./build/src/bitcoin-cli scanblocks status
{
"progress": 98,
"current_height": 570056,
"relevant_blocks": [
"0000000000005ecf9f819ea03abd8f2a3f0b2cad5e5124bdabd0d7a770fd9067",
"000000000000000479f286761e91b2c983ad63e19b0d53cffc67e731a7558d85"
]
}
scan completed
./build/src/bitcoin-cli scanblocks start '["addr(bc1qgqrn8gratlc59gn5v02nrz0rg8anjjaxt3efh8)"]'
{
"from_height": 0,
"to_height": 577394,
"relevant_blocks": [
"0000000000005ecf9f819ea03abd8f2a3f0b2cad5e5124bdabd0d7a770fd9067",
"000000000000000479f286761e91b2c983ad63e19b0d53cffc67e731a7558d85"
],
"completed": true
}
`
Not sure if it worth it but could craft an unit test that calls to the RPC command. Subclassing and setting the block manager class so the file opening method "stops" at a certain point. It would mimic the delay. |
Provides relevant block hashes to status output. Enables a user to start looking through matching blocks without having to wait on scan completion. Github-Pull: bitcoin#30713 Rebased-From: bdda0c14d9bea36248b4e26fd8b059b046cb0e7a
Github-Pull: bitcoin#30713 Rebased-From: 39ee30c31f5b33a084f420ed49170e669a8f6440
|
Any reason not to scope the new variables? luke-jr@851d354 |
|
Thanks. Planning to touch this up soon. |
Provides relevant block hashes to status output. Enables a user to start looking through matching blocks without having to wait on scan completion. Co-Authored-By: Luke Dashjr <[email protected]>
moved, thanks |
|
Updated with suggested changes |
|
Want to reemphasize that I think this is a good change worth doing. I have some questions about using |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code review ACK 5b2d021. Seems like a nice feature, and the implementation is pretty simple. I think there is a minor regression if scanblocks start is called from multiple threads, and suggested a fix below (#30713 (comment)).
re: #30713 (comment)
Any ideas on how to slow down
scanblocks()enough to allow astatuscall to consistently return status of a scan in progress?
Will suggest a very general solution that would probably be overkill here, but I think we could have a setmockcondition RPC that acts like the existing setmocktime RPC and lets tests toggle global state that could be useful for testing. In this case I imagine a test could call something like setmockcondition({"scanblocks_pause_at_height": 50}) to make the scanning pause at a certain height and setmockcondition({"scanblocks_pause_at_height": null}) to make it resume, and we could have some helpful functions that make this not too intrusive to implement.
| static GlobalMutex cs_relevant_blocks; | ||
| static UniValue relevant_blocks GUARDED_BY(cs_relevant_blocks); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In commit "rpc: add relevant_blocks to scanblocks status" (4c9dc4b)
It would be good to declare these next to g_scanfilter_ variables so all global state is declared in one place, and so other functions besides scanblocks can see this information (other RPCs and maybe tests should be able to access it). Would suggest renaming relevant_blocks to g_scanfilter_relevant_blocks and cs_relevant_blocks to g_scanfilter_relevant_blocks_mutex. (The "critical section" naming is also a little archaic.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks. Will include in next update.
| LOCK(cs_relevant_blocks); | ||
| ret.pushKV("relevant_blocks", std::move(relevant_blocks)); | ||
| ret.pushKV("completed", completed); | ||
| reserver.release(); // ensure this is before cs_relevant_blocks is released, so status doesn't try to use moved relevant_blocks |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In commit "rpc: add relevant_blocks to scanblocks status" (4c9dc4b)
Think this is missing a word, suggest "ensure this is called before"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will include
| } else if (request.params[0].get_str() == "start") { | ||
| { | ||
| LOCK(cs_relevant_blocks); | ||
| relevant_blocks = UniValue(UniValue::VARR); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In commit "rpc: add relevant_blocks to scanblocks status" (4c9dc4b)
Clearing relevant_blocks before checking g_scanfilter_in_progress seems not very nice, because it means if scanblocks start is called while another scan is in progress, instead of just returning an "already in progress" error, it will do that but also partially erase the state of the in-progress scan.
This behavior is not just a limitation of the new feature, but also a regression, because it messes up the "relevant_blocks" return value of the other RPC call when previously it would be accurate.
I think it should be straightforward to fix this by moving this new code below the reserve() call below.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch. Verified locally that truncation occurs. Fixed for next update.
| UniValue ret(UniValue::VOBJ); | ||
| if (request.params[0].get_str() == "status") { | ||
| BlockFiltersScanReserver reserver; | ||
| LOCK(cs_relevant_blocks); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In commit "rpc: add relevant_blocks to scanblocks status" (4c9dc4b)
Lock order here seems a little subtle. Would be good to have a comment saying it is important to lock this before calling reserve so if a scan is currently happening but is about to finish, an accurate "relevant_blocks" value can be returned before the scanning thread clears it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed. Comment will be added.
revelant_blocks to scanblocks statusrelevant_blocks to scanblocks status
Great idea. Playing around with it locally. Perhaps it could eventually absorb |
|
Will revisit later |
Provides relevant block hashes to status output. Enables a user to start looking through matching blocks without having to wait on scan completion. Co-Authored-By: Luke Dashjr <[email protected]> Github-Pull: bitcoin#30713 Rebased-From: 4c9dc4b
Github-Pull: bitcoin#30713 Rebased-From: 5b2d021
c6eca6f doc: add guidance for RPC to developer notes (tdb3) Pull request description: Adds guidance statements to the RPC interface section of the developer notes with examples of when to implement `-deprecatedrpc=`. Wanted to increase awareness of preferred RPC implementation approaches for newer contributors. This implements some of what's discussed in #29912 (comment) Opinions may differ, so please don't be shy. We want to make RPC as solid/safe as possible. Examples of discussions where guidelines/context might have added value: #30212 (comment) #29845 (comment) #30381 (review) #29954 (comment) #30410 (review) #30713 #30381 #29060 (review) ACKs for top commit: l0rinc: ACK c6eca6f fjahr: ACK c6eca6f maflcko: lgtm ACK c6eca6f jonatack: ACK c6eca6f Tree-SHA512: 01a98a8dc0eb91762b225d3278cdb4a5e380ceb7486fd096b4ad9122bed859cea8584d8996d3dce51272fdb792f4a793a1bd1c5445efeb87f0a30f9b6e59a790
Currently, after starting a scan with
scanblocksthe user must wait until the scan is complete to see the associated/relevant block hashes.This updates the
scanblocks statusresult object to provide therelevant_blocksfound so far.This enables earlier subsequent lookup within matching blocks (e.g. to run
getdescriptoractivityin PR #30708)Below is an example tested on signet by starting and obtaining status of a scan for an address that has received many coinbase outputs (so there are matches over many blocks, showing the increase in
relevant_blocksresults inscanblocks statusover the life of the scan). Also tested on mainnet (see #30713 (review)).or (to show snapshots over time)
-deprecatedrpcseems like overkill for the addition of a key (not a data type change). Release notes have been added (affecting user interface).If testing, be sure to enable the block filter index feature (e.g. adding
blockfilterindex=1to bitcoin.conf), and allow time for the index to build: