Skip to content

Ledger

This module defines the ledger transition system where valid transactions transform the ledger state.

{-# OPTIONS --safe #-}

import Data.List as L

open import Ledger.Prelude
open import Ledger.Conway.Specification.Abstract
open import Ledger.Conway.Specification.Transaction using (TransactionStructure)

module Ledger.Conway.Specification.Ledger
  (txs : _) (open TransactionStructure txs)
  (abs : AbstractFunctions txs) (open AbstractFunctions abs)
  where

open import Ledger.Conway.Specification.Enact govStructure
open import Ledger.Conway.Specification.Gov govStructure
open import Ledger.Conway.Specification.Utxo txs abs
open import Ledger.Conway.Specification.Utxow txs abs
open import Ledger.Conway.Specification.Certs govStructure

open Tx
open GState
open GovActionState
open EnactState using (cc)

LEDGER Transition System Types

record LEnv : Type where
  field
    slot        : Slot
    ppolicy     : Maybe ScriptHash
    pparams     : PParams
    enactState  : EnactState
    treasury    : Treasury
instance
  HasPParams-LEnv : HasPParams LEnv
  HasPParams-LEnv .PParamsOf = LEnv.pparams
record LState : Type where
  constructor ⟦_,_,_⟧ˡ
  field
    utxoSt     : UTxOState
    govSt      : GovState
    certState  : CertState
record HasLState {a} (A : Type a) : Type a where
  field LStateOf : A → LState
open HasLState ⦃...⦄ public

instance
  HasUTxOState-LState : HasUTxOState LState
  HasUTxOState-LState .UTxOStateOf = LState.utxoSt

  HasUTxO-LState : HasUTxO LState
  HasUTxO-LState .UTxOOf = UTxOOf ∘ UTxOStateOf

  HasGovState-LState : HasGovState LState
  HasGovState-LState .GovStateOf = LState.govSt

  HasCertState-LState : HasCertState LState
  HasCertState-LState .CertStateOf = LState.certState

  HasDeposits-LState : HasDeposits LState
  HasDeposits-LState .DepositsOf = DepositsOf ∘ UTxOStateOf

  HasPools-LState : HasPools LState
  HasPools-LState .PoolsOf = PoolsOf ∘ CertStateOf

  HasGState-LState : HasGState LState
  HasGState-LState .GStateOf = GStateOf ∘ CertStateOf

  HasDState-LState : HasDState LState
  HasDState-LState .DStateOf = DStateOf ∘ CertStateOf

  HasPState-LState : HasPState LState
  HasPState-LState .PStateOf = PStateOf ∘ CertStateOf

  HasVoteDelegs-LState : HasVoteDelegs LState
  HasVoteDelegs-LState .VoteDelegsOf = VoteDelegsOf ∘ DStateOf ∘ CertStateOf

  HasDonations-LState : HasDonations LState
  HasDonations-LState .DonationsOf = DonationsOf ∘ UTxOStateOf

  HasFees-LState : HasFees LState
  HasFees-LState .FeesOf = FeesOf ∘ UTxOStateOf

  HasCCHotKeys-LState : HasCCHotKeys LState
  HasCCHotKeys-LState .CCHotKeysOf = CCHotKeysOf ∘ GStateOf

  HasDReps-LState : HasDReps LState
  HasDReps-LState .DRepsOf = DRepsOf ∘ CertStateOf

open CertState
open DState
open GovVotes

instance
  unquoteDecl HasCast-LEnv HasCast-LState = derive-HasCast
    ((quote LEnv , HasCast-LEnv) ∷ (quote LState , HasCast-LState) ∷ [])

Helper Functions

txgov : TxBody → List (GovVote ⊎ GovProposal)
txgov txb = map inj₂ txGovProposals ++ map inj₁ txGovVotes
  where open TxBody txb

rmOrphanDRepVotes : CertState → GovState → GovState
rmOrphanDRepVotes cs govSt = L.map (map₂ go) govSt
  where
   ifDRepRegistered : Credential → Type
   ifDRepRegistered c = c ∈ dom (DRepsOf cs)

   go : GovActionState → GovActionState
   go gas = record gas { votes = record (gas .votes) { gvDRep = filterKeys ifDRepRegistered (gas .votes .gvDRep) } }

allColdCreds : GovState → EnactState → ℙ Credential
allColdCreds govSt es =
  ccCreds (es .cc) ∪ concatMapˢ (λ (_ , st) → proposedCC (GovActionOf st)) (fromList govSt)

LEDGER Transition System

private variable
  Γ                     : LEnv
  s s' s''              : LState
  utxoSt utxoSt'        : UTxOState
  govSt govSt'          : GovState
  certState certState'  : CertState
  tx                    : Tx
  slot                  : Slot
  ppolicy               : Maybe ScriptHash
  pp                    : PParams
  enactState            : EnactState
  treasury              : Treasury
data _⊢_⇀⦇_,LEDGER⦈_ : LEnv → LState → Tx → LState → Type where
  LEDGER-V :
    let  txb = tx .body
         open TxBody txb
    in
      ∙ isValid tx ≡ true
      ∙ $\begin{pmatrix} \,\href{Ledger.Conway.Specification.Ledger.html#4149}{\htmlId{4546}{\htmlClass{Generalizable}{\text{slot}}}}\, \\ \,\href{Ledger.Conway.Specification.Ledger.html#4223}{\htmlId{4553}{\htmlClass{Generalizable}{\text{pp}}}}\, \\ \,\href{Ledger.Conway.Specification.Ledger.html#4294}{\htmlId{4558}{\htmlClass{Generalizable}{\text{treasury}}}}\, \end{pmatrix}$  ⊢ utxoSt ⇀⦇ tx ,UTXOW⦈ utxoSt'
      ∙ $\begin{pmatrix} \,\href{Ledger.Core.Specification.Epoch.html#954}{\htmlId{4611}{\htmlClass{Function}{\text{epoch}}}}\, \,\href{Ledger.Conway.Specification.Ledger.html#4149}{\htmlId{4617}{\htmlClass{Generalizable}{\text{slot}}}}\, \\ \,\href{Ledger.Conway.Specification.Ledger.html#4223}{\htmlId{4624}{\htmlClass{Generalizable}{\text{pp}}}}\, \\ \,\href{Ledger.Conway.Specification.Transaction.html#5247}{\htmlId{4629}{\htmlClass{Function}{\text{txGovVotes}}}}\, \\ \,\href{Ledger.Conway.Specification.Transaction.html#5072}{\htmlId{4642}{\htmlClass{Function}{\text{txWithdrawals}}}}\, \\ \,\href{Ledger.Conway.Specification.Ledger.html#3680}{\htmlId{4658}{\htmlClass{Function}{\text{allColdCreds}}}}\, \,\href{Ledger.Conway.Specification.Ledger.html#4049}{\htmlId{4671}{\htmlClass{Generalizable}{\text{govSt}}}}\, \,\href{Ledger.Conway.Specification.Ledger.html#4257}{\htmlId{4677}{\htmlClass{Generalizable}{\text{enactState}}}}\, \end{pmatrix}$ ⊢ certState ⇀⦇ txCerts ,CERTS⦈ certState'
      ∙ $\begin{pmatrix} \,\href{Ledger.Conway.Specification.Transaction.html#4964}{\htmlId{4742}{\htmlClass{Function}{\text{txId}}}}\, \\ \,\href{Ledger.Core.Specification.Epoch.html#954}{\htmlId{4749}{\htmlClass{Function}{\text{epoch}}}}\, \,\href{Ledger.Conway.Specification.Ledger.html#4149}{\htmlId{4755}{\htmlClass{Generalizable}{\text{slot}}}}\, \\ \,\href{Ledger.Conway.Specification.Ledger.html#4223}{\htmlId{4762}{\htmlClass{Generalizable}{\text{pp}}}}\, \\ \,\href{Ledger.Conway.Specification.Ledger.html#4180}{\htmlId{4767}{\htmlClass{Generalizable}{\text{ppolicy}}}}\, \\ \,\href{Ledger.Conway.Specification.Ledger.html#4257}{\htmlId{4777}{\htmlClass{Generalizable}{\text{enactState}}}}\, \\ \,\href{Ledger.Conway.Specification.Ledger.html#4094}{\htmlId{4790}{\htmlClass{Generalizable}{\text{certState'}}}}\, \\ \,\href{Class.IsSet.html#916}{\htmlId{4803}{\htmlClass{Function}{\text{dom}}}}\, \,\htmlId{4807}{\htmlClass{Symbol}{\text{(}}}\,\,\href{Ledger.Conway.Specification.Certs.html#2034}{\htmlId{4808}{\htmlClass{Field}{\text{RewardsOf}}}}\, \,\href{Ledger.Conway.Specification.Ledger.html#4084}{\htmlId{4818}{\htmlClass{Generalizable}{\text{certState}}}}\,\,\htmlId{4827}{\htmlClass{Symbol}{\text{)}}}\, \end{pmatrix}$ ⊢ rmOrphanDRepVotes certState' govSt ⇀⦇ txgov txb ,GOVS⦈ govSt'
      ────────────────────────────────
      $\begin{pmatrix} \,\href{Ledger.Conway.Specification.Ledger.html#4149}{\htmlId{4942}{\htmlClass{Generalizable}{\text{slot}}}}\, \\ \,\href{Ledger.Conway.Specification.Ledger.html#4180}{\htmlId{4949}{\htmlClass{Generalizable}{\text{ppolicy}}}}\, \\ \,\href{Ledger.Conway.Specification.Ledger.html#4223}{\htmlId{4959}{\htmlClass{Generalizable}{\text{pp}}}}\, \\ \,\href{Ledger.Conway.Specification.Ledger.html#4257}{\htmlId{4964}{\htmlClass{Generalizable}{\text{enactState}}}}\, \\ \,\href{Ledger.Conway.Specification.Ledger.html#4294}{\htmlId{4977}{\htmlClass{Generalizable}{\text{treasury}}}}\, \end{pmatrix}$ ⊢ $\begin{pmatrix} \,\href{Ledger.Conway.Specification.Ledger.html#4013}{\htmlId{4992}{\htmlClass{Generalizable}{\text{utxoSt}}}}\, \\ \,\href{Ledger.Conway.Specification.Ledger.html#4049}{\htmlId{5001}{\htmlClass{Generalizable}{\text{govSt}}}}\, \\ \,\href{Ledger.Conway.Specification.Ledger.html#4084}{\htmlId{5009}{\htmlClass{Generalizable}{\text{certState}}}}\, \end{pmatrix}$ ⇀⦇ tx ,LEDGER⦈ $\begin{pmatrix} \,\href{Ledger.Conway.Specification.Ledger.html#4020}{\htmlId{5038}{\htmlClass{Generalizable}{\text{utxoSt'}}}}\, \\ \,\href{Ledger.Conway.Specification.Ledger.html#4055}{\htmlId{5048}{\htmlClass{Generalizable}{\text{govSt'}}}}\, \\ \,\href{Ledger.Conway.Specification.Ledger.html#4094}{\htmlId{5057}{\htmlClass{Generalizable}{\text{certState'}}}}\, \end{pmatrix}$

  LEDGER-I :
      ∙ isValid tx ≡ false
      ∙ $\begin{pmatrix} \,\href{Ledger.Conway.Specification.Ledger.html#4149}{\htmlId{5121}{\htmlClass{Generalizable}{\text{slot}}}}\, \\ \,\href{Ledger.Conway.Specification.Ledger.html#4223}{\htmlId{5128}{\htmlClass{Generalizable}{\text{pp}}}}\, \\ \,\href{Ledger.Conway.Specification.Ledger.html#4294}{\htmlId{5133}{\htmlClass{Generalizable}{\text{treasury}}}}\, \end{pmatrix}$ ⊢ utxoSt ⇀⦇ tx ,UTXOW⦈ utxoSt'
      ────────────────────────────────
      $\begin{pmatrix} \,\href{Ledger.Conway.Specification.Ledger.html#4149}{\htmlId{5222}{\htmlClass{Generalizable}{\text{slot}}}}\, \\ \,\href{Ledger.Conway.Specification.Ledger.html#4180}{\htmlId{5229}{\htmlClass{Generalizable}{\text{ppolicy}}}}\, \\ \,\href{Ledger.Conway.Specification.Ledger.html#4223}{\htmlId{5239}{\htmlClass{Generalizable}{\text{pp}}}}\, \\ \,\href{Ledger.Conway.Specification.Ledger.html#4257}{\htmlId{5244}{\htmlClass{Generalizable}{\text{enactState}}}}\, \\ \,\href{Ledger.Conway.Specification.Ledger.html#4294}{\htmlId{5257}{\htmlClass{Generalizable}{\text{treasury}}}}\, \end{pmatrix}$ ⊢ $\begin{pmatrix} \,\href{Ledger.Conway.Specification.Ledger.html#4013}{\htmlId{5272}{\htmlClass{Generalizable}{\text{utxoSt}}}}\, \\ \,\href{Ledger.Conway.Specification.Ledger.html#4049}{\htmlId{5281}{\htmlClass{Generalizable}{\text{govSt}}}}\, \\ \,\href{Ledger.Conway.Specification.Ledger.html#4084}{\htmlId{5289}{\htmlClass{Generalizable}{\text{certState}}}}\, \end{pmatrix}$ ⇀⦇ tx ,LEDGER⦈ $\begin{pmatrix} \,\href{Ledger.Conway.Specification.Ledger.html#4020}{\htmlId{5318}{\htmlClass{Generalizable}{\text{utxoSt'}}}}\, \\ \,\href{Ledger.Conway.Specification.Ledger.html#4049}{\htmlId{5328}{\htmlClass{Generalizable}{\text{govSt}}}}\, \\ \,\href{Ledger.Conway.Specification.Ledger.html#4084}{\htmlId{5336}{\htmlClass{Generalizable}{\text{certState}}}}\, \end{pmatrix}$

The rule LEDGER invokes the GOVS rule to process governance action proposals and votes.

Note

The governance state used as input to GOVS is filtered to remove votes from DReps that are no longer registered (see function rmOrphanDRepVotes).

This mechanism serves to prevent attacks where malicious adversaries could submit transactions that

  1. register a fraudulent DRep,
  2. cast numerous votes utilizing that DRep,
  3. deregisters the DRep thereby recovering the deposit.
pattern LEDGER-V⋯ w x y z = LEDGER-V (w , x , y , z)
pattern LEDGER-I⋯ y z     = LEDGER-I (y , z)

LEDGERS Transition System

_⊢_⇀⦇_,LEDGERS⦈_ : LEnv → LState → List Tx → LState → Type
_⊢_⇀⦇_,LEDGERS⦈_ = ReflexiveTransitiveClosure {sts = _⊢_⇀⦇_,LEDGER⦈_}