Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions cardano-chain-gen/cardano-chain-gen.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ library
Cardano.Mock.ChainDB
Cardano.Mock.ChainSync.Server
Cardano.Mock.ChainSync.State
Cardano.Mock.Forging.Examples
Cardano.Mock.Forging.Interpreter
Cardano.Mock.Forging.Tx.Alonzo
Cardano.Mock.Forging.Tx.Alonzo.ScriptsExamples
Expand Down
42 changes: 42 additions & 0 deletions cardano-chain-gen/src/Cardano/Mock/Forging/Examples.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
module Cardano.Mock.Forging.Examples where

import Cardano.Prelude hiding (length, (.))

import Data.List.Extra

import Cardano.Ledger.Mary.Value
import Cardano.Ledger.Shelley.API
import Cardano.Mock.Forging.Interpreter
import qualified Cardano.Mock.Forging.Tx.Alonzo as Alonzo
import Cardano.Mock.Forging.Tx.Generic
import Cardano.Mock.Forging.Types

delegateAndSendBlocks :: Int -> Interpreter -> IO [CardanoBlock]
delegateAndSendBlocks n interpreter = do
addrFrom <- withAlonzoLedgerState interpreter $ resolveAddress (UTxOIndex 0)
registerBlocks <- forM (chunksOf 500 creds) $ \blockCreds -> do
blockTxs <- withAlonzoLedgerState interpreter $ \_st ->
forM (chunksOf 10 blockCreds) $ \txCreds -> -- 10 per tx
Alonzo.mkDCertTx (fmap (DCertDeleg . RegKey) txCreds) (Wdrl mempty)
forgeNextFindLeader interpreter (TxAlonzo <$> blockTxs)

delegateBlocks <- forM (chunksOf 500 creds) $ \blockCreds -> do
blockTxs <- withAlonzoLedgerState interpreter $ \st ->
forM (chunksOf 10 blockCreds) $ \txCreds -> --do -- 10 per tx
Alonzo.mkDCertTx
(fmap (\ (poolIx, cred) -> DCertDeleg $ Delegate $ Delegation cred (resolvePool (PoolIndex poolIx) st))
(zip (cycle [0,1,2]) txCreds))
(Wdrl mempty)
forgeNextFindLeader interpreter (TxAlonzo <$> blockTxs)

let utxoIndex = UTxOAddress addrFrom
sendBlocks <- forM (chunksOf 500 addresses) $ \blockAddresses -> do
blockTxs <- withAlonzoLedgerState interpreter $ \st ->
forM (chunksOf 10 blockAddresses) $ \txAddresses ->
Alonzo.mkPaymentTx' utxoIndex (fmap (\addr -> (UTxOAddress addr, Value 1 mempty)) txAddresses) st
forgeNextFindLeader interpreter (TxAlonzo <$> blockTxs)
pure $ registerBlocks <> delegateBlocks <> sendBlocks
where
creds = createStakeCredentials n
pcreds = createPaymentCredentials n
addresses = fmap (\(pcred, cred) -> Addr Testnet pcred (StakeRefBase cred)) (zip pcreds creds)
20 changes: 19 additions & 1 deletion cardano-chain-gen/src/Cardano/Mock/Forging/Tx/Alonzo.hs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

module Cardano.Mock.Forging.Tx.Alonzo where

import Cardano.Prelude hiding ((.))
import Cardano.Prelude hiding (sum, (.))

import qualified Data.Map.Strict as Map
import Data.Maybe (fromJust)
Expand Down Expand Up @@ -109,6 +109,24 @@ mkPaymentTx inputIndex outputIndex amount fees sta = do
change = TxOut addr' (valueFromList (fromIntegral $ fromIntegral inputValue - amount - fees) []) Strict.SNothing
Right $ mkSimpleTx True $ consPaymentTxBody input mempty (StrictSeq.fromList [output, change]) (Coin fees) mempty

