Skip to content

Commit cf63b18

Browse files
committed
Break down loop into roll-forward and iterative processes
Now tracking the latest known block and UTxO view for retries.
1 parent 380fc97 commit cf63b18

File tree

3 files changed

+37
-13
lines changed

3 files changed

+37
-13
lines changed

hydra-chain-observer/hydra-chain-observer.cabal

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ library
7171
, hydra-plutus
7272
, hydra-prelude
7373
, hydra-tx
74+
, io-classes
7475
, optparse-applicative
7576
, ouroboros-network-protocols
7677
, retry

hydra-chain-observer/src/Hydra/Blockfrost/ChainObserver.hs

Lines changed: 35 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,12 @@ import Blockfrost.Client (
99
runBlockfrost,
1010
)
1111
import Blockfrost.Client qualified as Blockfrost
12-
import Control.Retry (RetryPolicyM, RetryStatus, exponentialBackoff, limitRetries, retrying)
12+
import Control.Concurrent.Class.MonadSTM (
13+
MonadSTM (readTVarIO),
14+
newTVarIO,
15+
writeTVar,
16+
)
17+
import Control.Retry (RetryPolicyM, RetryStatus (..), exponentialBackoff, limitRetries, retrying)
1318
import Hydra.Cardano.Api (
1419
BlockHeader,
1520
ChainPoint (..),
@@ -50,7 +55,7 @@ runBlockfrostM ::
5055
BlockfrostClientT IO a ->
5156
ExceptT APIBlockfrostError IO a
5257
runBlockfrostM prj action = do
53-
result <- liftIO $ runBlockfrost prj action
58+
result <- lift $ runBlockfrost prj action
5459
case result of
5560
Left err -> throwError (BlockfrostError $ show err)
5661
Right val -> pure val
@@ -93,26 +98,43 @@ blockfrostClient tracer projectPath startFromBlockHash = do
9398

9499
let blockTime = realToFrac _genesisSlotLength / realToFrac _genesisActiveSlotsCoefficient
95100

101+
stateTVar <- newTVarIO (block, mempty)
96102
void $
97-
retrying retryPolicy shouldRetry $ \_ ->
103+
retrying retryPolicy shouldRetry $ \RetryStatus{rsIterNumber} -> do
104+
-- XXX: wait on any iteration number, except 0 as it's the first try.
105+
when (rsIterNumber > 0) $ threadDelay blockTime
98106
either (error . show) id
99-
<$> runExceptT
100-
( do
101-
threadDelay blockTime
102-
loop tracer prj block networkId blockTime observerHandler mempty
103-
)
107+
<$> runExceptT (loop tracer prj networkId blockTime observerHandler stateTVar)
104108
}
105109

110+
-- | Iterative process that follows the chain using a naive roll-forward approach,
111+
-- keeping track of the latest known current block and UTxO view.
112+
-- This process operates at full speed without waiting between calls,
113+
-- favoring the catch-up process.
106114
loop ::
107115
Tracer IO ChainObserverLog ->
108116
Blockfrost.Project ->
109-
Blockfrost.Block ->
110117
NetworkId ->
111118
DiffTime ->
112119
ObserverHandler IO ->
113-
UTxO ->
120+
TVar IO (Blockfrost.Block, UTxO) ->
114121
ExceptT APIBlockfrostError IO a
115-
loop tracer prj block networkId blockTime observerHandler utxo = do
122+
loop tracer prj networkId blockTime observerHandler stateTVar = do
123+
current <- lift $ readTVarIO stateTVar
124+
next <- rollForward tracer prj networkId observerHandler current
125+
atomically $ writeTVar stateTVar next
126+
loop tracer prj networkId blockTime observerHandler stateTVar
127+
128+
-- | From the current block and UTxO view, we collect Hydra observations
129+
-- and yield the next block and adjusted UTxO view.
130+
rollForward ::
131+
Tracer IO ChainObserverLog ->
132+
Blockfrost.Project ->
133+
NetworkId ->
134+
ObserverHandler IO ->
135+
(Blockfrost.Block, UTxO) ->
136+
ExceptT APIBlockfrostError IO (Blockfrost.Block, UTxO)
137+
rollForward tracer prj networkId observerHandler (block, utxo) = do
116138
let Blockfrost.Block
117139
{ _blockHash
118140
, _blockConfirmations
@@ -151,11 +173,11 @@ loop tracer prj block networkId blockTime observerHandler utxo = do
151173
then [Tick point blockNo]
152174
else observationsAt
153175

154-
-- [7] Loop next.
176+
-- [7] Next.
155177
case _blockNextBlock of
156178
Just nextBlockHash -> do
157179
block' <- runBlockfrostM prj (Blockfrost.getBlock $ Right nextBlockHash)
158-
loop tracer prj block' networkId blockTime observerHandler adjustedUTxO
180+
pure (block', adjustedUTxO)
159181
Nothing ->
160182
throwError (MissingNextBlockHash _blockHash)
161183

hydra-chain-observer/src/Hydra/ChainObserver.hs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,5 @@ main observerHandler = do
2323
follow networkId startChainFrom observerHandler
2424
BlockfrostOptions{projectPath, startFromBlockHash} -> do
2525
let NodeClient{follow} = blockfrostClient tracer projectPath startFromBlockHash
26+
-- FIXME!
2627
follow (error "not-used") (error "not-used") observerHandler

0 commit comments

Comments
 (0)