Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 1 addition & 5 deletions src/Chainweb/CutDB.hs
Original file line number Diff line number Diff line change
Expand Up @@ -528,11 +528,7 @@ synchronizeProviders logger wbh providers c = do
pLog Debug $ "syncToBlock with fork info " <> encodeToText finfo

bhdb <- liftIO $ getWebBlockHeaderDb wbh cid
-- send a larger trace on startup (going back to the safe block)
-- this way the payload provider is more likely to be able to
-- resolve the fork
let startState = _consensusStateSafe (_forkInfoTargetState finfo)
liftIO (resolveForkInfoForProviderState pLog bhdb NullCas provider Nothing finfo startState) `catch` \(e :: SomeException) -> do
liftIO (resolveForkInfo pLog bhdb NullCas provider Nothing finfo) `catch` \(e :: SomeException) -> do
pLog Warn $ "resolveFork failed"
<> "; finfo: " <> encodeToText finfo
<> "; failure: " <> T.pack (displayException e)
Expand Down
61 changes: 33 additions & 28 deletions src/Chainweb/Sync/ForkInfo.hs
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@
-- Mining should be performed only on a fully caught up payload provider.

forkInfoChunkSize :: Int
forkInfoChunkSize = 1000

Check warning on line 72 in src/Chainweb/Sync/ForkInfo.hs

View workflow job for this annotation

GitHub Actions / Build (9.12.2, latest, ubuntu-24.04, false)

Defined but not used: ‘forkInfoChunkSize’

Check warning on line 72 in src/Chainweb/Sync/ForkInfo.hs

View workflow job for this annotation

GitHub Actions / Build (9.10.2, latest, ubuntu-24.04, false)

Defined but not used: ‘forkInfoChunkSize’

Check warning on line 72 in src/Chainweb/Sync/ForkInfo.hs

View workflow job for this annotation

GitHub Actions / Build (9.10.2, 3.14, ubuntu-22.04, true)

Defined but not used: ‘forkInfoChunkSize’

Check warning on line 72 in src/Chainweb/Sync/ForkInfo.hs

View workflow job for this annotation

GitHub Actions / Build (9.12.2, latest, macos-latest, false)

Defined but not used: ‘forkInfoChunkSize’

Check warning on line 72 in src/Chainweb/Sync/ForkInfo.hs

View workflow job for this annotation

GitHub Actions / Build (9.10.2, latest, ubuntu-22.04, false)

Defined but not used: ‘forkInfoChunkSize’

Check warning on line 72 in src/Chainweb/Sync/ForkInfo.hs

View workflow job for this annotation

GitHub Actions / Build (9.12.2, latest, macos-latest, true)

Defined but not used: ‘forkInfoChunkSize’

-- -------------------------------------------------------------------------- --

Expand Down Expand Up @@ -123,7 +123,7 @@
-- payload provider that is not caught up yet)
--
else do
resolveForkInfoForProviderState logg bhdb candidateHdrs provider hints finfo (_consensusStateLatest r)
resolveForkInfoForProviderState logg bhdb candidateHdrs provider hints finfo r
where
h = _latestRankedBlockHash . _forkInfoTargetState $ finfo

Expand All @@ -146,10 +146,11 @@
-> p
-> Maybe Hints
-> ForkInfo
-> SyncState
-> ConsensusState
-> IO ()
resolveForkInfoForProviderState logg bhdb candidateHdrs provider hints finfo ppKnownState
| ppRBH == trgHash = do
| ppLatestBlock == trgHash = do
-- nothing to do, we are at the target
logg Info "resolveForkInfo: payload provider is at target block"
-- If no payload production is requested we are done. Otherwise we
-- still need to issue the syncToBlock call to initiate payload
Expand All @@ -164,28 +165,43 @@
logg Info $ "resolveForkInfo: payload provider state: " <> brief ppKnownState
<> "; target state: " <> brief (_forkInfoTargetState finfo)

let lookupBhdb rbh = lookupRanked bhdb (int $ _rankedHeight rbh) (_ranked rbh)

hdr :: BlockHeader <- runMaybeT
(MaybeT (tableLookup candidateHdrs (_ranked trgHash))
<|> MaybeT (lookupRanked bhdb (int $ _rankedHeight trgHash) (_ranked trgHash)))
(MaybeT (tableLookup candidateHdrs (_ranked trgHash)) <|> MaybeT (lookupBhdb trgHash))
>>= \case
Nothing -> do
throwM $ InternalInvariantViolation $ "validatePayload: target block is missing: " <> brief trgHash
throwM $ InternalInvariantViolation $
"validatePayload: target block is missing: " <> brief trgHash
Just hdr -> return hdr

