Skip to content

Conversation

@kdafriend
Copy link

The objective of this PR is to make a standardized and homogeneous way to manage forks and rules by Height, and fork numbers.

The object ForkHeight as been extended to manage fork numbers as well.
Compare rules have been moved to the data definition from the predicates (after, atOrAfter, ...).

The same object can now be used for Rules definition too.

A new checkFork' function has been added to manage forks by numbers, while the old checkFork function still manages forks by heights.

Postulate: starting with fork number 1, no forks or rules change will use heights anymore.

Note : upgrades don't support fork numbers for now, as it requires a more complex mechanism.

Copy link

@edmundnoble edmundnoble left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall this seems to be an excellent idea that extends the existing machinery in a good way.

Comment on lines +365 to +368
succByHeight (ForkAtBlockHeight x) = ForkAtBlockHeight $ succ x
succByHeight ForkNever = ForkNever
succByHeight _ = error "Only a Blockheight defined fork can be succ'ed"

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note to self: This being somewhat hacky is expected because the mechanism it's working on is also somewhat hacky. In future, ForkNumber-based forks will make the definition of e.g. MaxBlockGasLimit much cleaner regardless.

kdafriend and others added 2 commits January 6, 2026 18:43
Co-authored-by: Edmund Noble <edmundnoble@users.noreply.github.com>
@edmundnoble
Copy link

There's one more thing I'd like: I'd like you to add an assertion to validateVersion that no rule has entries for a block height higher than the chainweb 3.1 fork height, if it has a fork height for chainweb 3.1.

@kdafriend
Copy link
Author

There's one more thing I'd like: I'd like you to add an assertion to validateVersion that no rule has entries for a block height higher than the chainweb 3.1 fork height, if it has a fork height for chainweb 3.1.

Yes 100% agree

case minimumBlockHeaderHistory cwVersion latestHeader of
-- Note, this behaviour may be dangerous in case of changes on the miniumum block history.
--
-- TODO = Option to prune headers history to the minimum should be enabled by flag.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd rather have a TODO for renaming the current minimumBlockHeaderHistory to versionSpvProofRootValidWindow and adding a new minimumBlockHeaderHistory which is set to Nothing (i.e. all history) for all existing versions for this to use.

chainweb219Pact' = guardCtx chainweb219Pact txCtx
chainweb223Pact' = guardCtx chainweb223Pact txCtx
allVerifiers = verifiersAt v cid currHeight
allVerifiers = verifiersAt v cid pact4ForkNumber currHeight

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is fine with me, using ctxParentForkNumber here would also have been fine.

Comment on lines +81 to +90
validateNoHeightAfterChainweb31' :: ChainwebVersion -> ForkHeight -> Either String ()
validateNoHeightAfterChainweb31' v fh =
case (fork31Height, fh) of
(Just (ForkAtBlockHeight refAth), ForkAtBlockHeight ath) ->
if ath > (refAth + 1)
then Left ("validateVersion: Forking rule must only defined by Fork numbers after Chainweb31: " ++ show ath ++ " > " ++ show refAth)
else Right ()
_ -> Right ()
where
fork31Height = v ^? versionForks . at Chainweb31 . _Just . atChain (unsafeChainId 0)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This needs to work properly if Chainweb31Fork is activated at genesis as well so here's a more pithy version that handles that:

Suggested change
validateNoHeightAfterChainweb31' :: ChainwebVersion -> ForkHeight -> Either String ()
validateNoHeightAfterChainweb31' v fh =
case (fork31Height, fh) of
(Just (ForkAtBlockHeight refAth), ForkAtBlockHeight ath) ->
if ath > (refAth + 1)
then Left ("validateVersion: Forking rule must only defined by Fork numbers after Chainweb31: " ++ show ath ++ " > " ++ show refAth)
else Right ()
_ -> Right ()
where
fork31Height = v ^? versionForks . at Chainweb31 . _Just . atChain (unsafeChainId 0)
validateNoBlockHeightForkAfterChainweb31' :: ChainwebVersion -> ForkHeight -> Either String ()
validateNoBlockHeightForkAfterChainweb31' v fh =
if fh `atOrAfter` fork31Height
then Left $ "validateVersion: Forking rule must only defined by Fork numbers after Chainweb31: " ++ show ath ++ " > " ++ show refAth
else Right ()
where
fork31Height = v ^? versionForks . at Chainweb31 . _Just . atChain (unsafeChainId 0)


-- We consider the following ordering for Forks:
-- - ForkAtGenesis
-- - ForkNumber = 0 (unusual case)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a good point. Please make ForkNumber 0 illegal for forks in validateVersion. I don't mind if this is in a followup PR.

Co-authored-by: Edmund Noble <edmundnoble@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants