Skip to content

Protocol Parameters

This section is part of the Ledger.Conway.PParams module of the formal ledger specification, in which we define the adjustable protocol parameters of the Cardano ledger.

Protocol parameters are used in block validation and can affect various features of the system, such as minimum fees, maximum and minimum sizes of certain components, and more.

{-# OPTIONS --safe #-}

open import Data.Product.Properties
open import Data.Nat.Properties using (m+1+n≢m)
open import Data.Rational using ()
open import Relation.Nullary.Decidable
open import Data.List.Relation.Unary.Any using (Any; here; there)

open import Tactic.Derive.Show

open import Ledger.Prelude
open import Ledger.Conway.Crypto
open import Ledger.Conway.Script.Base
open import Ledger.Conway.Types.Epoch
open import Ledger.Conway.Types.Numeric using (UnitInterval; ℕ⁺)

module Ledger.Conway.PParams
  (crypto : Crypto )
  (es     : _) (open EpochStructure es)
  (ss     : ScriptStructure crypto es) (open ScriptStructure ss)
  where

private variable
  m n : 

The Acnt record has two fields, treasury and reserves, so the field in NewEpochState keeps track of the total assets that remain in treasury and reserves.

record Acnt : Type where
  constructor ⟦_,_⟧ᵃ
  field
    treasury reserves : Coin

record Hastreasury {a} (A : Type a) : Type a where
  field treasuryOf : A  Coin
open Hastreasury ⦃...⦄ public

record Hasreserves {a} (A : Type a) : Type a where
  field reservesOf : A  Coin
open Hasreserves ⦃...⦄ public

ProtVer : Type
ProtVer =  × 

instance
  Show-ProtVer : Show ProtVer
  Show-ProtVer = Show-×

data pvCanFollow : ProtVer  ProtVer  Type where
  canFollowMajor : pvCanFollow (m , n) (m + 1 , 0)
  canFollowMinor : pvCanFollow (m , n) (m , n + 1)
instance
  unquoteDecl HasCast-Acnt = derive-HasCast
    [ (quote Acnt , HasCast-Acnt) ]

Protocol parameter group definition

data PParamGroup : Type where
  NetworkGroup     : PParamGroup
  EconomicGroup    : PParamGroup
  TechnicalGroup   : PParamGroup
  GovernanceGroup  : PParamGroup
  SecurityGroup    : PParamGroup

Protocol parameter threshold definitions

record DrepThresholds : Type where
  field
    P1 P2a P2b P3 P4 P5a P5b P5c P5d P6 : 

record PoolThresholds : Type where
  field
    Q1 Q2a Q2b Q4 Q5 : 

Protocol parameter definitions

record PParams : Type where
  field

Network group

        maxBlockSize                  : 
        maxTxSize                     : 
        maxHeaderSize                 : 
        maxTxExUnits                  : ExUnits
        maxBlockExUnits               : ExUnits
        maxValSize                    : 
        maxCollateralInputs           : 
        pv                            : ProtVer -- retired, keep for now

Economic group

        a                             : 
        b                             : 
        keyDeposit                    : Coin
        poolDeposit                   : Coin
        monetaryExpansion             : UnitInterval -- formerly: rho
        treasuryCut                   : UnitInterval -- formerly: tau
        coinsPerUTxOByte              : Coin
        prices                        : Prices
        minFeeRefScriptCoinsPerByte   : 
        maxRefScriptSizePerTx         : 
        maxRefScriptSizePerBlock      : 
        refScriptCostStride           : ℕ⁺
        refScriptCostMultiplier       : 
        minUTxOValue                  : Coin -- retired, keep for now

Technical group

        Emax                          : Epoch
        nopt                          : 
        a0                            : 
        collateralPercentage          : 
        -- costmdls                   : Language →/⇀ CostModel (Does not work with DecEq)
        costmdls                      : CostModel

Governance group

        poolThresholds                : PoolThresholds
        drepThresholds                : DrepThresholds
        ccMinSize                     : 
        ccMaxTermLength               : 
        govActionLifetime             : 
        govActionDeposit              : Coin
        drepDeposit                   : Coin
        drepActivity                  : Epoch

Security group

maxBlockSize maxTxSize maxHeaderSize maxValSize maxBlockExUnits a b minFeeRefScriptCoinsPerByte coinsPerUTxOByte govActionDeposit

record HasPParams {a} (A : Type a) : Type a where
  field PParamsOf : A  PParams
open HasPParams ⦃...⦄ public
record HasgovActionDeposit {a} (A : Type a) : Type a where
  field govActionDepositOf : A  Coin
open HasgovActionDeposit ⦃...⦄ public

record HasccMaxTermLength {a} (A : Type a) : Type a where
  field ccMaxTermLengthOf : A  
open HasccMaxTermLength ⦃...⦄ public

instance
  HasgovActionDeposit-PParams : HasgovActionDeposit PParams
  HasgovActionDeposit-PParams .govActionDepositOf = PParams.govActionDeposit

Protocol parameter well formedness

positivePParams : PParams  List 
positivePParams pp =  ( maxBlockSize  maxTxSize  maxHeaderSize
                       maxValSize  coinsPerUTxOByte
                       poolDeposit  collateralPercentage  ccMaxTermLength
                       govActionLifetime  govActionDeposit  drepDeposit  [] )
  where open PParams pp

paramsWellFormed : PParams  Type
paramsWellFormed pp = 0  fromList (positivePParams pp)
paramsWF-elim : (pp : PParams)  paramsWellFormed pp  (n : )  n ∈ˡ (positivePParams pp)  n > 0
paramsWF-elim pp pwf (suc n) x = z<s
paramsWF-elim pp pwf 0 0∈ = ⊥-elim (pwf (to ∈-fromList 0∈))
  where open Equivalence
instance
  unquoteDecl DecEq-DrepThresholds = derive-DecEq
    ((quote DrepThresholds , DecEq-DrepThresholds)  [])
  unquoteDecl DecEq-PoolThresholds = derive-DecEq
    ((quote PoolThresholds , DecEq-PoolThresholds)  [])
  unquoteDecl DecEq-PParams        = derive-DecEq
    ((quote PParams , DecEq-PParams)  [])
  unquoteDecl DecEq-PParamGroup    = derive-DecEq
    ((quote PParamGroup , DecEq-PParamGroup)  [])
  unquoteDecl Show-DrepThresholds = derive-Show
    ((quote DrepThresholds , Show-DrepThresholds)  [])
  unquoteDecl Show-PoolThresholds = derive-Show
    ((quote PoolThresholds , Show-PoolThresholds)  [])
  unquoteDecl Show-PParams        = derive-Show
    ((quote PParams , Show-PParams)  [])

module PParamsUpdate where
  record PParamsUpdate : Type where
    field
          maxBlockSize maxTxSize        : Maybe 
          maxHeaderSize maxValSize      : Maybe 
          maxCollateralInputs           : Maybe 
          maxTxExUnits maxBlockExUnits  : Maybe ExUnits
          pv                            : Maybe ProtVer -- retired, keep for now
          a b                           : Maybe 
          keyDeposit                    : Maybe Coin
          poolDeposit                   : Maybe Coin
          monetaryExpansion             : Maybe UnitInterval
          treasuryCut                   : Maybe UnitInterval
          coinsPerUTxOByte              : Maybe Coin
          prices                        : Maybe Prices
          minFeeRefScriptCoinsPerByte   : Maybe 
          maxRefScriptSizePerTx         : Maybe 
          maxRefScriptSizePerBlock      : Maybe 
          refScriptCostStride           : Maybe ℕ⁺
          refScriptCostMultiplier       : Maybe 
          minUTxOValue                  : Maybe Coin -- retired, keep for now
          a0                            : Maybe 
          Emax                          : Maybe Epoch
          nopt                          : Maybe 
          collateralPercentage          : Maybe 
          costmdls                      : Maybe CostModel
          drepThresholds                : Maybe DrepThresholds
          poolThresholds                : Maybe PoolThresholds
          govActionLifetime             : Maybe 
          govActionDeposit drepDeposit  : Maybe Coin
          drepActivity                  : Maybe Epoch
          ccMinSize ccMaxTermLength     : Maybe 

  paramsUpdateWellFormed : PParamsUpdate  Type
  paramsUpdateWellFormed ppu =
       just 0  fromList ( maxBlockSize  maxTxSize  maxHeaderSize  maxValSize
                          coinsPerUTxOByte  poolDeposit  collateralPercentage  ccMaxTermLength
                          govActionLifetime  govActionDeposit  drepDeposit  [] )
    where open PParamsUpdate ppu

  paramsUpdateWellFormed? : ( u : PParamsUpdate )  Dec (paramsUpdateWellFormed u)
  paramsUpdateWellFormed? u = ¿ paramsUpdateWellFormed u ¿

  modifiesNetworkGroup : PParamsUpdate  Bool
  modifiesNetworkGroup ppu = let open PParamsUpdate ppu in
    or
      ( is-just maxBlockSize
       is-just maxTxSize
       is-just maxHeaderSize
       is-just maxValSize
       is-just maxCollateralInputs
       is-just maxTxExUnits
       is-just maxBlockExUnits
       is-just pv
       [])

  modifiesEconomicGroup : PParamsUpdate  Bool
  modifiesEconomicGroup ppu = let open PParamsUpdate ppu in
    or
      ( is-just a
       is-just b
       is-just keyDeposit
       is-just poolDeposit
       is-just monetaryExpansion
       is-just treasuryCut
       is-just coinsPerUTxOByte
       is-just minFeeRefScriptCoinsPerByte
       is-just maxRefScriptSizePerTx
       is-just maxRefScriptSizePerBlock
       is-just refScriptCostStride
       is-just refScriptCostMultiplier
       is-just prices
       is-just minUTxOValue
       [])

  modifiesTechnicalGroup : PParamsUpdate  Bool
  modifiesTechnicalGroup ppu = let open PParamsUpdate ppu in
    or
      ( is-just a0
       is-just Emax
       is-just nopt
       is-just collateralPercentage
       is-just costmdls
       [])

  modifiesGovernanceGroup : PParamsUpdate  Bool
  modifiesGovernanceGroup ppu = let open PParamsUpdate ppu in
    or
      ( is-just drepThresholds
       is-just poolThresholds
       is-just govActionLifetime
       is-just govActionDeposit
       is-just drepDeposit
       is-just drepActivity
       is-just ccMinSize
       is-just ccMaxTermLength
       [])

  modifiesSecurityGroup : PParamsUpdate  Bool
  modifiesSecurityGroup ppu = let open PParamsUpdate ppu in
    or
      ( is-just maxBlockSize
       is-just maxTxSize
       is-just maxHeaderSize
       is-just maxValSize
       is-just maxBlockExUnits
       is-just b
       is-just a
       is-just coinsPerUTxOByte
       is-just govActionDeposit
       is-just minFeeRefScriptCoinsPerByte
       []
      )

  modifiedUpdateGroups : PParamsUpdate   PParamGroup
  modifiedUpdateGroups ppu =
    ( modifiesNetworkGroup    ?═⇒ NetworkGroup
     modifiesEconomicGroup   ?═⇒ EconomicGroup
     modifiesTechnicalGroup  ?═⇒ TechnicalGroup
     modifiesGovernanceGroup ?═⇒ GovernanceGroup
     modifiesSecurityGroup   ?═⇒ SecurityGroup
    )
    where
      _?═⇒_ : (PParamsUpdate  Bool)  PParamGroup   PParamGroup
      pred ?═⇒ grp = if pred ppu then  grp  else 

  _?↗_ :  {A : Type}  Maybe A  A  A
  just x ?↗ _ = x
  nothing ?↗ x = x

  ≡-update :  {A : Type} {u : Maybe A} {p : A} {x : A}  u ?↗ p  x  (u  just x  (p  x × u  nothing))
  ≡-update {u} {p} {x} = mk⇔ to from
    where
      to :  {A} {u : Maybe A} {p : A} {x : A}  u ?↗ p  x  (u  just x  (p  x × u  nothing))
      to {u = just x} refl = inj₁ refl
      to {u = nothing} refl = inj₂ (refl , refl)

      from :  {A} {u : Maybe A} {p : A} {x : A}  u  just x  (p  x × u  nothing)  u ?↗ p  x
      from (inj₁ refl) = refl
      from (inj₂ (refl , refl)) = refl

  applyPParamsUpdate : PParams  PParamsUpdate  PParams
  applyPParamsUpdate pp ppu =
    record
      { maxBlockSize                = U.maxBlockSize ?↗ P.maxBlockSize
      ; maxTxSize                   = U.maxTxSize ?↗ P.maxTxSize
      ; maxHeaderSize               = U.maxHeaderSize ?↗ P.maxHeaderSize
      ; maxValSize                  = U.maxValSize ?↗ P.maxValSize
      ; maxCollateralInputs         = U.maxCollateralInputs ?↗ P.maxCollateralInputs
      ; maxTxExUnits                = U.maxTxExUnits ?↗ P.maxTxExUnits
      ; maxBlockExUnits             = U.maxBlockExUnits ?↗ P.maxBlockExUnits
      ; pv                          = U.pv ?↗ P.pv
      ; a                           = U.a ?↗ P.a
      ; b                           = U.b ?↗ P.b
      ; keyDeposit                  = U.keyDeposit ?↗ P.keyDeposit
      ; poolDeposit                 = U.poolDeposit ?↗ P.poolDeposit
      ; monetaryExpansion           = U.monetaryExpansion ?↗ P.monetaryExpansion
      ; treasuryCut                 = U.treasuryCut ?↗ P.treasuryCut
      ; coinsPerUTxOByte            = U.coinsPerUTxOByte ?↗ P.coinsPerUTxOByte
      ; minFeeRefScriptCoinsPerByte = U.minFeeRefScriptCoinsPerByte ?↗ P.minFeeRefScriptCoinsPerByte
      ; maxRefScriptSizePerTx       = U.maxRefScriptSizePerTx ?↗ P.maxRefScriptSizePerTx
      ; maxRefScriptSizePerBlock    = U.maxRefScriptSizePerBlock ?↗ P.maxRefScriptSizePerBlock
      ; refScriptCostStride         = U.refScriptCostStride ?↗ P.refScriptCostStride
      ; refScriptCostMultiplier     = U.refScriptCostMultiplier ?↗ P.refScriptCostMultiplier
      ; prices                      = U.prices ?↗ P.prices
      ; minUTxOValue                = U.minUTxOValue ?↗ P.minUTxOValue
      ; a0                          = U.a0 ?↗ P.a0
      ; Emax                        = U.Emax ?↗ P.Emax
      ; nopt                        = U.nopt ?↗ P.nopt
      ; collateralPercentage        = U.collateralPercentage ?↗ P.collateralPercentage
      ; costmdls                    = U.costmdls ?↗ P.costmdls
      ; drepThresholds              = U.drepThresholds ?↗ P.drepThresholds
      ; poolThresholds              = U.poolThresholds ?↗ P.poolThresholds
      ; govActionLifetime           = U.govActionLifetime ?↗ P.govActionLifetime
      ; govActionDeposit            = U.govActionDeposit ?↗ P.govActionDeposit
      ; drepDeposit                 = U.drepDeposit ?↗ P.drepDeposit
      ; drepActivity                = U.drepActivity ?↗ P.drepActivity
      ; ccMinSize                   = U.ccMinSize ?↗ P.ccMinSize
      ; ccMaxTermLength             = U.ccMaxTermLength ?↗ P.ccMaxTermLength
      }
    where
      open module P = PParams pp
      open module U = PParamsUpdate ppu

  instance
    unquoteDecl DecEq-PParamsUpdate  = derive-DecEq
      ((quote PParamsUpdate , DecEq-PParamsUpdate)  [])

PParams contains parameters used in the Cardano ledger, which we group according to the general purpose that each parameter serves.

  • NetworkGroup: parameters related to the network settings;

  • EconomicGroup: parameters related to the economic aspects of the ledger;

  • TechnicalGroup: parameters related to technical settings;

  • GovernanceGroup: parameters related to governance settings;

  • SecurityGroup: parameters that can impact the security of the system.

The purpose of these groups is to determine voting thresholds for proposals aiming to change parameters. Given a proposal to change a certain set of parameters, we look at which groups those parameters fall into and from this we determine the voting threshold for that proposal. (The voting threshold calculation is described in detail in 'sec:ratification-requirements' (unresolved reference); in particular, the definition of the threshold function appears in Figure 'Functions-related-to-voting'.)

The first four groups have the property that every protocol parameter is associated to precisely one of these groups. The SecurityGroup is special: a protocol parameter may or may not be in the SecurityGroup. So, each protocol parameter belongs to at least one and at most two groups. Note that in CIP-1694 there is no SecurityGroup, but there is the concept of security-relevant protocol parameters (see ). The difference between these notions is only social, so we implement security-relevant protocol parameters as a group.

The new protocol parameters are declared in Figure 'Protocol-parameter-definitions' and denote the following concepts:

  • drepThresholds: governance thresholds for ; these are rational numbers named Pone, Ptwoa, Ptwob, Pthree, Pfour, Pfivea, Pfiveb, Pfivec, Pfived, and Psix;

  • : pool-related governance thresholds; these are rational numbers named Qone, Qtwoa, Qtwob, Qfour and Qfive;

  • ccMinSize: minimum constitutional committee size;

  • ccMaxTermLength: maximum term limit (in epochs) of constitutional committee members;

  • govActionLifetime: governance action expiration;

  • govActionDeposit: governance action deposit;

  • drepDeposit: DRep deposit amount;

  • drepActivity: DRep activity period;

  • minimumAVS: the minimum active voting threshold.

Figure 'Protocol-parameter-definitions' also defines the function paramsWellFormed which performs some sanity checks on protocol parameters. Figure 'Abstract-type-for-parameter-updates' defines types and functions to update parameters. These consist of an abstract type UpdateT and two functions applyUpdate and updateGroups. The type UpdateT is to be instantiated by a type that

  • can be used to update parameters, via the function applyUpdate

  • can be queried about what parameter groups it updates, via the function updateGroups

An element of the type UpdateT is well formed if it updates at least one group and applying the update preserves well-formedness.

instance
  pvCanFollow? :  {pv} {pv'}  Dec (pvCanFollow pv pv')
  pvCanFollow? {m , n} {pv} with pv  (m + 1 , 0) | pv  (m , n + 1)
  ... | no ¬p    | no ¬p₁   = no $ λ where canFollowMajor  ¬p  refl
                                           canFollowMinor  ¬p₁ refl
  ... | no ¬p    | yes refl = yes canFollowMinor
  ... | yes refl | no ¬p    = yes canFollowMajor
  ... | yes refl | yes p    = ⊥-elim $ m+1+n≢m m $ ×-≡,≡←≡ p .proj₁

Abstract type for parameter updates

record PParamsDiff : Type₁ where
  field

Abstract types & functions

    UpdateT : Type
    applyUpdate : PParams  UpdateT  PParams
    updateGroups : UpdateT   PParamGroup
     ppWF?  :  {u}  (∀ pp  paramsWellFormed pp  paramsWellFormed (applyUpdate pp u)) 

Well-formedness condition


  ppdWellFormed : UpdateT  Type
  ppdWellFormed u = updateGroups u  
    ×  pp  paramsWellFormed pp  paramsWellFormed (applyUpdate pp u)
record GovParams : Type₁ where
  field ppUpd : PParamsDiff
  open PParamsDiff ppUpd renaming (UpdateT to PParamsUpdate) public
  field  DecEq-UpdT  : DecEq PParamsUpdate
--         ⦃ Show-UpdT ⦄ : Show PParamsUpdate