-- Finding a fork from the latest block can fail if we don't know the
-- state of the payload provider.
-- This can happen if:
-- 1. the payload provider db comes from an external source.
-- 2. the payload provider has moved to a fork that catchup has not
-- finished validating.
-- In this case we can only guess where a common fork point might be --
-- in the worst case this is genesis. The more common case is 2. in
-- which case the "safe" block is probably known.
let ppSafeBlock = _syncStateRankedBlockHash $ _consensusStateSafe ppKnownState
let ppFinalBlock = _syncStateRankedBlockHash $ _consensusStateFinal ppKnownState
ppBlock <- runMaybeT
(MaybeT (lookupBhdb ppLatestBlock)
<|> MaybeT (lookupBhdb ppSafeBlock)
<|> MaybeT (lookupBhdb ppFinalBlock)) >>= \case
Nothing ->
throwM $ InternalInvariantViolation $ "Final payload provider block is missing: " <> brief ppFinalBlock
Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe include the full consensus state?

Just ppBlock -> return ppBlock

-- Lookup the state of the Payload Provider and query the trace
-- from the fork point to the target block.
--
-- This can fail if we don't know the state of the payload provider.
-- This really should only happen if the payload provider db comes from
-- an external source or the payload provider db is outdated and resides
-- on a fork that got already pruned. In this case we can only guess
-- where a common fork point might be -- which, in worst case, might be
-- the genesis. We should either do an exponential search or just fail.

-- Before we do the potentially expensive branch diff call, we check
-- whether the ppKnownState is in the trace of the finfo.
-- TODO this could be done more efficiently, but for now it is fine.
let idx = L.elemIndex ppRBH
let idx = L.elemIndex (view rankedBlockHash ppBlock)
$ unwrapParent . _evaluationCtxRankedParentHash <$> _forkInfoTrace finfo

newForkInfo <- case idx of
Expand All @@ -199,13 +215,10 @@
-- The the payload provider does a fast forward without rewind.
return finfo
{ _forkInfoTrace = drop i (_forkInfoTrace finfo)
, _forkInfoBasePayloadHash = Parent $ _ranked $ _syncStateRankedBlockPayloadHash ppKnownState
, _forkInfoBasePayloadHash = Parent $ _ranked $ view rankedBlockPayloadHash ppBlock
}
Nothing -> do
logg Info "resolveForkInfo: payload provider state not in trace, computing fork point"
ppBlock <- lookupRanked bhdb (int $ _rankedHeight ppRBH) (_ranked ppRBH) >>= \case
Nothing -> throwM $ InternalInvariantViolation $ "Payload provider block is missing: " <> brief ppRBH
Just ppBlock -> return ppBlock

-- FIXME: this stream can be very long if the payload provider
-- is out of sync. We should limit it and proceed iteratively if
Expand Down Expand Up @@ -293,25 +306,18 @@
e
throwM e

-- check if we made progress
--
let delta :: Int = int (_rankedHeight (_latestRankedBlockHash newState))
- int (_rankedHeight (_syncStateRankedBlockHash ppKnownState))

-- TODO: when this function is incremental, we will manage this more correctly.
if ppKnownState /= _consensusStateLatest newState
if ppKnownState /= newState
then do
logg Info $ "resolveForkInfo: made progress"
<> "; delta: " <> sshow delta
<> "; previous payload provider state: " <> brief ppKnownState
<> "; new payload provider state: " <> brief newState
<> "; target state: " <> brief (_forkInfoTargetState newForkInfo)
-- continue.
-- TODO compute the new fork info here.
resolveForkInfoForProviderState logg bhdb candidateHdrs provider hints newForkInfo (_consensusStateLatest newState)
resolveForkInfoForProviderState logg bhdb candidateHdrs provider hints newForkInfo newState
else do
logg Warn $ "resolveForkInfo: no progress"
<> "; delta: " <> sshow delta
<> "; previous payload provider state: " <> brief ppKnownState
<> "; new payload provider state: " <> brief newState
<> "; target state: " <> brief (_forkInfoTargetState newForkInfo)
Expand All @@ -321,14 +327,13 @@
-- so, we raise an exception.
--
throwM $ ForkInfoSyncFailure $ "unexpected result state"
<> "; delta: " <> sshow delta
<> "; previous payload provider state: " <> brief ppKnownState
<> "; new payload provider state: " <> brief newState
<> "; target state: " <> brief (_forkInfoTargetState newForkInfo)
<> "; trace: " <> brief (_forkInfoTrace newForkInfo)
where
trgHash = _latestRankedBlockHash . _forkInfoTargetState $ finfo
ppRBH = _syncStateRankedBlockHash ppKnownState
ppLatestBlock = _syncStateRankedBlockHash $ _consensusStateLatest ppKnownState

-- -------------------------------------------------------------------------- --
-- Trace Utils
Expand Down
Loading