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

Balance check #66

Draft
wants to merge 68 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
68 commits
Select commit Hold shift + click to select a range
b29783c
Refactor call + returned value + gas model for value 0
andreiburdusa Oct 30, 2024
6687fb4
Fix-bugs-in-RLP-and-Withdrawals
andreiburdusa Oct 31, 2024
e5628d6
Tests file path
andreiburdusa Oct 31, 2024
f0cede3
Update blacklist
andreiburdusa Oct 31, 2024
b964460
Extend storage keys' length to 32 in RLP; Model blob transactions
andreiburdusa Nov 3, 2024
f7f11c9
BLOBBASEFEE
andreiburdusa Nov 5, 2024
6394229
Transaction type is byte
andreiburdusa Nov 5, 2024
db747f6
Merge BlockEntry from the testing infrastructure with the internal Bl…
andreiburdusa Nov 5, 2024
5637d3a
Parse genesisBlockHeader
andreiburdusa Nov 5, 2024
9b8f9e5
BLOBHASH, blob gas
andreiburdusa Nov 7, 2024
c2953de
Fix arity of EXTCODESIZE
andreiburdusa Nov 7, 2024
db3b55e
Update tests submodule
andreiburdusa Nov 8, 2024
a049312
Only run Cancun tests
andreiburdusa Nov 8, 2024
efd6d05
Update statistics for stBadOpcode. It hadn't been updated for a while
andreiburdusa Nov 8, 2024
e7a95c6
Update tests' path and the blacklist
andreiburdusa Nov 9, 2024
6bd5aee
Update blacklist
andreiburdusa Nov 9, 2024
337daba
revisiting implementation of expmod, adding nat_of_slice
PetarMax Nov 6, 2024
b0d201a
streamlining modexp implementation
PetarMax Nov 6, 2024
47f5cbd
38 more modexp tests passing
PetarMax Nov 8, 2024
1dae99f
more tests passing
PetarMax Nov 8, 2024
8d633da
and even more passing tests
PetarMax Nov 8, 2024
50ed589
probably all precompiled tests passing
PetarMax Nov 8, 2024
7d7dc00
all precompile tests passing
PetarMax Nov 8, 2024
31a9dea
Update blacklist
andreiburdusa Nov 10, 2024
cf5f7ab
Fix Ξ_BN_ADD and Ξ_BN_MUL failure; update statistics
andreiburdusa Nov 11, 2024
47450ec
New UInt256 type
andreiburdusa Nov 13, 2024
cbea2c3
Cleanup after new UInt256
andreiburdusa Nov 14, 2024
45c842a
Update blacklist and statistics
andreiburdusa Nov 14, 2024
c5725cc
Update statistics
andreiburdusa Nov 14, 2024
05512ec
Parse chain id
andreiburdusa Nov 14, 2024
5813c25
Update gas comparison in precompiled contracts
andreiburdusa Nov 14, 2024
b3792ef
Make gas cost Nat; Use .toNat where needed; add new exception type
andreiburdusa Nov 14, 2024
1f8f53b
Update blob cas price cost according to EEL spec
andreiburdusa Nov 15, 2024
0aea982
Nat parsing
andreiburdusa Nov 15, 2024
b5778bc
Allow padding in returndatacopy; Emit warning when truncating large Nat
andreiburdusa Nov 15, 2024
104a61c
New exception type: INSUFFICIENT_MAX_FEE_PER_BLOB_GAS
andreiburdusa Nov 15, 2024
87c6a62
Add point eval to π
andreiburdusa Nov 15, 2024
9f7e11a
WIP
andreiburdusa Nov 19, 2024
74422f9
WIP
andreiburdusa Nov 21, 2024
cd4f3ee
wip
andreiburdusa Nov 21, 2024
9000424
Ggascap
andreiburdusa Nov 21, 2024
ba78976
Separate memory expansion cost from cost
andreiburdusa Nov 26, 2024
7f74dab
typos
PetarMax Nov 26, 2024
661bbd5
Code size check
andreiburdusa Nov 26, 2024
d26f397
Typo
andreiburdusa Nov 26, 2024
aedfc53
Compute refund balance in SSTORE
andreiburdusa Nov 27, 2024
0d15373
SELFDESTRUCT; Gas model for EXTCODECOPY, call ops; collision in create
andreiburdusa Nov 28, 2024
b103893
Update blacklist
andreiburdusa Nov 29, 2024
3d4c302
Code is byte array; first index is 0
andreiburdusa Nov 29, 2024
42ca5ce
WIP + don't erase output data so easily
andreiburdusa Dec 1, 2024
6e02717
High nonce
andreiburdusa Dec 2, 2024
a2b7e2d
Accessed accounts, SSTORE gas check, code deposit cost, cleanup
andreiburdusa Dec 2, 2024
40a8928
Patch activeWords for call operations
andreiburdusa Dec 2, 2024
3b157f6
Contract creation: keep output data only in case of revert
andreiburdusa Dec 3, 2024
92dae64
High nonce
andreiburdusa Dec 4, 2024
36f6aea
RIP160, EXPMOD - gas cost, padding
andreiburdusa Dec 4, 2024
6bd68a1
BN_MUL arguments
andreiburdusa Dec 4, 2024
620d2c3
Pseudo laziness in expmod
andreiburdusa Dec 4, 2024
8801e85
Gcallstipend for SSTORE; Clear transient storage
andreiburdusa Dec 5, 2024
715b88f
Drop arguments of CREATE from stack
andreiburdusa Dec 5, 2024
2a0be42
α and δ
andreiburdusa Dec 5, 2024
583d531
BLOCKHASH
andreiburdusa Dec 5, 2024
57d0b8e
RETURNDATACOPY overflow
andreiburdusa Dec 6, 2024
4ea0f01
RETURNDATACOPY error message
andreiburdusa Dec 6, 2024
a5c931b
BYTE
andreiburdusa Dec 6, 2024
b4512e0
Don't call Lambda without need
andreiburdusa Dec 6, 2024
ca18622
Limit init code size
andreiburdusa Dec 6, 2024
a58fec8
stSStoreTest 100%; Ξ must be refactored
andreiburdusa Dec 6, 2024
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
445 changes: 213 additions & 232 deletions Conform/Main.lean

