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

Check exception #67

Open
wants to merge 137 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
137 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
dd7fe93
Update statistics
andreiburdusa Dec 9, 2024
e3248aa
Check exception and improve TransactionException.INTRINSIC_GAS_TOO_LOW
andreiburdusa Dec 9, 2024
1fa898e
Check state after expected exception (only pre states so far)
andreiburdusa Dec 9, 2024
7af66c3
Patch block validation
andreiburdusa Dec 10, 2024
d897f45
Refactor: distinguish between execution success and revert
andreiburdusa Dec 11, 2024
7f7bedc
Execution success is not failure or revert
andreiburdusa Dec 11, 2024
492ca3a
Θ cleanup
andreiburdusa Dec 11, 2024
53de8f3
Separate transaction validation from transaction execution; Refactor …
andreiburdusa Dec 13, 2024
a2e1b2c
Throw only ExecutionException in execution
andreiburdusa Dec 13, 2024
2b52c2a
Efficient ByteArray read and write
andreiburdusa Dec 17, 2024
df4370b
Compute activeWords for each operation
andreiburdusa Dec 17, 2024
f04bbb8
Make machine memory a ByteArray
andreiburdusa Dec 17, 2024
e508b7d
Memory optimisation for length 0
andreiburdusa Dec 17, 2024
975778f
Handle fuel better + debug info
andreiburdusa Dec 18, 2024
8e6bd03
Increase fuel
andreiburdusa Dec 18, 2024
495fb23
Fix stack size check
andreiburdusa Dec 19, 2024
211455a
Don't forget the list of created accounts
andreiburdusa Dec 19, 2024
535c67a
Handla failing case for ECRECOVER
andreiburdusa Dec 19, 2024
d0b632c
Update substate even in contract creation failure
andreiburdusa Dec 19, 2024
949df83
fixing sstore_combinations_initial11_Paris_d171g0v0_Cancun
PetarMax Jan 6, 2025
4dc7780
use lexicographic ordering
Ferinko Jan 7, 2025
ba3ea5c
Cleanup
andreiburdusa Jan 7, 2025
94db662
Update shell.nix
andreiburdusa Jan 7, 2025
26fbdb8
Merge pull request #68 from NethermindEth/Ferinko/containsFix
andreiburdusa Jan 8, 2025
219a2c8
Cleanup
andreiburdusa Jan 8, 2025
00c24c6
Don't parse transaction sender, just recover it
andreiburdusa Jan 8, 2025
5f5582b
Throw OutOfFuel execution error further
andreiburdusa Jan 8, 2025
7fdec1f
Update statistics
andreiburdusa Jan 9, 2025
002380d
External call to keccak.py
andreiburdusa Jan 15, 2025
b952b16
Refactor: merge Account models
andreiburdusa Jan 15, 2025
4671694
Support post state hash
andreiburdusa Jan 16, 2025
385b63f
Cleanup
andreiburdusa Jan 16, 2025
9614036
Use sender balance value as fuel
andreiburdusa Jan 17, 2025
1676a08
Check uncle hash
andreiburdusa Jan 17, 2025
2598092
Give enough fuel but temporarily blacklist passing tests that used to…
andreiburdusa Jan 20, 2025
1ee983f
Fix call depth incrementation
andreiburdusa Jan 20, 2025
721e281
Fix expmod input parsing
andreiburdusa Jan 21, 2025
410841b
Add check to point eval precompiled contract
andreiburdusa Jan 21, 2025
d68592b
Don't update createdAccounts set in case of collision
andreiburdusa Jan 21, 2025
64986f1
Fix blockhash (use correct order of arguments for Array.getD)
andreiburdusa Jan 22, 2025
bc2fb02
Fix SSTORE gas cost. Use checkpoint state, not ostorage
andreiburdusa Jan 28, 2025
14c392d
Check if transaction causes block to go over blob gas limit
andreiburdusa Jan 29, 2025
1ccf3db
Make accessList a List to preserve the original order.
andreiburdusa Jan 30, 2025
a117201
Throw INSUFFICIENT_MAX_FEE_PER_GAS
andreiburdusa Jan 30, 2025
6849b72
Remove BaseFeeTooHigh exception
andreiburdusa Jan 30, 2025
1b4d0b3
Rename InconsistentFees exception to PRIORITY_GREATER_THAN_MAX_FEE_PE…
andreiburdusa Jan 30, 2025
ae38ed9
Throw GAS_ALLOWANCE_EXCEEDED
andreiburdusa Jan 30, 2025
7403e72
Use TYPE_3_TX_INVALID_BLOB_VERSIONED_HASH exception and move check
andreiburdusa Jan 30, 2025
d19f1ab
Throw TYPE_3_TX_CONTRACT_CREATION
andreiburdusa Jan 30, 2025
7b96ecf
Throw TYPE_3_TX_BLOB_COUNT_EXCEEDED and GASLIMIT_PRICE_PRODUCT_OVERFLOW
andreiburdusa Jan 30, 2025
eb841fc
Check for TYPE_3_TX_MAX_BLOB_GAS_ALLOWANCE_EXCEEDED earlier
andreiburdusa Jan 31, 2025
20e1c3d
RLP decoding + wip deserialize block
andreiburdusa Feb 3, 2025
fd3cad6
Cleanup: Use fromByteArrayBigEndian
andreiburdusa Feb 3, 2025
1ac0e5b
Look more carefully into the original state
andreiburdusa Feb 3, 2025
18c2870
Move check for TYPE_3_TX_MAX_BLOB_GAS_ALLOWANCE_EXCEEDED
andreiburdusa Feb 4, 2025
9c80523
Remove chainId from block header
andreiburdusa Feb 4, 2025
ff89926
Remove hash from BlockHeader; deserialize block header
andreiburdusa Feb 4, 2025
6ef9689
RLP deserialization for transactions and withdrawals
andreiburdusa Feb 4, 2025
d4ce3d6
Remove ommers from block
andreiburdusa Feb 5, 2025
dc802ae
Cleanup
andreiburdusa Feb 5, 2025
3143852
Put the RLP deserialization in its proper place, after json parsing; …
andreiburdusa Feb 5, 2025
5068b38
Read block rlp outside "rlp_decoded"
andreiburdusa Feb 5, 2025
6b79417
Fix transaction ordering during RLP deserialization
andreiburdusa Feb 6, 2025
ca66a39
Parse difficulty
andreiburdusa Feb 6, 2025
892ea21
Check block difficulty
andreiburdusa Feb 6, 2025
55793cb
Fix dynamic transaction RLP deserialization
andreiburdusa Feb 6, 2025
bcb4b94
Remove wrong check
andreiburdusa Feb 6, 2025
e2bac97
Fix check for GAS_ALLOWANCE_EXCEEDED
andreiburdusa Feb 6, 2025
ab1d3f3
Disable json parsing for block header, transactions and withdrawal; a…
andreiburdusa Feb 7, 2025
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
393 changes: 90 additions & 303 deletions Conform/Main.lean

