-
Notifications
You must be signed in to change notification settings - Fork 3.8k
Conversation
…t a time; all other tests compile and run
for( const auto& receipt : s.block->transactions ) { | ||
if( receipt.trx.contains<packed_transaction>() ) { | ||
auto& pt = receipt.trx.get<packed_transaction>(); | ||
s.trxs.push_back( std::make_shared<transaction_metadata>( std::make_shared<packed_transaction>(pt) ) ); |
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.
Would be nice to have a test that failed before that now works for transactions in fork_db. Maybe this is something @brianjohnson5972 or @taokayan could create.
With the changes here and in #6842, nodeos now supports an irreversible read-mode with the ability to easily switch back and forth between irreversible mode and the other read modes. Switching from speculative mode to irreversible modeShut down nodeos and then restart it with the At startup the nodeos logs should print a warning that looks something like the following:
These warnings will only appear on the first restart that switches from As the warning states, the reversible blocks database is erased. However, those blocks should still exist in the fork database (which is stored in the While in irreversible mode, the current state always reflects the state as of the end of the last irreversible block. This can be confirmed by comparing the Switching from irreversible mode to speculative modeShut down nodeos while it is configured to be in irreversible mode. Then restart nodeos with the At startup the nodeos logs should print a warning that looks something like the following:
Nodeos will recover the best available branch from the fork database and reapply those blocks. Doing so will add those blocks back into the reversible blocks database. It will also bring the current state back into sync with that of the best head block. This can be confirmed by comparing the |
Builds on top of PR #6588.
This PR allows irreversible mode to be enabled. It also fixes some bugs that were only triggered during irreversible mode.
This PR also refactors the fork database code to ensure that blocks that become irreversible are immediately appended to the block log, which resolves issues such as #6409.
This refactor changes the format of the portable serialized fork database file that is stored on exit of nodeos (in addition to the existing changes due to #6588). First, the file is saved as "fork_db.dat" rather than "forkdb.dat" to signal that the format has changed in an important way and also to force a replay which is going to be required anyway for other reasons. This new format has a magic number at the start to help distinguish the file as a serialized fork database file, and more importantly it now has a version number to enable future upgrades to the format without necessarily having to abandon support for reading from the old versions going forward.
The new fork database code distinguishes the best head in the fork tree when only considering fully validated blocks it knows about from the best head in the fork tree when considering all blocks it knows about that have at least passed block header validation; this latter type of head is called the pending head in the fork database code.
In modes other than irreversible mode, pending head and the regular head should be identical except for the brief period of time between adding the block to the fork database and applying it in
maybe_switch_forks
. If the block added to the fork database does not cause any new block to be applied, then the pending head and regular head still remain the same because the pending head would not have changed due to the addition of the block to the fork database (again this is in modes other than irreversible mode).In irreversible mode, the pending head becomes far more relevant. In that mode, the regular head and pending head are expected to be different. In fact, the regular head block should be the irreversible block from the perspective of the pending head, and so it will be an ancestor of the pending head block.
Two new fields are added to the results returned by
get_info
in the chain plugin:fork_db_head_block_num
andfork_db_head_block_id
. These represent the best known head in the fork database tree. The idea is thatget_info
now provides information for three blocks in the blockchain, where two of the three blocks should always be identical in theget_info
response. The three blocks are: the last irreversible block (orlast_irreversible_block
); the best known block in the fork database (known as thefork_db_head_block
); and the block that is tracked by the current consensus state of node (known simply as thehead_block
). In irreversible mode, thehead_block
is equivalent to thelast_irreversible_block
. In all other modes, thehead_block
is equivalent to thefork_db_head_block
.This PR also adds a unit test(
forked_tests/irreversible_mode
) which checks that a node in irreversible mode will properly be following the irreversible block even as two other nodes feed it conflicting blocks which cause it to do fork switches.I have identified further cleanup/refactoring of the code that try to find the appropriate block given a block number, but I am going to hold off on that for the time being so that I can continue making progress with the other features needed for protocol feature foundations.