Large diffs are not rendered by default.

27 changes: 14 additions & 13 deletions Conform/Model.lean
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import Lean.Data.Json
import EvmYul.Operations
import EvmYul.Wheels
import EvmYul.State.Withdrawal
import EvmYul.State.Block

import EvmYul.EVM.State

Expand Down Expand Up @@ -33,7 +34,7 @@ def AddrMap.keys {α : Type} [Inhabited α] (self : AddrMap α) : Multiset Accou
.ofList <| self.toList.map Prod.fst

instance : LE ((_ : UInt256) × UInt256) where
le lhs rhs := if lhs.1 = rhs.1 then lhs.2 ≤ rhs.2 else lhs.1 ≤ rhs.1
le lhs rhs := if lhs.1.val = rhs.1.val then lhs.2.val ≤ rhs.2.val else lhs.1.val ≤ rhs.1.val

instance : IsTrans ((_ : UInt256) × UInt256) (· ≤ ·) where
trans a b c h₁ h₂ := by
Expand Down Expand Up @@ -91,17 +92,17 @@ TODO - Temporary.
-/
private local instance : Repr Json := ⟨λ s _ ↦ Json.pretty s⟩

structure BlockEntry :=
blockHeader : BlockHeader
rlp : Json
transactions : Transactions
uncleHeaders : Json
withdrawals : Withdrawals
exception : String -- TODO - I am guessing there is a closed set of these to turn into a sum.
blocknumber : Nat
deriving Inhabited, Repr
-- structure BlockEntry :=
-- blockHeader : BlockHeader
-- rlp : ByteArray
-- transactions : Transactions
-- ommers : Array BlockHeader
-- withdrawals : Withdrawals
-- exception : String -- TODO - I am guessing there is a closed set of these to turn into a sum.
-- -- blocknumber : Nat
-- deriving Inhabited, Repr

abbrev Blocks := Array BlockEntry
-- abbrev Blocks := Array BlockEntry

/--
In theory, parts of the TestEntry could deserialise immediately into the underlying `EVM.State`.
Expand All @@ -113,10 +114,10 @@ an EVM model and write translations between them where convenient.
structure TestEntry :=
info : Json := ""
blocks : Blocks
genesisBlockHeader : Json := ""
genesisBlockHeader : BlockHeader
genesisRLP : Json := ""
lastblockhash : Json := ""
network : Json := ""
network : String
postState : Post
pre : Pre
sealEngine : Json := ""
Expand Down
90 changes: 53 additions & 37 deletions Conform/TestParser.lean
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ private def fromBlobString {α} (f : Blob → Except String α) : FromJson α :=
}

instance : FromJson UInt256 := fromBlobString UInt256.fromBlob?
instance : FromJson ℕ := fromBlobString Nat.fromBlob?

