Skip to content

Commit b67859f

Browse files
authored
Merge pull request #904 from argotorg/execution-refactor
EVM: Separate symbolic and concrete handling of SLOAD
2 parents 5786288 + fa1a99a commit b67859f

File tree

1 file changed

+26
-21
lines changed

1 file changed

+26
-21
lines changed

src/EVM.hs

Lines changed: 26 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -727,13 +727,21 @@ exec1 conf = do
727727

728728
OpSload -> {-# SCC "OpSload" #-}
729729
case stk of
730-
x:xs -> do
731-
acc <- accessStorageForGas self x
732-
let cost = if acc then g_warm_storage_read else g_cold_sload
733-
burn cost $
734-
accessStorage self x $ \y -> do
735-
next
736-
assign' (#state % #stack) (y:xs)
730+
x:xs ->
731+
let
732+
finalizeLoad readValue = do next; assign' (#state % #stack) (readValue:xs)
733+
734+
symbolicRead :: EVM t s () = if this.external
735+
then accessStorage self x finalizeLoad
736+
else finalizeLoad $ Expr.readStorage' (Expr.concKeccakOnePass x) this.storage
737+
738+
concreteRead :: EVM t s () = do
739+
acc <- accessStorageForGas self (forceLit x)
740+
let cost = if acc then g_warm_storage_read else g_cold_sload
741+
burn cost $ if this.external
742+
then accessStorage self x finalizeLoad
743+
else finalizeLoad $ Lit $ accessConcreteStorage this.storage (forceLit x)
744+
in whenSymbolicElse symbolicRead concreteRead
737745
_ -> underrun
738746

739747
OpSstore -> {-# SCC "OpSstore" #-}
@@ -748,12 +756,6 @@ exec1 conf = do
748756

749757
concreteSstore :: EVM t s () = do
750758
let
751-
accessConcreteStorage :: Expr Storage -> W256 -> W256
752-
accessConcreteStorage storage slot' =
753-
case storage of
754-
(ConcreteStore m) -> fromMaybe 0 $ Map.lookup slot' m
755-
_ -> internalError "Storage must be concrete"
756-
757759
slot = forceLit x
758760
currentVal = accessConcreteStorage this.storage slot
759761
newVal = forceLit new
@@ -765,7 +767,7 @@ exec1 conf = do
765767
| (currentVal == originalVal) = g_sreset
766768
| otherwise = g_sload
767769

768-
acc <- accessStorageForGas self x
770+
acc <- accessStorageForGas self slot
769771
let cold_storage_cost = if acc then 0 else g_cold_sload
770772
burn (storage_cost + cold_storage_cost) $ do
771773
updateVMState
@@ -1412,6 +1414,12 @@ fetchAccountWithFallback addr fallback continue =
14121414
continue c
14131415
GVar _ -> internalError "Unexpected GVar"
14141416

1417+
accessConcreteStorage :: Expr Storage -> W256 -> W256
1418+
accessConcreteStorage storage slot' =
1419+
case storage of
1420+
(ConcreteStore m) -> fromMaybe 0 $ Map.lookup slot' m
1421+
_ -> internalError "Storage must be concrete"
1422+
14151423
accessStorage :: forall s t . (?conf :: Config, VMOps t, Typeable t) => Expr EAddr
14161424
-> Expr EWord
14171425
-> (Expr EWord -> EVM t s ())
@@ -1746,15 +1754,12 @@ accessAccountForGas addr = do
17461754

17471755
-- | returns a wrapped boolean- if true, this slot has been touched before in the txn (warm gas cost as in EIP 2929)
17481756
-- otherwise cold
1749-
accessStorageForGas :: Expr EAddr -> Expr EWord -> EVM t s Bool
1757+
accessStorageForGas :: Expr EAddr -> W256 -> EVM t s Bool
17501758
accessStorageForGas addr key = do
17511759
accessedStrkeys <- use (#tx % #subState % #accessedStorageKeys)
1752-
case maybeLitWordSimp key of
1753-
Just litword -> do
1754-
let accessed = member (addr, litword) accessedStrkeys
1755-
assign (#tx % #subState % #accessedStorageKeys) (insert (addr, litword) accessedStrkeys)
1756-
pure accessed
1757-
_ -> pure False
1760+
let accessed = member (addr, key) accessedStrkeys
1761+
unless accessed $ assign (#tx % #subState % #accessedStorageKeys) (insert (addr, key) accessedStrkeys)
1762+
pure accessed
17581763

17591764
-- * Cheat codes
17601765

0 commit comments

Comments
 (0)