Skip to content

Commit 779de8b

Browse files
committed
fix unique conflict offchainvotedata
1 parent f8da18e commit 779de8b

File tree

8 files changed

+39
-391
lines changed

8 files changed

+39
-391
lines changed

cardano-chain-gen/test/Test/Cardano/Db/Mock/Unit/Alonzo/Config.hs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ insertConfig = do
3434
, sioPoolStats = PoolStatsConfig False
3535
, sioJsonType = JsonTypeDisable
3636
, sioRemoveJsonbFromSchema = RemoveJsonbFromSchemaConfig False
37+
, sioStopAtBlock = Nothing
3738
}
3839

3940
dncInsertOptions cfg @?= expected

cardano-chain-gen/test/Test/Cardano/Db/Mock/Unit/Conway/Config/Parse.hs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ insertConfig = do
104104
, sioPoolStats = PoolStatsConfig False
105105
, sioJsonType = JsonTypeDisable
106106
, sioRemoveJsonbFromSchema = RemoveJsonbFromSchemaConfig False
107+
, sioStopAtBlock = Nothing
107108
}
108109

109110
dncInsertOptions cfg @?= expected

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

Lines changed: 33 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import qualified Cardano.Ledger.Alonzo.Scripts as Ledger
2121
import Cardano.Ledger.Shelley.AdaPots as Shelley
2222
import Cardano.Prelude
2323
import Cardano.Slotting.Slot (EpochNo (..), SlotNo)
24+
import Data.List (span)
2425
import Ouroboros.Consensus.Cardano.Block (HardForkBlock (..))
2526
import qualified Ouroboros.Consensus.HardFork.Combinator as Consensus
2627
import Ouroboros.Network.Block (blockHash, blockNo, getHeaderFields, headerFieldBlockNo, unBlockNo)
@@ -29,7 +30,7 @@ import qualified Cardano.Db as DB
2930
import Cardano.DbSync.Api
3031
import Cardano.DbSync.Api.Ledger
3132
import Cardano.DbSync.Api.Types (ConsistentLevel (..), InsertOptions (..), LedgerEnv (..), SyncEnv (..), SyncOptions (..))
32-
import Cardano.DbSync.Config.Types (dncInsertOptions, sioStopAtBlock)
33+
import Cardano.DbSync.Config.Types (SyncInsertOptions (..), dncInsertOptions)
3334
import Cardano.DbSync.DbEvent (runDbSyncTransaction)
3435
import Cardano.DbSync.Epoch (epochHandler)
3536
import Cardano.DbSync.Era.Byron.Insert (insertByronBlock)
@@ -52,8 +53,37 @@ insertListBlocks ::
5253
[CardanoBlock] ->
5354
IO (Either SyncNodeError ())
5455
insertListBlocks syncEnv blocks = do
55-
runDbSyncTransaction (getTrace syncEnv) (envDbEnv syncEnv) $ do
56-
traverse_ (applyAndInsertBlockMaybe syncEnv (getTrace syncEnv)) blocks
56+
case sioStopAtBlock $ dncInsertOptions $ envSyncNodeConfig syncEnv of
57+
Nothing -> runDbSyncTransaction (getTrace syncEnv) (envDbEnv syncEnv) $ do
58+
traverse_ (applyAndInsertBlockMaybe syncEnv (getTrace syncEnv)) blocks
59+
Just targetBlock ->
60+
insertListBlocksWithStopCondition syncEnv blocks targetBlock
61+
62+
insertListBlocksWithStopCondition ::
63+
SyncEnv ->
64+
[CardanoBlock] ->
65+
Word64 -> -- target block number
66+
IO (Either SyncNodeError ())
67+
insertListBlocksWithStopCondition syncEnv blocks targetBlock = do
68+
-- Find all blocks up to and including the target block
69+
let (blocksToProcess, _) = span (\cblk -> unBlockNo (blockNo cblk) <= targetBlock) blocks
70+
71+
-- Check if we hit the stop condition in this batch
72+
let hitStopCondition = any (\cblk -> unBlockNo (blockNo cblk) >= targetBlock) blocks
73+
74+
-- Process the blocks in transaction
75+
result <- runDbSyncTransaction (getTrace syncEnv) (envDbEnv syncEnv) $ do
76+
traverse_ (applyAndInsertBlockMaybe syncEnv (getTrace syncEnv)) blocksToProcess
77+
78+
-- If we hit the stop condition and transaction succeeded, shutdown
79+
case result of
80+
Right () | hitStopCondition -> do
81+
let tracer = getTrace syncEnv
82+
liftIO $
83+
logInfo tracer $
84+
"Reached stop condition at block " <> textShow targetBlock <> ". Stopping db-sync gracefully."
85+
pure $ Left $ SNErrDefault (mkSyncNodeCallStack "insertListBlocks") "Stop condition reached"
86+
_ -> pure result
5787

