-
Notifications
You must be signed in to change notification settings - Fork 220
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
fix(core): always pass the correct timestamp window to header validatior #5624
fix(core): always pass the correct timestamp window to header validatior #5624
Conversation
ebab778
to
cc27e92
Compare
6ba4bc2
to
4f2f415
Compare
4f2f415
to
a1ff08e
Compare
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 looks functional, but I what I don't understand reasoning behind the original, and new implementation. So I don't know if the code is correct. 😅
let expected_timestamp_count = cmp::min(consensus_constants.median_timestamp_count() as u64, header.height); | ||
// Empty `timestamps` is never valid | ||
if timestamps.is_empty() { | ||
return Err(ValidationError::IncorrectNumberOfTimestampsProvided { | ||
expected: expected_timestamp_count, | ||
actual: 0, | ||
}); | ||
} | ||
|
||
if timestamps.len() as u64 != expected_timestamp_count { | ||
return Err(ValidationError::IncorrectNumberOfTimestampsProvided { | ||
actual: timestamps.len() as u64, |
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.
This code looks fine.
but tbh I don't really understand it just yet. It looks like we're receiving a slice of timestamps and seeing if the number of timestamps is the same as the median timestamp count. But this slice could contain the same single timestamp repeated and this sanity check passes.
So what I don't yet understand is why we're using this method of counting timestamps as a validation.
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.
Yup the blockchain db code is super hard to reason about. It's not strictly a header validation since the timestamps come from headers previously inserted into the main/orphan chains so the contract we're making in the HeaderChainLinkedValidator
trait is that the caller must provide the correct timestamps. This is why I renamed it to sanity_check because it's more about asserting an invariant we require when calling the validator. The other option is to take it out completely or to panic, but I went with the least risky approach.
00c6fb4
to
ab2f300
Compare
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.
Definite improvement
One comment nit
utACK
Description
fix(core): sanity check for timestamp window length checks for the correct length of the timestamp window
fix(core): always include the correct timestamp window to header validation
tests(core): add a reorg test of greater size than median timestamp window size
chore: remove allocations when logging hashes in blockchain database
Motivation and Context
sanity_check_timestamp_count
(previouslycheck_timestamp_count
) allowed timestamp windows ofmin(median_window_size, header.height - 1)
or greater. However, the window size must always be the correct size for a given block. If it is not, the median timestamp calculation will be incorrect. This check also subtracted 1 from the header height BEFORE checking the height is correct. This would cause a panic/underflow if a header of height 0 is passed in.In the reorg logic, we passed in the same timestamp window for the candidate block when validating orphan chains, this could cause correct reorgs to fail. This PR also ensures that timestamps are sorted as this is required for a correct median calculation.
How Has This Been Tested?
Adds a new unit test
it_does_a_sanity_check_on_the_number_of_timestamps_provided
Adds block chain unit test
it_links_many_orphan_branches_to_main_chain_with_greater_reorg_than_median_timestamp_window
Existing test
it_links_many_orphan_branches_to_main_chain
failed after the fix tocheck_timestamp_count
. Fixed in this PRManually caused a about 90 block reorg on localnet nodes
What process can a PR reviewer use to test or verify this change?
Create a reorg using localnet
Breaking Changes