diff --git a/cardano-db-sync/src/Cardano/DbSync/Era/Byron/Genesis.hs b/cardano-db-sync/src/Cardano/DbSync/Era/Byron/Genesis.hs index dd2e42a0e..c3c45fca0 100644 --- a/cardano-db-sync/src/Cardano/DbSync/Era/Byron/Genesis.hs +++ b/cardano-db-sync/src/Cardano/DbSync/Era/Byron/Genesis.hs @@ -182,6 +182,7 @@ insertTxOuts blkId (address, value) = do , DB.txBlockIndex = 0 , DB.txOutSum = Byron.unsafeGetLovelace value , DB.txFee = 0 + , DB.txDeposit = 0 , DB.txSize = 0 -- Genesis distribution address to not have a size. } void . DB.insertTxOut $ diff --git a/cardano-db-sync/src/Cardano/DbSync/Era/Shelley/Genesis.hs b/cardano-db-sync/src/Cardano/DbSync/Era/Shelley/Genesis.hs index 011457bc3..904b20853 100644 --- a/cardano-db-sync/src/Cardano/DbSync/Era/Shelley/Genesis.hs +++ b/cardano-db-sync/src/Cardano/DbSync/Era/Shelley/Genesis.hs @@ -198,6 +198,7 @@ insertTxOuts blkId (Shelley.TxIn txInId _, txOut) = do , DB.txBlockIndex = 0 , DB.txOutSum = unCoin (txOutCoin txOut) , DB.txFee = 0 + , DB.txDeposit = 0 , DB.txSize = 0 -- Genesis distribution address to not have a size. } void . DB.insertTxOut $ diff --git a/cardano-db-sync/src/Cardano/DbSync/Plugin/Default/Byron/Insert.hs b/cardano-db-sync/src/Cardano/DbSync/Plugin/Default/Byron/Insert.hs index ff5cd1e59..68f831b75 100644 --- a/cardano-db-sync/src/Cardano/DbSync/Plugin/Default/Byron/Insert.hs +++ b/cardano-db-sync/src/Cardano/DbSync/Plugin/Default/Byron/Insert.hs @@ -169,6 +169,7 @@ insertTx tracer blkId tx blockIndex = do , DB.txBlockIndex = blockIndex , DB.txOutSum = vfValue valFee , DB.txFee = vfFee valFee + , DB.txDeposit = 0 -- Byron does not have deposits/refunds -- Would be really nice to have a way to get the transaction size -- without re-serializing it. , DB.txSize = fromIntegral $ BS.length (serialize' $ Byron.taTx tx) diff --git a/cardano-db-sync/src/Cardano/DbSync/Plugin/Default/Shelley/Insert.hs b/cardano-db-sync/src/Cardano/DbSync/Plugin/Default/Shelley/Insert.hs index 2e34446d0..335f9c358 100644 --- a/cardano-db-sync/src/Cardano/DbSync/Plugin/Default/Shelley/Insert.hs +++ b/cardano-db-sync/src/Cardano/DbSync/Plugin/Default/Shelley/Insert.hs @@ -103,13 +103,17 @@ insertTx -> ExceptT DbSyncNodeError (ReaderT SqlBackend m) () insertTx tracer env blkId blockIndex tx = do -- Insert transaction and get txId from the DB. + let outSum = Shelley.txOutputSum tx + fees = Shelley.txFee tx + inSum <- lift $ queryTxInputSum (Shelley.txInputList tx) txId <- lift . DB.insertTx $ DB.Tx { DB.txHash = Shelley.txHash tx , DB.txBlock = blkId , DB.txBlockIndex = blockIndex - , DB.txOutSum = Shelley.txOutputSum tx - , DB.txFee = Shelley.txFee tx + , DB.txOutSum = outSum + , DB.txFee = fees + , DB.txDeposit = fromIntegral inSum - fromIntegral (outSum + fees) , DB.txSize = fromIntegral $ LBS.length (Shelley.txFullBytes tx) } diff --git a/cardano-db-sync/src/Cardano/DbSync/Plugin/Default/Shelley/Query.hs b/cardano-db-sync/src/Cardano/DbSync/Plugin/Default/Shelley/Query.hs index 82d810783..bc918cbdc 100644 --- a/cardano-db-sync/src/Cardano/DbSync/Plugin/Default/Shelley/Query.hs +++ b/cardano-db-sync/src/Cardano/DbSync/Plugin/Default/Shelley/Query.hs @@ -6,9 +6,11 @@ module Cardano.DbSync.Plugin.Default.Shelley.Query ( queryStakeAddress , queryStakePoolKeyHash + , queryTxInputSum ) where +import qualified Cardano.Crypto.Hash as Crypto import Cardano.Db import Cardano.DbSync.Types import Cardano.DbSync.Era.Shelley.Util (unKeyHashBS) @@ -17,11 +19,15 @@ import Control.Monad.IO.Class (MonadIO) import Control.Monad.Trans.Reader (ReaderT) import Data.ByteString.Char8 (ByteString) +import Data.Either (fromRight) import Data.Maybe (listToMaybe) +import Data.Word (Word64) import Database.Esqueleto (Value (..), (^.), (==.), from, select, val, where_) import Database.Persist.Sql (SqlBackend) +import qualified Shelley.Spec.Ledger.TxData as Shelley + queryStakeAddress :: MonadIO m => ByteString -> ReaderT SqlBackend m (Either LookupFail StakeAddressId) queryStakeAddress addr = do @@ -37,3 +43,10 @@ queryStakePoolKeyHash kh = do pure (pool ^. PoolId) pure $ maybeToEither (DbLookupMessage "StakePoolKeyHash") unValue (listToMaybe res) +queryTxInputSum :: MonadIO m => [ShelleyTxIn] -> ReaderT SqlBackend m Word64 +queryTxInputSum txins = + sum <$> mapM queryTxInputValue txins + where + queryTxInputValue :: MonadIO m => ShelleyTxIn -> ReaderT SqlBackend m Word64 + queryTxInputValue (Shelley.TxIn (Shelley.TxId hash) index) = + fromRight 0 <$> queryTxOutValue (Crypto.getHash hash, fromIntegral index) diff --git a/cardano-db/app/Cardano/Db/App/Validate/TotalSupply.hs b/cardano-db/app/Cardano/Db/App/Validate/TotalSupply.hs index c0590b398..5516375b9 100644 --- a/cardano-db/app/Cardano/Db/App/Validate/TotalSupply.hs +++ b/cardano-db/app/Cardano/Db/App/Validate/TotalSupply.hs @@ -17,14 +17,16 @@ validateTotalSupplyDecreasing :: IO () validateTotalSupplyDecreasing = do test <- genTestParameters - putStrF $ "Total supply plus fees at block " ++ show (testFirstBlockNo test) + putStrF $ "Total supply + fees + deposit at block " ++ show (testFirstBlockNo test) ++ " is same as genesis supply: " - (fee1, supply1) <- runDbNoLogging $ do - (,) <$> queryFeesUpToBlockNo (testFirstBlockNo test) - <*> fmap2 utxoSetSum queryUtxoAtBlockNo (testFirstBlockNo test) - if genesisSupply test == supply1 + fee1 + (fee1, depost1, supply1) + <- runDbNoLogging $ do + (,,) <$> queryFeesUpToBlockNo (testFirstBlockNo test) + <*> queryDepositUpToBlockNo (testFirstBlockNo test) + <*> fmap2 utxoSetSum queryUtxoAtBlockNo (testFirstBlockNo test) + if genesisSupply test == supply1 + fee1 + depost1 then putStrLn $ greenText "ok" - else error $ redText (show (genesisSupply test) ++ " /= " ++ show (supply1 + fee1)) + else error $ redText (show (genesisSupply test) ++ " /= " ++ show (supply1 + fee1 + depost1)) putStrF $ "Validate total supply decreasing from block " ++ show (testFirstBlockNo test) ++ " to block " ++ show (testSecondBlockNo test) ++ ": " diff --git a/cardano-db/src/Cardano/Db/Query.hs b/cardano-db/src/Cardano/Db/Query.hs index c05d337d4..f0d7b1883 100644 --- a/cardano-db/src/Cardano/Db/Query.hs +++ b/cardano-db/src/Cardano/Db/Query.hs @@ -15,6 +15,7 @@ module Cardano.Db.Query , queryBlockTxCount , queryCalcEpochEntry , queryCheckPoints + , queryDepositUpToBlockNo , queryEpochEntry , queryEpochNo , queryFeesUpToBlockNo @@ -252,6 +253,16 @@ queryCheckPoints limitCount = do then [ end, end - end `div` limitCount .. 1 ] else [ end, end - 2 .. 1 ] +queryDepositUpToBlockNo :: MonadIO m => Word64 -> ReaderT SqlBackend m Ada +queryDepositUpToBlockNo slotNo = do + res <- select . from $ \ (tx `InnerJoin` blk) -> do + on (tx ^. TxBlock ==. blk ^. BlockId) + where_ (isJust $ blk ^. BlockSlotNo) + where_ (blk ^. BlockSlotNo <=. just (val slotNo)) + pure $ sum_ (tx ^. TxDeposit) + pure $ unValueSumAda (listToMaybe res) + + queryEpochEntry :: MonadIO m => Word64 -> ReaderT SqlBackend m (Either LookupFail Epoch) queryEpochEntry epochNum = do res <- select . from $ \ epoch -> do diff --git a/cardano-db/src/Cardano/Db/Schema.hs b/cardano-db/src/Cardano/Db/Schema.hs index 3bd7aa1dc..d0c6bfca8 100644 --- a/cardano-db/src/Cardano/Db/Schema.hs +++ b/cardano-db/src/Cardano/Db/Schema.hs @@ -17,6 +17,7 @@ module Cardano.Db.Schema where import Data.ByteString.Char8 (ByteString) +import Data.Int (Int64) import Data.Text (Text) import Data.Time.Clock (UTCTime) import Data.Word (Word16, Word64) @@ -86,6 +87,7 @@ share blockIndex Word64 sqltype=uinteger -- The index of this transaction within the block. outSum Word64 sqltype=lovelace fee Word64 sqltype=lovelace + deposit Int64 size Word64 sqltype=uinteger UniqueTx hash diff --git a/cardano-db/test/Test/IO/Cardano/Db/Rollback.hs b/cardano-db/test/Test/IO/Cardano/Db/Rollback.hs index f3dd59f17..7b13eb4ac 100644 --- a/cardano-db/test/Test/IO/Cardano/Db/Rollback.hs +++ b/cardano-db/test/Test/IO/Cardano/Db/Rollback.hs @@ -99,7 +99,7 @@ createAndInsertBlocks blockCount = newMTxOutId <- if indx /= 0 then pure mTxOutId else do - txId <- insertTx $ Tx (mkTxHash blkId 0) blkId 0 0 0 12 + txId <- insertTx $ Tx (mkTxHash blkId 0) blkId 0 0 0 0 12 void $ insertTxOut (mkTxOut blkId txId) pure $ Just txId case (indx, mTxOutId) of diff --git a/cardano-db/test/Test/IO/Cardano/Db/TotalSupply.hs b/cardano-db/test/Test/IO/Cardano/Db/TotalSupply.hs index 8f298189e..02b12ad1b 100644 --- a/cardano-db/test/Test/IO/Cardano/Db/TotalSupply.hs +++ b/cardano-db/test/Test/IO/Cardano/Db/TotalSupply.hs @@ -36,7 +36,7 @@ initialSupplyTest = -- Spend from the Utxo set. bid1 <- insertBlock (mkBlock 1 slid) - tx1Id <- insertTx (Tx (mkTxHash bid1 1) bid1 0 500000000 100 123) + tx1Id <- insertTx (Tx (mkTxHash bid1 1) bid1 0 500000000 100 0 123) _ <- insertTxIn (TxIn tx1Id (head tx0Ids) 0) _ <- insertTxOut $ TxOut tx1Id 0 (mkAddressHash bid1 tx1Id) 500000000 supply1 <- queryTotalSupply diff --git a/cardano-db/test/Test/IO/Cardano/Db/Util.hs b/cardano-db/test/Test/IO/Cardano/Db/Util.hs index 2faf49d09..6b8af3eaf 100644 --- a/cardano-db/test/Test/IO/Cardano/Db/Util.hs +++ b/cardano-db/test/Test/IO/Cardano/Db/Util.hs @@ -73,7 +73,7 @@ mkTxs :: BlockId -> Word -> [Tx] mkTxs blkId count = take (fromIntegral count) $ map create [ 0 .. ] where - create w = Tx (mkTxHash blkId w) blkId 0 2 1 12 + create w = Tx (mkTxHash blkId w) blkId 0 2 1 0 12 testSlotLeader :: SlotLeader testSlotLeader = diff --git a/schema/migration-2-0003-20200630.sql b/schema/migration-2-0003-20200702.sql similarity index 99% rename from schema/migration-2-0003-20200630.sql rename to schema/migration-2-0003-20200702.sql index 1bb07d55b..b70432cf0 100644 --- a/schema/migration-2-0003-20200630.sql +++ b/schema/migration-2-0003-20200702.sql @@ -10,6 +10,7 @@ BEGIN EXECUTE 'ALTER TABLE "block" ADD COLUMN "vrf_key" hash32type NULL' ; EXECUTE 'ALTER TABLE "block" ADD COLUMN "op_cert" hash32type NULL' ; EXECUTE 'ALTER TABLE "block" ADD COLUMN "proto_version" VARCHAR NULL' ; + EXECUTE 'ALTER TABLE "tx" ADD COLUMN "deposit" INT8 NOT NULL' ; EXECUTE 'CREATe TABLE "stake_address"("id" SERIAL8 PRIMARY KEY UNIQUE,"hash" addr29type NOT NULL)' ; EXECUTE 'ALTER TABLE "stake_address" ADD CONSTRAINT "unique_stake_address" UNIQUE("hash")' ; EXECUTE 'CREATe TABLE "pool_meta_data"("id" SERIAL8 PRIMARY KEY UNIQUE,"url" VARCHAR NOT NULL,"hash" hash32type NOT NULL,"tx_id" INT8 NOT NULL)' ;