Skip to content

Commit 4d51b78

Browse files
authored
Merge pull request #20 from kda-community/manage_fork_numbers
Extend ForkHeight to manage Fork numbers
2 parents 968588b + 52c1a46 commit 4d51b78

20 files changed

Lines changed: 182 additions & 66 deletions

File tree

src/Chainweb/BlockHeaderDB/HeaderOracle.hs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,14 +29,14 @@ module Chainweb.BlockHeaderDB.HeaderOracle
2929
where
3030

3131
import Chainweb.BlockHash (BlockHash)
32-
import Chainweb.BlockHeader (BlockHeader, blockHash, blockHeight, genesisBlockHeader)
32+
import Chainweb.BlockHeader (BlockHeader, blockHash, blockHeight, blockForkNumber, genesisBlockHeader)
3333
import Chainweb.BlockHeaderDB (BlockHeaderDb)
3434
import Chainweb.TreeDB (seekAncestor)
3535
import Chainweb.TreeDB qualified as TreeDB
3636
import Chainweb.Version (_chainwebVersion)
3737
import Chainweb.Version.Guards (minimumBlockHeaderHistory)
3838
import Control.Exception (Exception(..), throwIO)
39-
import Control.Lens (view)
39+
import Control.Lens
4040
import Numeric.Natural (Natural)
4141

4242
-- | A 'HeaderOracle' is a 'BlockHeaderDb' with a lower and upper bound, and the only
@@ -52,7 +52,7 @@ data HeaderOracle = HeaderOracle
5252
-- The lower bound of the oracle is determined by the 'spvProofExpirationWindow'.
5353
createSpv :: BlockHeaderDb -> BlockHeader -> IO HeaderOracle
5454
createSpv db upperBound = do
55-
let mWindow = minimumBlockHeaderHistory (_chainwebVersion upperBound) (view blockHeight upperBound)
55+
let mWindow = minimumBlockHeaderHistory (_chainwebVersion upperBound) (upperBound ^. blockForkNumber) (upperBound ^. blockHeight)
5656
let gh = genesisBlockHeader (_chainwebVersion upperBound) upperBound
5757
let defaultOracle = create db gh upperBound
5858