5888
applyAndInsertBlockMaybe ::
5989
SyncEnv ->
@@ -127,16 +157,6 @@ insertBlock syncEnv cblk applyRes firstAfterRollback tookSnapshot = do
127157
let !withinHalfHour = isWithinHalfHour details
128158
insertNewEpochLedgerEvents syncEnv (sdEpochNo details) (apEvents applyResult)
129159

130-
-- Check stop condition after successful block insertion
131-
let stopAtBlock = sioStopAtBlock $ dncInsertOptions $ envSyncNodeConfig syncEnv
132-
case stopAtBlock of
133-
Just targetBlock | unBlockNo blkNo >= targetBlock -> do
134-
liftIO $
135-
logInfo tracer $
136-
"Reached stop condition at block " <> textShow targetBlock <> ". Stopping db-sync gracefully."
137-
throwError $ SNErrDefault (mkSyncNodeCallStack "insertBlock") "Stop condition reached"
138-
_ -> pure ()
139-
140160
let isNewEpochEvent = hasNewEpochEvent (apEvents applyResult)
141161
let isStartEventOrRollback = hasEpochStartEvent (apEvents applyResult) || firstAfterRollback
142162
let isMember poolId = Set.member poolId (apPoolsRegistered applyResult)

cardano-db/src/Cardano/Db/Schema/Core/StakeDeligation.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,7 @@ data EpochStake = EpochStake
253253
type instance Key EpochStake = EpochStakeId
254254

255255
instance DbInfo EpochStake where
256-
bulkUniqueFields _ = ["addr_id", "pool_id", "epoch_no"]
256+
uniqueFields _ = ["addr_id", "pool_id", "epoch_no"]
257257
unnestParamTypes _ =
258258
[ ("addr_id", "bigint[]")
259259
, ("pool_id", "bigint[]")

cardano-db/src/Cardano/Db/Statement/OffChain.hs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -454,7 +454,9 @@ insertBulkOffChainVoteAuthorsStmt =
454454

455455
insertBulkOffChainVoteDataStmt :: HsqlStmt.Statement [SO.OffChainVoteData] [Id.OffChainVoteDataId]
456456
insertBulkOffChainVoteDataStmt =
457-
insertBulk
457+
insertBulkWith
458+
(ReplaceWithColumns (uniqueFields (Proxy @SO.OffChainVoteData))) -- ON CONFLICT DO UPDATE to ensure we get IDs back
459+
False
458460
extractOffChainVoteData
459461
SO.offChainVoteDataBulkEncoder
460462
(WithResultBulk $ Id.idBulkDecoder Id.OffChainVoteDataId)

cardano-db/src/Cardano/Db/Statement/Types.hs

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -105,12 +105,6 @@ class Typeable a => DbInfo a where
105105
default uniqueFields :: Proxy a -> [Text]
106106
uniqueFields _ = []
107107

108-
-- | Manual constraint specification for bulk operations only.
109-
-- This doesn't affect singular inserts, only bulk operations with conflict handling.
110-
bulkUniqueFields :: Proxy a -> [Text]
111-
default bulkUniqueFields :: Proxy a -> [Text]
112-
bulkUniqueFields _ = []
113-
114108
-- \| Column names and their pg_array type. Used for UNNEST statements.
115109
unnestParamTypes :: Proxy a -> [(Text, Text)] -- (column_name, pg_array_type)
116110
default unnestParamTypes :: Proxy a -> [(Text, Text)]

doc/database-encode-decode.md

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,6 @@ instance DbInfo SomeTable where
5252
-- Unique constraints
5353
uniqueFields _ = ["col1", "col2"] -- Multi-column unique constraint
5454

55-
-- Bulk unique fields (for bulk operations only)
56-
bulkUniqueFields _ = ["bulk_unique_col"]
57-
5855
-- JSONB columns (require ::jsonb casting)
5956
jsonbFields _ = ["metadata", "config"]
6057

0 commit comments

Comments
 (0)