Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
e43c87c
Move Byron proofs to its own directory
javierdiaz72 Dec 4, 2019
1fd9778
Improve the project structure
javierdiaz72 Dec 5, 2019
bf1b0bf
Introduce structure for the Shelley release
javierdiaz72 Dec 5, 2019
d480162
Introduce UTxO value preservation lemma
javierdiaz72 Dec 12, 2019
ca5491a
Introduce proof of preservation of value for the UTxO subsystem
javierdiaz72 Dec 16, 2019
9186ef1
Use facts literally instead of numbers for better readability
javierdiaz72 Dec 16, 2019
278bdac
Remove resolved comments
javierdiaz72 Dec 17, 2019
eceacb9
Use Isar syntax for inductive definitions
javierdiaz72 Dec 17, 2019
7c6715b
Introduce update transition system
javierdiaz72 Dec 18, 2019
38a3c53
Remove duplicate declaration
javierdiaz72 Dec 20, 2019
40709f8
Introduce value preservation lemma for the DELEG subsystem
javierdiaz72 Dec 20, 2019
6f79bef
Introduce value preservation lemma for the DELEGS subsystem
javierdiaz72 Dec 23, 2019
4680d30
Introduce value preservation lemma for the POOLREAP subsystem
javierdiaz72 Dec 29, 2019
a08612f
Add `Rewards` theory to `ROOT`
javierdiaz72 Dec 29, 2019
13e8588
Introduce value preservation lemma 15.9 from the spec
javierdiaz72 Jan 9, 2020
5c1a2de
Introduce value preservation lemma for UTXOW subsystem
javierdiaz72 Jan 11, 2020
e51e53d
Fix typo
javierdiaz72 Jan 14, 2020
a8026f9
Improve lemma `delegs_value_preservation`
javierdiaz72 Jan 14, 2020
ff34d5e
Introduce value preservation lemma for the LEDGER subsystem
javierdiaz72 Jan 14, 2020
2d4484e
Introduce value preservation lemma for the LEDGERS subsystem
javierdiaz72 Jan 14, 2020
a185c11
Introduce value preservation lemma for the SNAP subsystem
javierdiaz72 Jan 14, 2020
5184740
Introduce preservation lemma for the NEWPP subsystem
javierdiaz72 Jan 16, 2020
efcb774
Introduce value preservation lemma for the EPOCH subsystem
javierdiaz72 Jan 17, 2020
59d1be0
Improve the state value calculation functions
javierdiaz72 Jan 17, 2020
d3aec94
Introduce value preservation lemmas for the NEWEPOCH, RUPD, TICK, BBO…
javierdiaz72 Jan 21, 2020
283a2a3
Fix README.md
javierdiaz72 Jan 21, 2020
9f1b259
Revert to the original order of rules in EPOCH subsystem
javierdiaz72 Jan 21, 2020
e4ce9f0
Add minor improvements
javierdiaz72 Jan 22, 2020
a9c2a85
Match some minor changes in the formal spec
javierdiaz72 Jan 22, 2020
a5b5269
Overhaul proof of `dom_res_union_distr`
javierdiaz72 Jan 22, 2020
7315df9
Match some changes in the spec (issue 1169)
javierdiaz72 Jan 24, 2020
470c78e
Simplify the redundant check for NEWEPOCH
javierdiaz72 Jan 28, 2020
e82140e
Improve proof of `fmran_singleton`
javierdiaz72 Jan 28, 2020
9bb32f4
Overhaul proof of `fmdiff_partition`
javierdiaz72 Jan 28, 2020
b2c3abd
Overhaul proof of `fmdiff_fmupd`
javierdiaz72 Feb 11, 2020
74e7f42
Overhaul proof of `inter_plus_addition_in`
javierdiaz72 Feb 12, 2020
308f100
Overhaul proof of `inter_plus_addition_notin`
javierdiaz72 Feb 12, 2020
f5bb8bd
Fix bug in proof
javierdiaz72 Feb 12, 2020
8fb5ad3
Adapt formalization to match improvements in spec
javierdiaz72 Feb 13, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions Isabelle/Byron/ROOT
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
chapter LedgerFormalization

session Byron (ledgerformalization) = HOL +
description \<open>Byron Release\<close>
sessions
"HOL-Library"
theories
UTxO
document_files
"root.tex"
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@

\begin{document}

