Skip to content
This repository was archived by the owner on Nov 24, 2025. It is now read-only.

Commit 41cb354

Browse files
committed
Use BlockHistory if ConsensusState table is empty
Otherwise, existing pact databases will trigger rewinds to genesis, because they will see no current ConsensusState rows. Change-Id: Id0000000f26422ea9dd60fb52574244b3e9c5e8b
1 parent 28efdc0 commit 41cb354

File tree

1 file changed

+31
-1
lines changed

1 file changed

+31
-1
lines changed

src/Chainweb/Pact/Backend/ChainwebPactDb.hs

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ module Chainweb.Pact.Backend.ChainwebPactDb
7777
, lookupRankedBlockHash
7878
, getPayloadsAfter
7979
, getEarliestBlock
80+
, getLatestBlock
8081
, getConsensusState
8182
, setConsensusState
8283
, throwOnDbError
@@ -785,7 +786,7 @@ setConsensusState db cs = do
785786

786787
getConsensusState :: SQ3.Database -> ExceptT LocatedSQ3Error IO (Maybe ConsensusState)
787788
getConsensusState db = do
788-
qry db "SELECT blockheight, hash, payloadhash, safety FROM ConsensusState ORDER BY safety ASC;"
789+
maybeState <- qry db "SELECT blockheight, hash, payloadhash, safety FROM ConsensusState ORDER BY safety ASC;"
789790
[] [RInt, RBlob, RBlob, RText] >>= \case
790791
[final, latest, safe] -> return $ Just ConsensusState
791792
{ _consensusStateFinal = readRow "final" final
@@ -794,6 +795,13 @@ getConsensusState db = do
794795
}
795796
[] -> return Nothing
796797
inv -> error $ "invalid contents of the ConsensusState table: " <> sshow inv
798+
case maybeState of
799+
Nothing -> do
800+
getLatestBlock db >>= \case
801+
Nothing -> return Nothing
802+
Just latest ->
803+
return $ Just $ ConsensusState latest latest latest
804+
Just s -> return (Just s)
797805
where
798806
readRow expectedType [SInt height, SBlob hash, SBlob payloadHash, SText type']
799807
| expectedType == type' = SyncState
@@ -907,6 +915,28 @@ getEarliestBlock db = do
907915
in return (RankedBlockHash (fromIntegral hgt) hash)
908916
go _ = fail "Chainweb.Pact.Backend.RelationalCheckpointer.doGetEarliest: impossible. This is a bug in chainweb-node."
909917

918+
-- | Get the checkpointer's idea of the latest block.
919+
getLatestBlock :: HasCallStack => SQLiteEnv -> ExceptT LocatedSQ3Error IO (Maybe SyncState)
920+
getLatestBlock db = do
921+
r <- qry db qtext [] [RInt, RBlob, RBlob] >>= mapM go
922+
case r of
923+
[] -> return Nothing
924+
(!o:_) -> return (Just o)
925+
where
926+
qtext = "SELECT blockheight, hash, payloadhash FROM BlockHistory2 ORDER BY blockheight DESC LIMIT 1"
927+
928+
go [SInt hgt, SBlob blob, SBlob pBlob] =
929+
let hash = either error id $ runGetEitherS decodeBlockHash blob
930+
in let pHash = either error id $ runGetEitherS decodeBlockPayloadHash pBlob
931+
in return $ SyncState
932+
{ _syncStateBlockHash = hash
933+
, _syncStateBlockPayloadHash = pHash
934+
, _syncStateHeight = int hgt
935+
}
936+
go r = fail $
937+
"Chainweb.Pact.Backend.RelationalCheckpointer.doGetLatest: impossible. This is a bug in chainweb-node. Details: "
938+
<> sshow r
939+
910940
lookupBlockWithHeight :: HasCallStack => SQ3.Database -> BlockHeight -> ExceptT LocatedSQ3Error IO (Maybe (Ranked BlockHash))
911941
lookupBlockWithHeight db bheight = do
912942
qry db qtext [SInt $ fromIntegral bheight] [RBlob] >>= \case

0 commit comments

Comments
 (0)