Skip to content

Commit 61d22d3

Browse files
committed
Do multiple updates in a single transaction
1 parent 1aea6f6 commit 61d22d3

File tree

2 files changed

+52
-37
lines changed

2 files changed

+52
-37
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{-# LANGUAGE OverloadedStrings #-}
22

3-
module Cardano.DbSync.Fix.ConsumedBy (fixConsumedBy) where
3+
module Cardano.DbSync.Fix.ConsumedBy (FixEntry, fixConsumedBy, fixEntriesConsumed) where
44

55
import Cardano.BM.Trace (Trace, logWarning)
66
import qualified Cardano.Chain.Block as Byron hiding (blockHash)
@@ -12,44 +12,45 @@ import Cardano.DbSync.Era.Byron.Util (blockPayload, unTxHash)
1212
import Cardano.DbSync.Era.Util
1313
import Cardano.DbSync.Error
1414
import Cardano.DbSync.Types
15-
import Cardano.Prelude hiding (length)
15+
import Cardano.Prelude hiding (length, (.))
1616
import Database.Persist.SqlBackend.Internal
1717
import Ouroboros.Consensus.Byron.Ledger (ByronBlock (..))
1818
import Ouroboros.Consensus.Cardano.Block (HardForkBlock (..))
1919

20-
fixConsumedBy :: SqlBackend -> Trace IO Text -> Integer -> CardanoBlock -> IO (Integer, Bool)
21-
fixConsumedBy backend tracer lastSize cblk = case cblk of
22-
BlockByron blk -> (\(n, bl) -> (n + lastSize, bl)) <$> fixBlock backend tracer blk
23-
_ -> pure (lastSize, True)
20+
type FixEntry = (DB.TxOutId, DB.TxId)
2421

25-
fixBlock :: SqlBackend -> Trace IO Text -> ByronBlock -> IO (Integer, Bool)
22+
-- | Nothing when the syncing must stop.
23+
fixConsumedBy :: SqlBackend -> Trace IO Text -> CardanoBlock -> IO (Maybe [FixEntry])
24+
fixConsumedBy backend tracer cblk = case cblk of
25+
BlockByron blk -> fixBlock backend tracer blk
26+
_ -> pure Nothing
27+
28+
fixBlock :: SqlBackend -> Trace IO Text -> ByronBlock -> IO (Maybe [FixEntry])
2629
fixBlock backend tracer bblk = case byronBlockRaw bblk of
27-
Byron.ABOBBoundary _ -> pure (0, False)
30+
Byron.ABOBBoundary _ -> pure $ Just []
2831
Byron.ABOBBlock blk -> do
29-
runReaderT (fix 0 (blockPayload blk)) backend
30-
where
31-
fix totalSize [] = pure (totalSize, False)
32-
fix totalSize (tx : txs) = do
33-
mn <- runExceptT $ fixTx tx
34-
case mn of
35-
Right n -> fix (totalSize + n) txs
36-
Left err -> do
37-
liftIO $
38-
logWarning tracer $
39-
mconcat
40-
[ "While fixing tx "
41-
, textShow tx
42-
, ", encountered error "
43-
, textShow err
44-
]
45-
pure (totalSize, True)
32+
mEntries <- runReaderT (runExceptT $ mapM fixTx (blockPayload blk)) backend
33+
case mEntries of
34+
Right newEntries -> pure $ Just $ concat newEntries
35+
Left err -> do
36+
liftIO $
37+
logWarning tracer $
38+
mconcat
39+
[ "While fixing block "
40+
, textShow bblk
41+
, ", encountered error "
42+
, textShow err
43+
]
44+
pure Nothing
4645

47-
fixTx :: MonadIO m => Byron.TxAux -> ExceptT SyncNodeError (ReaderT SqlBackend m) Integer
46+
fixTx :: MonadIO m => Byron.TxAux -> ExceptT SyncNodeError (ReaderT SqlBackend m) [FixEntry]
4847
fixTx tx = do
4948
txId <- liftLookupFail "resolving tx" $ DB.queryTxId txHash
5049
resolvedInputs <- mapM resolveTxInputs (toList $ Byron.txInputs (Byron.taTx tx))
51-
lift $ DB.updateListTxOutConsumedByTxId (prepUpdate txId <$> resolvedInputs)
52-
pure $ fromIntegral $ length resolvedInputs
50+
pure (prepUpdate txId <$> resolvedInputs)
5351
where
5452
txHash = unTxHash $ Crypto.serializeCborHash (Byron.taTx tx)
5553
prepUpdate txId (_, _, txOutId, _) = (txOutId, txId)
54+
55+
fixEntriesConsumed :: SqlBackend -> Trace IO Text -> [FixEntry] -> IO ()
56+
fixEntriesConsumed backend tracer = DB.runDbIohkLogging backend tracer . DB.updateListTxOutConsumedByTxId

cardano-db-sync/src/Cardano/DbSync/Sync.hs

+23-9
Original file line numberDiff line numberDiff line change
@@ -473,26 +473,40 @@ chainSyncClientFixConsumed backend tracer wrongTotalSize = Client.ChainSyncClien
473473
{ Client.recvMsgIntersectFound = \_blk _tip ->
474474
Client.ChainSyncClient $
475475
pure $
476-
Client.SendMsgRequestNext (pure ()) (clientStNext 0)
476+
Client.SendMsgRequestNext (pure ()) (clientStNext (0, (0, [])))
477477
, Client.recvMsgIntersectNotFound = \_tip ->
478478
panic "Failed to find intersection with genesis."
479479
}
480480

481-
clientStNext :: Integer -> Client.ClientStNext CardanoBlock (Point CardanoBlock) (Tip CardanoBlock) IO Integer
482-
clientStNext lastSize =
481+
clientStNext :: (Integer, (Integer, [[FixEntry]])) -> Client.ClientStNext CardanoBlock (Point CardanoBlock) (Tip CardanoBlock) IO Integer
482+
clientStNext (sizeFixedTotal, (sizeFixEntries, fixEntries)) =
483483
Client.ClientStNext
484484
{ Client.recvMsgRollForward = \blk _tip -> Client.ChainSyncClient $ do
485-
(lastSize', ended) <- fixConsumedBy backend tracer lastSize blk
486-
logSize lastSize lastSize'
487-
if ended
488-
then pure $ Client.SendMsgDone lastSize'
489-
else pure $ Client.SendMsgRequestNext (pure ()) (clientStNext lastSize')
485+
mNewEntries <- fixConsumedBy backend tracer blk
486+
case mNewEntries of
487+
Nothing -> do
488+
fixAccumulatedEntries fixEntries
489+
pure $ Client.SendMsgDone (sizeFixedTotal + sizeFixEntries)
490+
Just newEntries -> do
491+
let sizeNewEntries = fromIntegral (length newEntries)
492+
(sizeNewFixed, sizeUnfixed, unfixedEntries) <-
493+
fixAccumulatedEntriesMaybe (sizeFixEntries + sizeNewEntries, newEntries : fixEntries)
494+
let sizeNewFixedTotal = sizeFixedTotal + sizeNewFixed
495+
logSize sizeFixedTotal sizeNewFixedTotal
496+
pure $ Client.SendMsgRequestNext (pure ()) (clientStNext (sizeNewFixedTotal, (sizeUnfixed, unfixedEntries)))
490497
, Client.recvMsgRollBackward = \_point _tip ->
491498
Client.ChainSyncClient $
492499
pure $
493-
Client.SendMsgRequestNext (pure ()) (clientStNext lastSize)
500+
Client.SendMsgRequestNext (pure ()) (clientStNext (sizeFixedTotal, (sizeFixEntries, fixEntries)))
494501
}
495502

503+
fixAccumulatedEntries = fixEntriesConsumed backend tracer . concat . reverse
504+
505+
fixAccumulatedEntriesMaybe :: (Integer, [[FixEntry]]) -> IO (Integer, Integer, [[FixEntry]])
506+
fixAccumulatedEntriesMaybe (n, entries)
507+
| n >= 10_000 = fixAccumulatedEntries entries >> pure (n, 0, [])
508+
| otherwise = pure (0, n, entries)
509+
496510
logSize :: Integer -> Integer -> IO ()
497511
logSize lastSize newSize = do
498512
when (newSize `div` 200_000 > lastSize `div` 200_000) $

0 commit comments

Comments
 (0)