Skip to content

Commit

Permalink
Adjusted the OutputsToBig rule.
Browse files Browse the repository at this point in the history
  • Loading branch information
TimSheard committed Mar 8, 2021
1 parent 925b852 commit a1e0a44
Showing 1 changed file with 49 additions and 31 deletions.
80 changes: 49 additions & 31 deletions alonzo/impl/src/Cardano/Ledger/Alonzo/Rules/Utxo.hs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ import Cardano.Ledger.Shelley.Constraints
)
import Cardano.Ledger.ShelleyMA.Rules.Utxo (consumed, scaledMinDeposit)
import Cardano.Ledger.ShelleyMA.Timelocks (ValidityInterval (..), inInterval)
import Cardano.Ledger.Val ((<+>), (<×>))
import Cardano.Ledger.Val (coin, (<+>), (<×>))
import qualified Cardano.Ledger.Val as Val
import Cardano.Slotting.Slot (SlotNo)
import Control.Iterate.SetAlgebra (dom, eval, (⊆), (◁), (➖))
Expand All @@ -69,6 +69,7 @@ import Data.Set (Set)
import qualified Data.Set as Set
import Data.Typeable (Typeable)
import GHC.Generics (Generic)
import GHC.Int (Int64)
import GHC.Records
import NoThunks.Class (NoThunks)
import Numeric.Natural (Natural)
Expand Down Expand Up @@ -101,6 +102,20 @@ import Shelley.Spec.Ledger.UTxO
unUTxO,
)

-- ==================================================================
-- We need to estimate the size of storing 1 extra entry in the UTxO
-- type UTxO = Map (TxIn (Crypto era)) (TxOut era)
-- TxIn = (SafeHash,Word64), so sizeTxIn = sizeSafeHash + 8 bytes
-- So one extra entry adds ( sizeSafeHash + 8 + sizeTxOut + mapOverhead )
-- All this is computed by outputSize. Remember this is an estimate that
-- just needs to be proportional to the actual size.

outputSize :: Era era => TxOut era -> Int64
outputSize txout = sizeSafeHash + 8 + BSL.length (serialize txout) + mapOverhead
where
sizeSafeHash = 36
mapOverhead = 14

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

-- | The uninhabited type that marks the Alonzo UTxO rule
Expand Down Expand Up @@ -220,7 +235,7 @@ feesOK pp tx (utxo@(UTxO m)) = do
let txb = getField @"body" tx
theFee = getField @"txfee" txb -- Coin supplied to pay fees
fees = getField @"txinputs_fee" txb -- Inputs allocated to pay theFee
utxoFees = eval (fees m) -- restrict to those inputs where fees are paid
utxoFees = eval (fees m) -- restrict Utxo to those inputs we use to pay fees.
bal = Val.coin (balance @era (UTxO utxoFees))
nonNative txout = isNonNativeScriptAddress @era tx (getField @"address" txout)
minimumFee = minfee @era pp tx
Expand Down Expand Up @@ -272,12 +287,27 @@ utxoTransition = do
inInterval slot (getField @"vldt" txb)
?! OutsideValidityIntervalUTxO (getField @"vldt" txb) slot

txins @era txb /= Set.empty ?! InputSetEmptyUTxO
not (Set.null (txins @era txb)) ?! InputSetEmptyUTxO

feesOK pp tx utxo -- Generalizes the fee to small from earlier Era's
eval (txins @era txb dom utxo)
?! BadInputsUTxO (eval ((txins @era txb) (dom utxo)))

let consumed_ = consumed pp utxo txb
produced_ = Shelley.produced @era pp stakepools txb
consumed_ == produced_ ?! ValueNotConservedUTxO consumed_ produced_

-- Check that the mint field does not try to mint ADA. This is equivalent to
-- the check `adaPolicy ∉ supp mint tx` in the spec.
Val.coin (getField @"mint" txb) == Val.zero ?! TriesToForgeADA

let outputs = Map.elems $ unUTxO (txouts @era txb)
ok out =
coin (getField @"value" out)
>= (outputSize out <×> (getField @"_adaPerUTxOByte" pp))
outputsTooBig = filter (not . ok) outputs
null outputsTooBig ?! OutputTooBigUTxO outputsTooBig

ni <- liftSTS $ asks networkId
let addrsWrongNetwork =
filter
Expand All @@ -293,16 +323,10 @@ utxoTransition = do
ni
(Set.fromList wdrlsWrongNetwork)

let consumed_ = consumed pp utxo txb
produced_ = Shelley.produced @era pp stakepools txb
consumed_ == produced_ ?! ValueNotConservedUTxO consumed_ produced_

-- Check that the mint field does not try to mint ADA. This is equivalent to
-- the check `adaPolicy ∉ supp mint tx` in the spec.
Val.coin (getField @"mint" txb) == Val.zero ?! TriesToForgeADA

let outputs = Map.elems $ unUTxO (txouts @era txb)
minUTxOValue = getField @"_minUTxOValue" pp
-- TODO remove this?
-- This came from the ShelleyMA eras, I don't think it applies here.
-- It does not appear in the Alonzo specification
let minUTxOValue = getField @"_minUTxOValue" pp
outputsTooSmall =
filter
( \out ->
Expand All @@ -316,16 +340,17 @@ utxoTransition = do
outputs
null outputsTooSmall ?! OutputTooSmallUTxO outputsTooSmall

let outputsTooBig =
filter
( \out ->
let v = getField @"value" out
in (BSL.length . serialize) v > fromIntegral (unCoin (getField @"_adaPerUTxOByte" pp))
-- TODO I am sure this is not right.
)
outputs
null outputsTooBig ?! OutputTooBigUTxO outputsTooBig
let maxTxSize_ = fromIntegral (getField @"_maxTxSize" pp)
txSize_ = getField @"txsize" tx
txSize_ <= maxTxSize_ ?! MaxTxSizeUTxO txSize_ maxTxSize_

let maxTxEx = getField @"_maxTxExUnits" pp
totExunits = getField @"totExunits" tx
totExunits <= maxTxEx ?! ExUnitsTooSmallUTxO maxTxEx totExunits

-- TODO remove this?
-- This came from the ShelleyMA eras, I don't think it applies here.
-- It does not appear in the Alonzo specification
-- Bootstrap (i.e. Byron) addresses have variable sized attributes in them.
-- It is important to limit their overall size.
let outputsAttrsTooBig =
Expand All @@ -337,15 +362,8 @@ utxoTransition = do
outputs
null outputsAttrsTooBig ?! OutputBootAddrAttrsTooBig outputsAttrsTooBig

let maxTxSize_ = fromIntegral (getField @"_maxTxSize" pp)
txSize_ = getField @"txsize" tx
txSize_ <= maxTxSize_ ?! MaxTxSizeUTxO txSize_ maxTxSize_

let maxTxEx = getField @"_maxTxExUnits" pp
totExunits = getField @"totExunits" tx
totExunits <= maxTxEx ?! ExUnitsTooSmallUTxO maxTxEx totExunits

-- utxosTransition -- How do we call this?
-- TODO How do we call this
-- utxosTransition
utxoS tx -- instead of this stub?

utxoS :: Tx era -> TransitionRule (AlonzoUTXO era)
Expand Down

0 comments on commit a1e0a44

Please sign in to comment.