mkPaymentTx' :: AlonzoUTxOIndex
-> [(AlonzoUTxOIndex, Value StandardCrypto)]
-> AlonzoLedgerState
-> Either ForgingError (ValidatedTx (AlonzoEra StandardCrypto))
mkPaymentTx' inputIndex outputIndex sta = do
inputPair <- fst <$> resolveUTxOIndex inputIndex sta
outps <- mapM mkOuts outputIndex

let inps = Set.singleton $ fst inputPair
TxOut addr' (Value inputValue _) _ = snd inputPair
outValue = sum ((\ (Value vl _) -> vl) . snd <$> outputIndex)
change = TxOut addr' (valueFromList (fromIntegral $ fromIntegral inputValue - outValue) []) Strict.SNothing
Right $ mkSimpleTx True $ consPaymentTxBody inps mempty (StrictSeq.fromList $ outps ++ [change]) (Coin 0) mempty
where
mkOuts (outIx, vl) = do
addr <- resolveAddress outIx sta
Right $ TxOut addr vl Strict.SNothing

mkLockByScriptTx :: AlonzoUTxOIndex -> [Bool] -> Integer -> Integer
-> AlonzoLedgerState
-> Either ForgingError (ValidatedTx (AlonzoEra StandardCrypto))
Expand Down
18 changes: 18 additions & 0 deletions cardano-chain-gen/src/Cardano/Mock/Forging/Tx/Generic.hs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ module Cardano.Mock.Forging.Tx.Generic
, resolveUTxOIndex
, resolveStakeCreds
, resolvePool
, createStakeCredentials
, createPaymentCredentials
, mkDummyScriptHash
) where

import Cardano.Prelude hiding (length, (.))
Expand All @@ -24,7 +27,9 @@ import Cardano.Ledger.Address
import Cardano.Ledger.BaseTypes
import qualified Cardano.Ledger.Core as Core
import Cardano.Ledger.Credential
import Cardano.Ledger.Crypto (ADDRHASH)
import Cardano.Ledger.Era (Crypto)
import Cardano.Ledger.Hashes (ScriptHash (ScriptHash))
import Cardano.Ledger.Keys
import Cardano.Ledger.Shelley.LedgerState hiding (LedgerState)
import Cardano.Ledger.Shelley.TxBody
Expand All @@ -39,6 +44,8 @@ import qualified Ouroboros.Consensus.Shelley.Ledger.Ledger as Consensus
import Cardano.Mock.Forging.Tx.Alonzo.ScriptsExamples
import Cardano.Mock.Forging.Types

import Test.Cardano.Ledger.Shelley.Examples.Consensus (mkDummyHash)

resolveAddress :: forall era. (Crypto era ~ StandardCrypto, HasField "address" (Core.TxOut era) (Addr (Crypto era)))
=> UTxOIndex era -> LedgerState (ShelleyBlock era)
-> Either ForgingError (Addr (Crypto era))
Expand Down Expand Up @@ -161,3 +168,14 @@ unregisteredPools =
, KeyHash "222462543264795t3298745680239746523897456238974563298348"
, KeyHash "33323876542397465497834256329487563428975634827956348975"
]

createStakeCredentials :: Int -> [StakeCredential StandardCrypto]
createStakeCredentials n =
fmap (KeyHashObj . KeyHash . mkDummyHash (Proxy @(ADDRHASH StandardCrypto))) [1..n]

createPaymentCredentials :: Int -> [PaymentCredential StandardCrypto]
createPaymentCredentials n =
fmap (KeyHashObj . KeyHash . mkDummyHash (Proxy @(ADDRHASH StandardCrypto))) [1..n]

mkDummyScriptHash :: Int -> ScriptHash StandardCrypto
mkDummyScriptHash n = ScriptHash $ mkDummyHash (Proxy @(ADDRHASH StandardCrypto)) n
7 changes: 7 additions & 0 deletions cardano-chain-gen/test/Test/Cardano/Db/Mock/UnifiedApi.hs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
module Test.Cardano.Db.Mock.UnifiedApi where

import Control.Monad.Class.MonadSTM.Strict
import Data.Word (Word64)

