{-# OPTIONS --safe #-}

open import Ledger.Conway.Abstract
open import Ledger.Conway.Transaction

module Ledger.Conway.Properties
  (txs : _) (open TransactionStructure txs)
  (abs : AbstractFunctions txs) (open AbstractFunctions abs)
  where
open import Ledger.Conway.Certs govStructure
open import Ledger.Conway.Chain txs abs
open import Ledger.Conway.Enact govStructure
open import Ledger.Conway.Epoch txs abs
open import Ledger.Conway.Ledger txs abs
open import Ledger.Prelude
isCredDeposit : DepositPurpose  Type
isCredDeposit (CredentialDeposit x) = 
isCredDeposit _ = 

instance
  isCredDeposit? : isCredDeposit ⁇¹
  isCredDeposit? {CredentialDeposit x} =  (yes tt)
  isCredDeposit? {PoolDeposit x} =  (no λ ())
  isCredDeposit? {DRepDeposit x} =  (no λ ())
  isCredDeposit? {GovActionDeposit x} =  (no λ ())

isGADeposit : DepositPurpose  Type
isGADeposit (GovActionDeposit x) = 
isGADeposit _ = 

instance
  isGADeposit? : isGADeposit ⁇¹
  isGADeposit? {CredentialDeposit x} =  (no λ ())
  isGADeposit? {PoolDeposit x} =  (no λ ())
  isGADeposit? {DRepDeposit x} =  (no λ ())
  isGADeposit? {GovActionDeposit x} =  (yes tt)

activeDReps : Epoch  NewEpochState   Credential
activeDReps currentEpoch s = dom (filterᵐ  (_ , e)  currentEpoch  e) (DRepsOf s))

instance
  _ : IsSet Block Tx
  _ = record { toSet = fromList  Block.ts }

  _ : IsSet TxBody GovProposal
  _ = record { toSet = fromList  TxBody.txprop }

validBlockIn : ChainState  Block  Type
validBlockIn s b = ∃[ s' ] _  s ⇀⦇ b ,CHAIN⦈ s'

validBlock : Block  Type
validBlock b = ∃[ s ] validBlockIn s b

-- Transaction validity is complicated. In the truest sense, a
-- transaction is valid if it is part of a valid block,
-- i.e. `validTxIn₁`. However, a transaction can also be seen as valid
-- if it could be applied at a certain slot (with no knowledge of an
-- actual block). This is closer to how the mempool sees transaction
-- validity and is expressed by `validTxIn₂`.

-- Note that these two are not equivalent and in fact there is no
-- implication between the two in either direction. `2 => 1` would
-- require one to come up with a block, which we can't, but `1 => 2`
-- is also not true, since the transaction might depend on a previous
-- transaction in the same block. Maybe this means that `validTxIn₂`
-- should be changed so that it allows for applying a list of
-- transactions before the final transaction? However, the downside
-- then becomes that the transaction isn't applied to the given state
-- but to some intermediate one. Maybe we'll gain some insight on this
-- matter once we have proven more theorems.

validTxIn₁ : ChainState  Tx  Type
validTxIn₁ s tx = ∃[ b ] tx  b × validBlockIn s b

module _ (s : ChainState) (slot : Slot) where

  open ChainState s; open NewEpochState newEpochState
  open EpochState epochState; open EnactState es

  private
    ledgerEnv =  slot , constitution .proj₁ .proj₂ , pparams .proj₁ , es , Acnt.treasury acnt 

  validTxIn₂ : Tx  Type
  validTxIn₂ tx = ∃[ ls' ] ledgerEnv  ls ⇀⦇ tx ,LEDGER⦈ ls'

validTx₁ : Tx  Type
validTx₁ tx = ∃[ s ] validTxIn₁ s tx