-
Notifications
You must be signed in to change notification settings - Fork 38.7k
rpc,rest,zmq: faster getblock, NotifyBlock and rest_block by reading raw block #26415
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
1b62435 to
e58dcb3
Compare
4986d7a to
01999de
Compare
|
The following sections might be updated with supplementary metadata relevant to reviewers and maintainers. Code CoverageFor detailed information about the code coverage, see the test coverage report. 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. |
01999de to
d045ccf
Compare
1ea00e8 to
3e5aebf
Compare
3e5aebf to
e064571
Compare
e064571 to
e830c1f
Compare
129e7e8 to
3d7ae60
Compare
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.
As we only care about the data existence here, what about doing a more general check:
if (!(blockindex.nStatus & BLOCK_HAVE_DATA)) {
throw JSONRPCError(RPC_MISC_ERROR, "Block not available");
}(Unless you want to keep the same error message as 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.
I think this check is specifically done to see if the block is pruned, hence the error message (pruned data). This is taken verbatim from the above function, GetBlockChecked, which all it does inside the locked block is check if it is pruned or not. Here we also extract the FlatFilePos. However, if blockindex.nStatus & BLOCK_HAVE_DATA is false then the call to ReadRawBlockFromDisk will fail and throw the message Block not available. The first commit addresses the undefined behavior part of calling ReadRawBlockFromDisk with a null FlatFilePos, which is safe to do now.
3d7ae60 to
4fc91b3
Compare
|
@furszy @TheCharlatan updated with both your suggestions, thanks! |
furszy
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.
Code ACK 4fc91b38
sedited
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.
Re-ACK 4fc91b38ae8c715e0ebf9abcb6da17044fe418b3
|
ACK 4fc91b38ae8c715e0ebf9abcb6da17044fe418b3 |
src/node/blockstorage.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.
In 3f086a9353191a5df03aa595bdbb42c2195a23d2 "blockstorage: check nPos in ReadRawBlockFromDisk before seeking back"
Silent merge conflict here:
../../../src/node/blockstorage.cpp: In member function ‘bool node::BlockManager::ReadRawBlockFromDisk(std::vector<unsigned char>&, const FlatFilePos&) const’:
../../../src/node/blockstorage.cpp:1094:16: error: ‘error’ was not declared in this scope; did you mean ‘perror’?
1094 | return error("%s: OpenBlockFile failed for %s", __func__, pos.ToString());
| ^~~~~
| perror
error() was removed in #29236
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.
@achow101 resolved, thanks.
4fc91b3 to
39bb816
Compare
ReadRawBlockFromDisk assumes a non-null pos that has an nPos >= 8. This simple check makes the function safer to call in the future, so callers don't need to worry about causing UB if the pos is null.
Note that for speed this commit also removes the proof of work and signet signature checks before returning the block in getblock. It is assumed if a block is stored it will be valid.
Note that for speed this commit also removes the proof of work and signet signature checks before returning the block in getblock. It is assumed if a block is stored it will be valid.
39bb816 to
e710cef
Compare
|
re-ACK e710cef Verified rebase diff. |
ReadRawBlockFromDisk assumes a non-null pos that has an nPos >= 8. This simple check makes the function safer to call in the future, so callers don't need to worry about causing UB if the pos is null. Github-Pull: bitcoin#26415 Rebased-From: da338aa
Github-Pull: bitcoin#26415 Rebased-From: 38265cc
Github-Pull: bitcoin#26415 Rebased-From: 0865ab8
Note that for speed this commit also removes the proof of work and signet signature checks before returning the block in getblock. It is assumed if a block is stored it will be valid. Github-Pull: bitcoin#26415 Rebased-From: 95ce078
Note that for speed this commit also removes the proof of work and signet signature checks before returning the block in getblock. It is assumed if a block is stored it will be valid. Github-Pull: bitcoin#26415 Rebased-From: e710cef
For the
getblockendpoint withverbosity=0, therest_blockREST endpoint forbinandhex, and zmqNotifyBlockwe don't have to deserialize the block since we're just sending the raw data. This PR usesReadRawBlockFromDiskinstead ofReadBlockFromDiskto serve these requests, and only deserializes forverbosity > 0andjsonREST requests. See benchmarks in #26684.Benchmarked using ApacheBench. Requesting block 750,000 in binary 10k times on a single core (set
-rest=1in config):ab -n 10000 -c 1 "http://127.0.0.1:8332/rest/block/0000000000000000000592a974b1b9f087cb77628bb4a097d5c2c11b3476a58e.bin"On master, mean time 15ms.
On this branch, mean time 1ms.
For RPC
On master, mean time 32ms
On this branch, mean time 13ms