import Cardano.Slotting.Slot (SlotNo (..))

Expand Down Expand Up @@ -28,6 +29,12 @@ forgeNextFindLeaderAndSubmit interpreter mockServer txs' = do
atomically $ addBlock mockServer blk
pure blk

forgeNextSkipSlotsFindLeaderAndSubmit :: Interpreter -> ServerHandle IO CardanoBlock -> Word64 -> [TxEra] -> IO CardanoBlock
forgeNextSkipSlotsFindLeaderAndSubmit interpreter mockServer skipSlots txs' = do
blk <- forgeNextAfter interpreter skipSlots txs'
atomically $ addBlock mockServer blk
pure blk

forgeAndSubmitBlocks :: Interpreter -> ServerHandle IO CardanoBlock -> Int -> IO [CardanoBlock]
forgeAndSubmitBlocks interpreter mockServer blocksToCreate = do
forM [1..blocksToCreate] $ \_ -> forgeNextFindLeaderAndSubmit interpreter mockServer []
Expand Down
132 changes: 132 additions & 0 deletions cardano-chain-gen/test/Test/Cardano/Db/Mock/Unit.hs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import Cardano.SMASH.Server.PoolDataLayer
import Cardano.SMASH.Server.Types

import Cardano.Mock.ChainSync.Server
import Cardano.Mock.Forging.Examples
import Cardano.Mock.Forging.Interpreter
import qualified Cardano.Mock.Forging.Tx.Alonzo as Alonzo
import Cardano.Mock.Forging.Tx.Alonzo.ScriptsExamples
Expand Down Expand Up @@ -95,6 +96,14 @@ unitTests iom knownMigrations =
, test "rollback on epoch boundary" rollbackBoundary
, test "single MIR Cert multiple outputs" singleMIRCertMultiOut
]
, testGroup "stake distribution"
[ test "stake distribution from genesis" stakeDistGenesis
, test "2000 delegations" delegations2000
, test "2001 delegations" delegations2001
, test "8000 delegations" delegations8000
, test "many delegations" delegationsMany
, test "many delegations, not dense chain" delegationsManyNotDense
]
, testGroup "plutus spend scripts"
[ test "simple script lock" simpleScript
, test "unlock script in same block" unlockScriptSameBlock
Expand Down Expand Up @@ -842,6 +851,129 @@ singleMIRCertMultiOut =
where
testLabel = "singleMIRCertMultiOut"

stakeDistGenesis :: IOManager -> [(Text, Text)] -> Assertion
stakeDistGenesis =
withFullConfig "config" testLabel $ \interpreter mockServer dbSync -> do
startDBSync dbSync
a <- fillUntilNextEpoch interpreter mockServer
assertBlockNoBackoff dbSync (fromIntegral $ length a - 1)
-- There are 5 delegations in genesis
assertEpochStake dbSync 5
where
testLabel = "stakeDistGenesis"

delegations2000 :: IOManager -> [(Text, Text)] -> Assertion
delegations2000 =
withFullConfig "config" testLabel $ \interpreter mockServer dbSync -> do
startDBSync dbSync
a <- delegateAndSendBlocks 1995 interpreter
forM_ a $ atomically . addBlock mockServer
b <- fillUntilNextEpoch interpreter mockServer
c <- fillUntilNextEpoch interpreter mockServer

assertBlockNoBackoff dbSync (fromIntegral $ length a + length b + length c - 1)
-- There are exactly 2000 entries on the second epoch, 5 from genesis and 1995 manually added
assertEpochStakeEpoch dbSync 2 2000

_ <- forgeNextFindLeaderAndSubmit interpreter mockServer []
assertBlockNoBackoff dbSync (fromIntegral $ length a + length b + length c)
assertEpochStakeEpoch dbSync 2 2000
where
testLabel = "delegations2000"

delegations2001 :: IOManager -> [(Text, Text)] -> Assertion
delegations2001 =
withFullConfig "config" testLabel $ \interpreter mockServer dbSync -> do
startDBSync dbSync
a <- delegateAndSendBlocks 1996 interpreter
forM_ a $ atomically . addBlock mockServer
b <- fillUntilNextEpoch interpreter mockServer
c <- fillUntilNextEpoch interpreter mockServer

assertBlockNoBackoff dbSync (fromIntegral $ length a + length b + length c - 1)
-- The first block of epoch inserts 2000 out of 2001 epoch distribution.
assertEpochStakeEpoch dbSync 2 2000
-- The remaining entry is inserted on the next block.
_ <- forgeNextFindLeaderAndSubmit interpreter mockServer []
assertBlockNoBackoff dbSync (fromIntegral $ length a + length b + length c)
assertEpochStakeEpoch dbSync 2 2001
where
testLabel = "delegations2001"

delegations8000 :: IOManager -> [(Text, Text)] -> Assertion
delegations8000 =
withFullConfig "config" testLabel $ \interpreter mockServer dbSync -> do
startDBSync dbSync
a <- delegateAndSendBlocks 7995 interpreter
forM_ a $ atomically . addBlock mockServer
b <- fillEpochs interpreter mockServer 3

assertBlockNoBackoff dbSync (fromIntegral $ length a + length b - 1)
assertEpochStakeEpoch dbSync 3 2000

_ <- forgeNextFindLeaderAndSubmit interpreter mockServer []
assertEpochStakeEpoch dbSync 3 4000

_ <- forgeNextFindLeaderAndSubmit interpreter mockServer []
assertEpochStakeEpoch dbSync 3 6000

_ <- forgeNextFindLeaderAndSubmit interpreter mockServer []
assertEpochStakeEpoch dbSync 3 8000

_ <- forgeNextFindLeaderAndSubmit interpreter mockServer []
assertEpochStakeEpoch dbSync 3 8000
where
testLabel = "delegations8000"

delegationsMany :: IOManager -> [(Text, Text)] -> Assertion
delegationsMany =
withFullConfig "config" testLabel $ \interpreter mockServer dbSync -> do
startDBSync dbSync
a <- delegateAndSendBlocks 40000 interpreter
forM_ a $ atomically . addBlock mockServer
b <- fillEpochs interpreter mockServer 5

-- too long. We cannot use default delays
assertBlockNoBackoffTimes (repeat 10) dbSync (fromIntegral $ length a + length b - 1)
-- The slice size here is
-- 1 + div (delegationsLen * 5) expectedBlocks = 2001
-- instead of 2000, because there are many delegations
assertEpochStakeEpoch dbSync 7 2001

_ <- forgeNextFindLeaderAndSubmit interpreter mockServer []
assertEpochStakeEpoch dbSync 7 4002

_ <- forgeNextFindLeaderAndSubmit interpreter mockServer []
assertEpochStakeEpoch dbSync 7 6003
where
testLabel = "delegationsMany"

delegationsManyNotDense :: IOManager -> [(Text, Text)] -> Assertion
delegationsManyNotDense =
withFullConfig "config" testLabel $ \interpreter mockServer dbSync -> do
startDBSync dbSync
a <- delegateAndSendBlocks 40000 interpreter
forM_ a $ atomically . addBlock mockServer
b <- fillEpochs interpreter mockServer 5

-- too long. We cannot use default delays
assertBlockNoBackoffTimes (repeat 10) dbSync (fromIntegral $ length a + length b - 1)
-- The slice size here is
-- 1 + div (delegationsLen * 5) expectedBlocks = 2001
-- instead of 2000, because there are many delegations
assertEpochStakeEpoch dbSync 7 2001

-- Blocks come on average every 5 slots. If we skip 15 slots before each block,
-- we are expected to get only 1/4 of the expected blocks. The adjusted slices
-- should still be long enough to cover everything.
replicateM_ 40 $
forgeNextSkipSlotsFindLeaderAndSubmit interpreter mockServer 15 []

-- Even if the chain is not dense, all distributions are inserted.
assertEpochStakeEpoch dbSync 7 40005
where
testLabel = "delegationsManyNotDense"

simpleScript :: IOManager -> [(Text, Text)] -> Assertion
simpleScript =
withFullConfig "config" testLabel $ \interpreter mockServer dbSync -> do
Expand Down
27 changes: 24 additions & 3 deletions cardano-chain-gen/test/Test/Cardano/Db/Mock/Validate.hs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import Data.Word (Word64)
import GHC.Records (HasField (..))

import Database.Esqueleto.Legacy (InnerJoin (..), SqlExpr, countRows, from, on, select,
unValue, (==.), (^.))
unValue, val, where_, (==.), (^.))
import Database.Persist.Sql (Entity, SqlBackend, entityVal)
import Database.PostgreSQL.Simple (SqlError (..))