Large diffs are not rendered by default.

78 changes: 39 additions & 39 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 All @@ -20,20 +21,11 @@ section Model

open Lean

abbrev AddrMap (α : Type) [Inhabited α] := Batteries.RBMap AccountAddress α compare
abbrev Storage := Batteries.RBMap UInt256 UInt256 compare

def Storage.toFinmap (self : Storage) : Finmap (λ _ : UInt256 ↦ UInt256) :=
self.foldl (init := ∅) λ acc k v ↦ acc.insert (UInt256.ofNat k.1) v

def Storage.toEvmYulStorage (self : Storage) : EvmYul.Storage :=
self.foldl (init := ∅) λ acc k v ↦ acc.insert (UInt256.ofNat k.1) v

def AddrMap.keys {α : Type} [Inhabited α] (self : AddrMap α) : Multiset AccountAddress :=
.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 @@ -69,16 +61,9 @@ instance : DecidableRel (α := (_ : UInt256) × UInt256) (· ≤ ·) :=

abbrev Code := ByteArray

structure AccountEntry :=
nonce : UInt256
balance : UInt256
storage : Storage
code : ByteArray
deriving Inhabited, Repr, BEq

abbrev Pre := AddrMap AccountEntry
abbrev Pre := AddrMap PersistentAccountState

abbrev PostEntry := AccountEntry
abbrev PostEntry := PersistentAccountState

abbrev Post := AddrMap PostEntry

Expand All @@ -91,17 +76,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 @@ -110,24 +95,39 @@ This would be ever so slightly cleaner, but before we understand the exact corre
between all of the test file entires and the states, we sometimes keep a 'parsing model' *and*
an EVM model and write translations between them where convenient.
-/
structure TestEntry :=