instance : FromJson AccountAddress := fromBlobString AccountAddress.fromBlob?

Expand All @@ -55,11 +56,11 @@ Why is there no handy `unfold` - because of termination issues?
-/
def decodeMany (code : ByteArray) : Except String Code' := do
let mut result : Code' := #[]
let mut pc := 0
while pc < code.size do
let (instr, arg) ← (EVM.decode code pc |>.toExceptWith s!"Cannot decode the instruction: {code.data.get! pc}")
let mut pc : UInt256 := ⟨0⟩
while pc.toNat < code.size do
let (instr, arg) ← (EVM.decode code pc |>.toExceptWith s!"Cannot decode the instruction: {code.data.get! pc.toNat}")
result := result.push (instr, Prod.fst <$> arg)
pc := pc + 1 + arg.option 0 Prod.snd
pc := pc + .ofNat (1 + arg.option 0 Prod.snd)
pure result

end _Code'
Expand Down Expand Up @@ -94,6 +95,7 @@ instance : FromJson BlockHeader where
fromJson? json := do
try
pure {
hash := ← json.getObjValAsD! UInt256 "hash"
parentHash := ← json.getObjValAsD! UInt256 "parentHash"
ommersHash := TODO -- TODO - Set to whatever the KEC(RLP()) evaluates to.
beneficiary := ← json.getObjValAsD! AccountAddress "coinbase"
Expand All @@ -102,18 +104,20 @@ instance : FromJson BlockHeader where
receiptRoot := TODO -- TODO - Does not seem to be used in Υ?
logsBloom := ← json.getObjValAsD! ByteArray "bloom"
difficulty := 0 -- [deprecated] 0.
number := ← json.getObjValAsD! _ "number" <&> UInt256.toNat
gasLimit := ← json.getObjValAsD! _ "gasLimit" <&> UInt256.toNat
gasUsed := ← json.getObjValAsD! _ "gasUsed" <&> UInt256.toNat
timestamp := ← json.getObjValAsD! _ "timestamp" <&> UInt256.toNat
number := ← json.getObjValAsD! "number"
gasLimit := ← json.getObjValAsD! "gasLimit"
gasUsed := ← json.getObjValAsD! "gasUsed"
timestamp := ← json.getObjValAsD! "timestamp"
extraData := ← json.getObjValAsD! ByteArray "extraData"
minHash := TODO -- TODO - Does not seem to be used in Υ?
chainId := 1 -- (5)
chainId := ← json.getObjValAsD UInt256 "chainId" ⟨1⟩ -- (5)
nonce := 0 -- [deprecated] 0.
baseFeePerGas := ← json.getObjValAsD! _ "baseFeePerGas" <&> UInt256.toNat
baseFeePerGas := ← json.getObjValAsD! "baseFeePerGas"
parentBeaconBlockRoot := ← json.getObjValAsD! ByteArray "parentBeaconBlockRoot"
prevRandao := ← json.getObjValAsD! UInt256 "mixHash"
withdrawalsRoot := ← json.getObjValAsD! ByteArray "withdrawalsRoot"
withdrawalsRoot := ← json.getObjValAsD! (Option ByteArray) "withdrawalsRoot"
blobGasUsed := ← json.getObjValAsD! (Option UInt64) "blobGasUsed"
excessBlobGas := ← json.getObjValAsD! (Option UInt64) "excessBlobGas"
}
catch exct => dbg_trace s!"OOOOPSIE: {exct}\n json: {json}"
default
Expand All @@ -140,17 +144,17 @@ TODO - Currently we return `AccessListTransaction`. No idea if this is what we w
instance : FromJson Transaction where
fromJson? json := do
let baseTransaction : Transaction.Base := {
nonce := ← json.getObjValAsD! UInt256 "nonce"
gasLimit := ← json.getObjValAsD! UInt256 "gasLimit"
recipient := ← match json.getObjVal? "to" with
| .error _ => .ok .none
| .ok ok => do let str ← ok.getStr?
if str.isEmpty then .ok .none else FromJson.fromJson? str
value := ← json.getObjValAsD! UInt256 "value"
r := ← json.getObjValAsD! ByteArray "r"
s := ← json.getObjValAsD! ByteArray "s"
data := ← json.getObjValAsD! ByteArray "data"
dbgSender := ← json.getObjValAsD! AccountAddress "sender"
nonce := ← json.getObjValAsD! UInt256 "nonce"
gasLimit := ← json.getObjValAsD! UInt256 "gasLimit"
recipient := ← match json.getObjVal? "to" with
| .error _ => .ok .none
| .ok ok => do let str ← ok.getStr?
if str.isEmpty then .ok .none else FromJson.fromJson? str
value := ← json.getObjValAsD! UInt256 "value"
r := ← json.getObjValAsD! ByteArray "r"
s := ← json.getObjValAsD! ByteArray "s"
data := ← json.getObjValAsD! ByteArray "data"
expectedSender := ← json.getObjValAsD! AccountAddress "sender"
}

