-
Notifications
You must be signed in to change notification settings - Fork 11
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
P2P: Improve performance by not serializing and deserializing blocks from block log #785
Conversation
…id() to controller
Note:start |
libraries/chain/block_log.cpp
Outdated
|
||
std::optional<signed_block_header> h = my->read_block_header_by_num(block_num); | ||
if (h) { | ||
auto returd_id = h->calculate_id(); |
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
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.
Still reviewing, but thought I would get these comments out so you know why PR #803 was created.
P2P: Remove dead code
@@ -603,6 +619,46 @@ namespace eosio { namespace chain { | |||
return pos; | |||
} | |||
|
|||
block_pos_size_t get_block_position_and_size(uint32_t block_num) { |
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.
minor detail, I think it might be cleaner to declare the return value in the beginning and use it instead of intermadiate variables, as below, but no need to change:
block_pos_size_t get_block_position_and_size(uint32_t block_num) {
block_pos_size_t bps { .position = get_block_pos(block_num) };
if (bps.position == block_log::npos)
return bps;
assert(head);
uint32_t last_block_num = block_header::num_from_id(head->id);
EOS_ASSERT(block_num <= last_block_num, block_log_exception,
"block_num ${bn} should not be greater than last_block_num ${lbn}",
("bn", block_num)("lbn", last_block_num));
constexpr uint32_t block_pos_size = sizeof(uint64_t); // size of block position field in the block log file
if (block_num < last_block_num) {
// current block is not the last block in the log file.
uint64_t next_block_pos = get_block_pos(block_num + 1);
EOS_ASSERT(next_block_pos > bps.position + block_pos_size, block_log_exception,
"next block position ${np} should be greater than current block position ${p} plus block position field size ${bps}",
("np", next_block_pos)("p", bps.position)("bps", block_pos_size));
bps.size = next_block_pos - bps.position - block_pos_size;
} else {
// current block is the last block in the file.
block_file.seek_end(0);
auto file_size = block_file.tellp();
EOS_ASSERT(file_size > bps.position + block_pos_size, block_log_exception,
"block log file size ${fs} should be greater than current block position ${p} plus block position field size ${bps}",
("fs", file_size)("p", bps.position)("bps", block_pos_size));
bps.size = file_size - bps.position - block_pos_size;
}
return bps;
}
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 constructing return value right before returning makes it easier to see what to be returned.
std::optional<uint64_t> pos = get_block_position(block_num); | ||
|
||
if (!pos) { | ||
return {}; |
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.
Why a std::optional
here to mean not found, while we used
return block_pos_size_t {.position = block_log::npos, .size = 0};
in block_log.cpp:626
?
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.
Was trying to follow existing method patterns in the two files: get_block_position
in log_catalog.hpp
while get_block_pos
in block_log.cpp
returns block_log::npos
.
Currently, when a peer asks for a block, if the block is retrieved from the block log,
net plugin
This can be expensive and add up to considerable CPU, see #611.
Those conversions are not necessary, as the serialization format in block log is the same as on P2P.
This PR adds
read_serialized_block_by_num()
toblock_log
andfetch_serialized_block_by_number()
tocontroller
, and updatesnet plugin
to use the new interface.Resolves #612