inductive PostState :=
| Hash : ByteArray → PostState
| Map : Post → PostState
deriving Inhabited

structure RawTestEntry :=
info : Json := ""
blocks : Blocks
genesisBlockHeader : Json := ""
blocks : RawBlocks
genesisBlockHeader : BlockHeader
genesisRLP : Json := ""
lastblockhash : Json := ""
network : Json := ""
postState : Post
network : String
postState : PostState
pre : Pre
sealEngine : Json := ""
deriving Inhabited

abbrev Test := Batteries.RBMap String TestEntry compare
abbrev RawTestMap := Batteries.RBMap String RawTestEntry compare

structure DeserializedTestEntry :=
info : Json := ""
blocks : DeserializedBlocks
genesisBlockHeader : BlockHeader
genesisRLP : Json := ""
network : String
postState : PostState
pre : Pre
deriving Inhabited

abbrev DeserializedTestMap := Batteries.RBMap String DeserializedTestEntry compare

structure AccessListEntry :=
address : AccountAddress
storageKeys : Array UInt256
deriving Inhabited, Repr
abbrev AccessListEntry := AccountAddress × Array UInt256

abbrev AccessList := Array AccessListEntry

Expand Down
176 changes: 110 additions & 66 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 All @@ -72,7 +73,7 @@ This is also applicable for `FromJson Code`, as this is an abbrev for `ByteArray
-/
instance : FromJson ByteArray := fromBlobString (ByteArray.ofBlob)

instance : FromJson AccountEntry where
instance : FromJson PersistentAccountState where
fromJson? json := do
pure {
balance := ← json.getObjValAs? UInt256 "balance"
Expand All @@ -82,7 +83,7 @@ instance : FromJson AccountEntry where
}

instance : FromJson Pre where
fromJson? json := json.getObjVals? AccountAddress AccountEntry
fromJson? json := json.getObjVals? AccountAddress PersistentAccountState

instance : FromJson Post where
fromJson? json := json.getObjVals? AccountAddress PostEntry
Expand All @@ -95,35 +96,34 @@ instance : FromJson BlockHeader where
try
pure {
parentHash := ← json.getObjValAsD! UInt256 "parentHash"
ommersHash := TODO -- TODO - Set to whatever the KEC(RLP()) evaluates to.
ommersHash := ← json.getObjValAsD! UInt256 "uncleHash"
beneficiary := ← json.getObjValAsD! AccountAddress "coinbase"
stateRoot := ← json.getObjValAsD! UInt256 "stateRoot"
transRoot := TODO -- TODO - Does not seem to be used in Υ?
receiptRoot := TODO -- TODO - Does not seem to be used in Υ?
transRoot := ← json.getObjValAsD! UInt256 "transactionsTrie"
receiptRoot := ← json.getObjValAsD! UInt256 "receiptTrie"
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
difficulty := ← json.getObjValAsD! ℕ "difficulty"
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)
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

instance : FromJson AccessListEntry where
fromJson? json := do
pure {
address := ← json.getObjValAs? AccountAddress "address"
storageKeys := ← json.getObjValAs? (Array UInt256) "storageKeys"
}
let address := ← json.getObjValAs? AccountAddress "address"
let storageKeys := ← json.getObjValAs? (Array UInt256) "storageKeys"
pure (address, storageKeys)

instance : FromJson Withdrawal where
fromJson? json := do
Expand All @@ -140,17 +140,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,8 +160,8 @@ instance : FromJson Transaction where
-- Any other transaction now necessarily has an access list.
let accessListTransaction : Transaction.WithAccessList :=
{
chainId := let mainnet : Nat := 1; mainnet
accessList := ← FromJson.fromJson? accessList <&> accessListToRBMap
chainId := ← json.getObjValAsD UInt256 "chainId" ⟨1⟩
accessList := ← FromJson.fromJson? accessList
yParity := ← json.getObjValAsD! UInt256 "v"
}

Expand All @@ -170,16 +170,25 @@ 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

-- #eval DebuggingAndProfiling.testJsonParser Transaction r#"
-- {
Expand All @@ -198,47 +207,82 @@ instance : FromJson Transaction where
/--
- Format₀: `EthereumTests/BlockchainTests/GeneralStateTests/VMTests/vmArithmeticTest/add.json`
- Format₁: `EthereumTests/BlockchainTests/GeneralStateTests/Pyspecs/cancun/eip4844_blobs/invalid_static_excess_blob_gas.json`

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 RawBlock := 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"
let rlp ← json.getObjValAsD! ByteArray "rlp"
-- Descend to `rlp_decoded` - Format₁ if exists, Format₀ otherwise.
let json ← json.getObjValAsD Json "rlp_decoded" json
-- let json ← json.getObjValAsD Json "rlp_decoded" json
-- let blockHeader ← json.getObjValAsD! (Option BlockHeader) "blockHeader"
-- let transactions ← json.getObjValAsD! (Option Transactions) "transactions"
-- let withdrawals ← json.getObjValAsD! (Option Withdrawals) "withdrawals"

-- if blockHeader == none then
-- dbg_trace "blockHeader is none"
-- if transactions == none then
-- dbg_trace "transactions is none"
-- if withdrawals == none then
-- dbg_trace "withdrawals is none"

pure {
blockHeader := ← json.getObjValAsD! BlockHeader "blockHeader"
rlp := ← json.getObjValAsD! Json "rlp"
transactions := ← json.getObjValAsD! Transactions "transactions"
uncleHeaders := ← json.getObjValAsD! Json "uncleHeaders"
withdrawals := ← json.getObjValAsD! Withdrawals "withdrawals"
blocknumber := ← json.getObjValAsD _ "blocknumber" "1" >>= tryParseBlocknumber
exception := exception
rlp
blockHeader := none -- := ← json.getObjValAsD! (Option BlockHeader) "blockHeader"
transactions := none -- := ← json.getObjValAsD! (Option Transactions) "transactions"
withdrawals := none -- := ← json.getObjValAsD! (Option Withdrawals) "withdrawals"
exception -- := exception
}
where
tryParseBlocknumber (s : String) : Except String Nat :=
s.toNat?.elim (.error "Cannot parse `blocknumber`.") .ok

instance : FromJson BlockEntry := ⟨blockEntryOfJson⟩

deriving instance FromJson for TestEntry
instance : FromJson RawBlock := ⟨blockOfJson⟩

-- instance : FromJson PostState where
-- fromJson? json := do
-- let hash ← json.getObjValAsD! (Option ByteArray) "postStateHash"
-- match hash with
-- | some hash =>
-- dbg_trace s!"Read postStateHash: {hash}"
-- .ok <| PostState.Hash hash
-- | none =>
-- let map ← json.getObjValAsD! Post "postState"
-- dbg_trace s!"Read post state map of size {map.size}"
-- .ok <| PostState.Map map

instance : FromJson RawTestEntry where
fromJson? json := do
let post : PostState ←
match json.getObjVal? "postStateHash" with
| .error _ =>
-- dbg_trace s!"Read post state map"
.Map <$> json.getObjValAsD! PersistentAccountMap "postState"
| .ok postStateHash =>
-- dbg_trace s!"Read postStateHash: {postStateHash}"
.Hash <$> FromJson.fromJson? postStateHash
pure {
info := ← json.getObjValAs? Json "info"
blocks := ← json.getObjValAs? RawBlocks "blocks"
genesisBlockHeader := ← json.getObjValAs? BlockHeader "genesisBlockHeader"
genesisRLP := ← json.getObjValAs? Json "genesisRLP"
lastblockhash := ← json.getObjValAs? Json "lastblockhash"
network := ← json.getObjValAs? String "network"
postState := post
pre := ← json.getObjValAs? Pre "pre"
sealEngine := ← json.getObjValAs? Json "sealEngine"
}

instance : FromJson Test where
fromJson? json := json.getObjVals? String TestEntry
instance : FromJson RawTestMap where
fromJson? json := json.getObjVals? String RawTestEntry

end FromJson

def testNamesOfTest (test : Lean.Json) : Except String (Array String) :=
test.getObj? <&> (·.toArray.map Sigma.fst)

namespace Test

end Test

section PrettyPrinter

instance : ToString AccountEntry := ⟨ToString.toString ∘ repr⟩
instance : ToString PersistentAccountState := ⟨ToString.toString ∘ repr⟩

instance : ToString Pre := ⟨ToString.toString ∘ repr⟩

Expand Down
Loading