Protocol Parameters
This section defines the adjustable protocol parameters of the Cardano ledger.
{-# OPTIONS --safe #-}
open import Ledger.Prelude
open import Ledger.Core.Specification.Crypto using ( CryptoStructure )
open import Ledger.Core.Specification.Epoch using ( EpochStructure )
open import Ledger.Core.Specification.ProtocolVersion
open import Ledger.Dijkstra.Specification.Script.Base
module Ledger.Dijkstra.Specification.PParams
( cs : CryptoStructure )
( es : EpochStructure ) ( open EpochStructure es )
( Network : Type ) ( DecEq-Network : DecEq Network )
( ss : ScriptStructure cs es Network DecEq-Network ) ( open ScriptStructure ss )
where
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.Core.Specification.Crypto
open import Ledger.Core.Specification.Epoch
open import Ledger.Prelude.Numeric using ( UnitInterval ; ℕ⁺ )
private variable
m n : ℕ
Protocol Parameter Definitions
record Acnt : Type where
constructor ⟦_,_⟧ᵃ
field
treasury reserves : Coin
record HasAccount { a } ( A : Type a ) : Type a where
field AccountOf : A → Acnt
open HasAccount ⦃...⦄ public
instance
HasTreasury-Acnt : HasTreasury Acnt
HasTreasury-Acnt . TreasuryOf = Acnt.treasury
HasReserves-Acnt : HasReserves Acnt
HasReserves-Acnt . ReservesOf = Acnt.reserves
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 Declarations
record PParams : Type where
field
maxBlockSize : ℕ
maxTxSize : ℕ
maxHeaderSize : ℕ
maxTxExUnits : ExUnits
maxBlockExUnits : ExUnits
maxValSize : ℕ
maxCollateralInputs : ℕ
pv : ProtVer
leiosHeaderPeriod : Milliseconds
leiosVotingPeriod : Milliseconds
leiosDiffusionPeriod : Milliseconds
leiosMaxEBSize : ℕ
leiosMaxEBTxsSize : ℕ
leiosCommitteeSize : ℕ
leiosQuorumStakeThreshold : UnitInterval
leiosMaxEBExUnits : ExUnits
leiosMaxRefScriptSizePerEB : ℕ
a : ℕ
b : ℕ
keyDeposit : Coin
poolDeposit : Coin
minPoolCost : Coin
monetaryExpansion : UnitInterval
treasuryCut : UnitInterval
coinsPerUTxOByte : Coin
prices : Prices
minFeeRefScriptCoinsPerByte : ℚ
maxRefScriptSizePerTx : ℕ
maxRefScriptSizePerBlock : ℕ
refScriptCostStride : ℕ⁺
refScriptCostMultiplier : ℚ
minUTxOValue : Coin
Emax : Epoch
nopt : ℕ
a0 : ℚ
collateralPercentage : ℕ
costmdlsAssoc : LanguageCostModels
poolThresholds : PoolThresholds
drepThresholds : DrepThresholds
ccMinSize : ℕ
ccMaxTermLength : ℕ
govActionLifetime : ℕ
govActionDeposit : Coin
drepDeposit : Coin
drepActivity : Epoch
costmdls : Language ⇀ CostModel
costmdls = fromListᵐ ( languageCostModels costmdlsAssoc )
Leios parameters
Leios adds the endorser block (EB), an ordered list of transaction references
that a block producer announces alongside its ranking block; a committee of
stake pools votes on the EB, and a certificate carried by the following ranking
block brings the referenced transactions into the ledger. Three of the nine
parameters measure a Leios round in wall-clock time (header diffusion, voting,
and the additional diffusion that follows voting), four bound an EB (its
reference list, the transactions listed, their script execution, and their
reference scripts), leiosCommitteeSize (N_c) is the number of
committee seats — the committee being the N_c pools with the most active
stake — leiosQuorumStakeThreshold (τ) is the fraction of
the total active stake a certificate's signers must carry. The voting key age
bound is not a parameter: it is derived from the KES setup
(maxKeyAgeEpochs in the Epoch module). The
ranking block keeps its existing bound maxBlockSize, so Leios
adds no field for it. Zero-valued Leios parameters are meaningful: they are the protocol's
disabled state during rollout.
Security group
maxBlockSize maxTxSize
maxHeaderSize maxValSize
maxBlockExUnits a b
minFeeRefScriptCoinsPerByte coinsPerUTxOByte
govActionDeposit
leiosHeaderPeriod leiosVotingPeriod
leiosDiffusionPeriod leiosMaxEBSize
leiosMaxEBTxsSize leiosCommitteeSize
leiosQuorumStakeThreshold leiosMaxEBExUnits
leiosMaxRefScriptSizePerEB
The Leios parameters are deliberately absent from
positivePParams: zero values are the protocol's disabled
state, and governance must be able to reach it. CIP-164's quorum constraint
τ < σ(N_c) relates the threshold to the stake coverage of the selected
committee, a property of the stake distribution rather than of the parameters,
so it cannot be imposed here.
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
record HasPParams { a } ( A : Type a ) : Type a where
field PParamsOf : A → PParams
open HasPParams ⦃...⦄ public
record HasCCMaxTermLength { a } ( A : Type a ) : Type a where
field CCMaxTermLengthOf : A → ℕ
open HasCCMaxTermLength ⦃...⦄ public
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
leiosHeaderPeriod : Maybe Milliseconds
leiosVotingPeriod : Maybe Milliseconds
leiosDiffusionPeriod : Maybe Milliseconds
leiosMaxEBSize : Maybe ℕ
leiosMaxEBTxsSize : Maybe ℕ
leiosCommitteeSize : Maybe ℕ
leiosQuorumStakeThreshold : Maybe UnitInterval
leiosMaxEBExUnits : Maybe ExUnits
leiosMaxRefScriptSizePerEB : Maybe ℕ
a b : Maybe ℕ
keyDeposit : Maybe Coin
poolDeposit : Maybe Coin
minPoolCost : 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
a0 : Maybe ℚ
Emax : Maybe Epoch
nopt : Maybe ℕ
collateralPercentage : Maybe ℕ
costmdls : Maybe LanguageCostModels
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
∷ is-just leiosHeaderPeriod
∷ is-just leiosVotingPeriod
∷ is-just leiosDiffusionPeriod
∷ is-just leiosMaxEBSize
∷ is-just leiosMaxEBTxsSize
∷ is-just leiosCommitteeSize
∷ is-just leiosQuorumStakeThreshold
∷ is-just leiosMaxEBExUnits
∷ is-just leiosMaxRefScriptSizePerEB
∷ [] )
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 minPoolCost
∷ 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
∷ is-just leiosHeaderPeriod
∷ is-just leiosVotingPeriod
∷ is-just leiosDiffusionPeriod
∷ is-just leiosMaxEBSize
∷ is-just leiosMaxEBTxsSize
∷ is-just leiosCommitteeSize
∷ is-just leiosQuorumStakeThreshold
∷ is-just leiosMaxEBExUnits
∷ is-just leiosMaxRefScriptSizePerEB
∷ []
)
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
_∪ˡᶜᵐ_ : LanguageCostModels → LanguageCostModels → LanguageCostModels
l ∪ˡᶜᵐ l' = mkLanguageCostModels ( setToList ( fromListᵐ ( languageCostModels l ++ languageCostModels l' ) ˢ ))
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
; leiosHeaderPeriod = U.leiosHeaderPeriod ?↗ P.leiosHeaderPeriod
; leiosVotingPeriod = U.leiosVotingPeriod ?↗ P.leiosVotingPeriod
; leiosDiffusionPeriod = U.leiosDiffusionPeriod ?↗ P.leiosDiffusionPeriod
; leiosMaxEBSize = U.leiosMaxEBSize ?↗ P.leiosMaxEBSize
; leiosMaxEBTxsSize = U.leiosMaxEBTxsSize ?↗ P.leiosMaxEBTxsSize
; leiosCommitteeSize = U.leiosCommitteeSize ?↗ P.leiosCommitteeSize
; leiosQuorumStakeThreshold = U.leiosQuorumStakeThreshold ?↗ P.leiosQuorumStakeThreshold
; leiosMaxEBExUnits = U.leiosMaxEBExUnits ?↗ P.leiosMaxEBExUnits
; leiosMaxRefScriptSizePerEB = U.leiosMaxRefScriptSizePerEB ?↗ P.leiosMaxRefScriptSizePerEB
; a = U.a ?↗ P.a
; b = U.b ?↗ P.b
; keyDeposit = U.keyDeposit ?↗ P.keyDeposit
; poolDeposit = U.poolDeposit ?↗ P.poolDeposit
; minPoolCost = U.minPoolCost ?↗ P.minPoolCost
; 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
; costmdlsAssoc = if U.costmdls then (λ { cm } → cm ∪ˡᶜᵐ P.costmdlsAssoc )
else P.costmdlsAssoc
; 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 ) ∷ [] )
Abstract Type for Parameter Updates
record PParamsDiff : Type₁ where
field
UpdateT : Type
applyUpdate : PParams → UpdateT → PParams
updateGroups : UpdateT → ℙ PParamGroup
⦃ ppWF? ⦄ : ∀ { u } → (∀ pp → paramsWellFormed pp → paramsWellFormed ( applyUpdate pp u )) ⁇
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
References
[CKB+23] Jared Corduan
and Andre Knispel and Matthias Benkort and Kevin Hammond and Charles
Hoskinson and Samuel Leathers. A First Step Towards On-Chain
Decentralized Governance . 2023.