Skip to content
Draft
Show file tree
Hide file tree
Changes from all 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
1 change: 1 addition & 0 deletions execution_chain/core/chain/forked_chain/chain_private.nim
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ proc processBlock*(
# witness keys and block hashes when processing the block as these will be used
# when building the witness.
vmState.ledger.clearWitnessKeys()
vmState.ledger.clearDeployedCodeHashes()
vmState.ledger.clearBlockHashesCache()

processBlock()
Expand Down
1 change: 1 addition & 0 deletions execution_chain/core/chain/persist_blocks.nim
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,7 @@ proc persistBlock*(p: var Persister, blk: Block): Result[void, string] =
# witness keys and block hashes when processing the block as these will be used
# when building the witness.
vmState.ledger.clearWitnessKeys()
vmState.ledger.clearDeployedCodeHashes()
vmState.ledger.clearBlockHashesCache()

processBlock()
Expand Down
40 changes: 32 additions & 8 deletions execution_chain/db/ledger.nim
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,8 @@ type
dirty: Table[Address, AccountRef]
selfDestruct: HashSet[Address]
accessList: ac_access_list.AccessList
deployedCodeHashes: HashSet[Hash32]
## Caches codeHashes deployed via CREATE in this savepoint.

const
resetFlags = {
Expand Down Expand Up @@ -376,6 +378,7 @@ proc commit*(ledger: LedgerRef, savePoint: LedgerSpRef) =
ledger.savePoint.dirty.mergeAndReset(savePoint.dirty)
ledger.savePoint.accessList.mergeAndReset(savePoint.accessList)
ledger.savePoint.selfDestruct.mergeAndReset(savePoint.selfDestruct)
ledger.savePoint.deployedCodeHashes.mergeAndReset(savePoint.deployedCodeHashes)

savePoint.parentSavePoint = nil # Release memory

Expand Down Expand Up @@ -408,16 +411,30 @@ proc getNonce*(ledger: LedgerRef, address: Address): AccountNonce =
if acc.isNil: EMPTY_ACCOUNT.nonce
else: acc.statement.nonce

func isDeployedCode(ledger: LedgerRef, codeHash: Hash32): bool =
## Check if codeHash was deployed in any currently active save point.
var sp = ledger.savePoint
while sp != nil:
if codeHash in sp.deployedCodeHashes:
return true
sp = sp.parentSavePoint
false

proc getCode*(ledger: LedgerRef,
address: Address,
returnHash: static[bool] = false): auto =
let acc = ledger.getAccount(address, false)

if ledger.collectWitness:
let lookupKey = (address, Opt.none(UInt256))
# We overwrite any existing record here so that codeTouched is always set to
# true even if an account was previously accessed without touching the code
ledger.witnessKeys[lookupKey] = true
# Only mark codeTouched if the code isn't deployed in this block.
# Deployed code can be recovered from tx data directly.
# We overwrite any existing false entry so codeTouched is set to true
# even if the account was previously accessed without touching the code.
if acc.isNil or acc.statement.codeHash == EMPTY_CODE_HASH or
not ledger.isDeployedCode(acc.statement.codeHash):
ledger.witnessKeys[lookupKey] = true

let acc = ledger.getAccount(address, false)
if acc.isNil:
when returnHash:
return (EMPTY_CODE_HASH, CodeBytesRef())
Expand Down Expand Up @@ -445,13 +462,14 @@ proc getCode*(ledger: LedgerRef,
acc.code

proc getCodeSize*(ledger: LedgerRef, address: Address): int =
let acc = ledger.getAccount(address, false)

if ledger.collectWitness:
let lookupKey = (address, Opt.none(UInt256))
# We overwrite any existing record here so that codeTouched is always set to
# true even if an account was previously accessed without touching the code
ledger.witnessKeys[lookupKey] = true
if acc.isNil or acc.statement.codeHash == EMPTY_CODE_HASH or
not ledger.isDeployedCode(acc.statement.codeHash):
ledger.witnessKeys[lookupKey] = true

let acc = ledger.getAccount(address, false)
if acc.isNil:
return 0

Expand Down Expand Up @@ -575,6 +593,8 @@ proc setCode*(ledger: LedgerRef, address: Address, code: seq[byte]) =
# a given that it will be executed within LRU range
acc.code = ledger.code.get(codeHash).valueOr(CodeBytesRef.init(code))
acc.flags.incl CodeChanged
if ledger.collectWitness and code.len > 0:
ledger.savePoint.deployedCodeHashes.incl(codeHash)

proc setStorage*(ledger: LedgerRef, address: Address, slot, value: UInt256) =
let acc = ledger.getAccount(address)
Expand Down Expand Up @@ -663,6 +683,9 @@ template getWitnessKeys*(ledger: LedgerRef): WitnessTable =
template clearWitnessKeys*(ledger: LedgerRef) =
ledger.witnessKeys.clear()

template clearDeployedCodeHashes*(ledger: LedgerRef) =
ledger.savePoint.deployedCodeHashes.clear()

proc getBlockHash*(ledger: LedgerRef, blockNumber: BlockNumber): Hash32 =
ledger.blockHashes.get(blockNumber).valueOr:
let blockHash = ledger.txFrame.getBlockHash(blockNumber).valueOr:
Expand Down Expand Up @@ -742,6 +765,7 @@ proc persist*(ledger: LedgerRef,

if clearWitness:
ledger.clearWitnessKeys()
ledger.clearDeployedCodeHashes()
ledger.clearBlockHashesCache()

iterator addresses*(ledger: LedgerRef): Address =
Expand Down
1 change: 0 additions & 1 deletion tests/eest/eest_stateless_execution_test.nim
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,6 @@ const skipFiles = [
"varying_calldata_costs.json",
"bal_7002_partial_sweep.json",
"witness_codes_delegated_eoa_insufficient_balance.json",
"witness_codes_create_same_hash_then_read.json",
"witness_headers_blockhash_at_offset.json",
"witness_headers_blockhash_boundary.json",
"witness_headers_blockhash_in_reverted_tx.json",
Expand Down
Loading