-
Notifications
You must be signed in to change notification settings - Fork 984
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
Add get_checkpoint_block to the fork choice spec #3308
Conversation
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.
looks good just from a refactor perspective and I like the increased semantic content
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.
It looks like a nice-to-have to me. No strong opinion here.
/cc @adiasg
Some CircleCI didn't start with the latest commit. It may need a kick with a new commit. 😬
@@ -506,7 +516,7 @@ def on_block(store: Store, signed_block: SignedBeaconBlock) -> None: | |||
finalized_slot = compute_start_slot_at_epoch(store.finalized_checkpoint.epoch) | |||
assert block.slot > finalized_slot | |||
# Check block is a descendant of the finalized block at the checkpoint finalized slot | |||
assert get_ancestor(store, block.parent_root, finalized_slot) == store.finalized_checkpoint.root |
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.
it seems no need to modify this one
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.
@hwwhww Why do you think that there may be no need to modify this one?
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.
because we need to define the variable finalized_slot
to check assert block.slot > finalized_slot
anyway, the change of this change doesn't simplify much here.
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.
The objective of this PR is not so much about simplifying the code, but rather making explicit when we are computing an epoch boundary block.
For example, in this line, we are not only checking that store.finalized_checkpoint.root
is an ancestor of block.parent_root
, but also that store.finalized_checkpoint.root
is an epoch boundary block in the chain of block.parent_root
, which I don't think that it is immediate in the original code.
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.
But the difference between checking whether a block is just an ancestor or it is also an epoch boundary block is significant when performing security analysis on the code.
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.
You need to change the corresponding files in different forks that changed on_block
, eg. Bellatrix
👍 |
Please change the p2p network specs as well.
|
We should also update the pyspec correspondingly, if we want to apply this patch. For example, in finalized_slot = spec.compute_start_slot_at_epoch(store.finalized_checkpoint.epoch)
ancestor_at_finalized_slot = spec.get_ancestor(store, pre_store_justified_checkpoint_root, finalized_slot) Please run |
specs/deneb/fork-choice.md
Outdated
assert store.finalized_checkpoint.root == get_ancestor_at_epoch_boundary( | ||
store, | ||
block.parent_root, | ||
store.finalized_checkpoint.epoch, | ||
) |
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.
Doing an assignment before the assert is preferable to reduce line count and increase readability. ditto at a few other places in this patch
assert store.finalized_checkpoint.root == get_ancestor_at_epoch_boundary( | |
store, | |
block.parent_root, | |
store.finalized_checkpoint.epoch, | |
) | |
epoch_boundary_root = get_ancestor_at_epoch_boundary(store, block.parent_root, store.finalized_checkpoint.epoch) | |
assert store.finalized_checkpoint.root == epoch_boundary_root |
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.
Done here in all other places marked with "ditto"
specs/bellatrix/fork-choice.md
Outdated
@@ -170,7 +170,11 @@ def on_block(store: Store, signed_block: SignedBeaconBlock) -> None: | |||
finalized_slot = compute_start_slot_at_epoch(store.finalized_checkpoint.epoch) | |||
assert block.slot > finalized_slot | |||
# Check block is a descendant of the finalized block at the checkpoint finalized slot | |||
assert get_ancestor(store, block.parent_root, finalized_slot) == store.finalized_checkpoint.root | |||
assert store.finalized_checkpoint.root == get_ancestor_at_epoch_boundary( |
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.
ditto
specs/phase0/fork-choice.md
Outdated
correct_finalized = ( | ||
store.finalized_checkpoint.epoch == GENESIS_EPOCH | ||
or store.finalized_checkpoint.root == get_ancestor(store, block_root, finalized_slot) | ||
or store.finalized_checkpoint.root == get_ancestor_at_epoch_boundary( |
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.
ditto
specs/phase0/fork-choice.md
Outdated
@@ -506,7 +520,11 @@ def on_block(store: Store, signed_block: SignedBeaconBlock) -> None: | |||
finalized_slot = compute_start_slot_at_epoch(store.finalized_checkpoint.epoch) | |||
assert block.slot > finalized_slot | |||
# Check block is a descendant of the finalized block at the checkpoint finalized slot | |||
assert get_ancestor(store, block.parent_root, finalized_slot) == store.finalized_checkpoint.root | |||
assert store.finalized_checkpoint.root == get_ancestor_at_epoch_boundary( |
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.
ditto
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.
The fork choice & p2p spec do not refer to epoch boundary blocks before this PR. More generally, the spec refers to epoch boundary blocks as part of Checkpoint
s.
I'd prefer to avoid introducing the "epoch boundary block" nomenclature here, and instead rename get_ancestor_at_epoch_boundary
to get_checkpoint_block
.
|
Done |
Done |
This PR introduces the function
get_checkpoint_block
and replaces any computation of checkpoint blocks in the fork choice spec with a call to the newly introduced function.The objective of this PR is to increase the readability of the spec by better clarifying when we are interested in calculating an checkpoint block.