Expand Down Expand Up @@ -66,8 +66,11 @@ assertRewardCount env n =
assertEqBackoff env queryRewardCount n defaultDelays "Unexpected rewards count"

assertBlockNoBackoff :: DBSyncEnv -> Int -> IO ()
assertBlockNoBackoff env blockNo =
assertEqBackoff env queryBlockHeight (Just $ fromIntegral blockNo) defaultDelays "Unexpected BlockNo"
assertBlockNoBackoff = assertBlockNoBackoffTimes defaultDelays

assertBlockNoBackoffTimes :: [Int] -> DBSyncEnv -> Int -> IO ()
assertBlockNoBackoffTimes times env blockNo =
assertEqBackoff env queryBlockHeight (Just $ fromIntegral blockNo) times "Unexpected BlockNo"

defaultDelays :: [Int]
defaultDelays = [1,2,4,8,16,32,64,128]
Expand Down Expand Up @@ -201,6 +204,24 @@ assertRewardCounts env st filterAddr expected = do
pure (reward, stake_addr ^. StakeAddressHashRaw)
pure $ fmap (bimap entityVal unValue) res

assertEpochStake :: DBSyncEnv -> Word64 -> IO ()
assertEpochStake env expected =
assertEqBackoff env q expected defaultDelays "Unexpected epoch stake counts"
where
q =
maybe 0 unValue . listToMaybe <$>
(select . from $ \(_a :: SqlExpr (Entity EpochStake)) -> pure countRows)

