Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Preserved EVM state relation #10

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
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
59 changes: 59 additions & 0 deletions Clear/EVMState.lean
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import Mathlib.Data.Fin.Basic
import Clear.Ast
import Clear.Instr
import Clear.UInt256
import Clear.Wheels

open Clear Instr UInt256

Expand Down Expand Up @@ -163,6 +164,59 @@ instance : Inhabited EVMState :=

abbrev EVM := EVMState

def preserved : EVMState → EVMState → Prop :=
(Eq on EVMState.account_map) ∩
(Eq on EVMState.hash_collision) ∩
(Eq on EVMState.execution_env) ∩
(Eq on EVMState.keccak_map)

lemma preserved_def {e₀ e₁ : EVM} : preserved e₀ e₁ =
(e₀.account_map = e₁.account_map ∧
e₀.hash_collision = e₁.hash_collision ∧
e₀.execution_env = e₁.execution_env ∧
e₀.keccak_map = e₁.keccak_map) := by
unfold preserved
dsimp [(· ∩ ·)]
simp [Function.onFun, and_assoc]

def preserves_account_map {evm evm' : EVMState} (h : preserved evm evm') :
evm.account_map = evm'.account_map := h.1.1.1

def preserves_collision {evm evm' : EVMState} (h : preserved evm evm') :
evm.hash_collision = evm'.hash_collision := h.1.1.2

def preserves_execution_env {evm evm' : EVMState} (h : preserved evm evm') :
evm.execution_env = evm'.execution_env := h.1.2

def preserves_keccak_map {evm evm' : EVMState} (h : preserved evm evm') :
evm.keccak_map = evm'.keccak_map := h.2

@[simp]
lemma preserved_rfl {e : EVM} : preserved e e := by
rw [preserved_def]
simp

lemma preserved_symm {e₀ e₁ : EVM} : preserved e₀ e₁ = preserved e₁ e₀ := by
rw [preserved_def, preserved_def]
ext
apply Iff.intro <;> {
intro ⟨acc, col, env, kec⟩
symm at acc col env kec
exact ⟨acc, col, env, kec⟩
}

@[simp]
lemma preserved_trans {e₀ e₁ e₂ : EVM} :
preserved e₀ e₁ → preserved e₁ e₂ → preserved e₀ e₂ := by
rw (config := {occs := .pos [3]}) [preserved_def]
intro h₀ h₁
have acc := Eq.trans (preserves_account_map h₀) (preserves_account_map h₁)
have col := Eq.trans (preserves_collision h₀) (preserves_collision h₁)
have env := Eq.trans (preserves_execution_env h₀) (preserves_execution_env h₁)
have kec := Eq.trans (preserves_keccak_map h₀) (preserves_keccak_map h₁)
constructor; swap; constructor; swap; constructor
all_goals assumption

-- functions for querying balance

namespace EVMState
Expand Down Expand Up @@ -339,6 +393,11 @@ def evm_return (σ : EVMState) (mstart s : UInt256) : EVMState :=
def evm_revert (σ : EVMState) (mstart s : UInt256) : EVMState :=
σ.evm_return mstart s

lemma mstore_preserves {evm} {pos val} : preserved evm (evm.mstore pos val) := by
unfold mstore updateMemory
rw [preserved_def]
simp

end

end Clear.EVMState
44 changes: 44 additions & 0 deletions Clear/Utilities.lean
Original file line number Diff line number Diff line change
Expand Up @@ -82,4 +82,48 @@ lemma evm_eq_symm_of_isPure_ok_ok {evm evm'} {vs vs'} (h : isPure (Ok evm vs) (O
symm
aesop_spec

def preservesEvm (s₀ : State) (s₁ : State) : Prop :=
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this predicate should also compare evm states in the case where the second state is a Checkpoint no? 🙂

match s₀, s₁ with
| .Ok e₀ _, .Ok e₁ _ => preserved e₀ e₁
| _, _ => True

lemma preservesEvm_of_isOk {s₀ s₁ : State} (s₀_ok : s₀.isOk) (s₁_ok : s₁.isOk) :
preservesEvm s₀ s₁ →
(s₀.evm.account_map = s₁.evm.account_map ∧
s₀.evm.hash_collision = s₁.evm.hash_collision ∧
s₀.evm.execution_env = s₁.evm.execution_env ∧
s₀.evm.keccak_map = s₁.evm.keccak_map) := by
unfold preservesEvm
cases s₀ <;> cases s₁ <;> simp at *
rw [preserved_def]
intro _; assumption

@[simp]
lemma preservesEvm_rfl {s : State} : preservesEvm s s := by
unfold preservesEvm
cases s <;> simp

@[simp]
lemma preservesEvm_trans {s₀ s₁ s₂} (h : s₁.isOk) :
preservesEvm s₀ s₁ → preservesEvm s₁ s₂ → preservesEvm s₀ s₂ := by
unfold preservesEvm
cases s₀ <;> cases s₁ <;> cases s₂ <;> simp_all
exact preserved_trans

lemma preservesEvm_eq (s₀ : State) (s₁ : State) :
preserved s₀.evm s₁.evm → preservesEvm s₀ s₁ := by
unfold preservesEvm
cases s₀ <;> cases s₁ <;> simp
simp [evm]

lemma sload_eq_of_preservesEvm
{s s' : State} {a : UInt256} (h : s.isOk) (h' : s'.isOk) (hss : preservesEvm s s') :
s.evm.sload a = s'.evm.sload a := by
cases s <;> cases s' <;> simp_all
simp only [evm]
unfold EVMState.sload EVMState.lookupAccount
rw [ preserves_account_map hss
, preserves_execution_env hss
]

end Clear.Utilities
10 changes: 10 additions & 0 deletions Clear/Wheels.lean
Original file line number Diff line number Diff line change
@@ -1,7 +1,17 @@
import Aesop

import Mathlib.Data.Rel
import Mathlib.Tactic.ApplyAt

instance instRelInter {α β} : Inter (Rel α β) where
inter r s := λ a b ↦ r a b ∧ s a b

def Rel.inter {α β} (r : α → β → Prop) (s : α → β → Prop) : α → β → Prop :=
λ a b ↦ r a b ∧ s a b

instance instFunInter {α β : Type} : Inter (α → β → Prop) where
jkopanski marked this conversation as resolved.
Show resolved Hide resolved
inter r s := λ a b ↦ r a b ∧ s a b
jkopanski marked this conversation as resolved.
Show resolved Hide resolved

declare_aesop_rule_sets [Clear.aesop_ok, Clear.aesop_spec, Clear.aesop_varstore]

set_option hygiene false in
Expand Down