Skip to content

Commit

Permalink
db-sync: Fix a race condition maintaining ledger state
Browse files Browse the repository at this point in the history
When blocks and rollback notifications arrive via the chainsync protocol,
they are put in a queue and then a separate thread reads from the queue and
operates on the DB. When ledger-state management was added, code to apply a
block to a ledger state was added at the read end of the queue, but the
rollback handling was incorrectly added at the write end of the queue.

The solution to the problem is trivial, move the ledger state rollback
handling from the write end of the queue to the read end.
  • Loading branch information
erikd committed Nov 22, 2020
1 parent 696e3f8 commit 73358cd
Show file tree
Hide file tree
Showing 2 changed files with 6 additions and 6 deletions.
7 changes: 3 additions & 4 deletions cardano-db-sync/src/Cardano/DbSync.hs
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,7 @@ dbSyncProtocols trce env plugin queryVar ledgerVar _version codecs _connectionId
(cChainSyncCodec codecs)
channel
(chainSyncClientPeerPipelined
$ chainSyncClient trce env queryVar ledgerVar metrics latestPoints currentTip actionQueue)
$ chainSyncClient trce env queryVar metrics latestPoints currentTip actionQueue)
)
atomically $ writeDbActionQueue actionQueue DbFinish
cancel server
Expand Down Expand Up @@ -317,9 +317,9 @@ getCurrentTipBlockNo = do
chainSyncClient
:: Trace IO Text -> DbSyncEnv
-> StateQueryTMVar CardanoBlock (Interpreter (CardanoEras StandardCrypto))
-> LedgerStateVar -> Metrics -> [Point CardanoBlock] -> WithOrigin BlockNo -> DbActionQueue
-> Metrics -> [Point CardanoBlock] -> WithOrigin BlockNo -> DbActionQueue
-> ChainSyncClientPipelined CardanoBlock (Tip CardanoBlock) IO ()
chainSyncClient trce env queryVar ledgerVar metrics latestPoints currentTip actionQueue =
chainSyncClient trce env queryVar metrics latestPoints currentTip actionQueue =
ChainSyncClientPipelined $ pure $
-- Notify the core node about the our latest points at which we are
-- synchronised. This client is not persistent and thus it just
Expand Down Expand Up @@ -373,7 +373,6 @@ chainSyncClient trce env queryVar ledgerVar metrics latestPoints currentTip acti
-- but will only be incorrect for a short time span.
let slot = toRollbackSlot point
atomically $ writeDbActionQueue actionQueue (mkDbRollback slot)
loadLedgerState (envLedgerStateDir env) ledgerVar slot
newTip <- getCurrentTipBlockNo
pure $ finish newTip tip
}
Expand Down
5 changes: 3 additions & 2 deletions cardano-db-sync/src/Cardano/DbSync/Database.hs
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,9 @@ runActions trce env plugin ledgerState actions = do
case spanDbApply xs of
([], DbFinish:_) -> do
pure Done
([], DbRollBackToPoint pt:ys) -> do
runRollbacks trce plugin pt
([], DbRollBackToPoint sn:ys) -> do
runRollbacks trce plugin sn
liftIO $ loadLedgerState (envLedgerStateDir env) ledgerState sn
dbAction Continue ys
(ys, zs) -> do
insertBlockList trce env ledgerState plugin ys
Expand Down

0 comments on commit 73358cd

Please sign in to comment.