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
multi: Rework old fork rejection logic. #2945
multi: Rework old fork rejection logic. #2945
Conversation
67a452e
to
ca75fea
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.
This looks great. It's nice to consolidate this logic and not deal with both checkpoints and assume valid separately. I also think referring to the concept as allowing old forks is more self-explanatory than calling it checkpoints.
I don't see any logic issues and ran a few full syncs on mainnet
without issue with various combinations of --allowoldforks
and --assumevalid
options.
// Calculate the expected number of blocks in 2 weeks and cache it in order | ||
// to avoid repeated calculation. | ||
const timeInTwoWeeks = time.Hour * 24 * 14 | ||
expectedBlksInTwoWeeks := int64(timeInTwoWeeks / params.TargetTimePerBlock) |
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.
Nice, good call to cache this.
1c50347
to
e01c1fc
Compare
e01c1fc
to
185df25
Compare
This utility is no longer be necessary since the manual checkpoint logic is being reworked in upcoming commits.
This adds a new field to the blockchain instance to store a cached version of the number of expected blocks in two weeks to avoid repeated calculation.
Historically, checkpoints have been manually specified and used both for various optimizations and to protect against cheap DoS attacks by rejecting forks deep in history. The primary motivation for manually specifying the checkpoints was said optimizations, however, those optimization portions have now been decoupled from checkpoints in favor of other methods, so the only remaining use of checkpoints is the aforementioned rejection of forks deep in history. Thus, this reworks the old fork rejection logic to make it automatic based on an ancestor that is two weeks worth of blocks behind the hard-coded assumevalid block (clamped to the genesis block if necessary) that is manually specified at each release as opposed to needing to additionally manually specify checkpoints. Note the distinction here between the hard-coded assumevalid block specified at each release and the potentially overridden value specified by a user via CLI configuration options. This is an important distinction because old fork rejection affects consensus and thus must not move around based on user configuration. This approach means the user can still specify a more recent assume valid hash or disable assume valid optimizations independently without affecting the consensus logic while still removing the need to manually specify additional checkpoints. The following is a high level overview of the changes: - Modifies the blockchain.Config struct as follows: - Removes the LastestCheckpoint option - Adds a AllowOldForks option - Removes all code related to manually specified checkpoints and finding candidates - Removes the following errors since they are no longer used: - ErrBadCheckpoint - ErrCheckpointTimeTooOld - Renames checkpointNode to rejectForksCheckpoint to make it clear that is the only thing it applies to - Adds logic to potentially reject forks deep in history as follows: - Do not reject old forks if they are manually allowed or the hard-coded assumevalid block is not specified for the network - Automatically choose an ancestor that is two weeks worth of blocks prior to the hard-coded assumevalid block (clamped to the genesis block if necessary) - Replaces --nocheckpoints CLI option with --allowoldforks - Updates doc.go to match the changes to the CLI options
This method is no longer used since manual checkpoints no longer exist.
This deprecates the Checkpoints field of the chain parameters and removes all manually-specified entries for all networks since manual checkpoints no longer exist.
185df25
to
55ac703
Compare
This requires #2942 and #2943.Historically, checkpoints have been manually specified and used both for various optimizations and to protect against cheap DoS attacks by rejecting forks deep in history. The primary motivation for manually specifying the checkpoints was said optimizations, however, those optimization portions have now been decoupled from checkpoints in favor of other methods, so the only remaining use of checkpoints is the aforementioned rejection of forks deep in history.
Thus, this reworks the old fork rejection logic to make it automatic based on an ancestor that is two weeks worth of blocks behind the hard-coded
assumevalid
block (clamped to the genesis block if necessary) that is manually specified at each release as opposed to needing to additionally manually specify checkpoints.Note the distinction here between the hard-coded
assumevalid
block specified at each release and the potentially overridden value specified by a user via CLI configuration options. This is an important distinction because old fork rejection affects consensus and thus must not move around based on user configuration.This approach means the user can still specify a more recent assume valid hash or disable assume valid optimizations independently without affecting the consensus logic while still removing the need to manually specify additional checkpoints.
The changes have been split into multiple commits to help ease review.
The following is a high level overview of the changes:
findcheckpoints
utilityblockchain.Config
struct as follows:LastestCheckpoint
optionAllowOldForks
optionErrBadCheckpoint
ErrCheckpointTimeTooOld
checkpointNode
torejectForksCheckpoint
to make it clear that is the only thing it applies toassumevalid
block is not specified for the networkassumevalid
block (clamped to the genesis block if necessary)--nocheckpoints
CLI option with--allowoldforks
doc.go
to match the changes to the CLI optionschaincfg.LatestCheckpointHeight
chaincfg.Checkpoints
chaincfg.Checkpoints
entries since they are no longer used