Skip to content

Commit 627cf65

Browse files
committed
implement shelley stake address whitelist
1 parent 75ac4c1 commit 627cf65

File tree

17 files changed

+462
-355
lines changed

17 files changed

+462
-355
lines changed

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

+1-1
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

+4-4
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

+2-2
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 (Cache)
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

+66-38
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 (Cache (..), CacheInternal (..), CacheNew (..), CacheStatistics (..), StakeAddrCache, initCacheStatistics)
@@ -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
@@ -67,7 +71,7 @@ import Ouroboros.Consensus.Cardano.Block (StandardCrypto)
6771
-- NOTE: BlockId is cleaned up on rollbacks, since it may get reinserted on
6872
-- a different id.
6973
-- NOTE: Other tables are not cleaned up since they are not rollbacked.
70-
rollbackCache :: MonadIO m => Cache -> DB.BlockId -> ReaderT SqlBackend m ()
74+
rollbackCache :: (MonadIO m) => Cache -> DB.BlockId -> ReaderT SqlBackend m ()
7175
rollbackCache UninitiatedCache _ = pure ()
7276
rollbackCache (Cache cache) blockId = do
7377
liftIO $ do
@@ -83,46 +87,65 @@ getCacheStatistics cs =
8387

8488
queryOrInsertRewardAccount ::
8589
(MonadBaseControl IO m, MonadIO m) =>
90+
SyncEnv ->
8691
Cache ->
8792
CacheNew ->
8893
Ledger.RewardAcnt StandardCrypto ->
89-
ReaderT SqlBackend m DB.StakeAddressId
90-
queryOrInsertRewardAccount cache cacheNew rewardAddr = do
91-
eiAddrId <- queryRewardAccountWithCacheRetBs cache cacheNew rewardAddr
92-
case eiAddrId of
93-
Left (_err, bs) -> insertStakeAddress rewardAddr (Just bs)
94-
Right addrId -> pure addrId
94+
ReaderT SqlBackend m (Maybe DB.StakeAddressId)
95+
queryOrInsertRewardAccount syncEnv cache cacheNew 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 cacheNew 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
95109

96110
queryOrInsertStakeAddress ::
97111
(MonadBaseControl IO m, MonadIO m) =>
112+
SyncEnv ->
98113
Cache ->
99114
CacheNew ->
100115
Network ->
101116
StakeCred ->
102-
ReaderT SqlBackend m DB.StakeAddressId
103-
queryOrInsertStakeAddress cache cacheNew nw cred =
104-
queryOrInsertRewardAccount cache cacheNew $ Ledger.RewardAcnt nw cred
117+
ReaderT SqlBackend m (Maybe DB.StakeAddressId)
118+
queryOrInsertStakeAddress syncEnv cache cacheNew nw cred =
119+
queryOrInsertRewardAccount syncEnv cache cacheNew $ Ledger.RewardAcnt nw cred
105120

106121
-- If the address already exists in the table, it will not be inserted again (due to
107122
-- the uniqueness constraint) but the function will return the 'StakeAddressId'.
108123
insertStakeAddress ::
109124
(MonadBaseControl IO m, MonadIO m) =>
125+
SyncEnv ->
110126
Ledger.RewardAcnt StandardCrypto ->
111127
Maybe ByteString ->
112-
ReaderT SqlBackend m DB.StakeAddressId
113-
insertStakeAddress rewardAddr stakeCredBs =
114-
DB.insertStakeAddress $
115-
DB.StakeAddress
116-
{ DB.stakeAddressHashRaw = addrBs
117-
, DB.stakeAddressView = Generic.renderRewardAcnt rewardAddr
118-
, DB.stakeAddressScriptHash = Generic.getCredentialScriptHash $ Ledger.getRwdCred rewardAddr
119-
}
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
120142
where
121143
addrBs = fromMaybe (Ledger.serialiseRewardAcnt rewardAddr) stakeCredBs
144+
ioptsShelley = ioShelley . soptInsertOptions $ envOptions syncEnv
122145

123146
queryRewardAccountWithCacheRetBs ::
124147
forall m.
125-
MonadIO m =>
148+
(MonadIO m) =>
126149
Cache ->
127150
CacheNew ->
128151
Ledger.RewardAcnt StandardCrypto ->
@@ -132,7 +155,7 @@ queryRewardAccountWithCacheRetBs cache cacheNew rwdAcc =
132155

133156
queryStakeAddrWithCache ::
134157
forall m.
135-
MonadIO m =>
158+
(MonadIO m) =>
136159
Cache ->
137160
CacheNew ->
138161
Network ->
@@ -143,7 +166,7 @@ queryStakeAddrWithCache cache cacheNew nw cred =
143166