src/Chainweb/Chainweb.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -401,7 +401,7 @@ withChainwebInternal conf logger peer serviceSock rocksDb pactDbDir backupDir re
401401
(\cid x -> do
402402
let mcfg = validatingMempoolConfig cid v (_configBlockGasLimit conf) (_configMinGasPrice conf)
403403
-- NOTE: the gas limit may be set based on block height in future, so this approach may not be valid.
404-
let maxGasLimit = fromIntegral <$> maxBlockGasLimit v maxBound
404+
let maxGasLimit = fromIntegral <$> maxBlockGasLimit v maxBound maxBound
405405
case maxGasLimit of
406406
Just maxGasLimit'
407407
| _configBlockGasLimit conf > maxGasLimit' ->

src/Chainweb/Chainweb/Configuration.hs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -605,10 +605,12 @@ parseVersion = constructVersion
605605
maybe (_versionUpgrades winningVersion) (\fub' ->
606606
OnChains $ HM.mapWithKey
607607
(\cid _ ->
608-
case winningVersion ^?! versionForks . at fub' . _Just . atChain cid of
608+
let currentUpgrades = winningVersion ^?! versionUpgrades . atChain cid
609+
in case winningVersion ^?! versionForks . at fub' . _Just . atChain cid of
609610
ForkNever -> error "Chainweb.Chainweb.Configuration.parseVersion: the fork upper bound never occurs in this version."
610-
ForkAtBlockHeight fubHeight -> HM.filterWithKey (\bh _ -> bh <= fubHeight) (winningVersion ^?! versionUpgrades . atChain cid)
611+
ForkAtBlockHeight fubHeight -> HM.filterWithKey (\bh _ -> bh <= fubHeight) currentUpgrades
611612
ForkAtGenesis -> winningVersion ^?! versionUpgrades . atChain cid
613+
ForkAtForkNumber _ -> currentUpgrades -- For now, version upgrades were only allowed at block heights
612614
)
613615
(HS.toMap (chainIds winningVersion))
614616
) fub

src/Chainweb/ForkState.hs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ module Chainweb.ForkState
2525
-- * Fork Number
2626
, ForkNumber(..)
2727
, forkNumber
28+
, pact4ForkNumber
2829

2930
-- * Fork Votes
3031
, ForkVotes(..)
@@ -132,6 +133,11 @@ forkNumber = lens _forkNumber $ \(ForkState w) v -> ForkState
132133
$ (w .&. 0xFFFFFFFF00000000)
133134
.|. (fromIntegral v .&. 0xFFFFFFFF)
134135

136+
137+
-- Pact4 -> Pact5 transition happened during ForkNumber=0 era.
138+
pact4ForkNumber :: ForkNumber
139+
pact4ForkNumber = 0
140+
135141
-- ---------------------------------------------------------------------------
136142
-- Fork Votes
137143

src/Chainweb/Pact/Backend/Compaction.hs

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ import "yet-another-logger" System.Logger hiding (Logger)
6868
import "yet-another-logger" System.Logger qualified as YAL
6969
import "yet-another-logger" System.Logger.Backend.ColorOption (useColor)
7070
import Chainweb.BlockHash
71-
import Chainweb.BlockHeader (blockHeight, blockHash, blockPayloadHash)
71+
import Chainweb.BlockHeader (blockHeight, blockForkNumber, blockHash, blockPayloadHash)
7272
import Chainweb.BlockHeaderDB.Internal (BlockHeaderDb(..), RankedBlockHeader(..))
7373
import Chainweb.BlockHeight (BlockHeight(..))
7474
import Chainweb.Cut.CutHashes (cutIdToText)
@@ -762,7 +762,7 @@ doCompactRocksDb logger cwVersion cids minBlockHeight srcDb targetDb = do
762762
iterLast it
763763
iterValue it >>= \case
764764
Nothing -> exitLog logger "Missing final payload. This is likely due to a corrupted database."
765-
Just rbh -> pure (_getRankedBlockHeader rbh ^. blockHeight)
765+
Just rbh -> pure $ _getRankedBlockHeader rbh
766766

767767
-- The header that we start at depends on whether or not
768768
-- we have a minimal block header history window.
@@ -772,7 +772,10 @@ doCompactRocksDb logger cwVersion cids minBlockHeight srcDb targetDb = do
772772
--
773773
-- On new enough chainweb versions, we want to only copy over
774774
-- the minimal number of block headers.
775-
case minimumBlockHeaderHistory cwVersion latestHeader of
775+
-- Note, this behaviour may be dangerous in case of changes on the minimum block history.
776+
--
777+
-- TODO = Option to prune headers history to the minimum should be enabled by flag.
778+
case minimumBlockHeaderHistory cwVersion (latestHeader ^. blockForkNumber) (latestHeader ^. blockHeight) of
776779
-- Go to the earliest possible entry. We migrate all BlockHeaders, for now.
777780
-- They are needed for SPV.
778781
--
@@ -791,16 +794,18 @@ doCompactRocksDb logger cwVersion cids minBlockHeight srcDb targetDb = do
791794
earliestHeader <- do
792795
iterValue it >>= \case
793796
Nothing -> exitLog logger "Missing first payload. This is likely due to a corrupted database."
794-
Just rbh -> pure (_getRankedBlockHeader rbh ^. blockHeight)
797+
Just rbh -> pure $ _getRankedBlockHeader rbh
795798

796799
-- Ensure that we log progress 100 times per chain
797800
-- I just made this number up as something that felt somewhat sensible
798-
let offset = (latestHeader - earliestHeader) `div` 100
799-
let headerProgressPoints = [earliestHeader + i * offset | i <- [1..100]]
801+
let latestHeight = latestHeader ^. blockHeight
802+
earliestHeight = earliestHeader ^. blockHeight
803+
offset = (latestHeight - earliestHeight) `div` 100
804+
let headerProgressPoints = [earliestHeight + i * offset | i <- [1..100]]
800805

801806
let logHeaderProgress bHeight = do
802807
when (bHeight `elem` headerProgressPoints) $ do
803-
let percentDone = sshow $ 100 * fromIntegral @_ @Double (bHeight - earliestHeader) / fromIntegral @_ @Double (latestHeader - earliestHeader)
808+
let percentDone = sshow $ 100 * fromIntegral @_ @Double (bHeight - earliestHeight) / fromIntegral @_ @Double (latestHeight - earliestHeight)
804809
log' LL.Info $ percentDone <> "% done."
805810

806811
let go = do

src/Chainweb/Pact/PactService/Pact4/ExecBlock.hs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ import Chainweb.Payload.PayloadStore
9595
import Chainweb.Time
9696
import Chainweb.Utils hiding (check)
9797
import Chainweb.Version
98+
import Chainweb.ForkState (pact4ForkNumber)
9899
import Chainweb.Version.Guards
99100
import Chainweb.Pact4.Backend.ChainwebPactDb
100101
import Data.Coerce
@@ -163,7 +164,7 @@ execBlock currHeader payload = do
163164
return (totalGasUsed, pwo)
164165
where
165166
blockGasLimit =
166-
fromIntegral <$> maxBlockGasLimit v (view blockHeight currHeader)
167+
fromIntegral <$> maxBlockGasLimit v pact4ForkNumber (view blockHeight currHeader)
167168

168169
logInitCache = liftPactServiceM $ do
169170
mc <- fmap (fmap instr . _getModuleCache) <$> use psInitCache

src/Chainweb/Pact/PactService/Pact5/ExecBlock.hs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -577,7 +577,7 @@ execExistingBlock
577577
-> CheckablePayload
578578
-> PactBlockM logger tbl (P.Gas, PayloadWithOutputs)
579579
execExistingBlock currHeader payload = do
580-
parentBlockHeader <- view psParentHeader
580+
parentBlockHeader <- _parentHeader <$> view psParentHeader
581581
let plData = checkablePayloadToPayloadData payload
582582
miner :: Miner <- decodeStrictOrThrow (_minerData $ view payloadDataMiner plData)
583583
txs <- liftIO $ pact5TransactionsFromPayload plData
@@ -590,7 +590,7 @@ execExistingBlock currHeader payload = do
590590
isGenesis <- view psIsGenesis
591591
blockHandlePreCoinbase <- use pbBlockHandle
592592
let
593-
txValidationTime = ParentCreationTime (view blockCreationTime $ _parentHeader parentBlockHeader)
593+
txValidationTime = ParentCreationTime (parentBlockHeader ^. blockCreationTime)
594594
errors <- liftIO $ flip foldMap txs $ \tx -> do
595595
errorOrSuccess <- runExceptT $
596596
validateParsedChainwebTx logger v cid db blockHandlePreCoinbase txValidationTime
@@ -612,7 +612,7 @@ execExistingBlock currHeader payload = do
612612
postCoinbaseBlockHandle <- use pbBlockHandle
613613

614614
let blockGasLimit =
615-
Pact5.GasLimit . Pact5.Gas . fromIntegral <$> maxBlockGasLimit v (view blockHeight currHeader)
615+
Pact5.GasLimit . Pact5.Gas . fromIntegral <$> maxBlockGasLimit v (parentBlockHeader ^. blockForkNumber) (currHeader ^. blockHeight)
616616

617617
env <- ask
618618
(V.fromList -> results, (finalHandle, _finalBlockGasLimit)) <-

src/Chainweb/Pact4/ModuleCache.hs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,3 +72,4 @@ cleanModuleCache v cid bh =
7272
ForkAtBlockHeight bh' -> bh == bh'
7373
ForkAtGenesis -> bh == genesisHeight v cid
7474
ForkNever -> False
75+
ForkAtForkNumber _ -> error "ChainWeb217Pact is not supposed to be indexed by a ForkNumber"

src/Chainweb/Pact4/TransactionExec.hs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,7 @@ import qualified Pact.Utils.StableHashMap as SHM
144144

145145
import Chainweb.BlockHeader
146146
import Chainweb.BlockHeight
147+
import Chainweb.ForkState (pact4ForkNumber)
147148
import Chainweb.Logger
148149
import qualified Chainweb.ChainId as Chainweb
149150
import Chainweb.Mempool.Mempool (pact4RequestKeyToTransactionHash)
@@ -371,7 +372,7 @@ applyCmd v logger gasLogger txFailuresCounter pdbenv miner gasModel txCtx txIdxI
371372
chainweb217Pact' = guardCtx chainweb217Pact txCtx
372373
chainweb219Pact' = guardCtx chainweb219Pact txCtx
373374
chainweb223Pact' = guardCtx chainweb223Pact txCtx
374-
allVerifiers = verifiersAt v cid currHeight
375+
allVerifiers = verifiersAt v cid pact4ForkNumber currHeight
375376
toEmptyPactError (PactError errty _ _ _) = PactError errty noInfo [] mempty
376377

377378
toOldListErr pe = pe { peDoc = listErrMsg }
@@ -671,7 +672,8 @@ applyLocal logger gasLogger dbEnv gasModel txCtx spv cmdIn mc execConfig =
671672
currHeight = ctxCurrentBlockHeight txCtx
672673
cid = V._chainId txCtx
673674
v = _chainwebVersion txCtx
674-
allVerifiers = verifiersAt v cid currHeight
675+
676+
allVerifiers = verifiersAt v cid pact4ForkNumber currHeight
675677
-- Note [Throw out verifier proofs eagerly]
676678
!verifiersWithNoProof =
677679
(fmap . fmap) (\_ -> ()) verifiers

src/Chainweb/Pact5/TransactionExec.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,7 @@ runVerifiers txCtx cmd = do
183183
gasUsed <- liftIO . readIORef . _geGasRef . _txEnvGasEnv =<< ask
184184
let initGasRemaining = MilliGas $ case (gasToMilliGas (gasLimit ^. _GasLimit), gasUsed) of
185185
(MilliGas gasLimitMilliGasWord, MilliGas gasUsedMilliGasWord) -> gasLimitMilliGasWord - gasUsedMilliGasWord
186-
let allVerifiers = verifiersAt v (_chainId txCtx) (ctxCurrentBlockHeight txCtx)
186+
let allVerifiers = verifiersAt v (_chainId txCtx) (ctxParentForkNumber txCtx) (ctxCurrentBlockHeight txCtx)
187187
let toModuleName m =
188188
Pact4.ModuleName
189189
{ Pact4._mnName = _mnName m

0 commit comments

Comments
 (0)