match json.getObjVal? "accessList" with
Expand All @@ -160,7 +164,7 @@ instance : FromJson Transaction where
-- Any other transaction now necessarily has an access list.
let accessListTransaction : Transaction.WithAccessList :=
{
chainId := let mainnet : Nat := 1; mainnet
chainId := ← json.getObjValAsD UInt256 "chainId" ⟨1⟩
accessList := ← FromJson.fromJson? accessList <&> accessListToRBMap
yParity := ← json.getObjValAsD! UInt256 "v"
}
Expand All @@ -170,13 +174,24 @@ instance : FromJson Transaction where
-- dbg_trace "Constructing an access transaction."
return .access ⟨baseTransaction, accessListTransaction, ⟨← FromJson.fromJson? gasPrice⟩⟩
| .error _ =>
-- dbg_trace "Constructing an dynamic transaction."
return .dynamic ⟨
baseTransaction,
accessListTransaction,
← json.getObjValAsD! UInt256 "maxFeePerGas",
← json.getObjValAsD! UInt256 "maxPriorityFeePerGas"
let dynamic : DynamicFeeTransaction :=
⟨ baseTransaction
, accessListTransaction
, ← json.getObjValAsD! UInt256 "maxFeePerGas"
, ← json.getObjValAsD! UInt256 "maxPriorityFeePerGas"
match json.getObjVal? "maxFeePerBlobGas" with
| .error _ =>
pure <| .dynamic dynamic
| .ok maxFeePerBlobGas =>
-- dbg_trace "Constructing a blob transaction."
pure <|
.blob
⟨ dynamic
, ← FromJson.fromJson? maxFeePerBlobGas
, ← json.getObjValAsD! (List ByteArray) "blobVersionedHashes"


where accessListToRBMap (this : AccessList) : Batteries.RBMap AccountAddress (Array UInt256) compare :=
this.foldl (init := ∅) λ m ⟨addr, list⟩ ↦ m.insert addr list
Expand All @@ -202,25 +217,26 @@ instance : FromJson Transaction where
TODO -
- `EthereumTests/BlockchainTests/GeneralStateTests/Pyspecs/cancun/eip4844_blobs/invalid_blob_tx_contract_creation.json` - ?????
-/
private def blockEntryOfJson (json : Json) : Except String BlockEntry := do
private def blockOfJson (json : Json) : Except String Block := do
-- The exception, if exists, is always in the outermost object regardless of the `<Format>` (see this function's docs).
let exception ← json.getObjValAsD! String "expectException"
-- Descend to `rlp_decoded` - Format₁ if exists, Format₀ otherwise.
let json ← json.getObjValAsD Json "rlp_decoded" json
pure {
blockHeader := ← json.getObjValAsD! BlockHeader "blockHeader"
rlp := ← json.getObjValAsD! Json "rlp"
blockHeader := ← json.getObjValAsD! BlockHeader "blockHeader"
rlp := ← json.getObjValAsD! ByteArray "rlp"
transactions := ← json.getObjValAsD! Transactions "transactions"
uncleHeaders := ← json.getObjValAsD! Json "uncleHeaders"
withdrawals := ← json.getObjValAsD! Withdrawals "withdrawals"
blocknumber := ← json.getObjValAsD _ "blocknumber" "1" >>= tryParseBlocknumber
ommers := ← json.getObjValAsD! (Array BlockHeader) "uncleHeaders"
withdrawals := ← json.getObjValAsD! Withdrawals "withdrawals"
-- The block's number should be in the header.
-- blocknumber := ← json.getObjValAsD _ "blocknumber" "1" >>= tryParseBlocknumber
exception := exception
}
where
tryParseBlocknumber (s : String) : Except String Nat :=
s.toNat?.elim (.error "Cannot parse `blocknumber`.") .ok

instance : FromJson BlockEntry := ⟨blockEntryOfJson
instance : FromJson Block := ⟨blockOfJson

deriving instance FromJson for TestEntry

Expand Down
Loading