[1.0-beta3] avoid unnecessary state history log "unrotations" that can remove retained logs on replay/resync #298
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
In the early days, ship would truncate its log any time the applied block number was less than the log's head block. But this could lead to substantial chunks of the log being removed in the case of a replay or resync (such as when restarting from a snapshot).1
So instead, sometime in leap, the log behavior was modified such that when the applied block number decreases relative to the head of the log, the log would check if the blockid in the log matched that as the new applied block. If it matched, it'd do nothing, since that is indicative of a replay or resync. If it did not match, the log would be truncated as before, since that is indicative of a new fork being applied.
The log rewrite in spring 1.0 maintains this strategy. However, the blockid duplication check is performed in the
log
, not thelog_catalog
. This means for a partitioned log where a block is being applied in a retained log thelog_catalog
would always unrotate any higher numbered logs before figuring out it doesn't need to "truncate" (append now in spring1) the log.So, add a duplication check in
log_catalog
too to guard against this. And add a handful of tests that are in the same ballpark as replay/resync (writing identical blocks to the log again).(it is a little uneasy to see some code duplication in
log
andlog_catalog
. The original idea was thatlog
andlog_catalog
would share the same public interface such that if nodeos was configured without log splitting it could simply uselog
directly -- maybe via some template even since the interface would completely match up. This commonality of interface still remains:pack_and_write_entry()
,get_entry()
,get_block_id()
,block_range()
, andempty()
all have an identical interface between the two. But there was nothing ever attempted to strictly uselog
if that's all that is required)Footnotes
There also could be disastrous consequences if accidentally restarting from genesis that would erase the entire log. That is guarded against differently than what is further discussed here. ↩