diff --git a/cardano-db-sync/cardano-db-sync.cabal b/cardano-db-sync/cardano-db-sync.cabal index f6524707e..c575c6ba9 100644 --- a/cardano-db-sync/cardano-db-sync.cabal +++ b/cardano-db-sync/cardano-db-sync.cabal @@ -63,6 +63,7 @@ library Cardano.DbSync.Era.Byron.Util Cardano.DbSync.Era.Cardano.Insert Cardano.DbSync.Era.Cardano.Util + Cardano.DbSync.Era.Conway.Insert.GovAction Cardano.DbSync.Era.Shelley.Generic Cardano.DbSync.Era.Shelley.Generic.Block Cardano.DbSync.Era.Shelley.Generic.EpochUpdate @@ -83,19 +84,18 @@ library Cardano.DbSync.Era.Shelley.Generic.Tx.Types Cardano.DbSync.Era.Shelley.Generic.Util Cardano.DbSync.Era.Shelley.Generic.Witness - Cardano.DbSync.Era.Shelley.Genesis Cardano.DbSync.Era.Shelley.Query Cardano.DbSync.Era.Universal.Adjust Cardano.DbSync.Era.Universal.Block Cardano.DbSync.Era.Universal.Epoch - Cardano.DbSync.Era.Universal.Validate + Cardano.DbSync.Era.Universal.Genesis Cardano.DbSync.Era.Universal.Insert.Certificate - Cardano.DbSync.Era.Universal.Insert.GovAction Cardano.DbSync.Era.Universal.Insert.Grouped Cardano.DbSync.Era.Universal.Insert.LedgerEvent Cardano.DbSync.Era.Universal.Insert.Other Cardano.DbSync.Era.Universal.Insert.Pool Cardano.DbSync.Era.Universal.Insert.Tx + Cardano.DbSync.Era.Universal.Validate -- Temporary debugging validation @@ -140,6 +140,7 @@ library Cardano.DbSync.Util.Bech32 Cardano.DbSync.Util.Cbor Cardano.DbSync.Util.Constraint + Cardano.DbSync.Util.Whitelist Paths_cardano_db_sync diff --git a/cardano-db-sync/src/Cardano/DbSync.hs b/cardano-db-sync/src/Cardano/DbSync.hs index 743185cf9..3b2013956 100644 --- a/cardano-db-sync/src/Cardano/DbSync.hs +++ b/cardano-db-sync/src/Cardano/DbSync.hs @@ -47,7 +47,6 @@ import Cardano.Prelude hiding (Nat, (%)) import Cardano.Slotting.Slot (EpochNo (..)) import Control.Concurrent.Async import Control.Monad.Extra (whenJust) -import qualified Data.Strict.Maybe as Strict import qualified Data.Text as Text import Data.Version (showVersion) import Database.Persist.Postgresql (ConnectionString, withPostgresqlConn) @@ -160,8 +159,7 @@ runSyncNode :: IO () runSyncNode metricsSetters trce iomgr dbConnString ranMigrations runMigrationFnc syncNodeConfigFromFile syncNodeParams syncOptions = do whenJust maybeLedgerDir $ - \enpLedgerStateDir -> do - createDirectoryIfMissing True (unLedgerStateDir enpLedgerStateDir) + \enpLedgerStateDir -> createDirectoryIfMissing True (unLedgerStateDir enpLedgerStateDir) logInfo trce $ "Using byron genesis file from: " <> (show . unGenesisFile $ dncByronGenesisFile syncNodeConfigFromFile) logInfo trce $ "Using shelley genesis file from: " <> (show . unGenesisFile $ dncShelleyGenesisFile syncNodeConfigFromFile) logInfo trce $ "Using alonzo genesis file from: " <> (show . unGenesisFile $ dncAlonzoGenesisFile syncNodeConfigFromFile) @@ -170,39 +168,38 @@ runSyncNode metricsSetters trce iomgr dbConnString ranMigrations runMigrationFnc Db.runIohkLogging trce $ withPostgresqlConn dbConnString $ - \backend -> liftIO $ do - runOrThrowIO $ runExceptT $ do - genCfg <- readCardanoGenesisConfig syncNodeConfigFromFile - logProtocolMagicId trce $ genesisProtocolMagicId genCfg - syncEnv <- - ExceptT $ - mkSyncEnvFromConfig - trce - backend - dbConnString - syncOptions - genCfg - syncNodeConfigFromFile - syncNodeParams - ranMigrations - runMigrationFnc - liftIO $ runExtraMigrationsMaybe syncEnv - unless useLedger $ liftIO $ do - logInfo trce "Migrating to a no ledger schema" - Db.noLedgerMigrations backend trce - insertValidateGenesisDist syncEnv (dncNetworkName syncNodeConfigFromFile) genCfg (useShelleyInit syncNodeConfigFromFile) + \backend -> liftIO $ runOrThrowIO $ runExceptT $ do + genCfg <- readCardanoGenesisConfig syncNodeConfigFromFile + logProtocolMagicId trce $ genesisProtocolMagicId genCfg + syncEnv <- + ExceptT $ + mkSyncEnvFromConfig + trce + backend + dbConnString + syncOptions + genCfg + syncNodeConfigFromFile + syncNodeParams + ranMigrations + runMigrationFnc + liftIO $ runExtraMigrationsMaybe syncEnv + unless useLedger $ liftIO $ do + logInfo trce "Migrating to a no ledger schema" + Db.noLedgerMigrations backend trce + insertValidateGenesisDist syncEnv (dncNetworkName syncNodeConfigFromFile) genCfg (useShelleyInit syncNodeConfigFromFile) - -- communication channel between datalayer thread and chainsync-client thread - threadChannels <- liftIO newThreadChannels - liftIO $ - mapConcurrently_ - id - [ runDbThread syncEnv metricsSetters threadChannels - , runSyncNodeClient metricsSetters syncEnv iomgr trce threadChannels (enpSocketPath syncNodeParams) - , runFetchOffChainPoolThread syncEnv - , runFetchOffChainVoteThread syncEnv - , runLedgerStateWriteThread (getTrace syncEnv) (envLedgerEnv syncEnv) - ] + -- communication channel between datalayer thread and chainsync-client thread + threadChannels <- liftIO newThreadChannels + liftIO $ + mapConcurrently_ + id + [ runDbThread syncEnv metricsSetters threadChannels + , runSyncNodeClient metricsSetters syncEnv iomgr trce threadChannels (enpSocketPath syncNodeParams) + , runFetchOffChainPoolThread syncEnv + , runFetchOffChainVoteThread syncEnv + , runLedgerStateWriteThread (getTrace syncEnv) (envLedgerEnv syncEnv) + ] where useShelleyInit :: SyncNodeConfig -> Bool useShelleyInit cfg = @@ -245,12 +242,6 @@ extractSyncOptions snp aop snc = , snapshotEveryLagging = enpSnEveryLagging snp } where - maybeKeepMNames = - case sioMetadata (dncInsertOptions snc) of - MetadataKeys ks -> Strict.Just (map fromIntegral $ toList ks) - MetadataEnable -> Strict.Nothing - MetadataDisable -> Strict.Nothing - iopts = InsertOptions { ioInOut = isTxOutEnabled' @@ -258,10 +249,9 @@ extractSyncOptions snp aop snc = , ioShelley = isShelleyEnabled (sioShelley (dncInsertOptions snc)) , -- Rewards are only disabled on "disable_all" and "only_gov" presets ioRewards = True - , ioMultiAssets = isMultiAssetEnabled (sioMultiAsset (dncInsertOptions snc)) - , ioMetadata = isMetadataEnabled (sioMetadata (dncInsertOptions snc)) - , ioKeepMetadataNames = maybeKeepMNames - , ioPlutusExtra = isPlutusEnabled (sioPlutus (dncInsertOptions snc)) + , ioMultiAssets = sioMultiAsset (dncInsertOptions snc) + , ioMetadata = sioMetadata (dncInsertOptions snc) + , ioPlutus = sioPlutus (dncInsertOptions snc) , ioOffChainPoolData = useOffchainPoolData , ioGov = useGovernance } diff --git a/cardano-db-sync/src/Cardano/DbSync/Api/Types.hs b/cardano-db-sync/src/Cardano/DbSync/Api/Types.hs index 87ff8a101..460e02878 100644 --- a/cardano-db-sync/src/Cardano/DbSync/Api/Types.hs +++ b/cardano-db-sync/src/Cardano/DbSync/Api/Types.hs @@ -15,7 +15,7 @@ module Cardano.DbSync.Api.Types ( import qualified Cardano.Db as DB import Cardano.DbSync.Cache.Types (Cache) -import Cardano.DbSync.Config.Types (SyncNodeConfig) +import Cardano.DbSync.Config.Types (MetadataConfig, MultiAssetConfig, PlutusConfig, SyncNodeConfig) import Cardano.DbSync.Ledger.Types (HasLedgerEnv) import Cardano.DbSync.LocalStateQuery (NoLedgerEnv) import Cardano.DbSync.Types ( @@ -74,16 +74,15 @@ data SyncOptions = SyncOptions deriving (Show) data InsertOptions = InsertOptions - { ioInOut :: !Bool - , ioUseLedger :: !Bool - , ioShelley :: !Bool - , ioRewards :: !Bool - , ioMultiAssets :: !Bool - , ioMetadata :: !Bool - , ioKeepMetadataNames :: Strict.Maybe [Word64] - , ioPlutusExtra :: !Bool + { ioGov :: !Bool + , ioInOut :: !Bool + , ioMetadata :: !MetadataConfig + , ioMultiAssets :: !MultiAssetConfig , ioOffChainPoolData :: !Bool - , ioGov :: !Bool + , ioPlutus :: !PlutusConfig + , ioRewards :: !Bool + , ioShelley :: !Bool + , ioUseLedger :: !Bool } deriving (Show) diff --git a/cardano-db-sync/src/Cardano/DbSync/Config/Types.hs b/cardano-db-sync/src/Cardano/DbSync/Config/Types.hs index 4814deb2f..df9ba8a87 100644 --- a/cardano-db-sync/src/Cardano/DbSync/Config/Types.hs +++ b/cardano-db-sync/src/Cardano/DbSync/Config/Types.hs @@ -189,7 +189,8 @@ data LedgerInsertConfig data ShelleyInsertConfig = ShelleyEnable | ShelleyDisable - | ShelleyStakeAddrs (NonEmpty ShortByteString) + | -- Whitelist of Shelley stake addresses + ShelleyStakeAddrs (NonEmpty ShortByteString) deriving (Eq, Show) newtype RewardsConfig = RewardsConfig @@ -199,19 +200,22 @@ newtype RewardsConfig = RewardsConfig data MultiAssetConfig = MultiAssetEnable | MultiAssetDisable - | MultiAssetPolicies (NonEmpty ShortByteString) + | -- | Whitelist of multiAsset policy IDs + MultiAssetPolicies (NonEmpty ShortByteString) deriving (Eq, Show) data MetadataConfig = MetadataEnable | MetadataDisable - | MetadataKeys (NonEmpty Word) + | -- | Whitelist of metadata keys + MetadataKeys (NonEmpty Word) deriving (Eq, Show) data PlutusConfig = PlutusEnable | PlutusDisable - | PlutusScripts (NonEmpty ShortByteString) + | -- | Whitelist of plutus script hashes + PlutusScripts (NonEmpty ShortByteString) deriving (Eq, Show) newtype GovernanceConfig = GovernanceConfig diff --git a/cardano-db-sync/src/Cardano/DbSync/Default.hs b/cardano-db-sync/src/Cardano/DbSync/Default.hs index bb65ed12e..cbfc5cd23 100644 --- a/cardano-db-sync/src/Cardano/DbSync/Default.hs +++ b/cardano-db-sync/src/Cardano/DbSync/Default.hs @@ -18,6 +18,7 @@ import Cardano.DbSync.Api.Ledger import Cardano.DbSync.Api.Types (ConsistentLevel (..), InsertOptions (..), LedgerEnv (..), SyncEnv (..), SyncOptions (..)) import Cardano.DbSync.Epoch (epochHandler) import Cardano.DbSync.Era.Byron.Insert (insertByronBlock) + import qualified Cardano.DbSync.Era.Shelley.Generic as Generic import Cardano.DbSync.Era.Universal.Block (insertBlockUniversal) import Cardano.DbSync.Era.Universal.Epoch (hasEpochStartEvent, hasNewEpochEvent) @@ -165,15 +166,15 @@ insertBlock syncEnv cblk applyRes firstAfterRollback tookSnapshot = do BlockAlonzo blk -> newExceptT $ insertBlockUniversal' $ - Generic.fromAlonzoBlock (ioPlutusExtra iopts) (getPrices applyResult) blk + Generic.fromAlonzoBlock (ioPlutus iopts) (getPrices applyResult) blk BlockBabbage blk -> newExceptT $ insertBlockUniversal' $ - Generic.fromBabbageBlock (ioPlutusExtra iopts) (getPrices applyResult) blk + Generic.fromBabbageBlock (ioPlutus iopts) (getPrices applyResult) blk BlockConway blk -> newExceptT $ insertBlockUniversal' $ - Generic.fromConwayBlock (ioPlutusExtra iopts) (getPrices applyResult) blk + Generic.fromConwayBlock (ioPlutus iopts) (getPrices applyResult) blk -- update the epoch updateEpoch details isNewEpochEvent whenPruneTxOut syncEnv $ diff --git a/cardano-db-sync/src/Cardano/DbSync/Era.hs b/cardano-db-sync/src/Cardano/DbSync/Era.hs index 32c203f20..90bba42fb 100644 --- a/cardano-db-sync/src/Cardano/DbSync/Era.hs +++ b/cardano-db-sync/src/Cardano/DbSync/Era.hs @@ -9,7 +9,7 @@ module Cardano.DbSync.Era ( import Cardano.DbSync.Api.Types (SyncEnv) import Cardano.DbSync.Config import qualified Cardano.DbSync.Era.Byron.Genesis as Byron -import qualified Cardano.DbSync.Era.Shelley.Genesis as Shelley +import qualified Cardano.DbSync.Era.Universal.Genesis as Shelley import Cardano.DbSync.Error import Cardano.Prelude diff --git a/cardano-db-sync/src/Cardano/DbSync/Era/Conway/GovAction.hs b/cardano-db-sync/src/Cardano/DbSync/Era/Conway/Insert/GovAction.hs similarity index 95% rename from cardano-db-sync/src/Cardano/DbSync/Era/Conway/GovAction.hs rename to cardano-db-sync/src/Cardano/DbSync/Era/Conway/Insert/GovAction.hs index 5156251e4..dc17b418c 100644 --- a/cardano-db-sync/src/Cardano/DbSync/Era/Conway/GovAction.hs +++ b/cardano-db-sync/src/Cardano/DbSync/Era/Conway/Insert/GovAction.hs @@ -8,7 +8,7 @@ {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE NoImplicitPrelude #-} -module Cardano.DbSync.Era.Conway.GovAction ( +module Cardano.DbSync.Era.Conway.Insert.GovAction ( insertConstitution, insertCostModel, insertCredDrepHash, @@ -47,10 +47,12 @@ import Cardano.Ledger.Conway.Governance import qualified Cardano.Ledger.Credential as Ledger import Cardano.Ledger.DRep (DRepState (..)) import Cardano.Ledger.Keys (KeyRole (..)) -import qualified Cardano.Ledger.Plutus.CostModels as Ledger +import Cardano.Ledger.Plutus.CostModels (CostModel) import Cardano.Ledger.Plutus.Language (Language) import Cardano.Ledger.Shelley.API (Coin (..)) import Cardano.Prelude + +import Cardano.Ledger.Plutus (mkCostModels) import Control.Monad.Extra (whenJust) import Control.Monad.Trans.Control (MonadBaseControl) import qualified Data.Aeson as Aeson @@ -72,7 +74,7 @@ insertGovActionProposal :: insertGovActionProposal cache blkId txId govExpiresAt (index, pp) = do addrId <- lift $ queryOrInsertRewardAccount cache CacheNew $ pProcReturnAddr pp - votingAnchorId <- lift $ insertAnchor txId $ pProcAnchor pp + votingAnchorId <- lift $ insertVotingAnchor txId $ pProcAnchor pp mParamProposalId <- lift $ case pProcGovAction pp of ParameterChange _ pparams _ -> @@ -286,15 +288,6 @@ insertVotingAnchor txId anchor = , DB.votingAnchorDataHash = Generic.safeHashToByteString $ anchorDataHash anchor } -insertAnchor :: (MonadIO m, MonadBaseControl IO m) => DB.TxId -> Anchor StandardCrypto -> ReaderT SqlBackend m DB.VotingAnchorId -insertAnchor txId anchor = - DB.insertAnchor $ - DB.VotingAnchor - { DB.votingAnchorTxId = txId - , DB.votingAnchorUrl = DB.VoteUrl $ Ledger.urlToText $ anchorUrl anchor -- TODO: Conway check unicode and size of URL - , DB.votingAnchorDataHash = Generic.safeHashToByteString $ anchorDataHash anchor - } - -------------------------------------------------------------------------------------- -- DREP -------------------------------------------------------------------------------------- @@ -340,21 +333,19 @@ insertDrepDistr e pSnapshot = do insertCostModel :: (MonadBaseControl IO m, MonadIO m) => DB.BlockId -> - Map Language Ledger.CostModel -> + Map Language CostModel -> ReaderT SqlBackend m DB.CostModelId insertCostModel _blkId cms = DB.insertCostModel $ DB.CostModel - { DB.costModelHash = Crypto.abstractHashToBytes $ Crypto.serializeCborHash $ Ledger.mkCostModels cms + { DB.costModelHash = Crypto.abstractHashToBytes $ Crypto.serializeCborHash $ mkCostModels cms , DB.costModelCosts = Text.decodeUtf8 $ LBS.toStrict $ Aeson.encode cms } updateEnacted :: forall m. (MonadBaseControl IO m, MonadIO m) => Bool -> EpochNo -> EnactState StandardConway -> ExceptT SyncNodeError (ReaderT SqlBackend m) () updateEnacted isEnacted epochNo enactedState = do whenJust (strictMaybeToMaybe (enactedState ^. ensPrevPParamUpdateL)) $ \prevId -> do - gaId <- resolveGovActionProposal $ getPrevId prevId + gaId <- resolveGovActionProposal $ unGovPurposeId prevId if isEnacted then lift $ DB.updateGovActionEnacted gaId (unEpochNo epochNo) else lift $ DB.updateGovActionRatified gaId (unEpochNo epochNo) - where - getPrevId = unGovPurposeId diff --git a/cardano-db-sync/src/Cardano/DbSync/Era/Shelley/Generic/Block.hs b/cardano-db-sync/src/Cardano/DbSync/Era/Shelley/Generic/Block.hs index e74620297..ed8db311a 100644 --- a/cardano-db-sync/src/Cardano/DbSync/Era/Shelley/Generic/Block.hs +++ b/cardano-db-sync/src/Cardano/DbSync/Era/Shelley/Generic/Block.hs @@ -25,6 +25,7 @@ module Cardano.DbSync.Era.Shelley.Generic.Block ( import qualified Cardano.Crypto.Hash as Crypto import qualified Cardano.Crypto.KES.Class as KES +import Cardano.DbSync.Config.Types (PlutusConfig) import Cardano.DbSync.Era.Shelley.Generic.Tx import Cardano.DbSync.Types import Cardano.DbSync.Util.Bech32 (serialiseVerKeyVrfToBech32) @@ -120,8 +121,8 @@ fromMaryBlock blk = , blkTxs = map fromMaryTx (getTxs blk) } -fromAlonzoBlock :: Bool -> Maybe Prices -> ShelleyBlock TPraosStandard StandardAlonzo -> Block -fromAlonzoBlock iope mprices blk = +fromAlonzoBlock :: PlutusConfig -> Maybe Prices -> ShelleyBlock TPraosStandard StandardAlonzo -> Block +fromAlonzoBlock plutusConfig mprices blk = Block { blkEra = Alonzo , blkHash = blockHash blk @@ -134,11 +135,11 @@ fromAlonzoBlock iope mprices blk = , blkVrfKey = blockVrfKeyView $ blockVrfVkTPraos blk , blkOpCert = blockOpCertKeyTPraos blk , blkOpCertCounter = blockOpCertCounterTPraos blk - , blkTxs = map (fromAlonzoTx iope mprices) (getTxs blk) + , blkTxs = map (fromAlonzoTx plutusConfig mprices) (getTxs blk) } -fromBabbageBlock :: Bool -> Maybe Prices -> ShelleyBlock PraosStandard StandardBabbage -> Block -fromBabbageBlock iope mprices blk = +fromBabbageBlock :: PlutusConfig -> Maybe Prices -> ShelleyBlock PraosStandard StandardBabbage -> Block +fromBabbageBlock plutusConfig mprices blk = Block { blkEra = Babbage , blkHash = blockHash blk @@ -151,11 +152,11 @@ fromBabbageBlock iope mprices blk = , blkVrfKey = blockVrfKeyView $ blockVrfVkPraos blk , blkOpCert = blockOpCertKeyPraos blk , blkOpCertCounter = blockOpCertCounterPraos blk - , blkTxs = map (fromBabbageTx iope mprices) (getTxs blk) + , blkTxs = map (fromBabbageTx plutusConfig mprices) (getTxs blk) } -fromConwayBlock :: Bool -> Maybe Prices -> ShelleyBlock PraosStandard StandardConway -> Block -fromConwayBlock iope mprices blk = +fromConwayBlock :: PlutusConfig -> Maybe Prices -> ShelleyBlock PraosStandard StandardConway -> Block +fromConwayBlock plutusConfig mprices blk = Block { blkEra = Conway , blkHash = blockHash blk @@ -168,7 +169,7 @@ fromConwayBlock iope mprices blk = , blkVrfKey = blockVrfKeyView $ blockVrfVkPraos blk , blkOpCert = blockOpCertKeyPraos blk , blkOpCertCounter = blockOpCertCounterPraos blk - , blkTxs = map (fromConwayTx iope mprices) (getTxs blk) + , blkTxs = map (fromConwayTx plutusConfig mprices) (getTxs blk) } -- ------------------------------------------------------------------------------------------------- diff --git a/cardano-db-sync/src/Cardano/DbSync/Era/Shelley/Generic/Tx/Alonzo.hs b/cardano-db-sync/src/Cardano/DbSync/Era/Shelley/Generic/Tx/Alonzo.hs index 44918d97d..dd3b93691 100644 --- a/cardano-db-sync/src/Cardano/DbSync/Era/Shelley/Generic/Tx/Alonzo.hs +++ b/cardano-db-sync/src/Cardano/DbSync/Era/Shelley/Generic/Tx/Alonzo.hs @@ -27,6 +27,7 @@ module Cardano.DbSync.Era.Shelley.Generic.Tx.Alonzo ( import qualified Cardano.Crypto.Hash as Crypto import Cardano.Db (ScriptType (..)) +import Cardano.DbSync.Config.Types (PlutusConfig, isPlutusEnabled) import Cardano.DbSync.Era.Shelley.Generic.Metadata import Cardano.DbSync.Era.Shelley.Generic.Script (fromTimelock) import Cardano.DbSync.Era.Shelley.Generic.ScriptData (ScriptData (..)) @@ -66,8 +67,8 @@ import qualified Data.Set as Set import Lens.Micro import Ouroboros.Consensus.Cardano.Block (EraCrypto, StandardAlonzo, StandardCrypto) -fromAlonzoTx :: Bool -> Maybe Alonzo.Prices -> (Word64, Core.Tx StandardAlonzo) -> Tx -fromAlonzoTx ioExtraPlutus mprices (blkIndex, tx) = +fromAlonzoTx :: PlutusConfig -> Maybe Alonzo.Prices -> (Word64, Core.Tx StandardAlonzo) -> Tx +fromAlonzoTx plutusConfig mprices (blkIndex, tx) = Tx { txHash = txHashId tx , txBlockIndex = blkIndex @@ -129,7 +130,7 @@ fromAlonzoTx ioExtraPlutus mprices (blkIndex, tx) = MaryValue ada (MultiAsset maMap) = txOut ^. Core.valueTxOutL mDataHash = txOut ^. Alonzo.dataHashTxOutL - (finalMaps, redeemers) = resolveRedeemers ioExtraPlutus mprices tx (Left . toShelleyCert) + (finalMaps, redeemers) = resolveRedeemers plutusConfig mprices tx (Left . toShelleyCert) -- This is true if second stage contract validation passes or there are no contracts. isValid2 :: Bool @@ -178,13 +179,13 @@ resolveRedeemers :: , Core.EraTx era , DBScriptPurpose era ) => - Bool -> + PlutusConfig -> Maybe Alonzo.Prices -> Core.Tx era -> (TxCert era -> Cert) -> (RedeemerMaps, [(Word64, TxRedeemer)]) -resolveRedeemers ioExtraPlutus mprices tx toCert = - if not ioExtraPlutus +resolveRedeemers plutusConfig mprices tx toCert = + if not $ isPlutusEnabled plutusConfig then (initRedeemersMaps, []) else mkRdmrAndUpdateRec (initRedeemersMaps, []) $ diff --git a/cardano-db-sync/src/Cardano/DbSync/Era/Shelley/Generic/Tx/Babbage.hs b/cardano-db-sync/src/Cardano/DbSync/Era/Shelley/Generic/Tx/Babbage.hs index ad703543f..6966d26ac 100644 --- a/cardano-db-sync/src/Cardano/DbSync/Era/Shelley/Generic/Tx/Babbage.hs +++ b/cardano-db-sync/src/Cardano/DbSync/Era/Shelley/Generic/Tx/Babbage.hs @@ -6,6 +6,7 @@ {-# LANGUAGE TypeApplications #-} {-# LANGUAGE TypeOperators #-} {-# LANGUAGE NoImplicitPrelude #-} +{-# OPTIONS_GHC -Wno-unused-matches #-} module Cardano.DbSync.Era.Shelley.Generic.Tx.Babbage ( fromBabbageTx, @@ -13,6 +14,7 @@ module Cardano.DbSync.Era.Shelley.Generic.Tx.Babbage ( fromTxOut, ) where +import Cardano.DbSync.Config.Types (PlutusConfig) import Cardano.DbSync.Era.Shelley.Generic.Metadata import Cardano.DbSync.Era.Shelley.Generic.Tx.Allegra (getInterval) import Cardano.DbSync.Era.Shelley.Generic.Tx.Alonzo @@ -34,8 +36,8 @@ import qualified Data.Map.Strict as Map import Lens.Micro import Ouroboros.Consensus.Shelley.Eras (StandardBabbage, StandardCrypto) -fromBabbageTx :: Bool -> Maybe Alonzo.Prices -> (Word64, Core.Tx StandardBabbage) -> Tx -fromBabbageTx ioExtraPlutus mprices (blkIndex, tx) = +fromBabbageTx :: PlutusConfig -> Maybe Alonzo.Prices -> (Word64, Core.Tx StandardBabbage) -> Tx +fromBabbageTx plutusConfig mprices (blkIndex, tx) = Tx { txHash = txHashId tx , txBlockIndex = blkIndex @@ -101,7 +103,7 @@ fromBabbageTx ioExtraPlutus mprices (blkIndex, tx) = case Alonzo.isValid tx of Alonzo.IsValid x -> x - (finalMaps, redeemers) = resolveRedeemers ioExtraPlutus mprices tx (Left . toShelleyCert) + (finalMaps, redeemers) = resolveRedeemers plutusConfig mprices tx (Left . toShelleyCert) (invalidBef, invalidAfter) = getInterval txBody collInputs = mkCollTxIn txBody diff --git a/cardano-db-sync/src/Cardano/DbSync/Era/Shelley/Generic/Tx/Conway.hs b/cardano-db-sync/src/Cardano/DbSync/Era/Shelley/Generic/Tx/Conway.hs index a91da32a2..d6a926a45 100644 --- a/cardano-db-sync/src/Cardano/DbSync/Era/Shelley/Generic/Tx/Conway.hs +++ b/cardano-db-sync/src/Cardano/DbSync/Era/Shelley/Generic/Tx/Conway.hs @@ -8,6 +8,7 @@ module Cardano.DbSync.Era.Shelley.Generic.Tx.Conway ( fromConwayTx, ) where +import Cardano.DbSync.Config.Types (PlutusConfig) import Cardano.DbSync.Era.Shelley.Generic.Metadata import Cardano.DbSync.Era.Shelley.Generic.Tx.Allegra (getInterval) import Cardano.DbSync.Era.Shelley.Generic.Tx.Alonzo @@ -26,8 +27,8 @@ import qualified Data.Map.Strict as Map import Lens.Micro import Ouroboros.Consensus.Cardano.Block (StandardConway) -fromConwayTx :: Bool -> Maybe Alonzo.Prices -> (Word64, Core.Tx StandardConway) -> Tx -fromConwayTx ioExtraPlutus mprices (blkIndex, tx) = +fromConwayTx :: PlutusConfig -> Maybe Alonzo.Prices -> (Word64, Core.Tx StandardConway) -> Tx +fromConwayTx plutusConfig mprices (blkIndex, tx) = Tx { txHash = txHashId tx , txBlockIndex = blkIndex @@ -93,7 +94,7 @@ fromConwayTx ioExtraPlutus mprices (blkIndex, tx) = case Alonzo.isValid tx of Alonzo.IsValid x -> x - (finalMaps, redeemers) = resolveRedeemers ioExtraPlutus mprices tx Right + (finalMaps, redeemers) = resolveRedeemers plutusConfig mprices tx Right (invalidBef, invalidAfter) = getInterval txBody collInputs = mkCollTxIn txBody diff --git a/cardano-db-sync/src/Cardano/DbSync/Era/Universal/Block.hs b/cardano-db-sync/src/Cardano/DbSync/Era/Universal/Block.hs index 5fbe707e6..aac083232 100644 --- a/cardano-db-sync/src/Cardano/DbSync/Era/Universal/Block.hs +++ b/cardano-db-sync/src/Cardano/DbSync/Era/Universal/Block.hs @@ -15,17 +15,15 @@ import Cardano.BM.Trace (Trace, logDebug, logInfo) import qualified Cardano.Db as DB import Cardano.DbSync.Api import Cardano.DbSync.Api.Types (InsertOptions (..), SyncEnv (..), SyncOptions (..)) -import Cardano.DbSync.Cache ( - insertBlockAndCache, - queryPoolKeyWithCache, - queryPrevBlockWithCache, - ) +import Cardano.DbSync.Cache (insertBlockAndCache, queryPoolKeyWithCache, queryPrevBlockWithCache) import Cardano.DbSync.Cache.Epoch (writeEpochBlockDiffToCache) import Cardano.DbSync.Cache.Types (Cache (..), CacheNew (..), EpochBlockDiff (..)) - import qualified Cardano.DbSync.Era.Shelley.Generic as Generic import Cardano.DbSync.Era.Universal.Epoch import Cardano.DbSync.Era.Universal.Insert.Grouped +import Cardano.DbSync.Era.Universal.Insert.Pool ( + IsPoolMember, + ) import Cardano.DbSync.Era.Universal.Insert.Tx (insertTx) import Cardano.DbSync.Era.Util (liftLookupFail) import Cardano.DbSync.Error @@ -33,13 +31,10 @@ import Cardano.DbSync.Ledger.Types (ApplyResult (..)) import Cardano.DbSync.OffChain import Cardano.DbSync.Types import Cardano.DbSync.Util - -import Cardano.DbSync.Era.Universal.Insert.Pool (IsPoolMember) import Cardano.Ledger.BaseTypes import qualified Cardano.Ledger.BaseTypes as Ledger import Cardano.Ledger.Keys import Cardano.Prelude - import Control.Monad.Trans.Control (MonadBaseControl) import Control.Monad.Trans.Except.Extra (newExceptT) import Data.Either.Extra (eitherToMaybe) @@ -47,7 +42,6 @@ import Database.Persist.Sql (SqlBackend) -------------------------------------------------------------------------------------------- -- Insert a universal Block. --- This is the entry point for inserting a block into the database, used for all eras appart from Byron. -------------------------------------------------------------------------------------------- insertBlockUniversal :: (MonadBaseControl IO m, MonadIO m) => @@ -175,8 +169,8 @@ insertBlockUniversal syncEnv shouldLog withinTwoMins withinHalfHour blk details renderErrorMessage :: Generic.BlockEra -> Text renderErrorMessage eraText = case eraText of - Generic.Shelley -> "insertBlockForEra" - other -> mconcat ["insertBlockForEra(", textShow other, ")"] + Generic.Shelley -> "insertBlockUniversal" + other -> mconcat ["insertBlockUniversal(", textShow other, ")"] tracer :: Trace IO Text tracer = getTrace syncEnv diff --git a/cardano-db-sync/src/Cardano/DbSync/Era/Universal/Epoch.hs b/cardano-db-sync/src/Cardano/DbSync/Era/Universal/Epoch.hs index ada957458..b25d969d6 100644 --- a/cardano-db-sync/src/Cardano/DbSync/Era/Universal/Epoch.hs +++ b/cardano-db-sync/src/Cardano/DbSync/Era/Universal/Epoch.hs @@ -28,14 +28,20 @@ import Cardano.DbSync.Cache (queryOrInsertStakeAddress, queryPoolKeyOrInsert) import Cardano.DbSync.Cache.Types (Cache, CacheNew (..)) import qualified Cardano.DbSync.Era.Shelley.Generic as Generic import Cardano.DbSync.Era.Universal.Insert.Certificate (insertPots) -import Cardano.DbSync.Era.Universal.Insert.GovAction (insertCostModel, insertDrepDistr, updateEnacted) +import Cardano.DbSync.Era.Conway.Insert.GovAction (insertCostModel, insertDrepDistr, updateEnacted) import Cardano.DbSync.Era.Universal.Insert.Other (toDouble) import Cardano.DbSync.Error import Cardano.DbSync.Ledger.Event (LedgerEvent (..)) import Cardano.DbSync.Types import Cardano.DbSync.Util (whenStrictJust) -import Cardano.DbSync.Util.Constraint (constraintNameEpochStake, constraintNameReward) -import Cardano.Ledger.BaseTypes (Network, unEpochInterval) +import Cardano.DbSync.Util.Constraint ( + constraintNameEpochStake, + constraintNameReward, + ) +import Cardano.Ledger.BaseTypes ( + Network, + unEpochInterval, + ) import qualified Cardano.Ledger.BaseTypes as Ledger import Cardano.Ledger.Binary.Version (getVersion) import qualified Cardano.Ledger.Coin as Shelley @@ -51,8 +57,6 @@ import qualified Data.Map.Strict as Map import qualified Data.Set as Set import Database.Persist.Sql (SqlBackend) -{- HLINT ignore "Use readTVarIO" -} - -------------------------------------------------------------------------------------------- -- Insert Epoch -------------------------------------------------------------------------------------------- diff --git a/cardano-db-sync/src/Cardano/DbSync/Era/Shelley/Genesis.hs b/cardano-db-sync/src/Cardano/DbSync/Era/Universal/Genesis.hs similarity index 98% rename from cardano-db-sync/src/Cardano/DbSync/Era/Shelley/Genesis.hs rename to cardano-db-sync/src/Cardano/DbSync/Era/Universal/Genesis.hs index af3e9b391..67847105b 100644 --- a/cardano-db-sync/src/Cardano/DbSync/Era/Shelley/Genesis.hs +++ b/cardano-db-sync/src/Cardano/DbSync/Era/Universal/Genesis.hs @@ -7,7 +7,7 @@ {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE NoImplicitPrelude #-} -module Cardano.DbSync.Era.Shelley.Genesis ( +module Cardano.DbSync.Era.Universal.Genesis ( insertValidateGenesisDist, ) where @@ -17,7 +17,10 @@ import Cardano.DbSync.Api import Cardano.DbSync.Api.Types (SyncEnv (envBackend)) import Cardano.DbSync.Cache.Types (Cache (..), uninitiatedCache) import qualified Cardano.DbSync.Era.Shelley.Generic.Util as Generic -import Cardano.DbSync.Era.Universal.Insert.Certificate (insertDelegation, insertStakeRegistration) +import Cardano.DbSync.Era.Universal.Insert.Certificate ( + insertDelegation, + insertStakeRegistration, + ) import Cardano.DbSync.Era.Universal.Insert.Other (insertStakeAddressRefIfMissing) import Cardano.DbSync.Era.Universal.Insert.Pool (insertPoolRegister) import Cardano.DbSync.Era.Util (liftLookupFail) diff --git a/cardano-db-sync/src/Cardano/DbSync/Era/Universal/Insert/Certificate.hs b/cardano-db-sync/src/Cardano/DbSync/Era/Universal/Insert/Certificate.hs index 66e6df09f..08df28fcb 100644 --- a/cardano-db-sync/src/Cardano/DbSync/Era/Universal/Insert/Certificate.hs +++ b/cardano-db-sync/src/Cardano/DbSync/Era/Universal/Insert/Certificate.hs @@ -35,7 +35,11 @@ import Cardano.DbSync.Cache ( ) import Cardano.DbSync.Cache.Types (Cache (..), CacheNew (..)) import qualified Cardano.DbSync.Era.Shelley.Generic as Generic -import Cardano.DbSync.Era.Universal.Insert.GovAction (insertCredDrepHash, insertDrep, insertVotingAnchor) +import Cardano.DbSync.Era.Conway.Insert.GovAction ( + insertCredDrepHash, + insertDrep, + insertVotingAnchor, + ) import Cardano.DbSync.Era.Universal.Insert.Pool (IsPoolMember, insertPoolCert) import Cardano.DbSync.Error import Cardano.DbSync.Types @@ -59,6 +63,9 @@ import qualified Data.Map.Strict as Map import Database.Persist.Sql (SqlBackend) import Ouroboros.Consensus.Cardano.Block (StandardCrypto) +-------------------------------------------------------------------------------------------- +-- Insert Certificates +-------------------------------------------------------------------------------------------- insertCertificate :: (MonadBaseControl IO m, MonadIO m) => SyncEnv -> diff --git a/cardano-db-sync/src/Cardano/DbSync/Era/Universal/Insert/GovAction.hs b/cardano-db-sync/src/Cardano/DbSync/Era/Universal/Insert/GovAction.hs deleted file mode 100644 index aeee9493c..000000000 --- a/cardano-db-sync/src/Cardano/DbSync/Era/Universal/Insert/GovAction.hs +++ /dev/null @@ -1,360 +0,0 @@ -{-# LANGUAGE AllowAmbiguousTypes #-} -{-# LANGUAGE DataKinds #-} -{-# LANGUAGE FlexibleContexts #-} -{-# LANGUAGE LambdaCase #-} -{-# LANGUAGE OverloadedStrings #-} -{-# LANGUAGE RankNTypes #-} -{-# LANGUAGE ScopedTypeVariables #-} -{-# LANGUAGE TypeFamilies #-} -{-# LANGUAGE NoImplicitPrelude #-} - -module Cardano.DbSync.Era.Universal.Insert.GovAction ( - insertConstitution, - insertCostModel, - insertCredDrepHash, - insertDrep, - insertDrepDistr, - insertGovActionProposal, - insertParamProposal, - insertVotingProcedures, - insertVotingAnchor, - resolveGovActionProposal, - updateEnacted, -) -where - -import Cardano.BM.Trace (Trace) -import qualified Cardano.Crypto as Crypto -import Cardano.Db (DbWord64 (..)) -import qualified Cardano.Db as DB -import Cardano.DbSync.Cache (queryOrInsertRewardAccount, queryPoolKeyOrInsert) -import Cardano.DbSync.Cache.Types (Cache (..), CacheNew (..)) -import qualified Cardano.DbSync.Era.Shelley.Generic as Generic -import Cardano.DbSync.Era.Shelley.Generic.ParamProposal -import Cardano.DbSync.Era.Universal.Insert.Other (toDouble) -import Cardano.DbSync.Era.Util (liftLookupFail) -import Cardano.DbSync.Error -import Cardano.DbSync.Util -import Cardano.DbSync.Util.Bech32 (serialiseDrepToBech32) -import Cardano.Ledger.BaseTypes -import qualified Cardano.Ledger.BaseTypes as Ledger -import Cardano.Ledger.CertState (DRep (..)) -import Cardano.Ledger.Coin (Coin) -import qualified Cardano.Ledger.Coin as Ledger -import Cardano.Ledger.Compactible (Compactible (..)) -import Cardano.Ledger.Conway.Core (DRepVotingThresholds (..), PoolVotingThresholds (..)) -import Cardano.Ledger.Conway.Governance -import qualified Cardano.Ledger.Credential as Ledger -import Cardano.Ledger.DRep (DRepState (..)) -import Cardano.Ledger.Keys (KeyRole (..)) -import qualified Cardano.Ledger.Plutus.CostModels as Ledger -import Cardano.Ledger.Plutus.Language (Language) -import Cardano.Ledger.Shelley.API (Coin (..)) -import Cardano.Prelude -import Control.Monad.Extra (whenJust) -import Control.Monad.Trans.Control (MonadBaseControl) -import qualified Data.Aeson as Aeson -import qualified Data.ByteString.Lazy.Char8 as LBS -import qualified Data.Map.Strict as Map -import qualified Data.Text.Encoding as Text -import Database.Persist.Sql (SqlBackend) -import Lens.Micro ((^.)) -import Ouroboros.Consensus.Cardano.Block (StandardConway, StandardCrypto) - -insertGovActionProposal :: - (MonadIO m, MonadBaseControl IO m) => - Cache -> - DB.BlockId -> - DB.TxId -> - Maybe EpochNo -> - (Word64, ProposalProcedure StandardConway) -> - ExceptT SyncNodeError (ReaderT SqlBackend m) () -insertGovActionProposal cache blkId txId govExpiresAt (index, pp) = do - addrId <- - lift $ queryOrInsertRewardAccount cache CacheNew $ pProcReturnAddr pp - votingAnchorId <- lift $ insertAnchor txId $ pProcAnchor pp - mParamProposalId <- lift $ - case pProcGovAction pp of - ParameterChange _ pparams _ -> - Just <$> insertParamProposal blkId txId (convertConwayParamProposal pparams) - _ -> pure Nothing - prevGovActionDBId <- case mprevGovAction of - Nothing -> pure Nothing - Just prevGovActionId -> Just <$> resolveGovActionProposal prevGovActionId - govActionProposalId <- - lift $ - DB.insertGovActionProposal $ - DB.GovActionProposal - { DB.govActionProposalTxId = txId - , DB.govActionProposalIndex = index - , DB.govActionProposalPrevGovActionProposal = prevGovActionDBId - , DB.govActionProposalDeposit = Generic.coinToDbLovelace $ pProcDeposit pp - , DB.govActionProposalReturnAddress = addrId - , DB.govActionProposalExpiration = unEpochNo <$> govExpiresAt - , DB.govActionProposalVotingAnchorId = Just votingAnchorId - , DB.govActionProposalType = Generic.toGovAction $ pProcGovAction pp - , DB.govActionProposalDescription = Text.decodeUtf8 $ LBS.toStrict $ Aeson.encode (pProcGovAction pp) - , DB.govActionProposalParamProposal = mParamProposalId - , DB.govActionProposalRatifiedEpoch = Nothing - , DB.govActionProposalEnactedEpoch = Nothing - , DB.govActionProposalDroppedEpoch = Nothing - , DB.govActionProposalExpiredEpoch = Nothing - } - case pProcGovAction pp of - TreasuryWithdrawals mp _ -> lift $ mapM_ (insertTreasuryWithdrawal govActionProposalId) (Map.toList mp) - UpdateCommittee _ removed added q -> lift $ insertNewCommittee govActionProposalId removed added q - NewConstitution _ constitution -> lift $ insertConstitution txId govActionProposalId constitution - _ -> pure () - where - mprevGovAction :: Maybe (GovActionId StandardCrypto) = case pProcGovAction pp of - ParameterChange prv _ _ -> unGovPurposeId <$> strictMaybeToMaybe prv - HardForkInitiation prv _ -> unGovPurposeId <$> strictMaybeToMaybe prv - NoConfidence prv -> unGovPurposeId <$> strictMaybeToMaybe prv - UpdateCommittee prv _ _ _ -> unGovPurposeId <$> strictMaybeToMaybe prv - NewConstitution prv _ -> unGovPurposeId <$> strictMaybeToMaybe prv - _ -> Nothing - - insertTreasuryWithdrawal gaId (rwdAcc, coin) = do - addrId <- - queryOrInsertRewardAccount cache CacheNew rwdAcc - DB.insertTreasuryWithdrawal $ - DB.TreasuryWithdrawal - { DB.treasuryWithdrawalGovActionProposalId = gaId - , DB.treasuryWithdrawalStakeAddressId = addrId - , DB.treasuryWithdrawalAmount = Generic.coinToDbLovelace coin - } - - insertNewCommittee gaId removed added q = do - void . DB.insertNewCommittee $ - DB.NewCommittee - { DB.newCommitteeGovActionProposalId = gaId - , DB.newCommitteeQuorumNumerator = fromIntegral $ numerator r - , DB.newCommitteeQuorumDenominator = fromIntegral $ denominator r - , DB.newCommitteeDeletedMembers = textShow removed - , DB.newCommitteeAddedMembers = textShow added - } - where - r = unboundRational q -- TODO work directly with Ratio Word64. This is not currently supported in ledger - --------------------------------------------------------------------------------------- --- PROPOSAL --------------------------------------------------------------------------------------- -resolveGovActionProposal :: - MonadIO m => - GovActionId StandardCrypto -> - ExceptT SyncNodeError (ReaderT SqlBackend m) DB.GovActionProposalId -resolveGovActionProposal gaId = do - gaTxId <- - liftLookupFail "resolveGovActionProposal.queryTxId" $ - DB.queryTxId $ - Generic.unTxHash $ - gaidTxId gaId - let (GovActionIx index) = gaidGovActionIx gaId - liftLookupFail "resolveGovActionProposal.queryGovActionProposalId" $ - DB.queryGovActionProposalId gaTxId (fromIntegral index) -- TODO: Use Word32? - -insertParamProposal :: - (MonadBaseControl IO m, MonadIO m) => - DB.BlockId -> - DB.TxId -> - ParamProposal -> - ReaderT SqlBackend m DB.ParamProposalId -insertParamProposal blkId txId pp = do - cmId <- maybe (pure Nothing) (fmap Just . insertCostModel blkId) (pppCostmdls pp) - DB.insertParamProposal $ - DB.ParamProposal - { DB.paramProposalRegisteredTxId = txId - , DB.paramProposalEpochNo = unEpochNo <$> pppEpochNo pp - , DB.paramProposalKey = pppKey pp - , DB.paramProposalMinFeeA = fromIntegral <$> pppMinFeeA pp - , DB.paramProposalMinFeeB = fromIntegral <$> pppMinFeeB pp - , DB.paramProposalMaxBlockSize = fromIntegral <$> pppMaxBlockSize pp - , DB.paramProposalMaxTxSize = fromIntegral <$> pppMaxTxSize pp - , DB.paramProposalMaxBhSize = fromIntegral <$> pppMaxBhSize pp - , DB.paramProposalKeyDeposit = Generic.coinToDbLovelace <$> pppKeyDeposit pp - , DB.paramProposalPoolDeposit = Generic.coinToDbLovelace <$> pppPoolDeposit pp - , DB.paramProposalMaxEpoch = fromIntegral . unEpochInterval <$> pppMaxEpoch pp - , DB.paramProposalOptimalPoolCount = fromIntegral <$> pppOptimalPoolCount pp - , DB.paramProposalInfluence = fromRational <$> pppInfluence pp - , DB.paramProposalMonetaryExpandRate = toDouble <$> pppMonetaryExpandRate pp - , DB.paramProposalTreasuryGrowthRate = toDouble <$> pppTreasuryGrowthRate pp - , DB.paramProposalDecentralisation = toDouble <$> pppDecentralisation pp - , DB.paramProposalEntropy = Generic.nonceToBytes =<< pppEntropy pp - , DB.paramProposalProtocolMajor = getVersion . Ledger.pvMajor <$> pppProtocolVersion pp - , DB.paramProposalProtocolMinor = fromIntegral . Ledger.pvMinor <$> pppProtocolVersion pp - , DB.paramProposalMinUtxoValue = Generic.coinToDbLovelace <$> pppMinUtxoValue pp - , DB.paramProposalMinPoolCost = Generic.coinToDbLovelace <$> pppMinPoolCost pp - , -- New for Alonzo - DB.paramProposalCoinsPerUtxoSize = Generic.coinToDbLovelace <$> pppCoinsPerUtxo pp - , DB.paramProposalCostModelId = cmId - , DB.paramProposalPriceMem = realToFrac <$> pppPriceMem pp - , DB.paramProposalPriceStep = realToFrac <$> pppPriceStep pp - , DB.paramProposalMaxTxExMem = DbWord64 <$> pppMaxTxExMem pp - , DB.paramProposalMaxTxExSteps = DbWord64 <$> pppMaxTxExSteps pp - , DB.paramProposalMaxBlockExMem = DbWord64 <$> pppMaxBlockExMem pp - , DB.paramProposalMaxBlockExSteps = DbWord64 <$> pppMaxBlockExSteps pp - , DB.paramProposalMaxValSize = DbWord64 . fromIntegral <$> pppMaxValSize pp - , DB.paramProposalCollateralPercent = fromIntegral <$> pppCollateralPercentage pp - , DB.paramProposalMaxCollateralInputs = fromIntegral <$> pppMaxCollateralInputs pp - , -- New for Conway - DB.paramProposalPvtMotionNoConfidence = toDouble . pvtMotionNoConfidence <$> pppPoolVotingThresholds pp - , DB.paramProposalPvtCommitteeNormal = toDouble . pvtCommitteeNormal <$> pppPoolVotingThresholds pp - , DB.paramProposalPvtCommitteeNoConfidence = toDouble . pvtCommitteeNoConfidence <$> pppPoolVotingThresholds pp - , DB.paramProposalPvtHardForkInitiation = toDouble . pvtHardForkInitiation <$> pppPoolVotingThresholds pp - , DB.paramProposalDvtMotionNoConfidence = toDouble . dvtMotionNoConfidence <$> pppDRepVotingThresholds pp - , DB.paramProposalDvtCommitteeNormal = toDouble . dvtCommitteeNormal <$> pppDRepVotingThresholds pp - , DB.paramProposalDvtCommitteeNoConfidence = toDouble . dvtCommitteeNoConfidence <$> pppDRepVotingThresholds pp - , DB.paramProposalDvtUpdateToConstitution = toDouble . dvtUpdateToConstitution <$> pppDRepVotingThresholds pp - , DB.paramProposalDvtHardForkInitiation = toDouble . dvtHardForkInitiation <$> pppDRepVotingThresholds pp - , DB.paramProposalDvtPPNetworkGroup = toDouble . dvtPPNetworkGroup <$> pppDRepVotingThresholds pp - , DB.paramProposalDvtPPEconomicGroup = toDouble . dvtPPEconomicGroup <$> pppDRepVotingThresholds pp - , DB.paramProposalDvtPPTechnicalGroup = toDouble . dvtPPTechnicalGroup <$> pppDRepVotingThresholds pp - , DB.paramProposalDvtPPGovGroup = toDouble . dvtPPGovGroup <$> pppDRepVotingThresholds pp - , DB.paramProposalDvtTreasuryWithdrawal = toDouble . dvtTreasuryWithdrawal <$> pppDRepVotingThresholds pp - , DB.paramProposalCommitteeMinSize = DbWord64 . fromIntegral <$> pppCommitteeMinSize pp - , DB.paramProposalCommitteeMaxTermLength = DbWord64 . fromIntegral . unEpochInterval <$> pppCommitteeMaxTermLength pp - , DB.paramProposalGovActionLifetime = fromIntegral . unEpochInterval <$> pppGovActionLifetime pp - , DB.paramProposalGovActionDeposit = DbWord64 . fromIntegral <$> pppGovActionDeposit pp - , DB.paramProposalDrepDeposit = DbWord64 . fromIntegral <$> pppDRepDeposit pp - , DB.paramProposalDrepActivity = fromIntegral . unEpochInterval <$> pppDRepActivity pp - } - -insertConstitution :: (MonadIO m, MonadBaseControl IO m) => DB.TxId -> DB.GovActionProposalId -> Constitution StandardConway -> ReaderT SqlBackend m () -insertConstitution txId gapId constitution = do - votingAnchorId <- insertVotingAnchor txId $ constitutionAnchor constitution - void . DB.insertConstitution $ - DB.Constitution - { DB.constitutionGovActionProposalId = gapId - , DB.constitutionVotingAnchorId = votingAnchorId - , DB.constitutionScriptHash = Generic.unScriptHash <$> strictMaybeToMaybe (constitutionScript constitution) - } - --------------------------------------------------------------------------------------- --- VOTING PROCEDURES --------------------------------------------------------------------------------------- -insertVotingProcedures :: - (MonadIO m, MonadBaseControl IO m) => - Trace IO Text -> - Cache -> - DB.TxId -> - (Voter StandardCrypto, [(GovActionId StandardCrypto, VotingProcedure StandardConway)]) -> - ExceptT SyncNodeError (ReaderT SqlBackend m) () -insertVotingProcedures trce cache txId (voter, actions) = - mapM_ (insertVotingProcedure trce cache txId voter) (zip [0 ..] actions) - -insertVotingProcedure :: - (MonadIO m, MonadBaseControl IO m) => - Trace IO Text -> - Cache -> - DB.TxId -> - Voter StandardCrypto -> - (Word16, (GovActionId StandardCrypto, VotingProcedure StandardConway)) -> - ExceptT SyncNodeError (ReaderT SqlBackend m) () -insertVotingProcedure trce cache txId voter (index, (gaId, vp)) = do - govActionId <- resolveGovActionProposal gaId - votingAnchorId <- whenMaybe (strictMaybeToMaybe $ vProcAnchor vp) $ lift . insertVotingAnchor txId - (mCommitteeVoter, mDRepVoter, mStakePoolVoter) <- case voter of - CommitteeVoter cred -> - pure (Just $ Generic.unCredentialHash cred, Nothing, Nothing) - DRepVoter cred -> do - drep <- lift $ insertCredDrepHash cred - pure (Nothing, Just drep, Nothing) - StakePoolVoter poolkh -> do - poolHashId <- lift $ queryPoolKeyOrInsert "insertVotingProcedure" trce cache CacheNew False poolkh - pure (Nothing, Nothing, Just poolHashId) - void - . lift - . DB.insertVotingProcedure - $ DB.VotingProcedure - { DB.votingProcedureTxId = txId - , DB.votingProcedureIndex = index - , DB.votingProcedureGovActionProposalId = govActionId - , DB.votingProcedureCommitteeVoter = mCommitteeVoter - , DB.votingProcedureDrepVoter = mDRepVoter - , DB.votingProcedurePoolVoter = mStakePoolVoter - , DB.votingProcedureVoterRole = Generic.toVoterRole voter - , DB.votingProcedureVote = Generic.toVote $ vProcVote vp - , DB.votingProcedureVotingAnchorId = votingAnchorId - } - -insertVotingAnchor :: (MonadIO m, MonadBaseControl IO m) => DB.TxId -> Anchor StandardCrypto -> ReaderT SqlBackend m DB.VotingAnchorId -insertVotingAnchor txId anchor = - DB.insertAnchor $ - DB.VotingAnchor - { DB.votingAnchorTxId = txId - , DB.votingAnchorUrl = DB.VoteUrl $ Ledger.urlToText $ anchorUrl anchor -- TODO: Conway check unicode and size of URL - , DB.votingAnchorDataHash = Generic.safeHashToByteString $ anchorDataHash anchor - } - -insertAnchor :: (MonadIO m, MonadBaseControl IO m) => DB.TxId -> Anchor StandardCrypto -> ReaderT SqlBackend m DB.VotingAnchorId -insertAnchor txId anchor = - DB.insertAnchor $ - DB.VotingAnchor - { DB.votingAnchorTxId = txId - , DB.votingAnchorUrl = DB.VoteUrl $ Ledger.urlToText $ anchorUrl anchor -- TODO: Conway check unicode and size of URL - , DB.votingAnchorDataHash = Generic.safeHashToByteString $ anchorDataHash anchor - } - --------------------------------------------------------------------------------------- --- DREP --------------------------------------------------------------------------------------- -insertDrep :: (MonadBaseControl IO m, MonadIO m) => DRep StandardCrypto -> ReaderT SqlBackend m DB.DrepHashId -insertDrep = \case - DRepCredential cred -> insertCredDrepHash cred - DRepAlwaysAbstain -> DB.insertAlwaysAbstainDrep - DRepAlwaysNoConfidence -> DB.insertAlwaysNoConfidence - -insertCredDrepHash :: (MonadBaseControl IO m, MonadIO m) => Ledger.Credential 'DRepRole StandardCrypto -> ReaderT SqlBackend m DB.DrepHashId -insertCredDrepHash cred = do - DB.insertDrepHash - DB.DrepHash - { DB.drepHashRaw = Just bs - , DB.drepHashView = serialiseDrepToBech32 bs - , DB.drepHashHasScript = Generic.hasCredScript cred - } - where - bs = Generic.unCredentialHash cred - -insertDrepDistr :: forall m. (MonadBaseControl IO m, MonadIO m) => EpochNo -> PulsingSnapshot StandardConway -> ReaderT SqlBackend m () -insertDrepDistr e pSnapshot = do - drepsDB <- mapM mkEntry (Map.toList $ psDRepDistr pSnapshot) - DB.insertManyDrepDistr drepsDB - where - mkEntry :: (DRep StandardCrypto, Ledger.CompactForm Coin) -> ReaderT SqlBackend m DB.DrepDistr - mkEntry (drep, coin) = do - drepId <- insertDrep drep - pure $ - DB.DrepDistr - { DB.drepDistrHashId = drepId - , DB.drepDistrAmount = fromIntegral $ unCoin $ fromCompact coin - , DB.drepDistrEpochNo = unEpochNo e - , DB.drepDistrActiveUntil = unEpochNo <$> isActiveEpochNo drep - } - - isActiveEpochNo :: DRep StandardCrypto -> Maybe EpochNo - isActiveEpochNo = \case - DRepAlwaysAbstain -> Nothing - DRepAlwaysNoConfidence -> Nothing - DRepCredential cred -> drepExpiry <$> Map.lookup cred (psDRepState pSnapshot) - -insertCostModel :: - (MonadBaseControl IO m, MonadIO m) => - DB.BlockId -> - Map Language Ledger.CostModel -> - ReaderT SqlBackend m DB.CostModelId -insertCostModel _blkId cms = - DB.insertCostModel $ - DB.CostModel - { DB.costModelHash = Crypto.abstractHashToBytes $ Crypto.serializeCborHash $ Ledger.mkCostModels cms - , DB.costModelCosts = Text.decodeUtf8 $ LBS.toStrict $ Aeson.encode cms - } - -updateEnacted :: forall m. (MonadBaseControl IO m, MonadIO m) => Bool -> EpochNo -> EnactState StandardConway -> ExceptT SyncNodeError (ReaderT SqlBackend m) () -updateEnacted isEnacted epochNo enactedState = do - whenJust (strictMaybeToMaybe (enactedState ^. ensPrevPParamUpdateL)) $ \prevId -> do - gaId <- resolveGovActionProposal $ getPrevId prevId - if isEnacted - then lift $ DB.updateGovActionEnacted gaId (unEpochNo epochNo) - else lift $ DB.updateGovActionRatified gaId (unEpochNo epochNo) - where - getPrevId = unGovPurposeId diff --git a/cardano-db-sync/src/Cardano/DbSync/Era/Universal/Insert/Other.hs b/cardano-db-sync/src/Cardano/DbSync/Era/Universal/Insert/Other.hs index aca8adb6c..487408d4f 100644 --- a/cardano-db-sync/src/Cardano/DbSync/Era/Universal/Insert/Other.hs +++ b/cardano-db-sync/src/Cardano/DbSync/Era/Universal/Insert/Other.hs @@ -35,6 +35,7 @@ import qualified Cardano.Ledger.Credential as Ledger import Cardano.Ledger.Mary.Value (AssetName (..), PolicyID (..)) import Cardano.Prelude import Control.Monad.Trans.Control (MonadBaseControl) +import Data.ByteString.Short (ShortByteString, fromShort) import Database.Persist.Sql (SqlBackend) import Ouroboros.Consensus.Cardano.Block (StandardCrypto) @@ -164,14 +165,24 @@ insertStakeAddressRefIfMissing _trce cache addr = insertMultiAsset :: (MonadBaseControl IO m, MonadIO m) => Cache -> + Maybe (NonEmpty ShortByteString) -> PolicyID StandardCrypto -> AssetName -> - ReaderT SqlBackend m DB.MultiAssetId -insertMultiAsset cache policy aName = do + ReaderT SqlBackend m (Maybe DB.MultiAssetId) +insertMultiAsset cache mWhitelist policy aName = do mId <- queryMAWithCache cache policy aName case mId of - Right maId -> pure maId + Right maId -> pure $ Just maId Left (policyBs, assetNameBs) -> + case mWhitelist of + -- we want to check the whitelist at the begining + Just whitelist -> + if policyBs `elem` (fromShort <$> whitelist) + then Just <$> insertAssettIntoDB policyBs assetNameBs + else pure Nothing + Nothing -> Just <$> insertAssettIntoDB policyBs assetNameBs + where + insertAssettIntoDB policyBs assetNameBs = DB.insertMultiAssetUnchecked $ DB.MultiAsset { DB.multiAssetPolicy = policyBs diff --git a/cardano-db-sync/src/Cardano/DbSync/Era/Universal/Insert/Pool.hs b/cardano-db-sync/src/Cardano/DbSync/Era/Universal/Insert/Pool.hs index be0af10d8..37626e31f 100644 --- a/cardano-db-sync/src/Cardano/DbSync/Era/Universal/Insert/Pool.hs +++ b/cardano-db-sync/src/Cardano/DbSync/Era/Universal/Insert/Pool.hs @@ -64,9 +64,7 @@ insertPoolRegister _tracer cache isMember network (EpochNo epoch) blkId txId idx mdId <- case strictMaybeToMaybe $ PoolP.ppMetadata params of Just md -> Just <$> insertPoolMetaDataRef poolHashId txId md Nothing -> pure Nothing - epochActivationDelay <- mkEpochActivationDelay poolHashId - saId <- lift $ queryOrInsertRewardAccount cache CacheNew (adjustNetworkTag $ PoolP.ppRewardAcnt params) poolUpdateId <- lift diff --git a/cardano-db-sync/src/Cardano/DbSync/Era/Universal/Insert/Tx.hs b/cardano-db-sync/src/Cardano/DbSync/Era/Universal/Insert/Tx.hs index 3237bd5a4..c04a54f7f 100644 --- a/cardano-db-sync/src/Cardano/DbSync/Era/Universal/Insert/Tx.hs +++ b/cardano-db-sync/src/Cardano/DbSync/Era/Universal/Insert/Tx.hs @@ -20,10 +20,11 @@ import Cardano.DbSync.Api import Cardano.DbSync.Api.Types (InsertOptions (..), SyncEnv (..)) import Cardano.DbSync.Cache.Types (Cache (..)) +import Cardano.DbSync.Config.Types (MetadataConfig (..), MultiAssetConfig (..), PlutusConfig (..), isPlutusEnabled) import qualified Cardano.DbSync.Era.Shelley.Generic as Generic import Cardano.DbSync.Era.Shelley.Generic.Metadata (TxMetadataValue (..), metadataValueToJsonNoSchema) import Cardano.DbSync.Era.Universal.Insert.Certificate (insertCertificate) -import Cardano.DbSync.Era.Universal.Insert.GovAction ( +import Cardano.DbSync.Era.Conway.Insert.GovAction ( insertGovActionProposal, insertParamProposal, insertVotingProcedures, @@ -44,6 +45,7 @@ import Cardano.DbSync.Error import Cardano.DbSync.Ledger.Types (ApplyResult (..), getGovExpiresAt, lookupDepositsMap) import Cardano.DbSync.Util import Cardano.DbSync.Util.Cbor (serialiseTxMetadataToCbor) +import Cardano.DbSync.Util.Whitelist (plutusMultiAssetWhitelistCheck) import Cardano.Ledger.BaseTypes import Cardano.Ledger.Coin (Coin (..)) import Cardano.Ledger.Mary.Value (AssetName (..), MultiAsset (..), PolicyID (..)) @@ -53,9 +55,9 @@ import Control.Monad.Trans.Control (MonadBaseControl) import qualified Data.Aeson as Aeson import qualified Data.ByteString.Lazy.Char8 as LBS import qualified Data.Map.Strict as Map -import qualified Data.Strict.Maybe as Strict -import Database.Persist.Sql (SqlBackend) -import Ouroboros.Consensus.Cardano.Block (StandardCrypto) +import Database.Persist.Sql ( SqlBackend, SqlBackend ) +import Ouroboros.Consensus.Cardano.Block ( StandardCrypto, StandardCrypto ) +import Data.ByteString.Short (ShortByteString, toShort) -------------------------------------------------------------------------------------- -- INSERT TX @@ -121,7 +123,11 @@ insertTx syncEnv isMember blkId epochNo slotNo applyResult blockIndex tx grouped if not (Generic.txValidContract tx) then do - !txOutsGrouped <- mapM (insertTxOut tracer cache iopts (txId, txHash)) (Generic.txOutputs tx) + !txOutsGrouped <- do + let txOuts = Generic.txOutputs tx + if plutusMultiAssetWhitelistCheck syncEnv txOuts + then mapM (insertTxOut tracer cache iopts (txId, txHash)) txOuts + else pure mempty let !txIns = map (prepareTxIn txId Map.empty) resolvedInputs -- There is a custom semigroup instance for BlockGroupedData which uses addition for the values `fees` and `outSum`. @@ -130,27 +136,31 @@ insertTx syncEnv isMember blkId epochNo slotNo applyResult blockIndex tx grouped else do -- The following operations only happen if the script passes stage 2 validation (or the tx has -- no script). - !txOutsGrouped <- mapM (insertTxOut tracer cache iopts (txId, txHash)) (Generic.txOutputs tx) + !txOutsGrouped <- do + let txOuts = Generic.txOutputs tx + if plutusMultiAssetWhitelistCheck syncEnv txOuts + then mapM (insertTxOut tracer cache iopts (txId, txHash)) txOuts + else pure mempty !redeemers <- Map.fromList <$> whenFalseMempty - (ioPlutusExtra iopts) + (isPlutusEnabled $ ioPlutus iopts) (mapM (insertRedeemer tracer disInOut (fst <$> groupedTxOut grouped) txId) (Generic.txRedeemer tx)) - when (ioPlutusExtra iopts) $ do + when (isPlutusEnabled $ ioPlutus iopts) $ do mapM_ (insertDatum tracer cache txId) (Generic.txData tx) mapM_ (insertCollateralTxIn tracer txId) (Generic.txCollateralInputs tx) mapM_ (insertReferenceTxIn tracer txId) (Generic.txReferenceInputs tx) mapM_ (insertCollateralTxOut tracer cache iopts (txId, txHash)) (Generic.txCollateralOutputs tx) txMetadata <- - whenFalseMempty (ioMetadata iopts) $ - insertTxMetadata - tracer - txId - iopts - (Generic.txMetadata tx) + case ioMetadata iopts of + MetadataDisable -> pure mempty + MetadataEnable -> + insertTxMetadata tracer Nothing txId (Generic.txMetadata tx) + MetadataKeys whitelist -> + insertTxMetadata tracer (Just whitelist) txId (Generic.txMetadata tx) mapM_ (insertCertificate syncEnv isMember blkId txId epochNo slotNo redeemers) $ Generic.txCertificates tx @@ -162,15 +172,16 @@ insertTx syncEnv isMember blkId epochNo slotNo applyResult blockIndex tx grouped Generic.txParamProposal tx maTxMint <- - whenFalseMempty (ioMultiAssets iopts) $ - insertMaTxMint tracer cache txId $ - Generic.txMint tx + case ioMultiAssets iopts of + MultiAssetDisable -> pure mempty + MultiAssetEnable -> insertMaTxMint tracer cache Nothing txId $ Generic.txMint tx + MultiAssetPolicies whitelist -> insertMaTxMint tracer cache (Just whitelist) txId $ Generic.txMint tx - when (ioPlutusExtra iopts) $ + when (isPlutusEnabled $ ioPlutus iopts) $ mapM_ (lift . insertScript tracer txId) $ Generic.txScripts tx - when (ioPlutusExtra iopts) $ + when (isPlutusEnabled $ ioPlutus iopts) $ mapM_ (insertExtraKeyWitness tracer txId) $ Generic.txExtraKeyWitnesses tx @@ -196,61 +207,69 @@ insertTxOut :: (DB.TxId, ByteString) -> Generic.TxOut -> ExceptT SyncNodeError (ReaderT SqlBackend m) (ExtendedTxOut, [MissingMaTxOut]) -insertTxOut tracer cache iopts (txId, txHash) (Generic.TxOut index addr value maMap mScript dt) = do - mSaId <- lift $ insertStakeAddressRefIfMissing tracer cache addr - mDatumId <- - whenFalseEmpty (ioPlutusExtra iopts) Nothing $ - Generic.whenInlineDatum dt $ - insertDatum tracer cache txId - mScriptId <- - whenFalseEmpty (ioPlutusExtra iopts) Nothing $ - whenMaybe mScript $ - lift . insertScript tracer txId - let !txOut = - DB.TxOut - { DB.txOutTxId = txId - , DB.txOutIndex = index - , DB.txOutAddress = Generic.renderAddress addr - , DB.txOutAddressHasScript = hasScript - , DB.txOutPaymentCred = Generic.maybePaymentCred addr - , DB.txOutStakeAddressId = mSaId - , DB.txOutValue = Generic.coinToDbLovelace value - , DB.txOutDataHash = Generic.dataHashToBytes <$> Generic.getTxOutDatumHash dt - , DB.txOutInlineDatumId = mDatumId - , DB.txOutReferenceScriptId = mScriptId - } - let !eutxo = ExtendedTxOut txHash txOut - !maTxOuts <- whenFalseMempty (ioMultiAssets iopts) $ insertMaTxOuts tracer cache maMap - pure (eutxo, maTxOuts) +insertTxOut tracer cache iopts (txId, txHash) (Generic.TxOut index addr value maMap mScript dt) = case ioPlutus iopts of + PlutusDisable -> buildExtendedTxOutPart2 Nothing Nothing + _ -> buildExtendedTxOutPart1 where + buildExtendedTxOutPart1 :: + (MonadBaseControl IO m, MonadIO m) => + ExceptT SyncNodeError (ReaderT SqlBackend m) (ExtendedTxOut, [MissingMaTxOut]) + buildExtendedTxOutPart1 = do + mDatumId <- Generic.whenInlineDatum dt $ insertDatum tracer cache txId + mScriptId <- whenMaybe mScript $ lift . insertScript tracer txId + buildExtendedTxOutPart2 mDatumId mScriptId + + buildExtendedTxOutPart2 :: + (MonadBaseControl IO m, MonadIO m) => + Maybe DB.DatumId -> + Maybe DB.ScriptId -> + ExceptT SyncNodeError (ReaderT SqlBackend m) (ExtendedTxOut, [MissingMaTxOut]) + buildExtendedTxOutPart2 mDatumId mScriptId = do + mSaId <- lift $ insertStakeAddressRefIfMissing tracer cache addr + let !txOut = + DB.TxOut + { DB.txOutTxId = txId + , DB.txOutIndex = index + , DB.txOutAddress = Generic.renderAddress addr + , DB.txOutAddressHasScript = hasScript + , DB.txOutPaymentCred = Generic.maybePaymentCred addr + , DB.txOutStakeAddressId = mSaId + , DB.txOutValue = Generic.coinToDbLovelace value + , DB.txOutDataHash = Generic.dataHashToBytes <$> Generic.getTxOutDatumHash dt + , DB.txOutInlineDatumId = mDatumId + , DB.txOutReferenceScriptId = mScriptId + } + let !eutxo = ExtendedTxOut txHash txOut + case ioMultiAssets iopts of + MultiAssetDisable -> pure (eutxo, mempty) + _ -> do + !maTxOuts <- insertMaTxOuts tracer cache Nothing maMap + pure (eutxo, maTxOuts) + hasScript :: Bool hasScript = maybe False Generic.hasCredScript (Generic.getPaymentCred addr) insertTxMetadata :: (MonadBaseControl IO m, MonadIO m) => Trace IO Text -> + Maybe (NonEmpty Word) -> DB.TxId -> - InsertOptions -> Maybe (Map Word64 TxMetadataValue) -> ExceptT SyncNodeError (ReaderT SqlBackend m) [DB.TxMetadata] -insertTxMetadata tracer txId inOpts mmetadata = do - case mmetadata of - Nothing -> pure [] - Just metadata -> mapMaybeM prepare $ Map.toList metadata +insertTxMetadata tracer mWhitelist txId mmetadata = case mmetadata of + Nothing -> pure [] + Just metadata -> mapMaybeM prepare $ Map.toList metadata where prepare :: (MonadBaseControl IO m, MonadIO m) => (Word64, TxMetadataValue) -> ExceptT SyncNodeError (ReaderT SqlBackend m) (Maybe DB.TxMetadata) - prepare (key, md) = do - case ioKeepMetadataNames inOpts of - Strict.Just metadataNames -> do - let isMatchingKey = key `elem` metadataNames - if isMatchingKey - then mkDbTxMetadata (key, md) - else pure Nothing - -- if we have TxMetadata and keepMetadataNames is Nothing then we want to keep all metadata - Strict.Nothing -> mkDbTxMetadata (key, md) + prepare (key, md) = case mWhitelist of + Just whitelist -> + if fromIntegral key `elem` whitelist + then mkDbTxMetadata (key, md) + else pure Nothing + Nothing -> pure Nothing mkDbTxMetadata :: (MonadBaseControl IO m, MonadIO m) => @@ -276,10 +295,11 @@ insertMaTxMint :: (MonadBaseControl IO m, MonadIO m) => Trace IO Text -> Cache -> + Maybe (NonEmpty ShortByteString) -> DB.TxId -> MultiAsset StandardCrypto -> ExceptT SyncNodeError (ReaderT SqlBackend m) [DB.MaTxMint] -insertMaTxMint _tracer cache txId (MultiAsset mintMap) = +insertMaTxMint _tracer cache mWhitelist txId (MultiAsset mintMap) = concatMapM (lift . prepareOuter) $ Map.toList mintMap where prepareOuter :: @@ -287,29 +307,33 @@ insertMaTxMint _tracer cache txId (MultiAsset mintMap) = (PolicyID StandardCrypto, Map AssetName Integer) -> ReaderT SqlBackend m [DB.MaTxMint] prepareOuter (policy, aMap) = - mapM (prepareInner policy) $ Map.toList aMap + mapMaybeM (prepareInner policy) $ Map.toList aMap prepareInner :: (MonadBaseControl IO m, MonadIO m) => PolicyID StandardCrypto -> (AssetName, Integer) -> - ReaderT SqlBackend m DB.MaTxMint + ReaderT SqlBackend m (Maybe DB.MaTxMint) prepareInner policy (aname, amount) = do - maId <- insertMultiAsset cache policy aname - pure $ - DB.MaTxMint - { DB.maTxMintIdent = maId - , DB.maTxMintQuantity = DB.integerToDbInt65 amount - , DB.maTxMintTxId = txId - } + maybeMaId <- insertMultiAsset cache mWhitelist policy aname + pure $ case maybeMaId of + Just maId -> + Just $ + DB.MaTxMint + { DB.maTxMintIdent = maId + , DB.maTxMintQuantity = DB.integerToDbInt65 amount + , DB.maTxMintTxId = txId + } + Nothing -> Nothing insertMaTxOuts :: (MonadBaseControl IO m, MonadIO m) => Trace IO Text -> Cache -> + Maybe (NonEmpty ShortByteString) -> Map (PolicyID StandardCrypto) (Map AssetName Integer) -> ExceptT SyncNodeError (ReaderT SqlBackend m) [MissingMaTxOut] -insertMaTxOuts _tracer cache maMap = +insertMaTxOuts _tracer cache mWhitelist maMap = concatMapM (lift . prepareOuter) $ Map.toList maMap where prepareOuter :: @@ -317,24 +341,24 @@ insertMaTxOuts _tracer cache maMap = (PolicyID StandardCrypto, Map AssetName Integer) -> ReaderT SqlBackend m [MissingMaTxOut] prepareOuter (policy, aMap) = - mapM (prepareInner policy) $ Map.toList aMap + mapMaybeM (prepareInner policy) $ Map.toList aMap prepareInner :: (MonadBaseControl IO m, MonadIO m) => PolicyID StandardCrypto -> (AssetName, Integer) -> - ReaderT SqlBackend m MissingMaTxOut + ReaderT SqlBackend m (Maybe MissingMaTxOut) prepareInner policy (aname, amount) = do - maId <- insertMultiAsset cache policy aname - pure $ - MissingMaTxOut - { mmtoIdent = maId - , mmtoQuantity = DbWord64 (fromIntegral amount) - } + mMaId <- insertMultiAsset cache mWhitelist policy aname + pure $ case mMaId of + Just maId -> + Just $ + MissingMaTxOut + { mmtoIdent = maId + , mmtoQuantity = DbWord64 (fromIntegral amount) + } + Nothing -> Nothing --------------------------------------------------------------------------------------- --- INSERT COLLATERAL --------------------------------------------------------------------------------------- insertCollateralTxOut :: (MonadBaseControl IO m, MonadIO m) => Trace IO Text -> @@ -343,36 +367,51 @@ insertCollateralTxOut :: (DB.TxId, ByteString) -> Generic.TxOut -> ExceptT SyncNodeError (ReaderT SqlBackend m) () -insertCollateralTxOut tracer cache iopts (txId, _txHash) (Generic.TxOut index addr value maMap mScript dt) = do - mSaId <- lift $ insertStakeAddressRefIfMissing tracer cache addr - mDatumId <- - whenFalseEmpty (ioPlutusExtra iopts) Nothing $ - Generic.whenInlineDatum dt $ - insertDatum tracer cache txId - mScriptId <- - whenFalseEmpty (ioPlutusExtra iopts) Nothing $ - whenMaybe mScript $ - lift . insertScript tracer txId - _ <- - lift - . DB.insertCollateralTxOut - $ DB.CollateralTxOut - { DB.collateralTxOutTxId = txId - , DB.collateralTxOutIndex = index - , DB.collateralTxOutAddress = Generic.renderAddress addr - , DB.collateralTxOutAddressHasScript = hasScript - , DB.collateralTxOutPaymentCred = Generic.maybePaymentCred addr - , DB.collateralTxOutStakeAddressId = mSaId - , DB.collateralTxOutValue = Generic.coinToDbLovelace value - , DB.collateralTxOutDataHash = Generic.dataHashToBytes <$> Generic.getTxOutDatumHash dt - , DB.collateralTxOutMultiAssetsDescr = textShow maMap - , DB.collateralTxOutInlineDatumId = mDatumId - , DB.collateralTxOutReferenceScriptId = mScriptId - } - pure () +insertCollateralTxOut tracer cache iopts (txId, _txHash) (Generic.TxOut index addr value maMap mScript dt) = case ioPlutus iopts of + PlutusDisable -> do + _ <- insertColTxOutPart2 Nothing Nothing + pure () + PlutusEnable -> insertColTxOutPart1 + -- if we have a whitelist we need to check both txOutAddress OR txOutScript are in the whitelist + PlutusScripts whitelist -> + case (mScript, Generic.maybePaymentCred addr) of + (Just script, _) -> + if toShort (Generic.txScriptHash script) `elem` whitelist + then insertColTxOutPart1 + else void $ insertColTxOutPart2 Nothing Nothing + (_, Just address) -> + if toShort address `elem` whitelist + then insertColTxOutPart1 + else void $ insertColTxOutPart2 Nothing Nothing + (Nothing, Nothing) -> void $ insertColTxOutPart2 Nothing Nothing where - -- TODO: Is there any reason to add new tables for collateral multi-assets/multi-asset-outputs + insertColTxOutPart1 = do + mDatumId <- Generic.whenInlineDatum dt $ insertDatum tracer cache txId + mScriptId <- whenMaybe mScript $ lift . insertScript tracer txId + insertColTxOutPart2 mDatumId mScriptId + pure () + insertColTxOutPart2 mDatumId mScriptId = do + mSaId <- lift $ insertStakeAddressRefIfMissing tracer cache addr + _ <- + lift + . DB.insertCollateralTxOut + $ DB.CollateralTxOut + { DB.collateralTxOutTxId = txId + , DB.collateralTxOutIndex = index + , DB.collateralTxOutAddress = Generic.renderAddress addr + , DB.collateralTxOutAddressHasScript = hasScript + , DB.collateralTxOutPaymentCred = Generic.maybePaymentCred addr + , DB.collateralTxOutStakeAddressId = mSaId + , DB.collateralTxOutValue = Generic.coinToDbLovelace value + , DB.collateralTxOutDataHash = Generic.dataHashToBytes <$> Generic.getTxOutDatumHash dt + , DB.collateralTxOutMultiAssetsDescr = textShow maMap + , DB.collateralTxOutInlineDatumId = mDatumId + , DB.collateralTxOutReferenceScriptId = mScriptId + } + pure () + + -- TODO: Is there any reason to add new tables for collateral multi-assets/multi-asset-outputs hasScript :: Bool hasScript = maybe False Generic.hasCredScript (Generic.getPaymentCred addr) diff --git a/cardano-db-sync/src/Cardano/DbSync/Util/Whitelist.hs b/cardano-db-sync/src/Cardano/DbSync/Util/Whitelist.hs new file mode 100644 index 000000000..6d038c533 --- /dev/null +++ b/cardano-db-sync/src/Cardano/DbSync/Util/Whitelist.hs @@ -0,0 +1,57 @@ +module Cardano.DbSync.Util.Whitelist where + +import Cardano.DbSync.Api.Types (InsertOptions (..), SyncEnv (..), SyncOptions (..)) +import Cardano.DbSync.Config.Types (MultiAssetConfig (..), PlutusConfig (..)) +import qualified Cardano.DbSync.Era.Shelley.Generic as Generic +import Cardano.Ledger.Crypto (StandardCrypto) +import Cardano.Ledger.Mary.Value (PolicyID (..)) +import Cardano.Prelude (NonEmpty) +import Data.ByteString.Short (ShortByteString, toShort) +import Data.Map (keys) + +-- check both whitelist but also checking plutus Maybes first +plutusMultiAssetWhitelistCheck :: SyncEnv -> [Generic.TxOut] -> Bool +plutusMultiAssetWhitelistCheck syncEnv txOuts = + plutusWhitelistCheck syncEnv txOuts || multiAssetWhitelistCheck syncEnv txOuts + +plutusWhitelistCheck :: SyncEnv -> [Generic.TxOut] -> Bool +plutusWhitelistCheck syncEnv txOuts = do + -- first check the config option + case ioPlutus iopts of + PlutusEnable -> True + PlutusDisable -> True + PlutusScripts plutusWhitelist -> plutuswhitelistCheck plutusWhitelist + where + iopts = soptInsertOptions $ envOptions syncEnv + plutuswhitelistCheck :: NonEmpty ShortByteString -> Bool + plutuswhitelistCheck whitelist = + any (\txOut -> isScriptHashWhitelisted whitelist txOut || isAddressWhitelisted whitelist txOut) txOuts + -- check if the script hash is in the whitelist + isScriptHashWhitelisted :: NonEmpty ShortByteString -> Generic.TxOut -> Bool + isScriptHashWhitelisted whitelist txOut = + maybe False ((`elem` whitelist) . toShort . Generic.txScriptHash) (Generic.txOutScript txOut) + -- check if the address is in the whitelist + isAddressWhitelisted :: NonEmpty ShortByteString -> Generic.TxOut -> Bool + isAddressWhitelisted whitelist txOut = + maybe False ((`elem` whitelist) . toShort) (Generic.maybePaymentCred $ Generic.txOutAddress txOut) + +multiAssetWhitelistCheck :: SyncEnv -> [Generic.TxOut] -> Bool +multiAssetWhitelistCheck syncEnv txOuts = do + let iopts = soptInsertOptions $ envOptions syncEnv + case ioMultiAssets iopts of + MultiAssetEnable -> True + MultiAssetDisable -> True + MultiAssetPolicies multiAssetWhitelist -> + or multiAssetwhitelistCheck + where + -- txOutMaValue is a Map and we want to check if any of the keys match our whitelist + multiAssetwhitelistCheck :: [Bool] + multiAssetwhitelistCheck = + ( \txout -> + any (checkMAValueMap multiAssetWhitelist) (keys $ Generic.txOutMaValue txout) + ) + <$> txOuts + + checkMAValueMap :: NonEmpty ShortByteString -> PolicyID StandardCrypto -> Bool + checkMAValueMap maWhitelist policyId = + toShort (Generic.unScriptHash (policyID policyId)) `elem` maWhitelist