\title{Formalization of the Cardano Ledger Specification in Isabelle/HOL}
\title{Formalization of the Cardano Ledger Specification in Isabelle/HOL (Byron release)}
\author{Javier D\'iaz\\\small\texttt{javier.diaz@iohk.io}\\\small\texttt{github.com/input-output-hk/fm-ouroboros}}

\maketitle
Expand Down
4 changes: 2 additions & 2 deletions Isabelle/ROOTS
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
UTxO

Byron
Shelley
27 changes: 27 additions & 0 deletions Isabelle/Shelley/Address.thy
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
section \<open> Addresses \<close>

theory Address
imports Main
begin

text \<open> Credential \<close>

typedecl credential \<comment> \<open>NOTE: Abstract for now\<close>
axiomatization where credential_linorder: "OFCLASS(credential, linorder_class)"
instance credential :: linorder by (rule credential_linorder)

text \<open> Output address \<close>

typedecl addr \<comment> \<open>NOTE: Abstract for now\<close>

text \<open> Reward account \<close>

typedecl addr_rwd \<comment> \<open>NOTE: Abstract for now\<close>
axiomatization where addr_rwd_linorder: "OFCLASS(addr_rwd, linorder_class)"
instance addr_rwd :: linorder by (rule addr_rwd_linorder)

text \<open> Construct a reward account \<close>

consts addr_rwd :: "credential \<Rightarrow> addr_rwd" \<comment> \<open>NOTE: Abstract for now\<close>

end
27 changes: 27 additions & 0 deletions Isabelle/Shelley/Basic_Types.thy
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
section \<open> Basic Types \<close>

theory Basic_Types
imports Main
begin

text \<open> Epoch \<close>

type_synonym epoch = nat

text \<open> Unit of value \<close>

type_synonym coin = int

text \<open> Index \<close>

type_synonym ix = nat

text \<open> Absolute slot \<close>

type_synonym slot = nat

text \<open> Application versions \<close>

typedecl applications \<comment> \<open>NOTE: Abstract for now\<close>

end
262 changes: 262 additions & 0 deletions Isabelle/Shelley/Chain.thy
Original file line number Diff line number Diff line change
@@ -0,0 +1,262 @@
section \<open> Blockchain layer \<close>

theory Chain
imports Rewards
begin

subsection \<open> Verifiable Random Functions (VRF) \<close>

text \<open> Seed for pseudo-random number generator \<close>

typedecl seed

text \<open> Stake pool distribution \<close>

typedecl pool_distr \<comment> \<open>NOTE: Abstract for now\<close>

subsection \<open> Block Definitions \<close>

text \<open> Abstract Types \<close>

typedecl hash_header \<comment> \<open>hash of a block header\<close>

typedecl hash_b_body \<comment> \<open>hash of a block body\<close>

text \<open> Block Header Body \<close>

typedecl b_h_body \<comment> \<open>NOTE: Abstract for now\<close>

text \<open> Block Types \<close>

typedecl b_header \<comment> \<open>NOTE: Abstract for now\<close>

typedecl block \<comment> \<open>NOTE: Abstract for now\<close>

text \<open> Abstract Functions \<close>

consts b_header_size :: "b_header \<Rightarrow> nat" \<comment> \<open>size of a block header\<close>

consts b_body_size :: "tx list \<Rightarrow> nat" \<comment> \<open>size of a block body\<close>

text \<open> Accessor Functions \<close>

\<comment> \<open>NOTE: The following function is actually a block header body field in the spec. Abstract for now\<close>
consts bhash :: "b_h_body \<Rightarrow> hash_b_body" \<comment> \<open>block body hash\<close>

consts bheader :: "block \<Rightarrow> b_header" \<comment> \<open>NOTE: Abstract for now\<close>

consts bhbody :: "b_header \<Rightarrow> b_h_body" \<comment> \<open>NOTE: Abstract for now\<close>

consts bbody :: "block \<Rightarrow> tx list" \<comment> \<open>NOTE: Abstract for now\<close>

consts bvkcold :: "b_h_body \<Rightarrow> v_key" \<comment> \<open>NOTE: Abstract for now\<close>

consts bslot :: "b_h_body \<Rightarrow> slot" \<comment> \<open>NOTE: Abstract for now\<close>

consts h_b_bsize :: "b_h_body \<Rightarrow> nat" \<comment> \<open>NOTE: Abstract for now\<close>

consts bbodyhash :: "tx list \<Rightarrow> hash_b_body"

subsection \<open> MIR Transition \<close>

inductive mir_sts :: "epoch_state \<Rightarrow> epoch_state \<Rightarrow> bool"
(\<open>\<turnstile> _ \<rightarrow>\<^bsub>MIR\<^esub> _\<close> [0, 50])
where
mir: "
\<turnstile> (acnt, ss, (us, (ds, ps)), pp) \<rightarrow>\<^bsub>MIR\<^esub> (acnt', ss, (us, (ds', ps)), pp)"
if "(stk_creds, rewards, i\<^sub>r\<^sub>w\<^sub>d) = ds"
and "(treasury, reserves) = acnt"
and "i'\<^sub>r\<^sub>w\<^sub>d = fmdom' stk_creds \<lhd> i\<^sub>r\<^sub>w\<^sub>d"
and "tot = (\<Sum> k \<in> fmdom' i'\<^sub>r\<^sub>w\<^sub>d. i'\<^sub>r\<^sub>w\<^sub>d $$! k)"
and "update = fmap_of_list [(addr_rwd hk, val). (hk, val) \<leftarrow> sorted_list_of_fmap i'\<^sub>r\<^sub>w\<^sub>d]"
and "tot \<le> reserves"
and "acnt' = (treasury, reserves - tot)"
and "ds' = (stk_creds, rewards \<union>\<^sub>+ update, {$$})"
| mir_skip: "
\<turnstile> (acnt, ss, (us, (ds, ps)), pp) \<rightarrow>\<^bsub>MIR\<^esub> (acnt, ss, (us, (ds', ps)), pp)"
if "(stk_creds, rewards, i\<^sub>r\<^sub>w\<^sub>d) = ds"
and "(_, reserves) = acnt"
and "i'\<^sub>r\<^sub>w\<^sub>d = fmdom' stk_creds \<lhd> i\<^sub>r\<^sub>w\<^sub>d"
and "tot = (\<Sum> k \<in> fmdom' i'\<^sub>r\<^sub>w\<^sub>d. i'\<^sub>r\<^sub>w\<^sub>d $$! k)"
and "tot > reserves"
and "ds' = (stk_creds, rewards, {$$})"

subsection \<open> New Epoch Transition \<close>

text \<open> New Epoch environments \<close>

type_synonym new_epoch_env = "
slot \<times> \<comment> \<open>current slot\<close>
key_hash_g set \<comment> \<open>genesis key hashes\<close>"

text \<open> New Epoch states \<close>

type_synonym new_epoch_state = "
epoch \<times> \<comment> \<open>last epoch\<close>
blocks_made \<times> \<comment> \<open>blocks made last epoch\<close>
blocks_made \<times> \<comment> \<open>blocks made this epoch\<close>
epoch_state \<times> \<comment> \<open>epoch state\<close>
reward_update option \<times> \<comment> \<open>reward state\<close>
pool_distr \<times> \<comment> \<open>pool stake distribution\<close>
(slot, key_hash_g option) fmap \<comment> \<open>OBFT overlay schedule\<close>"

text \<open> New Epoch rules \<close>

text \<open>
NOTE:
\<^item> The general constraints in the spec are not enforced for now.
\<^item> \<open>pd'\<close> and \<open>osched'\<close> are undefined for now.
\<close>
inductive new_epoch_sts :: "new_epoch_env \<Rightarrow> new_epoch_state \<Rightarrow> epoch \<Rightarrow> new_epoch_state \<Rightarrow> bool"
(\<open>_ \<turnstile> _ \<rightarrow>\<^bsub>NEWEPOCH\<^esub>{_} _\<close> [51, 0, 51] 50)
where
new_epoch: "
\<Gamma> \<turnstile>
(e\<^sub>l, b\<^sub>p\<^sub>r\<^sub>e\<^sub>v, b\<^sub>c\<^sub>u\<^sub>r, es, ru, pd, osched) \<rightarrow>\<^bsub>NEWEPOCH\<^esub>{e} (e, b\<^sub>c\<^sub>u\<^sub>r, {$$}, es''', None, pd', osched')"
if "e = e\<^sub>l + 1"
and "ru = Some ru'"
and "(\<Delta>t, \<Delta>r, rs, \<Delta>f) = ru'"
and "\<Delta>t + \<Delta>r + (\<Sum> k \<in> fmdom' rs. rs $$! k) + \<Delta>f = 0"
and "es' = apply_r_upd ru' es"
and "\<turnstile> es' \<rightarrow>\<^bsub>MIR\<^esub> es''"
and "\<turnstile> es'' \<rightarrow>\<^bsub>EPOCH\<^esub>{e} es'''"
and "pd' = undefined"
and "osched' = undefined"
| not_new_epoch: "
\<Gamma> \<turnstile> nes \<rightarrow>\<^bsub>NEWEPOCH\<^esub>{e} nes"
if "e \<noteq> e\<^sub>l + 1"
| no_reward_update: "
\<Gamma> \<turnstile> nes \<rightarrow>\<^bsub>NEWEPOCH\<^esub>{e} nes"
if "e = e\<^sub>l + 1"
and "(_, _, _, _, ru, _, _) = nes"
and "ru = None"

subsection \<open> Reward Update Transition \<close>

text \<open> Reward Update environments \<close>

type_synonym r_upd_env = "
blocks_made \<times> \<comment> \<open>blocks made\<close>
epoch_state \<comment> \<open>epoch state\<close>"

text \<open> Reward Update rules \<close>

inductive rupd_sts :: "r_upd_env \<Rightarrow> reward_update option \<Rightarrow> slot \<Rightarrow> reward_update option \<Rightarrow> bool"
(\<open>_ \<turnstile> _ \<rightarrow>\<^bsub>RUPD\<^esub>{_} _\<close> [51, 0, 51] 50)
where
create_reward_update: "
(b, es) \<turnstile> ru \<rightarrow>\<^bsub>RUPD\<^esub>{s} ru'"
if "s > first_slot (epoch s) + start_rewards"
and "ru = None"
and "ru' = Some (create_r_upd b es)"
| reward_update_exists: "
_ \<turnstile> ru \<rightarrow>\<^bsub>RUPD\<^esub>{s} ru"
if "ru \<noteq> None"
| reward_too_early: "
_ \<turnstile> ru \<rightarrow>\<^bsub>RUPD\<^esub>{s} ru"
if "ru = None"
and "s \<le> first_slot (epoch s) + start_rewards"

subsection \<open> Chain Tick Transition \<close>

inductive tick_sts :: "key_hash_g set \<Rightarrow> new_epoch_state \<Rightarrow> slot \<Rightarrow> new_epoch_state \<Rightarrow> bool"
(\<open>_ \<turnstile> _ \<rightarrow>\<^bsub>TICK\<^esub>{_} _\<close> [51, 0, 51] 50)
where
tick: "
gkeys \<turnstile> nes \<rightarrow>\<^bsub>TICK\<^esub>{s} nes''"
if "(s, gkeys) \<turnstile> nes \<rightarrow>\<^bsub>NEWEPOCH\<^esub>{epoch s} nes'"
and "(_, b\<^sub>p\<^sub>r\<^sub>e\<^sub>v, _, es, _, _, _) = nes"
and "(e\<^sub>l', b\<^sub>p\<^sub>r\<^sub>e\<^sub>v', b\<^sub>c\<^sub>u\<^sub>r', es', ru', pd', osched') = nes'"
and "(b\<^sub>p\<^sub>r\<^sub>e\<^sub>v, es) \<turnstile> ru' \<rightarrow>\<^bsub>RUPD\<^esub>{s} ru''"
and "nes'' = (e\<^sub>l', b\<^sub>p\<^sub>r\<^sub>e\<^sub>v', b\<^sub>c\<^sub>u\<^sub>r', es', ru'', pd', osched')"

subsection \<open> Block Body Transition \<close>

text \<open> BBody environments \<close>

type_synonym b_body_env = "
slot set \<times> \<comment> \<open>overlay slots\<close>
p_params \<times> \<comment> \<open>protocol parameters\<close>
coin \<comment> \<open>total reserves\<close>"

text \<open> BBody states \<close>

type_synonym b_body_state = "
l_state \<times> \<comment> \<open>ledger state\<close>
blocks_made \<comment> \<open>blocks made\<close>"

text \<open> BBody helper function \<close>

fun incr_blocks :: "bool \<Rightarrow> key_hash \<Rightarrow> blocks_made \<Rightarrow> blocks_made" where
"incr_blocks is_overlay hk b = undefined" \<comment> \<open>NOTE: Undefined for now\<close>

text \<open> BBody rules \<close>

inductive bbody_sts :: "b_body_env \<Rightarrow> b_body_state \<Rightarrow> block \<Rightarrow> b_body_state \<Rightarrow> bool"
(\<open>_ \<turnstile> _ \<rightarrow>\<^bsub>BBODY\<^esub>{_} _\<close> [51, 0, 51] 50)
where
block_body: "
(oslots, pp, reserves) \<turnstile>
(ls, b) \<rightarrow>\<^bsub>BBODY\<^esub>{block} (ls', incr_blocks (bslot bhb \<in> oslots) hk b)"
if "txs = bbody block"
and "bhb = bhbody (bheader block)"
and "hk = hash_key (bvkcold bhb)"
and "b_body_size txs = h_b_bsize bhb"
and "bbodyhash txs = bhash bhb"
and "(bslot bhb, pp, reserves) \<turnstile> ls \<rightarrow>\<^bsub>LEDGERS\<^esub>{txs} ls'"

subsection \<open> Chain Transition \<close>

text \<open> Chain states \<close>

type_synonym chain_state = "
new_epoch_state \<times> \<comment> \<open>epoch specific state\<close>
(key_hash, nat) fmap \<times> \<comment> \<open>operational certificate issue numbers\<close>
seed \<times> \<comment> \<open>epoch nonce\<close>
seed \<times> \<comment> \<open>evolving nonce\<close>
seed \<times> \<comment> \<open>candidate nonce\<close>
seed \<times> \<comment> \<open>seed generated from hash of previous epoch\<close>
hash_header \<times> \<comment> \<open>latest header hash\<close>
slot \<comment> \<open>last slot\<close>"

text \<open> Chain Transition Helper Functions \<close>

fun get_g_keys :: "new_epoch_state \<Rightarrow> key_hash_g set" where
"get_g_keys nes = undefined" \<comment> \<open>NOTE: Undefined for now\<close>

fun update_nes :: "new_epoch_state \<Rightarrow> blocks_made \<Rightarrow> l_state \<Rightarrow> new_epoch_state" where
"update_nes (e\<^sub>l, b\<^sub>p\<^sub>r\<^sub>e\<^sub>v, _, (acnt, ss, _, pp), ru, pd, osched) b\<^sub>c\<^sub>u\<^sub>r ls =
(e\<^sub>l, b\<^sub>p\<^sub>r\<^sub>e\<^sub>v, b\<^sub>c\<^sub>u\<^sub>r, (acnt, ss, ls, pp), ru, pd, osched)"

text \<open> Chain Rules \<close>

text \<open>
NOTE:
\<^item> The \<open>PRTCL\<close> rule is not included for now.
\<close>
inductive chain_sts :: "slot \<Rightarrow> chain_state \<Rightarrow> block \<Rightarrow> chain_state \<Rightarrow> bool"
(\<open>_ \<turnstile> _ \<rightarrow>\<^bsub>CHAIN\<^esub>{_} _\<close> [51, 0, 51] 50)
where
chain: "
s\<^sub>n\<^sub>o\<^sub>w \<turnstile> (nes, cs, \<eta>\<^sub>0, \<eta>\<^sub>v, \<eta>\<^sub>c, \<eta>\<^sub>h, h, s\<^sub>l) \<rightarrow>\<^bsub>CHAIN\<^esub>{block} (nes'', cs', \<eta>'\<^sub>0, \<eta>'\<^sub>v, \<eta>'\<^sub>c, \<eta>'\<^sub>h, h', s'\<^sub>l)"
if "bh = bheader block"
and "bhb = bhbody bh"
and "gkeys = get_g_keys nes"
and "s = bslot bhb"
and "(_, _, _, (_, _, _, pp), _, _, _) = nes"
and "b_header_size bh \<le> max_header_size pp"
and "h_b_bsize bhb \<le> max_block_size pp"
and "gkeys \<turnstile> nes \<rightarrow>\<^bsub>TICK\<^esub>{s} nes'"
and "(_, _, b\<^sub>c\<^sub>u\<^sub>r, es, _, _, osched) = nes'"
and "(acnt, _, ls, pp') = es"
and "(_, reserves) = acnt"
and "(fmdom' osched, pp', reserves) \<turnstile> (ls, b\<^sub>c\<^sub>u\<^sub>r) \<rightarrow>\<^bsub>BBODY\<^esub>{block} (ls', b'\<^sub>c\<^sub>u\<^sub>r)"
and "nes'' = update_nes nes' b'\<^sub>c\<^sub>u\<^sub>r ls'"
and "cs' = undefined"
and "\<eta>'\<^sub>0 = undefined"
and "\<eta>'\<^sub>v = undefined"
and "\<eta>'\<^sub>c = undefined"
and "\<eta>'\<^sub>h = undefined"
and "h' = undefined"
and "s'\<^sub>l = undefined"
end
23 changes: 23 additions & 0 deletions Isabelle/Shelley/Cryptography.thy
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
section \<open> Cryptographic Primitives \<close>

theory Cryptography
imports Main
begin

text \<open> Public verifying key \<close>

typedecl v_key

text \<open> Hash of a key \<close>

typedecl key_hash

text \<open> Genesis key hash \<close>

typedecl key_hash_g

text \<open> hashKey function \<close>

consts hash_key :: "v_key \<Rightarrow> key_hash"

end
Loading