assertEpochStakeEpoch :: DBSyncEnv -> Word64 -> Word64 -> IO ()
assertEpochStakeEpoch env e expected =
assertEqBackoff env q expected defaultDelays "Unexpected epoch stake counts"
where
q =
maybe 0 unValue . listToMaybe <$>
(select . from $ \(a :: SqlExpr (Entity EpochStake)) -> do
where_ (a ^. EpochStakeEpochNo ==. val e)
pure countRows
)

assertAlonzoCounts :: DBSyncEnv -> (Word64, Word64, Word64, Word64, Word64, Word64, Word64, Word64) -> IO ()
assertAlonzoCounts env expected =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,6 @@
{ "summand": "155381000000000" , "multiplier": "43946000000" }
, "unlockStakeEpoch": "18446744073709551615"
}
, "protocolConsts": { "k": 216 , "protocolMagic": 42 }
, "protocolConsts": { "k": 10 , "protocolMagic": 42 }
, "avvmDistr": {}
}
2 changes: 1 addition & 1 deletion cardano-chain-gen/test/testfiles/config/test-config.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"ApplicationName": "cardano-sl",
"ApplicationVersion": 0,
"ByronGenesisFile": "genesis.byron.json",
"ByronGenesisHash": "462bb9869a5a6e4325cc294ca659d68607e8a6f37b5be96ea663fdedfe2b5949",
"ByronGenesisHash": "865a9da19944fc00cefe5a0cdcb6dc9d3964a74681d9488ab79967f13a6400b3",
"LastKnownBlockVersion-Alt": 0,
"LastKnownBlockVersion-Major": 5,
"LastKnownBlockVersion-Minor": 1,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[3,4,6,13,22,31,43,46,52,54,56,64,69,73,76,78,79,90,98,99,104,105,106,109,111,113,114,120,122,124,132,142,143,144,152,158,163,167,199,201,209,210,216,219,235,237,254,261,268,273,275,279,280,285,303,304,306,309,310,313,322,325,327,329,330,331,335,340,346,348,353,361,366,372,373,376,377,378,383,388,391,392,393,397,406,408,409,413,420,422,430,438,440,444,452,454,456,460,461,468,469,471,478,483,488,503,507,511,513,514,529,530,536,547,550,554,556,558,561,562,565,566,577,591,594,595,596,599,605,606,611,620,625,627,629,643,644,655,658,667,676,684,690,695,701,704,711,715,720,723,730,732,737,739,741,748,752,755,758,765,772,776,779,780,781,785,790,806,810,816,818,820,822,835,843,846,852,854,855,858,864,865,866,875,878,880,883,888,891,900,904,905,906,907,911,914,917,920,925,934,939,945,951,953,959,962,968,971,975,979,983,988,992,993,996,1002,1003]
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[3,4,6,13,22,31,43,46,52,54,56,64,69,73,76,78,79,90,98,99,104,105,106,109,111,113,114,120,122,124,132,142,143,144,152,158,163,167,199,201,209,210,216,219,235,237,254,261,268,273,275,279,280,285,303,304,306,309,310,313,322,325,327,329,330,331,335,340,346,348,353,361,366,372,373,376,377,378,383,388,391,392,393,397,406,408,409,413,420,422,430,438,440,444,452,454,456,460,461,468,469,471,478,483,488,503,507,511,513,514,529,530,536,547,550,554,556,558,561,562,565,566,577,591,594,595,596,599,605,606,611,620,625,627,629,643,644,655,658,667,676,684,690,695,701,704,711,715,720,723,730,732,737,739,741,748,752,755,758,765,772,776,779,780,781,785,790,806,810,816,818,820,822,835,843,846,852,854,855,858,864,865,866,875,878,880,883,888,891,900,904,905,906,907,911,914,917,920,925,934,939,945,951,953,959,962,968,971,975,979,983,988,992,993,996,1006,1011]
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[3,4,6,13,22,31,43,46,52,54,56,64,69,73,76,78,79,90,98,99,104,105,106,109,111,113,114,120,122,124,132,142,143,144,152,158,163,167,199,201,209,210,216,219,235,237,254,261,268,273,275,279,280,285,303,304,306,309,310,313,322,325,327,329,330,331,335,340,346,348,353,361,366,372,373,376,377,378,383,388,391,392,393,397,406,408,409,413,420,422,430,438,440,444,452,454,456,460,461,468,469,471,478,483,488,503,507,511,513,514,529,530,536,547,550,554,556,558,561,562,565,566,577,591,594,595,596,599,605,606,611,620,625,627,629,643,644,655,658,667,676,684,690,695,701,704,711,715,720,723,730,732,737,739,741,748,752,755,758,765,772,776,779,780,781,785,790,806,810,816,818,820,822,835,843,846,852,854,855,858,864,865,866,875,878,880,883,888,891,900,904,905,906,907,911,914,917,920,925,934,939,945,951,953,959,962,968,971,975,979,983,988,992,993,996,1002,1007,1012,1014,1021,1022,1025,1026,1028,1038,1041,1058,1059,1060,1062,1063,1064,1069,1070,1079,1084,1092,1093,1109,1110,1111,1119,1120,1132,1134,1135,1148,1149,1167,1173,1178,1189,1192,1194,1195,1196,1202,1203,1209,1221,1223,1232,1233,1240,1246,1257,1263,1267,1268,1271,1273,1277,1280,1282,1285,1297,1299,1306,1313,1318,1319,1323,1325,1328,1333,1336,1341,1344,1348,1350,1352,1359,1362,1371,1372,1378,1379,1383,1393,1397,1399,1414,1417,1420,1421,1433,1434,1435,1460,1466,1467,1472,1474,1476,1479,1481,1482,1485,1497,1499,1503,1506,1515,1517,1521]
Loading