-
Notifications
You must be signed in to change notification settings - Fork 37.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
std::vector<uint8_t> data{}; | ||
FlatFilePos pos{}; | ||
{ | ||
LOCK(cs_main); | ||
if (blockman.IsBlockPruned(blockindex)) { | ||
throw JSONRPCError(RPC_MISC_ERROR, "Block not available (pruned data)"); | ||
} | ||
pos = blockindex.GetBlockPos(); | ||
} |
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! |
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 4fc91b3
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 4fc91b3
ACK 4fc91b3 |
src/node/blockstorage.cpp
Outdated
// If nPos is less than 8 the pos is null and we don't have the block data | ||
// Return early to prevent undefined behavior of unsigned int underflow | ||
if (hpos.nPos < 8) { | ||
return error("%s: OpenBlockFile failed for %s", __func__, pos.ToString()); |
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 3f086a9 "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
getblock
endpoint withverbosity=0
, therest_block
REST endpoint forbin
andhex
, and zmqNotifyBlock
we don't have to deserialize the block since we're just sending the raw data. This PR usesReadRawBlockFromDisk
instead ofReadBlockFromDisk
to serve these requests, and only deserializes forverbosity > 0
andjson
REST requests. See benchmarks in #26684.Benchmarked using ApacheBench. Requesting block 750,000 in binary 10k times on a single core (set
-rest=1
in 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