144167
queryStakeAddrWithCacheRetBs ::
145168
forall m.
146-
MonadIO m =>
169+
(MonadIO m) =>
147170
Cache ->
148171
CacheNew ->
149172
Network ->
@@ -161,7 +184,7 @@ queryStakeAddrWithCacheRetBs cache cacheNew nw cred = do
161184
pure mAddrId
162185

163186
queryStakeAddrAux ::
164-
MonadIO m =>
187+
(MonadIO m) =>
165188
CacheNew ->
166189
StakeAddrCache ->
167190
StrictTVar IO CacheStatistics ->
@@ -185,13 +208,13 @@ queryStakeAddrAux cacheNew mp sts nw cred =
185208
(err, _) -> pure (err, mp)
186209

187210
queryPoolKeyWithCache ::
188-
MonadIO m =>
189-
Cache ->
211+
(MonadIO m) =>
212+
SyncEnv ->
190213
CacheNew ->
191214
PoolKeyHash ->
192215
ReaderT SqlBackend m (Either DB.LookupFail DB.PoolHashId)
193-
queryPoolKeyWithCache cache cacheNew hsh =
194-
case cache of
216+
queryPoolKeyWithCache syncEnv cacheNew hsh =
217+
case envCache syncEnv of
195218
UninitiatedCache -> do
196219
mPhId <- queryPoolHashId (Generic.unKeyHashRaw hsh)
197220
case mPhId of
@@ -266,14 +289,14 @@ insertPoolKeyWithCache cache cacheNew pHash =
266289
queryPoolKeyOrInsert ::
267290
(MonadBaseControl IO m, MonadIO m) =>
268291
Text ->
269-
Trace IO Text ->
292+
SyncEnv ->
270293
Cache ->
271294
CacheNew ->
272295
Bool ->
273296
PoolKeyHash ->
274297
ReaderT SqlBackend m DB.PoolHashId
275-
queryPoolKeyOrInsert txt trce cache cacheNew logsWarning hsh = do
276-
pk <- queryPoolKeyWithCache cache cacheNew hsh
298+
queryPoolKeyOrInsert txt syncEnv cache cacheNew logsWarning hsh = do
299+
pk <- queryPoolKeyWithCache syncEnv cacheNew hsh
277300
case pk of
278301
Right poolHashId -> pure poolHashId
279302
Left err -> do
@@ -290,9 +313,11 @@ queryPoolKeyOrInsert txt trce cache cacheNew logsWarning hsh = do
290313
, ". We will assume that the pool exists and move on."
291314
]
292315
insertPoolKeyWithCache cache cacheNew hsh
316+
where
317+
trce = getTrace syncEnv
293318

294319
queryMAWithCache ::
295-
MonadIO m =>
320+
(MonadIO m) =>
296321
Cache ->
297322
PolicyID StandardCrypto ->
298323
AssetName ->
@@ -317,11 +342,14 @@ queryMAWithCache cache policyId asset =
317342
let !assetNameBs = Generic.unAssetName asset
318343
maId <- maybe (Left (policyBs, assetNameBs)) Right <$> DB.queryMultiAssetId policyBs assetNameBs
319344
whenRight maId $
320-
liftIO . atomically . modifyTVar (cMultiAssets ci) . LRU.insert (policyId, asset)
345+
liftIO
346+
. atomically
347+
. modifyTVar (cMultiAssets ci)
348+
. LRU.insert (policyId, asset)
321349
pure maId
322350

323351
queryPrevBlockWithCache ::
324-
MonadIO m =>
352+
(MonadIO m) =>
325353
Text ->
326354
Cache ->
327355
ByteString ->
@@ -342,7 +370,7 @@ queryPrevBlockWithCache msg cache hsh =
342370
Nothing -> queryFromDb ci
343371
where
344372
queryFromDb ::
345-
MonadIO m =>
373+
(MonadIO m) =>
346374
CacheInternal ->
347375
ExceptT SyncNodeError (ReaderT SqlBackend m) DB.BlockId
348376
queryFromDb ci = do
@@ -365,7 +393,7 @@ insertBlockAndCache cache block =
365393
pure bid
366394

367395
queryDatum ::
368-
MonadIO m =>
396+
(MonadIO m) =>
369397
Cache ->
370398
DataHash ->
371399
ReaderT SqlBackend m (Maybe DB.DatumId)

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

+14
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

0 commit comments

Comments
 (0)