Skip to content

Commit 48d86ab

Browse files
committed
implement shelley stake address whitelist
1 parent e28136f commit 48d86ab

File tree

17 files changed

+421
-327
lines changed

17 files changed

+421
-327
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -246,7 +246,7 @@ extractSyncOptions snp aop snc =
246246
InsertOptions
247247
{ ioInOut = isTxOutEnabled'
248248
, ioUseLedger = useLedger
249-
, ioShelley = isShelleyEnabled (sioShelley (dncInsertOptions snc))
249+
, ioShelley = sioShelley (dncInsertOptions snc)
250250
, -- Rewards are only disabled on "disable_all" and "only_gov" presets
251251
ioRewards = True
252252
, ioMultiAssets = sioMultiAsset (dncInsertOptions snc)

cardano-db-sync/src/Cardano/DbSync/Api/Ledger.hs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ import Data.ByteString (ByteString)
3939
import Data.List.Extra
4040
import Data.Map (Map)
4141
import qualified Data.Map.Strict as Map
42+
import Data.Maybe (catMaybes)
4243
import qualified Data.Text as Text
4344
import Database.Persist.Sql (SqlBackend)
4445
import Lens.Micro
@@ -145,7 +146,7 @@ storePage ::
145146
ExceptT SyncNodeError (ReaderT SqlBackend m) ()
146147
storePage syncEnv cache percQuantum (n, ls) = do
147148
when (n `mod` 10 == 0) $ liftIO $ logInfo trce $ "Bootstrap in progress " <> prc <> "%"
148-
txOuts <- mapM (prepareTxOut syncEnv cache) ls
149+
txOuts <- catMaybes <$> mapM (prepareTxOut syncEnv cache) ls
149150
txOutIds <- lift . DB.insertManyTxOutPlex True False $ etoTxOut . fst <$> txOuts
150151
let maTxOuts = concatMap mkmaTxOuts $ zip txOutIds (snd <$> txOuts)
151152
void . lift $ DB.insertManyMaTxOut maTxOuts
@@ -166,14 +167,13 @@ prepareTxOut ::
166167
SyncEnv ->
167168
TxCache ->
168169
(TxIn StandardCrypto, BabbageTxOut era) ->
169-
ExceptT SyncNodeError (ReaderT SqlBackend m) (ExtendedTxOut, [MissingMaTxOut])
170+
ExceptT SyncNodeError (ReaderT SqlBackend m) (Maybe (ExtendedTxOut, [MissingMaTxOut]))
170171
prepareTxOut syncEnv txCache (TxIn txHash (TxIx index), txOut) = do
171172
let txHashByteString = Generic.safeHashToByteString $ unTxId txHash
172173
let genTxOut = fromTxOut index txOut
173174
txId <- queryTxIdWithCache txCache txHashByteString
174-
insertTxOut trce cache iopts (txId, txHashByteString) genTxOut
175+
insertTxOut syncEnv cache iopts (txId, txHashByteString) genTxOut
175176
where
176-
trce = getTrace syncEnv
177177
cache = envCache syncEnv
178178
iopts = soptInsertOptions $ envOptions syncEnv
179179

cardano-db-sync/src/Cardano/DbSync/Api/Types.hs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ module Cardano.DbSync.Api.Types (
1515

1616
import qualified Cardano.Db as DB
1717
import Cardano.DbSync.Cache.Types (CacheStatus)
18-
import Cardano.DbSync.Config.Types (MetadataConfig, MultiAssetConfig, PlutusConfig, SyncNodeConfig)
18+
import Cardano.DbSync.Config.Types (MetadataConfig, MultiAssetConfig, PlutusConfig, ShelleyInsertConfig, SyncNodeConfig)
1919
import Cardano.DbSync.Ledger.Types (HasLedgerEnv)
2020
import Cardano.DbSync.LocalStateQuery (NoLedgerEnv)
2121
import Cardano.DbSync.Types (
@@ -81,7 +81,7 @@ data InsertOptions = InsertOptions
8181
, ioOffChainPoolData :: !Bool
8282
, ioPlutus :: !PlutusConfig
8383
, ioRewards :: !Bool
84-
, ioShelley :: !Bool
84+
, ioShelley :: !ShelleyInsertConfig
8585
, ioUseLedger :: !Bool
8686
}
8787
deriving (Show)

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

Lines changed: 61 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -11,23 +11,26 @@ module Cardano.DbSync.Cache (
1111
insertBlockAndCache,
1212
insertDatumAndCache,
1313
insertPoolKeyWithCache,
14+
insertStakeAddress,
1415
queryDatum,
1516
queryMAWithCache,
17+
queryOrInsertRewardAccount,
18+
queryOrInsertStakeAddress,
1619
queryPoolKeyOrInsert,
1720
queryPoolKeyWithCache,
1821
queryPrevBlockWithCache,
19-
queryOrInsertStakeAddress,
20-
queryOrInsertRewardAccount,
21-
insertStakeAddress,
2222
queryStakeAddrWithCache,
2323
rollbackCache,
2424

2525
-- * CacheStatistics
2626
getCacheStatistics,
27-
) where
27+
)
28+
where
2829

2930
import Cardano.BM.Trace
3031
import qualified Cardano.Db as DB
32+
import Cardano.DbSync.Api (getTrace)
33+
import Cardano.DbSync.Api.Types (InsertOptions (..), SyncEnv (..), SyncOptions (..))
3134
import Cardano.DbSync.Cache.Epoch (rollbackMapEpochInCache)
3235
import qualified Cardano.DbSync.Cache.LRU as LRU
3336
import Cardano.DbSync.Cache.Types (CacheAction (..), CacheInternal (..), CacheStatistics (..), CacheStatus (..), initCacheStatistics, isCacheActionUpdate)
@@ -36,6 +39,7 @@ import Cardano.DbSync.Era.Shelley.Query
3639
import Cardano.DbSync.Era.Util
3740
import Cardano.DbSync.Error
3841
import Cardano.DbSync.Types
42+
import Cardano.DbSync.Util.Whitelist (shelleyInsertWhitelistCheck)
3943
import qualified Cardano.Ledger.Address as Ledger
4044
import Cardano.Ledger.BaseTypes (Network)
4145
import Cardano.Ledger.Mary.Value
@@ -68,8 +72,8 @@ import Ouroboros.Consensus.Cardano.Block (StandardCrypto)
6872
-- a different id.
6973
-- NOTE: Other tables are not cleaned up since they are not rollbacked.
7074
rollbackCache :: MonadIO m => CacheStatus -> DB.BlockId -> ReaderT SqlBackend m ()
71-
rollbackCache NoCache _ = pure ()
72-
rollbackCache (ActiveCache cache) blockId = do
75+
rollbackCache UninitiatedCache _ = pure ()
76+
rollbackCache (Cache cache) blockId = do
7377
liftIO $ do
7478
atomically $ writeTVar (cPrevBlock cache) Nothing
7579
atomically $ modifyTVar (cDatum cache) LRU.cleanup
@@ -83,44 +87,61 @@ getCacheStatistics cs =
8387

8488
queryOrInsertRewardAccount ::
8589
(MonadBaseControl IO m, MonadIO m) =>
86-
Trace IO Text ->
90+
SyncEnv ->
8791
CacheStatus ->
8892
CacheAction ->
8993
Ledger.RewardAccount StandardCrypto ->
90-
ReaderT SqlBackend m DB.StakeAddressId
91-
queryOrInsertRewardAccount trce cache cacheUA rewardAddr = do
92-
eiAddrId <- queryRewardAccountWithCacheRetBs trce cache cacheUA rewardAddr
93-
case eiAddrId of
94-
Left (_err, bs) -> insertStakeAddress rewardAddr (Just bs)
95-
Right addrId -> pure addrId
94+
ReaderT SqlBackend m (Maybe DB.StakeAddressId)
95+
queryOrInsertRewardAccount syncEnv cache cacheUA rewardAddr = do
96+
-- check if the stake address is in the whitelist
97+
if shelleyInsertWhitelistCheck (ioShelley iopts) laBs
98+
then do
99+
eiAddrId <- queryRewardAccountWithCacheRetBs cache cacheUA rewardAddr
100+
case eiAddrId of
101+
Left (_err, bs) -> insertStakeAddress syncEnv rewardAddr (Just bs)
102+
Right addrId -> pure $ Just addrId
103+
else pure Nothing
104+
where
105+
nw = Ledger.getRwdNetwork rewardAddr
106+
cred = Ledger.getRwdCred rewardAddr
107+
!laBs = Ledger.serialiseRewardAcnt (Ledger.RewardAcnt nw cred)
108+
iopts = soptInsertOptions $ envOptions syncEnv
96109

97110
queryOrInsertStakeAddress ::
98111
(MonadBaseControl IO m, MonadIO m) =>
99-
Trace IO Text ->
112+
SyncEnv ->
100113
CacheStatus ->
101114
CacheAction ->
102115
Network ->
103116
StakeCred ->
104-
ReaderT SqlBackend m DB.StakeAddressId
105-
queryOrInsertStakeAddress trce cache cacheUA nw cred =
106-
queryOrInsertRewardAccount trce cache cacheUA $ Ledger.RewardAccount nw cred
117+
ReaderT SqlBackend m (Maybe DB.StakeAddressId)
118+
queryOrInsertStakeAddress syncEnv cache cacheUA nw cred =
119+
queryOrInsertRewardAccount syncEnv cache cacheUA $ Ledger.RewardAccount nw cred
107120

108121
-- If the address already exists in the table, it will not be inserted again (due to
109122
-- the uniqueness constraint) but the function will return the 'StakeAddressId'.
110123
insertStakeAddress ::
111124
(MonadBaseControl IO m, MonadIO m) =>
125+
SyncEnv ->
112126
Ledger.RewardAccount StandardCrypto ->
113127
Maybe ByteString ->
114-
ReaderT SqlBackend m DB.StakeAddressId
115-
insertStakeAddress rewardAddr stakeCredBs = do
116-
DB.insertStakeAddress $
117-
DB.StakeAddress
118-
{ DB.stakeAddressHashRaw = addrBs
119-
, DB.stakeAddressView = Generic.renderRewardAccount rewardAddr
120-
, DB.stakeAddressScriptHash = Generic.getCredentialScriptHash $ Ledger.raCredential rewardAddr
121-
}
128+
ReaderT SqlBackend m (Maybe DB.StakeAddressId)
129+
insertStakeAddress syncEnv rewardAddr stakeCredBs =
130+
-- check if the address is in the whitelist
131+
if shelleyInsertWhitelistCheck ioptsShelley addrBs
132+
then do
133+
stakeAddrsId <-
134+
DB.insertStakeAddress $
135+
DB.StakeAddress
136+
{ DB.stakeAddressHashRaw = addrBs
137+
, DB.stakeAddressView = Generic.renderRewardAcnt rewardAddr
138+
, DB.stakeAddressScriptHash = Generic.getCredentialScriptHash $ Ledger.getRwdCred rewardAddr
139+
}
140+
pure $ Just stakeAddrsId
141+
else pure Nothing
122142
where
123-
addrBs = fromMaybe (Ledger.serialiseRewardAccount rewardAddr) stakeCredBs
143+
addrBs = fromMaybe (Ledger.serialiseRewardAcnt rewardAddr) stakeCredBs
144+
ioptsShelley = ioShelley . soptInsertOptions $ envOptions syncEnv
124145

125146
queryRewardAccountWithCacheRetBs ::
126147
forall m.
@@ -154,8 +175,7 @@ queryStakeAddrWithCacheRetBs ::
154175
Network ->
155176
StakeCred ->
156177
ReaderT SqlBackend m (Either (DB.LookupFail, ByteString) DB.StakeAddressId)
157-
queryStakeAddrWithCacheRetBs trce cache cacheUA nw cred = do
158-
let !bs = Ledger.serialiseRewardAccount (Ledger.RewardAccount nw cred)
178+
queryStakeAddrWithCacheRetBs cache cacheUA nw cred = do
159179
case cache of
160180
NoCache -> do
161181
mapLeft (,bs) <$> queryStakeAddress bs
@@ -198,11 +218,12 @@ queryStakeAddrWithCacheRetBs trce cache cacheUA nw cred = do
198218

199219
queryPoolKeyWithCache ::
200220
MonadIO m =>
221+
SyncEnv ->
201222
CacheStatus ->
202223
CacheAction ->
203224
PoolKeyHash ->
204225
ReaderT SqlBackend m (Either DB.LookupFail DB.PoolHashId)
205-
queryPoolKeyWithCache cache cacheUA hsh =
226+
queryPoolKeyWithCache syncEnv cache cacheUA hsh =
206227
case cache of
207228
NoCache -> do
208229
mPhId <- queryPoolHashId (Generic.unKeyHashRaw hsh)
@@ -278,14 +299,14 @@ insertPoolKeyWithCache cache cacheUA pHash =
278299
queryPoolKeyOrInsert ::
279300
(MonadBaseControl IO m, MonadIO m) =>
280301
Text ->
281-
Trace IO Text ->
302+
SyncEnv ->
282303
CacheStatus ->
283304
CacheAction ->
284305
Bool ->
285306
PoolKeyHash ->
286307
ReaderT SqlBackend m DB.PoolHashId
287-
queryPoolKeyOrInsert txt trce cache cacheUA logsWarning hsh = do
288-
pk <- queryPoolKeyWithCache cache cacheUA hsh
308+
queryPoolKeyOrInsert txt syncEnv cache cacheUA logsWarning hsh = do
309+
pk <- queryPoolKeyWithCache syncEnv cache cacheUA hsh
289310
case pk of
290311
Right poolHashId -> pure poolHashId
291312
Left err -> do
@@ -304,8 +325,8 @@ queryPoolKeyOrInsert txt trce cache cacheUA logsWarning hsh = do
304325
insertPoolKeyWithCache cache cacheUA hsh
305326

306327
queryMAWithCache ::
307-
MonadIO m =>
308-
CacheStatus ->
328+
(MonadIO m) =>
329+
Cache ->
309330
PolicyID StandardCrypto ->
310331
AssetName ->
311332
ReaderT SqlBackend m (Either (ByteString, ByteString) DB.MultiAssetId)
@@ -329,11 +350,14 @@ queryMAWithCache cache policyId asset =
329350
let !assetNameBs = Generic.unAssetName asset
330351
maId <- maybe (Left (policyBs, assetNameBs)) Right <$> DB.queryMultiAssetId policyBs assetNameBs
331352
whenRight maId $
332-
liftIO . atomically . modifyTVar (cMultiAssets ci) . LRU.insert (policyId, asset)
353+
liftIO
354+
. atomically
355+
. modifyTVar (cMultiAssets ci)
356+
. LRU.insert (policyId, asset)
333357
pure maId
334358

335359
queryPrevBlockWithCache ::
336-
MonadIO m =>
360+
(MonadIO m) =>
337361
Text ->
338362
CacheStatus ->
339363
ByteString ->
@@ -354,7 +378,7 @@ queryPrevBlockWithCache msg cache hsh =
354378
Nothing -> queryFromDb ci
355379
where
356380
queryFromDb ::
357-
MonadIO m =>
381+
(MonadIO m) =>
358382
CacheInternal ->
359383
ExceptT SyncNodeError (ReaderT SqlBackend m) DB.BlockId
360384
queryFromDb ci = do

cardano-db-sync/src/Cardano/DbSync/Era/Shelley/Query.hs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
module Cardano.DbSync.Era.Shelley.Query (
99
queryPoolHashId,
1010
queryStakeAddress,
11+
queryMultipleStakeAddress,
1112
queryStakeRefPtr,
1213
resolveInputTxId,
1314
resolveInputTxOutId,
@@ -29,6 +30,7 @@ import Database.Esqueleto.Experimental (
2930
Value (..),
3031
desc,
3132
from,
33+
in_,
3234
innerJoin,
3335
just,
3436
limit,
@@ -37,6 +39,7 @@ import Database.Esqueleto.Experimental (
3739
select,
3840
table,
3941
val,
42+
valList,
4043
where_,
4144
(:&) ((:&)),
4245
(==.),
@@ -64,6 +67,17 @@ queryStakeAddress addr = do
6467
pure (saddr ^. StakeAddressId)
6568
pure $ maybeToEither (DbLookupMessage $ "StakeAddress " <> renderByteArray addr) unValue (listToMaybe res)
6669

70+
queryMultipleStakeAddress ::
71+
MonadIO m =>
72+
[ByteString] ->
73+
ReaderT SqlBackend m (Either LookupFail [StakeAddressId])
74+
queryMultipleStakeAddress addrs = do
75+
res <- select $ do
76+
saddr <- from $ table @StakeAddress
77+
where_ (saddr ^. StakeAddressHashRaw `in_` valList addrs)
78+
pure (saddr ^. StakeAddressId)
79+
pure $ Right $ map unValue res
80+
6781
resolveInputTxId :: MonadIO m => Generic.TxIn -> ReaderT SqlBackend m (Either LookupFail TxId)
6882
resolveInputTxId = queryTxId . Generic.txInHash
6983

cardano-db-sync/src/Cardano/DbSync/Era/Universal/Adjust.hs

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,13 @@
55

66
module Cardano.DbSync.Era.Universal.Adjust (
77
adjustEpochRewards,
8-
) where
8+
)
9+
where
910

10-
import Cardano.BM.Trace (Trace, logInfo)
11+
import Cardano.BM.Trace (logInfo)
1112
import qualified Cardano.Db as Db
13+
import Cardano.DbSync.Api (getTrace)
14+
import Cardano.DbSync.Api.Types (SyncEnv (..))
1215
import Cardano.DbSync.Cache (
1316
queryPoolKeyWithCache,
1417
queryStakeAddrWithCache,
@@ -48,38 +51,37 @@ import Database.Esqueleto.Experimental (
4851

4952
adjustEpochRewards ::
5053
(MonadBaseControl IO m, MonadIO m) =>
51-
Trace IO Text ->
54+
SyncEnv ->
5255
Network ->
53-
CacheStatus ->
5456
EpochNo ->
5557
Generic.Rewards ->
5658
Set StakeCred ->
5759
ReaderT SqlBackend m ()
58-
adjustEpochRewards trce nw cache epochNo rwds creds = do
60+
adjustEpochRewards syncEnv nw epochNo rwds creds = do
5961
let eraIgnored = Map.toList $ Generic.unRewards rwds
60-
liftIO . logInfo trce $
61-
mconcat
62+
liftIO
63+
. Cardano.BM.Trace.logInfo (getTrace syncEnv)
64+
$ mconcat
6265
[ "Removing "
6366
, if null eraIgnored then "" else Db.textShow (length eraIgnored) <> " rewards and "
6467
, show (length creds)
6568
, " orphaned rewards"
6669
]
6770
forM_ eraIgnored $ \(cred, rewards) ->
6871
forM_ (Set.toList rewards) $ \rwd ->
69-
deleteReward trce nw cache epochNo (cred, rwd)
70-
crds <- rights <$> forM (Set.toList creds) (queryStakeAddrWithCache trce cache DoNotUpdateCache nw)
72+
deleteReward nw cache epochNo (cred, rwd)
73+
crds <- rights <$> forM (Set.toList creds) (queryStakeAddrWithCache (envCache syncEnv) DoNotUpdateCache nw)
7174
deleteOrphanedRewards epochNo crds
7275

7376
deleteReward ::
7477
(MonadBaseControl IO m, MonadIO m) =>
75-
Trace IO Text ->
78+
SyncEnv ->
7679
Network ->
77-
CacheStatus ->
7880
EpochNo ->
7981
(StakeCred, Generic.Reward) ->
8082
ReaderT SqlBackend m ()
81-
deleteReward trce nw cache epochNo (cred, rwd) = do
82-
mAddrId <- queryStakeAddrWithCache trce cache DoNotUpdateCache nw cred
83+
deleteReward syncEnv nw epochNo (cred, rwd) = do
84+
mAddrId <- queryStakeAddrWithCache cache DoNotUpdateCache nw cred
8385
eiPoolId <- queryPoolKeyWithCache cache DoNotUpdateCache (Generic.rewardPool rwd)
8486
case (mAddrId, eiPoolId) of
8587
(Right addrId, Right poolId) -> do
@@ -90,8 +92,10 @@ deleteReward trce nw cache epochNo (cred, rwd) = do
9092
where_ (rwdDb ^. Db.RewardSpendableEpoch ==. val (unEpochNo epochNo))
9193
where_ (rwdDb ^. Db.RewardPoolId ==. val poolId)
9294
_ -> pure ()
95+
where
96+
cache = envCache syncEnv
9397

94-
deleteOrphanedRewards :: MonadIO m => EpochNo -> [Db.StakeAddressId] -> ReaderT SqlBackend m ()
98+
deleteOrphanedRewards :: (MonadIO m) => EpochNo -> [Db.StakeAddressId] -> ReaderT SqlBackend m ()
9599
deleteOrphanedRewards (EpochNo epochNo) xs =
96100
delete $ do
97101
rwd <- from $ table @Db.Reward

0 commit comments

Comments
 (0)