Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
Soupstraw committed Jan 17, 2025
1 parent 7683b73 commit 930bddd
Show file tree
Hide file tree
Showing 32 changed files with 428 additions and 113 deletions.
5 changes: 3 additions & 2 deletions eras/alonzo/impl/src/Cardano/Ledger/Alonzo/Rules/Utxo.hs
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,10 @@ import Cardano.Ledger.BaseTypes (
ShelleyBase,
StrictMaybe (..),
epochInfo,
knownNonZero,
networkId,
systemStart,
(%?),
)
import Cardano.Ledger.Binary (DecCBOR (..), EncCBOR (..), serialize)
import Cardano.Ledger.Binary.Coders (
Expand Down Expand Up @@ -104,7 +106,6 @@ import Data.Coerce (coerce)
import Data.Either (isRight)
import Data.Foldable as F (foldl', sequenceA_, toList)
import qualified Data.Map.Strict as Map
import Data.Ratio ((%))
import Data.Set (Set)
import qualified Data.Set as Set
import GHC.Generics (Generic)
Expand Down Expand Up @@ -331,7 +332,7 @@ validateInsufficientCollateral pp txBody bal =
failureUnless (Val.scale (100 :: Int) bal >= Val.scale collPerc (toDeltaCoin txfee)) $
InsufficientCollateral bal $
rationalToCoinViaCeiling $
(fromIntegral collPerc * unCoin txfee) % 100
(fromIntegral collPerc * unCoin txfee) %? knownNonZero @100
where
txfee = txBody ^. feeTxBodyL -- Coin supplied to pay fees
collPerc = pp ^. ppCollateralPercentageL
Expand Down
9 changes: 6 additions & 3 deletions eras/conway/impl/src/Cardano/Ledger/Conway/Governance.hs
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,10 @@ import Cardano.Ledger.BaseTypes (
EpochNo (..),
Globals (..),
StrictMaybe (..),
knownNonZero,
mulNonZero,
toIntegerNonZero,
(%?),
)
import Cardano.Ledger.Binary (
DecCBOR (..),
Expand Down Expand Up @@ -251,7 +255,6 @@ import qualified Data.Foldable as F (foldl')
import Data.Map.Strict (Map)
import qualified Data.Map.Strict as Map
import qualified Data.Set as Set
import Data.Word (Word64)
import GHC.Generics (Generic)
import Lens.Micro
import Lens.Micro.Extras (view)
Expand Down Expand Up @@ -491,14 +494,14 @@ setFreshDRepPulsingState epochNo stakePoolDistr epochState = do
k = securityParameter globals -- On mainnet set to 2160
umap = dsUnified dState
umapSize = Map.size $ umElems umap
pulseSize = max 1 (umapSize `div` (fromIntegral :: Word64 -> Int) (4 * k))
pulseSize = max 1 (fromIntegral umapSize %? (knownNonZero @4 `mulNonZero` toIntegerNonZero k))
govState' =
predictFuturePParams $
govState
& cgsDRepPulsingStateL
.~ DRPulsing
( DRepPulser
{ dpPulseSize = pulseSize
{ dpPulseSize = floor pulseSize
, dpUMap = dsUnified dState
, dpIndex = 0 -- used as the index of the remaining UMap
, dpStakeDistr = stakeDistr -- used as part of the snapshot
Expand Down
5 changes: 5 additions & 0 deletions eras/conway/impl/src/Cardano/Ledger/Conway/Plutus/Context.hs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import Cardano.Ledger.Alonzo.PParams (
)
import Cardano.Ledger.Alonzo.Plutus.Context (EraPlutusTxInfo)
import Cardano.Ledger.Babbage.PParams (CoinPerByte (..), ppuCoinsPerUTxOByteL)
import Cardano.Ledger.BaseTypes (HasZero, NonZero (..), nonZero)
import Cardano.Ledger.Coin (Coin (..))
import Cardano.Ledger.Conway.PParams (
ConwayEraPParams (..),
Expand Down Expand Up @@ -156,6 +157,10 @@ instance ToPlutusData CoinPerByte where
toPlutusData (CoinPerByte c) = toPlutusData @Coin c
fromPlutusData x = CoinPerByte <$> fromPlutusData @Coin x

instance (ToPlutusData a, HasZero a) => ToPlutusData (NonZero a) where
toPlutusData = toPlutusData . unNonZero
fromPlutusData x = nonZero =<< fromPlutusData x

-- ==========================================================

-- | A Map for the Conway era
Expand Down
25 changes: 14 additions & 11 deletions eras/conway/impl/src/Cardano/Ledger/Conway/Rules/Ratify.hs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ import Cardano.Ledger.BaseTypes (
ShelleyBase,
StrictMaybe (..),
addEpochInterval,
nonZero,
(%?),
)
import Cardano.Ledger.CertState (CommitteeAuthorization (..), CommitteeState (csCommitteeCreds))
import Cardano.Ledger.Coin (Coin (..), CompactForm (..))
Expand Down Expand Up @@ -81,7 +83,6 @@ import Control.State.Transition.Extended (
import Data.Foldable (Foldable (..))
import Data.Map.Strict (Map)
import qualified Data.Map.Strict as Map
import Data.Ratio ((%))
import qualified Data.Sequence as Seq
import qualified Data.Sequence.Strict as SSeq
import qualified Data.Set as Set
Expand Down Expand Up @@ -140,9 +141,10 @@ committeeAcceptedRatio ::
CommitteeState era ->
EpochNo ->
Rational
committeeAcceptedRatio members votes committeeState currentEpoch
| totalExcludingAbstain == 0 = 0
| otherwise = yesVotes % totalExcludingAbstain
committeeAcceptedRatio members votes committeeState currentEpoch =
case nonZero totalExcludingAbstain of
Just totalExcludingAbstainNZ -> yesVotes %? totalExcludingAbstainNZ
Nothing -> 0
where
accumVotes ::
(Integer, Integer) ->
Expand Down Expand Up @@ -200,10 +202,10 @@ spoAcceptedRatio
{ gasStakePoolVotes
, gasProposalProcedure = ProposalProcedure {pProcGovAction}
}
pv
| totalActiveStake == 0 = 0 -- guard against the degenerate case when active stake is zero.
| totalActiveStake == abstainStake = 0 -- guard against the degenerate case when all abstain.
| otherwise = toInteger yesStake % toInteger (totalActiveStake - abstainStake)
pv =
case nonZero . toInteger $ totalActiveStake - abstainStake of
Just d -> toInteger yesStake %? d
Nothing -> 0
where
accumStake (!yes, !abstain) poolId distr =
let CompactCoin stake = individualTotalPoolStake distr
Expand Down Expand Up @@ -253,9 +255,10 @@ dRepAcceptedRatio ::
Map (Credential 'DRepRole) Vote ->
GovAction era ->
Rational
dRepAcceptedRatio RatifyEnv {reDRepDistr, reDRepState, reCurrentEpoch} gasDRepVotes govAction
| totalExcludingAbstainStake == 0 = 0
| otherwise = toInteger yesStake % toInteger totalExcludingAbstainStake
dRepAcceptedRatio RatifyEnv {reDRepDistr, reDRepState, reCurrentEpoch} gasDRepVotes govAction =
case nonZero $ toInteger totalExcludingAbstainStake of
Just d -> toInteger yesStake %? d
Nothing -> 0
where
accumStake (!yes, !tot) drep (CompactCoin stake) =
case drep of
Expand Down
5 changes: 2 additions & 3 deletions eras/conway/impl/src/Cardano/Ledger/Conway/Tx.hs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ import Cardano.Ledger.Conway.TxBody ()
import Cardano.Ledger.Conway.TxWits ()
import Cardano.Ledger.Core
import Cardano.Ledger.Val (Val (..))
import Data.Ratio ((%))
import GHC.Stack
import Lens.Micro ((^.))

Expand Down Expand Up @@ -125,10 +124,10 @@ tierRefScriptFee multiplier sizeIncrement
where
go !acc !curTierPrice !n
| n < sizeIncrement =
Coin $ floor (acc + (toInteger n % 1) * curTierPrice)
Coin $ floor (acc + toRational n * curTierPrice)
| otherwise =
go (acc + sizeIncrementRational * curTierPrice) (multiplier * curTierPrice) (n - sizeIncrement)
sizeIncrementRational = toInteger sizeIncrement % 1
sizeIncrementRational = toRational sizeIncrement

instance AlonzoEraTx ConwayEra where
isValidTxL = isValidAlonzoTxL
Expand Down
15 changes: 10 additions & 5 deletions eras/shelley/impl/src/Cardano/Ledger/Shelley/API/Wallet.hs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ import Cardano.Ledger.BaseTypes (
NonNegativeInterval,
UnitInterval,
epochInfoPure,
nonZero,
nonZeroOr,
(%?),
)
import Cardano.Ledger.Binary (
DecCBOR (..),
Expand Down Expand Up @@ -110,7 +113,6 @@ import Data.Default (Default (def))
import Data.Foldable (foldMap')
import Data.Map.Strict (Map)
import qualified Data.Map.Strict as Map
import Data.Ratio ((%))
import Data.Set (Set)
import qualified Data.Set as Set
import qualified Data.VMap as VMap
Expand Down Expand Up @@ -197,7 +199,8 @@ poolsByTotalStakeFraction globals ss =
where
snap = currentSnapshot ss
Coin totalStake = getTotalStake globals ss
stakeRatio = unCoin (fromCompact totalActiveStake) % totalStake
totalStakeNonZero = totalStake `nonZeroOr` error "Total stake is zero"
stakeRatio = unCoin (fromCompact totalActiveStake) %? totalStakeNonZero
PoolDistr poolsByActiveStake totalActiveStake = calculatePoolDistr snap
poolsByTotalStake = Map.map toTotalStakeFrac poolsByActiveStake
toTotalStakeFrac ::
Expand Down Expand Up @@ -231,8 +234,10 @@ getNonMyopicMemberRewards globals ss =
Map.fromSet (\cred -> Map.map (mkNMMRewards $ memShare cred) poolData)
where
maxSupply = Coin . fromIntegral $ maxLovelaceSupply globals
Coin totalStake = circulation es maxSupply
toShare (Coin x) = StakeShare (x % totalStake)
totalStakeCoin@(Coin totalStake) = circulation es maxSupply
toShare (Coin x) = StakeShare $ case nonZero totalStake of
Just d -> x %? d
Nothing -> 0
memShare (Right cred) =
toShare $ maybe mempty fromCompact $ VMap.lookup cred (EB.unStake stake)
memShare (Left coin) = toShare coin
Expand All @@ -255,7 +260,7 @@ getNonMyopicMemberRewards globals ss =
topPools =
getTopRankedPoolsVMap
rPot
(Coin totalStake)
(totalStakeCoin `nonZeroOr` error "Total stake is zero")
pp
poolParams
(fmap percentile' ls)
Expand Down
16 changes: 10 additions & 6 deletions eras/shelley/impl/src/Cardano/Ledger/Shelley/Genesis.hs
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,12 @@ import Cardano.Ledger.BaseTypes (
EpochSize (..),
Globals (..),
Network,
NonZero (..),
Nonce (..),
PositiveUnitInterval,
mkActiveSlotCoeff,
nonZeroOr,
(/?),
)
import Cardano.Ledger.Binary (
DecCBOR (..),
Expand Down Expand Up @@ -211,7 +214,7 @@ data ShelleyGenesis = ShelleyGenesis
, sgNetworkMagic :: !Word32
, sgNetworkId :: !Network
, sgActiveSlotsCoeff :: !PositiveUnitInterval
, sgSecurityParam :: !Word64
, sgSecurityParam :: !(NonZero Word64)
, sgEpochLength :: !EpochSize
, sgSlotsPerKESPeriod :: !Word64
, sgMaxKESEvolutions :: !Word64
Expand Down Expand Up @@ -634,14 +637,15 @@ validateGenesis
let activeSlotsCoeff = unboundRational sgActiveSlotsCoeff
minLength =
EpochSize . ceiling $
fromIntegral @_ @Double (3 * sgSecurityParam)
/ fromRational activeSlotsCoeff
fromIntegral @_ @Double (3 * unNonZero sgSecurityParam)
/? fromRational activeSlotsCoeff
`nonZeroOr` error "activeSlotsCoeff is zero after conversion to Double"
in if minLength > sgEpochLength
then
Just $
EpochNotLongEnough
sgEpochLength
sgSecurityParam
(unNonZero sgSecurityParam)
activeSlotsCoeff
minLength
else Nothing
Expand Down Expand Up @@ -680,6 +684,6 @@ mkShelleyGlobals genesis epochInfoAc =
systemStart = SystemStart $ sgSystemStart genesis
k = sgSecurityParam genesis
stabilityWindow =
computeStabilityWindow k (sgActiveSlotCoeff genesis)
computeStabilityWindow (unNonZero k) (sgActiveSlotCoeff genesis)
randomnessStabilisationWindow =
computeRandomnessStabilisationWindow k (sgActiveSlotCoeff genesis)
computeRandomnessStabilisationWindow (unNonZero k) (sgActiveSlotCoeff genesis)
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}

module Cardano.Ledger.Shelley.LedgerState.PulsingReward (
startStep,
Expand All @@ -24,8 +25,15 @@ import Cardano.Ledger.BaseTypes (
ActiveSlotCoeff,
BlocksMade (..),
BoundedRational (..),
NonZero,
ShelleyBase,
activeSlotVal,
knownNonZero,
mulNonZero,
nonZero,
nonZeroOr,
toIntegerNonZero,
(%?),
)
import Cardano.Ledger.CertState (
CertState (..),
Expand Down Expand Up @@ -79,8 +87,8 @@ import Cardano.Ledger.Val ((<->))
import Data.Group (invert)
import Data.Map.Strict (Map)
import qualified Data.Map.Strict as Map
import Data.Maybe (fromMaybe)
import Data.Pulse (Pulsable (..), completeM)
import Data.Ratio ((%))
import qualified Data.Set as Set
import qualified Data.VMap as VMap
import Data.Word (Word64)
Expand All @@ -102,13 +110,12 @@ startStep ::
EpochState era ->
Coin ->
ActiveSlotCoeff ->
Word64 ->
NonZero Word64 ->
PulsingRewUpdate
startStep slotsPerEpoch b@(BlocksMade b') es@(EpochState acnt ls ss nm) maxSupply asc secparam =
let SnapShot stake delegs poolParams = ssStakeGo ss
numStakeCreds, k :: Rational
numStakeCreds = fromIntegral (VMap.size $ unStake stake)
k = fromIntegral secparam
k = toIntegerNonZero secparam
-- We expect approximately 10k-many blocks to be produced each epoch.
-- The reward calculation begins (4k/f)-many slots into the epoch,
-- and we guarantee that it ends (2k/f)-many slots before the end
Expand All @@ -120,7 +127,7 @@ startStep slotsPerEpoch b@(BlocksMade b') es@(EpochState acnt ls ss nm) maxSuppl
-- stake credential rewards we should calculate each block.
-- If it does not finish in this amount of time, the calculation is
-- forced to completion.
pulseSize = max 1 (ceiling (numStakeCreds / (4 * k)))
pulseSize = max 1 (ceiling (numStakeCreds %? (knownNonZero @4 `mulNonZero` k)))
-- We now compute the amount of total rewards that can potentially be given
-- out this epoch, and the adjustments to the reserves and the treasury.
Coin reserves = asReserves acnt
Expand All @@ -134,21 +141,25 @@ startStep slotsPerEpoch b@(BlocksMade b') es@(EpochState acnt ls ss nm) maxSuppl
* fromIntegral reserves
d = unboundRational (pr ^. ppDG)
expectedBlocks =
floor $
(1 - d) * unboundRational (activeSlotVal asc) * fromIntegral (unEpochSize slotsPerEpoch)
-- TODO what should happen here?
fromMaybe (error "Expected blocks is zero")
. nonZero
. floor
$ (1 - d) * unboundRational (activeSlotVal asc) * fromIntegral (unEpochSize slotsPerEpoch)
-- TODO asc is a global constant, and slotsPerEpoch should not change often at all,
-- it would be nice to not have to compute expectedBlocks every epoch
blocksMade = fromIntegral $ Map.foldr (+) 0 b' :: Integer
eta
| unboundRational (pr ^. ppDG) >= 0.8 = 1
| otherwise = blocksMade % expectedBlocks
| d >= 0.8 = 1
| otherwise = blocksMade %? expectedBlocks
Coin rPot = ssFee ss <> deltaR1
deltaT1 = floor $ unboundRational (pr ^. ppTauL) * fromIntegral rPot
_R = Coin $ rPot - deltaT1
-- We now compute stake pool specific values that are needed for computing
-- member and leader rewards.
activeStake = sumAllStake stake
totalStake = circulation es maxSupply
activeStake = sumAllStake stake `nonZeroOr` error "Active stake is zero"
totalStake =
circulation es maxSupply `nonZeroOr` error "Total stake is zero"
stakePerPool = sumStakePerPool delegs stake
mkPoolRewardInfoCurry =
mkPoolRewardInfo
Expand Down Expand Up @@ -306,7 +317,7 @@ createRUpd ::
EpochState era ->
Coin ->
ActiveSlotCoeff ->
Word64 ->
NonZero Word64 ->
ShelleyBase RewardUpdate
createRUpd slotsPerEpoch blocksmade epstate maxSupply asc secparam = do
let step1 = startStep slotsPerEpoch blocksmade epstate maxSupply asc secparam
Expand Down
Loading

0 comments on commit 930bddd

Please sign in to comment.