-
Notifications
You must be signed in to change notification settings - Fork 25
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
Prototype lightweight checkpointing (non-combinator approach) #453
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.
First impressions
ouroboros-consensus-cardano/src/byron/Ouroboros/Consensus/Byron/Ledger/HeaderValidation.hs
Outdated
Show resolved
Hide resolved
@@ -297,6 +297,7 @@ protocolInfoTPraosShelleyBased ProtocolParamsShelleyBased { | |||
protVer | |||
genesis | |||
(shelleyBlockIssuerVKey <$> credentialss) | |||
mempty -- TODO propagate? |
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.
What's the hypothesis for why we wouldn't need to propagate?
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 function isn't ever called by protocolInfoCardano
(which is the only place actually interesting to us), so I just did the lazy thing and didn't propagate it further for this prototype PR.
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.
I would consider addressing this if necessary for testing.
ouroboros-consensus-cardano/src/shelley/Ouroboros/Consensus/Shelley/Protocol/Praos.hs
Outdated
Show resolved
Hide resolved
unless (m <= maxpv) $ throwError (ObsoleteNode m maxpv) | ||
unless (fromIntegral (bhviewHSize bhv) <= maxHeaderSize) $ | ||
throwError $ | ||
HeaderSizeTooLarge (fromIntegral $ bhviewHSize bhv) maxHeaderSize | ||
unless (bhviewBSize bhv <= maxBodySize) $ | ||
throwError $ | ||
BlockSizeTooLarge (bhviewBSize bhv) maxBodySize | ||
whenJust (Map.lookup (pHeaderBlock hdr) checkpoints) $ \checkpoint -> | ||
unless (checkpoint == pHeaderHash hdr) $ |
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.
same comment as other guard
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.
Yeah, I am always paralyzed by the choice between when
and unless
... I used unless
here as it is also used in all preceeding checks (even though it would be easy to rewrite these places from eg unless (m <= maxpv)
to when (m > maxpv)
), and then also used it in all other additionalEnvelopeChecks
for consistency.
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.
Switched unless to when in 7ca4c63
ouroboros-consensus-cardano/src/shelley/Ouroboros/Consensus/Shelley/Protocol/TPraos.hs
Outdated
Show resolved
Hide resolved
ouroboros-consensus-cardano/src/shelley/Ouroboros/Consensus/Shelley/Protocol/TPraos.hs
Outdated
Show resolved
Hide resolved
cbc3877
to
e88f6c2
Compare
...consensus-cardano/changelog.d/20240111_195320_facundo.dominguez_lightweight_checkpointing.md
Show resolved
Hide resolved
d2507b5
to
eb1740f
Compare
The plan now is to rearrange the PR so validateIfCheckpoint :: TopLevelConfig blk -> Header blk -> Except (HeaderEnvelopeError blk) () This has the advantage of only needing to call the validation code at one place for ALL types of blocks. This in turn requires getting the map of checkpoints at this point in the code. This can be done by adding the map as a method to the class class ... => ValidateEnvelope blk where
...
-- | Checkpoints to validate. See 'validateIfCheckpoint'.
checkpoints :: TopLevelConfig blk -> Map BlockNo (HeaderHash blk) I wouldn't use a default method for this. It is better to signal to authors of instances that they need to define this method if they care about checkpointing, and they can easily return the empty map when they don't care. Then the instances of As testing plan, we would only test |
I suggest we take the "universality"-based approach even farther, and simply add a field ouroboros-consensus/ouroboros-consensus/src/ouroboros-consensus/Ouroboros/Consensus/Config.hs Lines 38 to 45 in 982eff4
|
Just ensured that there are no roadblocks for this approach: #898 (diff could get much smaller with a compat layer/pattern synonym, but also not really necessary). For completeness: A (we think relatively minor) disadvantage of #898 is that it adds checkpointing as a built-in concept to the abstract Consensus layer, despite this not being strictly necessary. (It is of course always possible to not do checkpointing by simply not providing any checkpoints.) A small subtlety I noticed: In the HFC, we often create |
I'm not seeing the "in the HFC" aspect of this in the PR 898 diff. I see
Does that imply that it's harmless for the per-era configs to have an empty checkpoints field? Since our intended semantics is for the checkpoints field to only affect |
It happens here: Lines 199 to 211 in 982eff4
mkTopLevelConfig is touched in #898 and currently always uses mempty (just was the most direct thing to get things to compile).
Yes, that is exactly right 👍 (Theoretically, some concrete block could of course depend on them in some non-trivial way in eg |
eb1740f
to
d83a3a9
Compare
Superseded by #898 |
Lightweight checkpointing is a mechanism to ensure that new nodes end up in the correct chain even when the chain is too sparse for normal operation of Praos and Genesis. The idea is to supply the new node with a list of block hashes that should be present on the chain at specific block numbers. This list is provided in the TopLevelConfig record, and it is used during validation of headers in validateIfCheckpoint called by validateEnvelope. If the hashes of checkpoints don't match the hashes of a supplied header for a given block number, then validation of the header fails. The substance of the change is modifying TopLevelConfig and validateEnvelope. Most other changes derive from these modifications. There are three new unit tests of validateIfCheckpoint added in ouroboros-consensus:test:consensus-test. Implements #453 (comment)
Prototype of lightweight checkpointing, see #448
To be merged, this would need more polish (Haddocks, addressing the inline TODOs) and tests.
Notably, this PR adds a new field to
ProtocolParams (CardanoBlock c)
:with the semantics described in #447 (comment).
Note that this is not the approach described in #447 (comment); the approach of this PR is likely less invasive/has a smaller diff, but less elegant than the combinator-based appraoch.