Rename stateDB to ledger (#2966)

* Rename stateDB to ledger

* Fix readOnlyLedger
This commit is contained in:
andri lim 2024-12-21 20:46:13 +07:00 committed by GitHub
parent 7112a19d6c
commit aba9b582db
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
45 changed files with 266 additions and 266 deletions

View File

@ -48,7 +48,7 @@ proc processBlock(
let com = vmState.com let com = vmState.com
if com.daoForkSupport and if com.daoForkSupport and
com.daoForkBlock.get == header.number: com.daoForkBlock.get == header.number:
vmState.mutateStateDB: vmState.mutateLedger:
db.applyDAOHardFork() db.applyDAOHardFork()
if header.parentBeaconBlockRoot.isSome: if header.parentBeaconBlockRoot.isSome:
@ -58,7 +58,7 @@ proc processBlock(
if com.isShanghaiOrLater(header.timestamp): if com.isShanghaiOrLater(header.timestamp):
for withdrawal in blk.withdrawals.get: for withdrawal in blk.withdrawals.get:
vmState.stateDB.addBalance(withdrawal.address, withdrawal.weiAmount) vmState.ledger.addBalance(withdrawal.address, withdrawal.weiAmount)
if header.ommersHash != EMPTY_UNCLE_HASH: if header.ommersHash != EMPTY_UNCLE_HASH:
discard com.db.persistUncles(blk.uncles) discard com.db.persistUncles(blk.uncles)
@ -67,7 +67,7 @@ proc processBlock(
if com.proofOfStake(header): if com.proofOfStake(header):
vmState.calculateReward(header, blk.uncles) vmState.calculateReward(header, blk.uncles)
vmState.mutateStateDB: vmState.mutateLedger:
let clearEmptyAccount = com.isSpuriousOrLater(header.number) let clearEmptyAccount = com.isSpuriousOrLater(header.number)
db.persist(clearEmptyAccount) db.persist(clearEmptyAccount)

View File

@ -37,12 +37,12 @@ proc genesisHeader(node: JsonNode): Header =
proc initializeDb(memDB: CoreDbRef, node: JsonNode): Hash32 = proc initializeDb(memDB: CoreDbRef, node: JsonNode): Hash32 =
let let
genesisHeader = node.genesisHeader genesisHeader = node.genesisHeader
stateDB = LedgerRef.init(memDB) ledger = LedgerRef.init(memDB)
memDB.persistHeaderAndSetHead(genesisHeader).expect("persistHeader no error") memDB.persistHeaderAndSetHead(genesisHeader).expect("persistHeader no error")
setupStateDB(node["pre"], stateDB) setupLedger(node["pre"], ledger)
stateDB.persist() ledger.persist()
doAssert stateDB.getStateRoot == genesisHeader.stateRoot doAssert ledger.getStateRoot == genesisHeader.stateRoot
genesisHeader.blockHash genesisHeader.blockHash

View File

@ -145,9 +145,9 @@ const
# ApplyDAOHardFork modifies the state database according to the DAO hard-fork # ApplyDAOHardFork modifies the state database according to the DAO hard-fork
# rules, transferring all balances of a set of DAO accounts to a single refund # rules, transferring all balances of a set of DAO accounts to a single refund
# contract. # contract.
proc applyDAOHardFork*(statedb: LedgerRef) = proc applyDAOHardFork*(ledger: LedgerRef) =
const zero = 0.u256 const zero = 0.u256
# Move every DAO account and extra-balance account funds into the refund contract # Move every DAO account and extra-balance account funds into the refund contract
for address in DAODrainList: for address in DAODrainList:
statedb.addBalance(DAORefundContract, statedb.getBalance(address)) ledger.addBalance(DAORefundContract, ledger.getBalance(address))
statedb.setBalance(address, zero) ledger.setBalance(address, zero)

View File

@ -59,11 +59,11 @@ proc calculateReward*(vmState: BaseVMState; account: Address;
uncleReward -= number.u256 uncleReward -= number.u256
uncleReward = uncleReward * blockReward uncleReward = uncleReward * blockReward
uncleReward = uncleReward div 8.u256 uncleReward = uncleReward div 8.u256
vmState.mutateStateDB: vmState.mutateLedger:
db.addBalance(uncle.coinbase, uncleReward) db.addBalance(uncle.coinbase, uncleReward)
mainReward += blockReward div 32.u256 mainReward += blockReward div 32.u256
vmState.mutateStateDB: vmState.mutateLedger:
db.addBalance(account, mainReward) db.addBalance(account, mainReward)

View File

@ -53,7 +53,7 @@ proc makeReceipt*(vmState: BaseVMState; txType: TxType): Receipt =
rec.status = vmState.status rec.status = vmState.status
else: else:
rec.isHash = true rec.isHash = true
rec.hash = vmState.stateDB.getStateRoot() rec.hash = vmState.ledger.getStateRoot()
# we set the status for the t8n output consistency # we set the status for the t8n output consistency
rec.status = vmState.status rec.status = vmState.status

View File

@ -113,7 +113,7 @@ proc procBlkPreamble(
let com = vmState.com let com = vmState.com
if com.daoForkSupport and com.daoForkBlock.get == header.number: if com.daoForkSupport and com.daoForkBlock.get == header.number:
vmState.mutateStateDB: vmState.mutateLedger:
db.applyDAOHardFork() db.applyDAOHardFork()
if not skipValidation: # Expensive! if not skipValidation: # Expensive!
@ -156,7 +156,7 @@ proc procBlkPreamble(
return err("Post-Shanghai block body must have withdrawals") return err("Post-Shanghai block body must have withdrawals")
for withdrawal in blk.withdrawals.get: for withdrawal in blk.withdrawals.get:
vmState.stateDB.addBalance(withdrawal.address, withdrawal.weiAmount) vmState.ledger.addBalance(withdrawal.address, withdrawal.weiAmount)
else: else:
if header.withdrawalsRoot.isSome: if header.withdrawalsRoot.isSome:
return err("Pre-Shanghai block header must not have withdrawalsRoot") return err("Pre-Shanghai block header must not have withdrawalsRoot")
@ -190,7 +190,7 @@ proc procBlkEpilogue(
blk.header blk.header
# Reward beneficiary # Reward beneficiary
vmState.mutateStateDB: vmState.mutateLedger:
if vmState.collectWitnessData: if vmState.collectWitnessData:
db.collectWitnessData() db.collectWitnessData()
@ -212,7 +212,7 @@ proc procBlkEpilogue(
consolidationReqs = processDequeueConsolidationRequests(vmState) consolidationReqs = processDequeueConsolidationRequests(vmState)
if not skipValidation: if not skipValidation:
let stateRoot = vmState.stateDB.getStateRoot() let stateRoot = vmState.ledger.getStateRoot()
if header.stateRoot != stateRoot: if header.stateRoot != stateRoot:
# TODO replace logging with better error # TODO replace logging with better error
debug "wrong state root in block", debug "wrong state root in block",

View File

@ -50,12 +50,12 @@ proc commitOrRollbackDependingOnGasUsed(
# an early stop. It would rather detect differing values for the block # an early stop. It would rather detect differing values for the block
# header `gasUsed` and the `vmState.cumulativeGasUsed` at a later stage. # header `gasUsed` and the `vmState.cumulativeGasUsed` at a later stage.
if header.gasLimit < vmState.cumulativeGasUsed + gasBurned: if header.gasLimit < vmState.cumulativeGasUsed + gasBurned:
vmState.stateDB.rollback(accTx) vmState.ledger.rollback(accTx)
err(&"invalid tx: block header gasLimit reached. gasLimit={header.gasLimit}, gasUsed={vmState.cumulativeGasUsed}, addition={gasBurned}") err(&"invalid tx: block header gasLimit reached. gasLimit={header.gasLimit}, gasUsed={vmState.cumulativeGasUsed}, addition={gasBurned}")
else: else:
# Accept transaction and collect mining fee. # Accept transaction and collect mining fee.
vmState.stateDB.commit(accTx) vmState.ledger.commit(accTx)
vmState.stateDB.addBalance(vmState.coinbase(), gasBurned.u256 * priorityFee.u256) vmState.ledger.addBalance(vmState.coinbase(), gasBurned.u256 * priorityFee.u256)
vmState.cumulativeGasUsed += gasBurned vmState.cumulativeGasUsed += gasBurned
# Return remaining gas to the block gas counter so it is # Return remaining gas to the block gas counter so it is
@ -75,7 +75,7 @@ proc processTransactionImpl(
let let
fork = vmState.fork fork = vmState.fork
roDB = vmState.readOnlyStateDB roDB = vmState.readOnlyLedger
baseFee256 = header.eip1559BaseFee(fork) baseFee256 = header.eip1559BaseFee(fork)
baseFee = baseFee256.truncate(GasInt) baseFee = baseFee256.truncate(GasInt)
priorityFee = min(tx.maxPriorityFeePerGasNorm(), tx.maxFeePerGasNorm() - baseFee) priorityFee = min(tx.maxPriorityFeePerGasNorm(), tx.maxFeePerGasNorm() - baseFee)
@ -106,12 +106,12 @@ proc processTransactionImpl(
txRes = roDB.validateTransaction(tx, sender, header.gasLimit, baseFee256, excessBlobGas, fork) txRes = roDB.validateTransaction(tx, sender, header.gasLimit, baseFee256, excessBlobGas, fork)
res = if txRes.isOk: res = if txRes.isOk:
# EIP-1153 # EIP-1153
vmState.stateDB.clearTransientStorage() vmState.ledger.clearTransientStorage()
# Execute the transaction. # Execute the transaction.
vmState.captureTxStart(tx.gasLimit) vmState.captureTxStart(tx.gasLimit)
let let
accTx = vmState.stateDB.beginSavepoint accTx = vmState.ledger.beginSavepoint
gasBurned = tx.txCallEvm(sender, vmState, baseFee) gasBurned = tx.txCallEvm(sender, vmState, baseFee)
vmState.captureTxEnd(tx.gasLimit - gasBurned) vmState.captureTxEnd(tx.gasLimit - gasBurned)
@ -120,9 +120,9 @@ proc processTransactionImpl(
err(txRes.error) err(txRes.error)
if vmState.collectWitnessData: if vmState.collectWitnessData:
vmState.stateDB.collectWitnessData() vmState.ledger.collectWitnessData()
vmState.stateDB.persist(clearEmptyAccount = fork >= FkSpurious) vmState.ledger.persist(clearEmptyAccount = fork >= FkSpurious)
res res
@ -137,7 +137,7 @@ proc processBeaconBlockRoot*(vmState: BaseVMState, beaconRoot: Hash32):
## If EIP-4788 is enabled, we need to invoke the beaconroot storage ## If EIP-4788 is enabled, we need to invoke the beaconroot storage
## contract with the new root. ## contract with the new root.
let let
statedb = vmState.stateDB ledger = vmState.ledger
call = CallParams( call = CallParams(
vmState : vmState, vmState : vmState,
sender : SYSTEM_ADDRESS, sender : SYSTEM_ADDRESS,
@ -159,7 +159,7 @@ proc processBeaconBlockRoot*(vmState: BaseVMState, beaconRoot: Hash32):
if res.len > 0: if res.len > 0:
return err("processBeaconBlockRoot: " & res) return err("processBeaconBlockRoot: " & res)
statedb.persist(clearEmptyAccount = true) ledger.persist(clearEmptyAccount = true)
ok() ok()
proc processParentBlockHash*(vmState: BaseVMState, prevHash: Hash32): proc processParentBlockHash*(vmState: BaseVMState, prevHash: Hash32):
@ -167,7 +167,7 @@ proc processParentBlockHash*(vmState: BaseVMState, prevHash: Hash32):
## processParentBlockHash stores the parent block hash in the ## processParentBlockHash stores the parent block hash in the
## history storage contract as per EIP-2935. ## history storage contract as per EIP-2935.
let let
statedb = vmState.stateDB ledger = vmState.ledger
call = CallParams( call = CallParams(
vmState : vmState, vmState : vmState,
sender : SYSTEM_ADDRESS, sender : SYSTEM_ADDRESS,
@ -189,14 +189,14 @@ proc processParentBlockHash*(vmState: BaseVMState, prevHash: Hash32):
if res.len > 0: if res.len > 0:
return err("processParentBlockHash: " & res) return err("processParentBlockHash: " & res)
statedb.persist(clearEmptyAccount = true) ledger.persist(clearEmptyAccount = true)
ok() ok()
proc processDequeueWithdrawalRequests*(vmState: BaseVMState): seq[byte] = proc processDequeueWithdrawalRequests*(vmState: BaseVMState): seq[byte] =
## processDequeueWithdrawalRequests applies the EIP-7002 system call ## processDequeueWithdrawalRequests applies the EIP-7002 system call
## to the withdrawal requests contract. ## to the withdrawal requests contract.
let let
statedb = vmState.stateDB ledger = vmState.ledger
call = CallParams( call = CallParams(
vmState : vmState, vmState : vmState,
sender : SYSTEM_ADDRESS, sender : SYSTEM_ADDRESS,
@ -214,13 +214,13 @@ proc processDequeueWithdrawalRequests*(vmState: BaseVMState): seq[byte] =
# runComputation a.k.a syscall/evm.call # runComputation a.k.a syscall/evm.call
result = call.runComputation(seq[byte]) result = call.runComputation(seq[byte])
statedb.persist(clearEmptyAccount = true) ledger.persist(clearEmptyAccount = true)
proc processDequeueConsolidationRequests*(vmState: BaseVMState): seq[byte] = proc processDequeueConsolidationRequests*(vmState: BaseVMState): seq[byte] =
## processDequeueConsolidationRequests applies the EIP-7251 system call ## processDequeueConsolidationRequests applies the EIP-7251 system call
## to the consolidation requests contract. ## to the consolidation requests contract.
let let
statedb = vmState.stateDB ledger = vmState.ledger
call = CallParams( call = CallParams(
vmState : vmState, vmState : vmState,
sender : SYSTEM_ADDRESS, sender : SYSTEM_ADDRESS,
@ -238,7 +238,7 @@ proc processDequeueConsolidationRequests*(vmState: BaseVMState): seq[byte] =
# runComputation a.k.a syscall/evm.call # runComputation a.k.a syscall/evm.call
result = call.runComputation(seq[byte]) result = call.runComputation(seq[byte])
statedb.persist(clearEmptyAccount = true) ledger.persist(clearEmptyAccount = true)
proc processTransaction*( proc processTransaction*(
vmState: BaseVMState; ## Parent accounts environment for transaction vmState: BaseVMState; ## Parent accounts environment for transaction

View File

@ -208,19 +208,19 @@ func excessBlobGas*(xp: TxPoolRef): GasInt =
xp.vmState.blockCtx.excessBlobGas xp.vmState.blockCtx.excessBlobGas
proc getBalance*(xp: TxPoolRef; account: Address): UInt256 = proc getBalance*(xp: TxPoolRef; account: Address): UInt256 =
## Wrapper around `vmState.readOnlyStateDB.getBalance()` for a `vmState` ## Wrapper around `vmState.readOnlyLedger.getBalance()` for a `vmState`
## descriptor positioned at the `dh.head`. This might differ from the ## descriptor positioned at the `dh.head`. This might differ from the
## `dh.vmState.readOnlyStateDB.getBalance()` which returnes the current ## `dh.vmState.readOnlyLedger.getBalance()` which returnes the current
## balance relative to what has been accumulated by the current packing ## balance relative to what has been accumulated by the current packing
## procedure. ## procedure.
xp.vmState.stateDB.getBalance(account) xp.vmState.ledger.getBalance(account)
proc getNonce*(xp: TxPoolRef; account: Address): AccountNonce = proc getNonce*(xp: TxPoolRef; account: Address): AccountNonce =
## Wrapper around `vmState.readOnlyStateDB.getNonce()` for a `vmState` ## Wrapper around `vmState.readOnlyLedger.getNonce()` for a `vmState`
## descriptor positioned at the `dh.head`. This might differ from the ## descriptor positioned at the `dh.head`. This might differ from the
## `dh.vmState.readOnlyStateDB.getNonce()` which returnes the current balance ## `dh.vmState.readOnlyLedger.getNonce()` which returnes the current balance
## relative to what has been accumulated by the current packing procedure. ## relative to what has been accumulated by the current packing procedure.
xp.vmState.stateDB.getNonce(account) xp.vmState.ledger.getNonce(account)
func head*(xp: TxPoolRef): Header = func head*(xp: TxPoolRef): Header =
## Getter, cached block chain insertion point. Typocally, this should be the ## Getter, cached block chain insertion point. Typocally, this should be the

View File

@ -69,7 +69,7 @@ proc persist(pst: var TxPacker)
let vmState = pst.vmState let vmState = pst.vmState
if not pst.cleanState: if not pst.cleanState:
let clearEmptyAccount = vmState.fork >= FkSpurious let clearEmptyAccount = vmState.fork >= FkSpurious
vmState.stateDB.persist(clearEmptyAccount) vmState.ledger.persist(clearEmptyAccount)
pst.cleanState = true pst.cleanState = true
proc classifyValidatePacked(vmState: BaseVMState; item: TxItemRef): bool = proc classifyValidatePacked(vmState: BaseVMState; item: TxItemRef): bool =
@ -77,7 +77,7 @@ proc classifyValidatePacked(vmState: BaseVMState; item: TxItemRef): bool =
## is a wrapper around the `verifyTransaction()` call to be used in a similar ## is a wrapper around the `verifyTransaction()` call to be used in a similar
## fashion as in `asyncProcessTransactionImpl()`. ## fashion as in `asyncProcessTransactionImpl()`.
let let
roDB = vmState.readOnlyStateDB roDB = vmState.readOnlyLedger
baseFee = vmState.blockCtx.baseFeePerGas.get(0.u256) baseFee = vmState.blockCtx.baseFeePerGas.get(0.u256)
fork = vmState.fork fork = vmState.fork
gasLimit = vmState.blockCtx.gasLimit gasLimit = vmState.blockCtx.gasLimit
@ -142,7 +142,7 @@ proc runTxCommit(pst: var TxPacker; item: TxItemRef; gasBurned: GasInt)
# are vetted for profitability before entering that bucket. # are vetted for profitability before entering that bucket.
assert 0 <= gasTip assert 0 <= gasTip
let reward = gasBurned.u256 * gasTip.u256 let reward = gasBurned.u256 * gasTip.u256
vmState.stateDB.addBalance(pst.feeRecipient, reward) vmState.ledger.addBalance(pst.feeRecipient, reward)
pst.blockValue += reward pst.blockValue += reward
# Save accounts via persist() is not needed unless the fork is smaller # Save accounts via persist() is not needed unless the fork is smaller
@ -236,23 +236,23 @@ proc vmExecGrabItem(pst: var TxPacker; item: TxItemRef): GrabResult
return ContinueWithNextAccount return ContinueWithNextAccount
# EIP-1153 # EIP-1153
vmState.stateDB.clearTransientStorage() vmState.ledger.clearTransientStorage()
let let
accTx = vmState.stateDB.beginSavepoint accTx = vmState.ledger.beginSavepoint
gasUsed = pst.runTx(item) # this is the crucial part, running the tx gasUsed = pst.runTx(item) # this is the crucial part, running the tx
# Find out what to do next: accepting this tx or trying the next account # Find out what to do next: accepting this tx or trying the next account
if not vmState.classifyPacked(gasUsed): if not vmState.classifyPacked(gasUsed):
vmState.stateDB.rollback(accTx) vmState.ledger.rollback(accTx)
if vmState.classifyPackedNext(): if vmState.classifyPackedNext():
return ContinueWithNextAccount return ContinueWithNextAccount
return StopCollecting return StopCollecting
# Commit account state DB # Commit account state DB
vmState.stateDB.commit(accTx) vmState.ledger.commit(accTx)
vmState.stateDB.persist(clearEmptyAccount = vmState.fork >= FkSpurious) vmState.ledger.persist(clearEmptyAccount = vmState.fork >= FkSpurious)
# Finish book-keeping and move item to `packed` bucket # Finish book-keeping and move item to `packed` bucket
pst.runTxCommit(item, gasUsed) pst.runTxCommit(item, gasUsed)
@ -262,12 +262,12 @@ proc vmExecGrabItem(pst: var TxPacker; item: TxItemRef): GrabResult
proc vmExecCommit(pst: var TxPacker): Result[void, string] = proc vmExecCommit(pst: var TxPacker): Result[void, string] =
let let
vmState = pst.vmState vmState = pst.vmState
stateDB = vmState.stateDB ledger = vmState.ledger
# EIP-4895 # EIP-4895
if vmState.fork >= FkShanghai: if vmState.fork >= FkShanghai:
for withdrawal in vmState.com.pos.withdrawals: for withdrawal in vmState.com.pos.withdrawals:
stateDB.addBalance(withdrawal.address, withdrawal.weiAmount) ledger.addBalance(withdrawal.address, withdrawal.weiAmount)
# EIP-6110, EIP-7002, EIP-7251 # EIP-6110, EIP-7002, EIP-7251
if vmState.fork >= FkPrague: if vmState.fork >= FkPrague:
@ -275,8 +275,8 @@ proc vmExecCommit(pst: var TxPacker): Result[void, string] =
pst.consolidationReqs = processDequeueConsolidationRequests(vmState) pst.consolidationReqs = processDequeueConsolidationRequests(vmState)
pst.depositReqs = ?parseDepositLogs(vmState.allLogs, vmState.com.depositContractAddress) pst.depositReqs = ?parseDepositLogs(vmState.allLogs, vmState.com.depositContractAddress)
# Finish up, then vmState.stateDB.stateRoot may be accessed # Finish up, then vmState.ledger.stateRoot may be accessed
stateDB.persist(clearEmptyAccount = vmState.fork >= FkSpurious) ledger.persist(clearEmptyAccount = vmState.fork >= FkSpurious)
# Update flexi-array, set proper length # Update flexi-array, set proper length
let nItems = pst.txDB.byStatus.eq(txItemPacked).nItems let nItems = pst.txDB.byStatus.eq(txItemPacked).nItems
@ -284,7 +284,7 @@ proc vmExecCommit(pst: var TxPacker): Result[void, string] =
pst.receiptsRoot = vmState.receipts.calcReceiptsRoot pst.receiptsRoot = vmState.receipts.calcReceiptsRoot
pst.logsBloom = vmState.receipts.createBloom pst.logsBloom = vmState.receipts.createBloom
pst.stateRoot = vmState.stateDB.getStateRoot() pst.stateRoot = vmState.ledger.getStateRoot()
ok() ok()
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------

View File

@ -285,7 +285,7 @@ proc validateTxBasic*(
ok() ok()
proc validateTransaction*( proc validateTransaction*(
roDB: ReadOnlyStateDB; ## Parent accounts environment for transaction roDB: ReadOnlyLedger; ## Parent accounts environment for transaction
tx: Transaction; ## tx to validate tx: Transaction; ## tx to validate
sender: Address; ## tx.recoverSender sender: Address; ## tx.recoverSender
maxLimit: GasInt; ## gasLimit from block header maxLimit: GasInt; ## gasLimit from block header

View File

@ -173,7 +173,7 @@ proc partPut*(
for n,key in chain: for n,key in chain:
var var
rvid: RootedVertexID rvid: RootedVertexID
(stopHere, vidFromStateDb) = (false,false) # not both `true` (stopHere, vidFromLedger) = (false,false) # not both `true`
# Parent might have been part of an earlier chain, already # Parent might have been part of an earlier chain, already
if n < chain.len - 1: if n < chain.len - 1:
@ -193,10 +193,10 @@ proc partPut*(
# Get vertex ID and set a flag whether it was seen on state lookup # Get vertex ID and set a flag whether it was seen on state lookup
if not rvid.isValid: if not rvid.isValid:
(rvid, vidFromStateDb) = ? ps.getRvid(root, key) (rvid, vidFromLedger) = ? ps.getRvid(root, key)
# Use from partial state database if possible # Use from partial state database if possible
if vidFromStateDb and not ps.isCore(key): if vidFromLedger and not ps.isCore(key):
let vtx = ps.db.getVtx rvid let vtx = ps.db.getVtx rvid
if vtx.isValid: if vtx.isValid:
# Register core node. Even though these nodes are only local to this # Register core node. Even though these nodes are only local to this

View File

@ -256,19 +256,19 @@ proc getRvid*(
ps: PartStateRef; ps: PartStateRef;
root: VertexID; root: VertexID;
key: HashKey; key: HashKey;
): Result[tuple[rvid: RootedVertexID, fromStateDb: bool],AristoError] = ): Result[tuple[rvid: RootedVertexID, fromLedger: bool],AristoError] =
## Find key in `ps[]` or create a new key. the value `onStateDb` is ## Find key in `ps[]` or create a new key. the value `onStateDb` is
## return `false` if a new entry was created. ## return `false` if a new entry was created.
## ##
var (rvid, fromStateDb) = (ps[key], true) var (rvid, fromLedger) = (ps[key], true)
if not rvid.isValid: if not rvid.isValid:
# Create new one # Create new one
(rvid, fromStateDb) = ((root, ps.db.vidFetch()), false) (rvid, fromLedger) = ((root, ps.db.vidFetch()), false)
ps[key] = rvid ps[key] = rvid
elif root != rvid.root: elif root != rvid.root:
# Oops # Oops
return err(PartRootVidsDontMatch) return err(PartRootVidsDontMatch)
ok((rvid, fromStateDb)) ok((rvid, fromLedger))
proc updateAccountsTree*( proc updateAccountsTree*(

View File

@ -90,7 +90,7 @@ type
## over and over again to the database to avoid the WAL and compation ## over and over again to the database to avoid the WAL and compation
## write amplification that ensues ## write amplification that ensues
ReadOnlyStateDB* = distinct LedgerRef ReadOnlyLedger* = distinct LedgerRef
TransactionState = enum TransactionState = enum
Pending Pending
@ -936,29 +936,29 @@ proc getStorageProof*(ac: LedgerRef, address: Address, slots: openArray[UInt256]
# Public virtual read-only methods # Public virtual read-only methods
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
proc getStateRoot*(db: ReadOnlyStateDB): Hash32 {.borrow.} proc getStateRoot*(db: ReadOnlyLedger): Hash32 {.borrow.}
proc getCodeHash*(db: ReadOnlyStateDB, address: Address): Hash32 = getCodeHash(distinctBase db, address) proc getCodeHash*(db: ReadOnlyLedger, address: Address): Hash32 = getCodeHash(distinctBase db, address)
proc getStorageRoot*(db: ReadOnlyStateDB, address: Address): Hash32 = getStorageRoot(distinctBase db, address) proc getStorageRoot*(db: ReadOnlyLedger, address: Address): Hash32 = getStorageRoot(distinctBase db, address)
proc getBalance*(db: ReadOnlyStateDB, address: Address): UInt256 = getBalance(distinctBase db, address) proc getBalance*(db: ReadOnlyLedger, address: Address): UInt256 = getBalance(distinctBase db, address)
proc getStorage*(db: ReadOnlyStateDB, address: Address, slot: UInt256): UInt256 = getStorage(distinctBase db, address, slot) proc getStorage*(db: ReadOnlyLedger, address: Address, slot: UInt256): UInt256 = getStorage(distinctBase db, address, slot)
proc getNonce*(db: ReadOnlyStateDB, address: Address): AccountNonce = getNonce(distinctBase db, address) proc getNonce*(db: ReadOnlyLedger, address: Address): AccountNonce = getNonce(distinctBase db, address)
proc getCode*(db: ReadOnlyStateDB, address: Address): CodeBytesRef = getCode(distinctBase db, address) proc getCode*(db: ReadOnlyLedger, address: Address): CodeBytesRef = getCode(distinctBase db, address)
proc getCodeSize*(db: ReadOnlyStateDB, address: Address): int = getCodeSize(distinctBase db, address) proc getCodeSize*(db: ReadOnlyLedger, address: Address): int = getCodeSize(distinctBase db, address)
proc contractCollision*(db: ReadOnlyStateDB, address: Address): bool = contractCollision(distinctBase db, address) proc contractCollision*(db: ReadOnlyLedger, address: Address): bool = contractCollision(distinctBase db, address)
proc accountExists*(db: ReadOnlyStateDB, address: Address): bool = accountExists(distinctBase db, address) proc accountExists*(db: ReadOnlyLedger, address: Address): bool = accountExists(distinctBase db, address)
proc isDeadAccount*(db: ReadOnlyStateDB, address: Address): bool = isDeadAccount(distinctBase db, address) proc isDeadAccount*(db: ReadOnlyLedger, address: Address): bool = isDeadAccount(distinctBase db, address)
proc isEmptyAccount*(db: ReadOnlyStateDB, address: Address): bool = isEmptyAccount(distinctBase db, address) proc isEmptyAccount*(db: ReadOnlyLedger, address: Address): bool = isEmptyAccount(distinctBase db, address)
proc getCommittedStorage*(db: ReadOnlyStateDB, address: Address, slot: UInt256): UInt256 = getCommittedStorage(distinctBase db, address, slot) proc getCommittedStorage*(db: ReadOnlyLedger, address: Address, slot: UInt256): UInt256 = getCommittedStorage(distinctBase db, address, slot)
proc inAccessList*(db: ReadOnlyStateDB, address: Address): bool = inAccessList(distinctBase db, address) proc inAccessList*(db: ReadOnlyLedger, address: Address): bool = inAccessList(distinctBase db, address)
proc inAccessList*(db: ReadOnlyStateDB, address: Address, slot: UInt256): bool = inAccessList(distinctBase db, address) proc inAccessList*(db: ReadOnlyLedger, address: Address, slot: UInt256): bool = inAccessList(distinctBase db, address)
proc getTransientStorage*(db: ReadOnlyStateDB, proc getTransientStorage*(db: ReadOnlyLedger,
address: Address, slot: UInt256): UInt256 = getTransientStorage(distinctBase db, address, slot) address: Address, slot: UInt256): UInt256 = getTransientStorage(distinctBase db, address, slot)
proc getAccountProof*(db: ReadOnlyStateDB, address: Address): seq[seq[byte]] = getAccountProof(distinctBase db, address) proc getAccountProof*(db: ReadOnlyLedger, address: Address): seq[seq[byte]] = getAccountProof(distinctBase db, address)
proc getStorageProof*(db: ReadOnlyStateDB, address: Address, slots: openArray[UInt256]): seq[seq[seq[byte]]] = getStorageProof(distinctBase db, address, slots) proc getStorageProof*(db: ReadOnlyLedger, address: Address, slots: openArray[UInt256]): seq[seq[seq[byte]]] = getStorageProof(distinctBase db, address, slots)
proc resolveCodeHash*(db: ReadOnlyStateDB, address: Address): Hash32 = resolveCodeHash(distinctBase db, address) proc resolveCodeHash*(db: ReadOnlyLedger, address: Address): Hash32 = resolveCodeHash(distinctBase db, address)
proc resolveCode*(db: ReadOnlyStateDB, address: Address): CodeBytesRef = resolveCode(distinctBase db, address) proc resolveCode*(db: ReadOnlyLedger, address: Address): CodeBytesRef = resolveCode(distinctBase db, address)
proc resolveCodeSize*(db: ReadOnlyStateDB, address: Address): int = resolveCodeSize(distinctBase db, address) proc resolveCodeSize*(db: ReadOnlyLedger, address: Address): int = resolveCodeSize(distinctBase db, address)
proc getDelegateAddress*(db: ReadOnlyStateDB, address: Address): Address = getDelegateAddress(distinctBase db, address) proc getDelegateAddress*(db: ReadOnlyLedger, address: Address): Address = getDelegateAddress(distinctBase db, address)
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
# End # End

View File

@ -154,34 +154,34 @@ template accountExists*(c: Computation, address: Address): bool =
c.host.accountExists(address) c.host.accountExists(address)
else: else:
if c.fork >= FkSpurious: if c.fork >= FkSpurious:
not c.vmState.readOnlyStateDB.isDeadAccount(address) not c.vmState.readOnlyLedger.isDeadAccount(address)
else: else:
c.vmState.readOnlyStateDB.accountExists(address) c.vmState.readOnlyLedger.accountExists(address)
template getStorage*(c: Computation, slot: UInt256): UInt256 = template getStorage*(c: Computation, slot: UInt256): UInt256 =
when evmc_enabled: when evmc_enabled:
c.host.getStorage(c.msg.contractAddress, slot) c.host.getStorage(c.msg.contractAddress, slot)
else: else:
c.vmState.readOnlyStateDB.getStorage(c.msg.contractAddress, slot) c.vmState.readOnlyLedger.getStorage(c.msg.contractAddress, slot)
template getBalance*(c: Computation, address: Address): UInt256 = template getBalance*(c: Computation, address: Address): UInt256 =
when evmc_enabled: when evmc_enabled:
c.host.getBalance(address) c.host.getBalance(address)
else: else:
c.vmState.readOnlyStateDB.getBalance(address) c.vmState.readOnlyLedger.getBalance(address)
template getCodeSize*(c: Computation, address: Address): uint = template getCodeSize*(c: Computation, address: Address): uint =
when evmc_enabled: when evmc_enabled:
c.host.getCodeSize(address) c.host.getCodeSize(address)
else: else:
uint(c.vmState.readOnlyStateDB.getCodeSize(address)) uint(c.vmState.readOnlyLedger.getCodeSize(address))
template getCodeHash*(c: Computation, address: Address): Hash32 = template getCodeHash*(c: Computation, address: Address): Hash32 =
when evmc_enabled: when evmc_enabled:
c.host.getCodeHash(address) c.host.getCodeHash(address)
else: else:
let let
db = c.vmState.readOnlyStateDB db = c.vmState.readOnlyLedger
if not db.accountExists(address) or db.isEmptyAccount(address): if not db.accountExists(address) or db.isEmptyAccount(address):
default(Hash32) default(Hash32)
else: else:
@ -197,20 +197,20 @@ template getCode*(c: Computation, address: Address): CodeBytesRef =
when evmc_enabled: when evmc_enabled:
CodeBytesRef.init(c.host.copyCode(address)) CodeBytesRef.init(c.host.copyCode(address))
else: else:
c.vmState.readOnlyStateDB.getCode(address) c.vmState.readOnlyLedger.getCode(address)
template setTransientStorage*(c: Computation, slot, val: UInt256) = template setTransientStorage*(c: Computation, slot, val: UInt256) =
when evmc_enabled: when evmc_enabled:
c.host.setTransientStorage(c.msg.contractAddress, slot, val) c.host.setTransientStorage(c.msg.contractAddress, slot, val)
else: else:
c.vmState.stateDB. c.vmState.ledger.
setTransientStorage(c.msg.contractAddress, slot, val) setTransientStorage(c.msg.contractAddress, slot, val)
template getTransientStorage*(c: Computation, slot: UInt256): UInt256 = template getTransientStorage*(c: Computation, slot: UInt256): UInt256 =
when evmc_enabled: when evmc_enabled:
c.host.getTransientStorage(c.msg.contractAddress, slot) c.host.getTransientStorage(c.msg.contractAddress, slot)
else: else:
c.vmState.readOnlyStateDB. c.vmState.readOnlyLedger.
getTransientStorage(c.msg.contractAddress, slot) getTransientStorage(c.msg.contractAddress, slot)
template resolveCodeSize*(c: Computation, address: Address): uint = template resolveCodeSize*(c: Computation, address: Address): uint =
@ -221,7 +221,7 @@ template resolveCodeSize*(c: Computation, address: Address): uint =
else: else:
c.host.getCodeSize(delegateTo) c.host.getCodeSize(delegateTo)
else: else:
uint(c.vmState.readOnlyStateDB.resolveCodeSize(address)) uint(c.vmState.readOnlyLedger.resolveCodeSize(address))
template resolveCodeHash*(c: Computation, address: Address): Hash32= template resolveCodeHash*(c: Computation, address: Address): Hash32=
when evmc_enabled: when evmc_enabled:
@ -232,7 +232,7 @@ template resolveCodeHash*(c: Computation, address: Address): Hash32=
c.host.getCodeHash(delegateTo) c.host.getCodeHash(delegateTo)
else: else:
let let
db = c.vmState.readOnlyStateDB db = c.vmState.readOnlyLedger
if not db.accountExists(address) or db.isEmptyAccount(address): if not db.accountExists(address) or db.isEmptyAccount(address):
default(Hash32) default(Hash32)
else: else:
@ -246,7 +246,7 @@ template resolveCode*(c: Computation, address: Address): CodeBytesRef =
else: else:
CodeBytesRef.init(c.host.copyCode(delegateTo)) CodeBytesRef.init(c.host.copyCode(delegateTo))
else: else:
c.vmState.readOnlyStateDB.resolveCode(address) c.vmState.readOnlyLedger.resolveCode(address)
func newComputation*(vmState: BaseVMState, func newComputation*(vmState: BaseVMState,
keepStack: bool, keepStack: bool,
@ -279,13 +279,13 @@ func shouldBurnGas*(c: Computation): bool =
c.isError and c.error.burnsGas c.isError and c.error.burnsGas
proc snapshot*(c: Computation) = proc snapshot*(c: Computation) =
c.savePoint = c.vmState.stateDB.beginSavepoint() c.savePoint = c.vmState.ledger.beginSavepoint()
proc commit*(c: Computation) = proc commit*(c: Computation) =
c.vmState.stateDB.commit(c.savePoint) c.vmState.ledger.commit(c.savePoint)
proc dispose*(c: Computation) = proc dispose*(c: Computation) =
c.vmState.stateDB.safeDispose(c.savePoint) c.vmState.ledger.safeDispose(c.savePoint)
if c.stack != nil: if c.stack != nil:
if c.keepStack: if c.keepStack:
c.finalStack = toSeq(c.stack.items()) c.finalStack = toSeq(c.stack.items())
@ -295,7 +295,7 @@ proc dispose*(c: Computation) =
c.savePoint = nil c.savePoint = nil
proc rollback*(c: Computation) = proc rollback*(c: Computation) =
c.vmState.stateDB.rollback(c.savePoint) c.vmState.ledger.rollback(c.savePoint)
func setError*(c: Computation, msg: sink string, burnsGas = false) = func setError*(c: Computation, msg: sink string, burnsGas = false) =
c.error = Error(evmcStatus: EVMC_FAILURE, info: move(msg), burnsGas: burnsGas) c.error = Error(evmcStatus: EVMC_FAILURE, info: move(msg), burnsGas: burnsGas)
@ -361,7 +361,7 @@ proc writeContract*(c: Computation) =
c.gasMeter.consumeGas(codeCost, c.gasMeter.consumeGas(codeCost,
reason = "Write new contract code"). reason = "Write new contract code").
expect("enough gas since we checked against gasRemaining") expect("enough gas since we checked against gasRemaining")
c.vmState.mutateStateDB: c.vmState.mutateLedger:
db.setCode(c.msg.contractAddress, c.output) db.setCode(c.msg.contractAddress, c.output)
withExtra trace, "Writing new contract code" withExtra trace, "Writing new contract code"
return return
@ -387,7 +387,7 @@ template chainTo*(c: Computation,
after after
proc execSelfDestruct*(c: Computation, beneficiary: Address) = proc execSelfDestruct*(c: Computation, beneficiary: Address) =
c.vmState.mutateStateDB: c.vmState.mutateLedger:
let localBalance = c.getBalance(c.msg.contractAddress) let localBalance = c.getBalance(c.msg.contractAddress)
# Register the account to be deleted # Register the account to be deleted
@ -412,7 +412,7 @@ proc execSelfDestruct*(c: Computation, beneficiary: Address) =
# Using `proc` as `addLogEntry()` might be `proc` in logging mode # Using `proc` as `addLogEntry()` might be `proc` in logging mode
proc addLogEntry*(c: Computation, log: Log) = proc addLogEntry*(c: Computation, log: Log) =
c.vmState.stateDB.addLogEntry(log) c.vmState.ledger.addLogEntry(log)
# some gasRefunded operations still relying # some gasRefunded operations still relying
# on negative number # on negative number
@ -432,7 +432,7 @@ func addRefund*(c: Computation, amount: int64) =
# Using `proc` as `selfDestructLen()` might be `proc` in logging mode # Using `proc` as `selfDestructLen()` might be `proc` in logging mode
proc refundSelfDestruct*(c: Computation) = proc refundSelfDestruct*(c: Computation) =
let cost = gasFees[c.fork][RefundSelfDestruct] let cost = gasFees[c.fork][RefundSelfDestruct]
let num = c.vmState.stateDB.selfDestructLen let num = c.vmState.ledger.selfDestructLen
c.gasMeter.refundGas(cost * num) c.gasMeter.refundGas(cost * num)
func tracingEnabled*(c: Computation): bool = func tracingEnabled*(c: Computation): bool =

View File

@ -68,7 +68,7 @@ proc gasCallEIP2929(c: Computation, address: Address): GasInt =
if c.host.accessAccount(address) == EVMC_ACCESS_COLD: if c.host.accessAccount(address) == EVMC_ACCESS_COLD:
return ColdAccountAccessCost - WarmStorageReadCost return ColdAccountAccessCost - WarmStorageReadCost
else: else:
c.vmState.mutateStateDB: c.vmState.mutateLedger:
if not db.inAccessList(address): if not db.inAccessList(address):
db.accessList(address) db.accessList(address)

View File

@ -42,7 +42,7 @@ proc gasEip2929AccountCheck*(c: Computation; address: Address): GasInt =
else: else:
WarmStorageReadCost WarmStorageReadCost
else: else:
c.vmState.mutateStateDB: c.vmState.mutateLedger:
result = if not db.inAccessList(address): result = if not db.inAccessList(address):
db.accessList(address) db.accessList(address)
ColdAccountAccessCost ColdAccountAccessCost
@ -56,7 +56,7 @@ proc gasEip2929AccountCheck*(c: Computation; address: Address, slot: UInt256): G
else: else:
WarmStorageReadCost WarmStorageReadCost
else: else:
c.vmState.mutateStateDB: c.vmState.mutateLedger:
result = if not db.inAccessList(address, slot): result = if not db.inAccessList(address, slot):
db.accessList(address, slot) db.accessList(address, slot)
ColdSloadCost ColdSloadCost
@ -79,7 +79,7 @@ proc delegateResolutionCost*(c: Computation, address: Address): GasInt =
else: else:
WarmStorageReadCost WarmStorageReadCost
else: else:
c.vmState.mutateStateDB: c.vmState.mutateLedger:
if not db.inAccessList(address): if not db.inAccessList(address):
db.accessList(address) db.accessList(address)
return ColdAccountAccessCost return ColdAccountAccessCost
@ -90,7 +90,7 @@ proc gasEip7702CodeCheck*(c: Computation; address: Address): GasInt =
let code = when defined(evmc_enabled): let code = when defined(evmc_enabled):
CodeBytesRef.init(c.host.copyCode(address)) CodeBytesRef.init(c.host.copyCode(address))
else: else:
c.vmState.readOnlyStateDB.getCode(address) c.vmState.readOnlyLedger.getCode(address)
let delegateTo = parseDelegationAddress(code).valueOr: let delegateTo = parseDelegationAddress(code).valueOr:
return 0 return 0
c.delegateResolutionCost(delegateTo) c.delegateResolutionCost(delegateTo)

View File

@ -61,19 +61,19 @@ else:
? c.opcodeGasCost(Sstore, res.gasCost, "SSTORE") ? c.opcodeGasCost(Sstore, res.gasCost, "SSTORE")
c.gasMeter.refundGas(res.gasRefund) c.gasMeter.refundGas(res.gasRefund)
c.vmState.mutateStateDB: c.vmState.mutateLedger:
db.setStorage(c.msg.contractAddress, slot, newValue) db.setStorage(c.msg.contractAddress, slot, newValue)
ok() ok()
proc sstoreNetGasMeteringImpl(c: Computation; slot, newValue: UInt256, coldAccess = 0.GasInt): EvmResultVoid = proc sstoreNetGasMeteringImpl(c: Computation; slot, newValue: UInt256, coldAccess = 0.GasInt): EvmResultVoid =
let let
stateDB = c.vmState.readOnlyStateDB ledger = c.vmState.readOnlyLedger
currentValue = c.getStorage(slot) currentValue = c.getStorage(slot)
gasParam = GasParamsSs( gasParam = GasParamsSs(
currentValue: currentValue, currentValue: currentValue,
originalValue: stateDB.getCommittedStorage(c.msg.contractAddress, slot)) originalValue: ledger.getCommittedStorage(c.msg.contractAddress, slot))
res = c.gasCosts[Sstore].ss_handler(newValue, gasParam) res = c.gasCosts[Sstore].ss_handler(newValue, gasParam)
@ -81,7 +81,7 @@ else:
c.gasMeter.refundGas(res.gasRefund) c.gasMeter.refundGas(res.gasRefund)
c.vmState.mutateStateDB: c.vmState.mutateLedger:
db.setStorage(c.msg.contractAddress, slot, newValue) db.setStorage(c.msg.contractAddress, slot, newValue)
ok() ok()
@ -249,7 +249,7 @@ proc sstoreEIP2929Op(cpt: VmCpt): EvmResultVoid =
if cpt.host.accessStorage(cpt.msg.contractAddress, slot) == EVMC_ACCESS_COLD: if cpt.host.accessStorage(cpt.msg.contractAddress, slot) == EVMC_ACCESS_COLD:
coldAccessGas = ColdSloadCost coldAccessGas = ColdSloadCost
else: else:
cpt.vmState.mutateStateDB: cpt.vmState.mutateLedger:
if not db.inAccessList(cpt.msg.contractAddress, slot): if not db.inAccessList(cpt.msg.contractAddress, slot):
db.accessList(cpt.msg.contractAddress, slot) db.accessList(cpt.msg.contractAddress, slot)
coldAccessGas = ColdSloadCost coldAccessGas = ColdSloadCost

View File

@ -131,7 +131,7 @@ proc selfDestructEIP2929Op(cpt: VmCpt): EvmResultVoid =
if cpt.host.accessAccount(beneficiary) == EVMC_ACCESS_COLD: if cpt.host.accessAccount(beneficiary) == EVMC_ACCESS_COLD:
gasCost = gasCost + ColdAccountAccessCost gasCost = gasCost + ColdAccountAccessCost
else: else:
cpt.vmState.mutateStateDB: cpt.vmState.mutateLedger:
if not db.inAccessList(beneficiary): if not db.inAccessList(beneficiary):
db.accessList(beneficiary) db.accessList(beneficiary)
gasCost = gasCost + ColdAccountAccessCost gasCost = gasCost + ColdAccountAccessCost

View File

@ -68,7 +68,7 @@ macro selectVM(v: VmCpt, fork: EVMFork, tracingEnabled: bool): EvmResultVoid =
proc beforeExecCall(c: Computation) = proc beforeExecCall(c: Computation) =
c.snapshot() c.snapshot()
if c.msg.kind == EVMC_CALL: if c.msg.kind == EVMC_CALL:
c.vmState.mutateStateDB: c.vmState.mutateLedger:
db.subBalance(c.msg.sender, c.msg.value) db.subBalance(c.msg.sender, c.msg.value)
db.addBalance(c.msg.contractAddress, c.msg.value) db.addBalance(c.msg.contractAddress, c.msg.value)
@ -80,7 +80,7 @@ proc afterExecCall(c: Computation) =
if c.isError or c.fork >= FkByzantium: if c.isError or c.fork >= FkByzantium:
if c.msg.contractAddress == RIPEMD_ADDR: if c.msg.contractAddress == RIPEMD_ADDR:
# Special case to account for geth+parity bug # Special case to account for geth+parity bug
c.vmState.stateDB.ripemdSpecial() c.vmState.ledger.ripemdSpecial()
if c.isSuccess: if c.isSuccess:
c.commit() c.commit()
@ -88,7 +88,7 @@ proc afterExecCall(c: Computation) =
c.rollback() c.rollback()
proc beforeExecCreate(c: Computation): bool = proc beforeExecCreate(c: Computation): bool =
c.vmState.mutateStateDB: c.vmState.mutateLedger:
let nonce = db.getNonce(c.msg.sender) let nonce = db.getNonce(c.msg.sender)
if nonce + 1 < nonce: if nonce + 1 < nonce:
let sender = c.msg.sender.toHex let sender = c.msg.sender.toHex
@ -106,13 +106,13 @@ proc beforeExecCreate(c: Computation): bool =
c.snapshot() c.snapshot()
if c.vmState.readOnlyStateDB().contractCollision(c.msg.contractAddress): if c.vmState.readOnlyLedger().contractCollision(c.msg.contractAddress):
let blurb = c.msg.contractAddress.toHex let blurb = c.msg.contractAddress.toHex
c.setError("Address collision when creating contract address=" & blurb, true) c.setError("Address collision when creating contract address=" & blurb, true)
c.rollback() c.rollback()
return true return true
c.vmState.mutateStateDB: c.vmState.mutateLedger:
db.subBalance(c.msg.sender, c.msg.value) db.subBalance(c.msg.sender, c.msg.value)
db.addBalance(c.msg.contractAddress, c.msg.value) db.addBalance(c.msg.contractAddress, c.msg.value)
db.clearStorage(c.msg.contractAddress) db.clearStorage(c.msg.contractAddress)

View File

@ -26,7 +26,7 @@ proc generateContractAddress*(vmState: BaseVMState,
salt = ZERO_CONTRACTSALT, salt = ZERO_CONTRACTSALT,
code = CodeBytesRef(nil)): Address = code = CodeBytesRef(nil)): Address =
if kind == EVMC_CREATE: if kind == EVMC_CREATE:
let creationNonce = vmState.readOnlyStateDB().getNonce(sender) let creationNonce = vmState.readOnlyLedger().getNonce(sender)
generateAddress(sender, creationNonce) generateAddress(sender, creationNonce)
else: else:
generateSafeAddress(sender, salt, code.bytes) generateSafeAddress(sender, salt, code.bytes)
@ -37,6 +37,6 @@ proc getCallCode*(vmState: BaseVMState, codeAddress: Address): CodeBytesRef =
return CodeBytesRef(nil) return CodeBytesRef(nil)
if vmState.fork >= FkPrague: if vmState.fork >= FkPrague:
vmState.readOnlyStateDB.resolveCode(codeAddress) vmState.readOnlyLedger.resolveCode(codeAddress)
else: else:
vmState.readOnlyStateDB.getCode(codeAddress) vmState.readOnlyLedger.getCode(codeAddress)

View File

@ -36,7 +36,7 @@ proc init(
## Initialisation helper ## Initialisation helper
# Take care to (re)set all fields since the VMState might be recycled # Take care to (re)set all fields since the VMState might be recycled
self.com = com self.com = com
self.stateDB = ac self.ledger = ac
self.gasPool = blockCtx.gasLimit self.gasPool = blockCtx.gasLimit
assign(self.parent, parent) assign(self.parent, parent)
assign(self.blockCtx, blockCtx) assign(self.blockCtx, blockCtx)
@ -110,15 +110,15 @@ proc reinit*(self: BaseVMState; ## Object descriptor
## queries about its `getStateRoot()`, i.e. `isTopLevelClean` evaluated `true`. If ## queries about its `getStateRoot()`, i.e. `isTopLevelClean` evaluated `true`. If
## this function returns `false`, the function argument `self` is left ## this function returns `false`, the function argument `self` is left
## untouched. ## untouched.
if not self.stateDB.isTopLevelClean: if not self.ledger.isTopLevelClean:
return false return false
let let
tracer = self.tracer tracer = self.tracer
com = self.com com = self.com
db = com.db db = com.db
ac = if linear or self.stateDB.getStateRoot() == parent.stateRoot: self.stateDB ac = if linear or self.ledger.getStateRoot() == parent.stateRoot: self.ledger
else: LedgerRef.init(db, self.stateDB.storeSlotHash) else: LedgerRef.init(db, self.ledger.storeSlotHash)
flags = self.flags flags = self.flags
self.init( self.init(
ac = ac, ac = ac,
@ -257,16 +257,16 @@ method getAncestorHash*(
return default(Hash32) return default(Hash32)
blockHash blockHash
proc readOnlyStateDB*(vmState: BaseVMState): ReadOnlyStateDB {.inline.} = proc readOnlyLedger*(vmState: BaseVMState): ReadOnlyLedger {.inline.} =
ReadOnlyStateDB(vmState.stateDB) ReadOnlyLedger(vmState.ledger)
template mutateStateDB*(vmState: BaseVMState, body: untyped) = template mutateLedger*(vmState: BaseVMState, body: untyped) =
block: block:
var db {.inject.} = vmState.stateDB var db {.inject.} = vmState.ledger
body body
proc getAndClearLogEntries*(vmState: BaseVMState): seq[Log] = proc getAndClearLogEntries*(vmState: BaseVMState): seq[Log] =
vmState.stateDB.getAndClearLogEntries() vmState.ledger.getAndClearLogEntries()
proc status*(vmState: BaseVMState): bool = proc status*(vmState: BaseVMState): bool =
ExecutionOK in vmState.flags ExecutionOK in vmState.flags

View File

@ -105,9 +105,9 @@ proc captureOpImpl(ctx: JsonTracer, c: Computation, pc: int,
if TracerFlags.DisableStorage notin ctx.flags: if TracerFlags.DisableStorage notin ctx.flags:
var storage = newJObject() var storage = newJObject()
if c.msg.depth < ctx.storageKeys.len: if c.msg.depth < ctx.storageKeys.len:
var stateDB = c.vmState.stateDB var ledger = c.vmState.ledger
for key in ctx.storage(c.msg.depth): for key in ctx.storage(c.msg.depth):
let value = stateDB.getStorage(c.msg.contractAddress, key) let value = ledger.getStorage(c.msg.contractAddress, key)
storage[key.encodeHex] = %(value.encodeHex) storage[key.encodeHex] = %(value.encodeHex)
res["storage"] = storage res["storage"] = storage

View File

@ -135,9 +135,9 @@ method captureOpEnd*(ctx: LegacyTracer, c: Computation,
if TracerFlags.DisableStorage notin ctx.flags: if TracerFlags.DisableStorage notin ctx.flags:
var storage = newJObject() var storage = newJObject()
if c.msg.depth < ctx.storageKeys.len: if c.msg.depth < ctx.storageKeys.len:
var stateDB = c.vmState.stateDB var ledger = c.vmState.ledger
for key in ctx.storage(c.msg.depth): for key in ctx.storage(c.msg.depth):
let value = stateDB.getStorage(c.msg.contractAddress, key) let value = ledger.getStorage(c.msg.contractAddress, key)
storage[key.dumpHex] = %(value.dumpHex) storage[key.dumpHex] = %(value.dumpHex)
j["storage"] = storage j["storage"] = storage

View File

@ -58,7 +58,7 @@ type
BaseVMState* = ref object of RootObj BaseVMState* = ref object of RootObj
com* : CommonRef com* : CommonRef
stateDB* : LedgerRef ledger* : LedgerRef
gasPool* : GasInt gasPool* : GasInt
parent* : Header parent* : Header
blockCtx* : BlockContext blockCtx* : BlockContext

View File

@ -148,7 +148,7 @@ proc wdNode(ctx: GraphqlContextRef, wd: Withdrawal): Node =
wd: wd wd: wd
) )
proc getStateDB(com: CommonRef, header: Header): LedgerRef {.deprecated: "LedgerRef does not support loading a particular state".} = proc getLedger(com: CommonRef, header: Header): LedgerRef {.deprecated: "LedgerRef does not support loading a particular state".} =
## Retrieves the account db from canonical head ## Retrieves the account db from canonical head
## we don't use accounst_cache here because it's read only operations ## we don't use accounst_cache here because it's read only operations
# TODO the ledger initialized here refers to the base, not the given header! # TODO the ledger initialized here refers to the base, not the given header!
@ -322,7 +322,7 @@ proc getTxByHash(ctx: GraphqlContextRef, hash: Hash32): RespResult =
proc accountNode(ctx: GraphqlContextRef, header: Header, address: Address): RespResult = proc accountNode(ctx: GraphqlContextRef, header: Header, address: Address): RespResult =
try: try:
let db = getStateDB(ctx.com, header) let db = getLedger(ctx.com, header)
when false: when false:
# EIP 1767 unclear about non existent account # EIP 1767 unclear about non existent account
# but hive test case demand something # but hive test case demand something

View File

@ -261,7 +261,7 @@ proc createAccessList*(header: Header,
fork = com.toEVMFork(forkDeterminationInfo(header.number, header.timestamp)) fork = com.toEVMFork(forkDeterminationInfo(header.number, header.timestamp))
sender = args.sender sender = args.sender
# TODO: nonce should be retrieved from txPool # TODO: nonce should be retrieved from txPool
nonce = vmState.stateDB.getNonce(sender) nonce = vmState.ledger.getNonce(sender)
to = if args.to.isSome: args.to.get to = if args.to.isSome: args.to.get
else: generateAddress(sender, nonce) else: generateAddress(sender, nonce)
precompiles = activePrecompilesList(fork) precompiles = activePrecompilesList(fork)

View File

@ -169,7 +169,7 @@ proc traceTransactionImpl(
tracerInst = newLegacyTracer(tracerFlags) tracerInst = newLegacyTracer(tracerFlags)
cc = activate CaptCtxRef.init(com, header) cc = activate CaptCtxRef.init(com, header)
vmState = BaseVMState.new(header, com, storeSlotHash = true).valueOr: return newJNull() vmState = BaseVMState.new(header, com, storeSlotHash = true).valueOr: return newJNull()
stateDb = vmState.stateDB ledger = vmState.ledger
defer: cc.release() defer: cc.release()
@ -192,25 +192,25 @@ proc traceTransactionImpl(
if idx.uint64 == txIndex: if idx.uint64 == txIndex:
vmState.tracer = tracerInst # only enable tracer on target tx vmState.tracer = tracerInst # only enable tracer on target tx
before.captureAccount(stateDb, sender, senderName) before.captureAccount(ledger, sender, senderName)
before.captureAccount(stateDb, recipient, recipientName) before.captureAccount(ledger, recipient, recipientName)
before.captureAccount(stateDb, miner, minerName) before.captureAccount(ledger, miner, minerName)
stateDb.persist() ledger.persist()
stateDiff["beforeRoot"] = %(stateDb.getStateRoot().toHex) stateDiff["beforeRoot"] = %(ledger.getStateRoot().toHex)
discard com.db.ctx.getAccounts.getStateRoot() # lazy hashing! discard com.db.ctx.getAccounts.getStateRoot() # lazy hashing!
stateCtx = CaptCtxRef.init(com, stateDb.getStateRoot()) stateCtx = CaptCtxRef.init(com, ledger.getStateRoot())
let rc = vmState.processTransaction(tx, sender, header) let rc = vmState.processTransaction(tx, sender, header)
gasUsed = if rc.isOk: rc.value else: 0 gasUsed = if rc.isOk: rc.value else: 0
if idx.uint64 == txIndex: if idx.uint64 == txIndex:
discard com.db.ctx.getAccounts.getStateRoot() # lazy hashing! discard com.db.ctx.getAccounts.getStateRoot() # lazy hashing!
after.captureAccount(stateDb, sender, senderName) after.captureAccount(ledger, sender, senderName)
after.captureAccount(stateDb, recipient, recipientName) after.captureAccount(ledger, recipient, recipientName)
after.captureAccount(stateDb, miner, minerName) after.captureAccount(ledger, miner, minerName)
tracerInst.removeTracedAccounts(sender, recipient, miner) tracerInst.removeTracedAccounts(sender, recipient, miner)
stateDb.persist() ledger.persist()
stateDiff["afterRoot"] = %(stateDb.getStateRoot().toHex) stateDiff["afterRoot"] = %(ledger.getStateRoot().toHex)
break break
# internal transactions: # internal transactions:
@ -223,7 +223,7 @@ proc traceTransactionImpl(
before.captureAccount(ldgBefore, acc, internalTxName & $idx) before.captureAccount(ldgBefore, acc, internalTxName & $idx)
for idx, acc in tracedAccountsPairs(tracerInst): for idx, acc in tracedAccountsPairs(tracerInst):
after.captureAccount(stateDb, acc, internalTxName & $idx) after.captureAccount(ledger, acc, internalTxName & $idx)
result = tracerInst.getTracingResult() result = tracerInst.getTracingResult()
result["gas"] = %gasUsed result["gas"] = %gasUsed
@ -273,7 +273,7 @@ proc dumpBlockStateImpl(
discard vmState.processBlock(blk) discard vmState.processBlock(blk)
var stateAfter = vmState.stateDB var stateAfter = vmState.ledger
for idx, tx in blk.transactions: for idx, tx in blk.transactions:
let sender = tx.recoverSender().expect("valid signature") let sender = tx.recoverSender().expect("valid signature")

View File

@ -53,7 +53,7 @@ proc initialAccessListEIP2929(call: CallParams) =
if vmState.fork < FkBerlin: if vmState.fork < FkBerlin:
return return
vmState.mutateStateDB: vmState.mutateLedger:
db.accessList(call.sender) db.accessList(call.sender)
# For contract creations the EVM will add the contract address to the # For contract creations the EVM will add the contract address to the
# access list itself, after calculating the new contract address. # access list itself, after calculating the new contract address.
@ -80,7 +80,7 @@ proc initialAccessListEIP2929(call: CallParams) =
proc preExecComputation(vmState: BaseVMState, call: CallParams): int64 = proc preExecComputation(vmState: BaseVMState, call: CallParams): int64 =
var gasRefund = 0 var gasRefund = 0
let ledger = vmState.stateDB let ledger = vmState.ledger
if not call.isCreate: if not call.isCreate:
ledger.incNonce(call.sender) ledger.incNonce(call.sender)
@ -225,7 +225,7 @@ proc prepareToRunComputation(host: TransactionHost, call: CallParams) =
vmState = host.vmState vmState = host.vmState
fork = vmState.fork fork = vmState.fork
vmState.mutateStateDB: vmState.mutateLedger:
db.subBalance(call.sender, call.gasLimit.u256 * call.gasPrice.u256) db.subBalance(call.sender, call.gasLimit.u256 * call.gasPrice.u256)
# EIP-4844 # EIP-4844
@ -256,7 +256,7 @@ proc calculateAndPossiblyRefundGas(host: TransactionHost, call: CallParams): Gas
# Refund for unused gas. # Refund for unused gas.
if result > 0 and not call.noGasCharge: if result > 0 and not call.noGasCharge:
host.vmState.mutateStateDB: host.vmState.mutateLedger:
db.addBalance(call.sender, result.u256 * call.gasPrice.u256) db.addBalance(call.sender, result.u256 * call.gasPrice.u256)
proc finishRunningComputation( proc finishRunningComputation(

View File

@ -96,7 +96,7 @@ proc rpcEstimateGas*(args: TransactionArgs,
if args.source.isNone: if args.source.isNone:
return err(evmErr(EvmInvalidParam)) return err(evmErr(EvmInvalidParam))
let balance = vmState.readOnlyStateDB.getBalance(args.source.get) let balance = vmState.readOnlyLedger.getBalance(args.source.get)
var available = balance var available = balance
if args.value.isSome: if args.value.isSome:
let value = args.value.get let value = args.value.get

View File

@ -114,27 +114,27 @@ when use_evmc_glue:
proc accountExists(host: TransactionHost, address: HostAddress): bool {.show.} = proc accountExists(host: TransactionHost, address: HostAddress): bool {.show.} =
if host.vmState.fork >= FkSpurious: if host.vmState.fork >= FkSpurious:
not host.vmState.readOnlyStateDB.isDeadAccount(address) not host.vmState.readOnlyLedger.isDeadAccount(address)
else: else:
host.vmState.readOnlyStateDB.accountExists(address) host.vmState.readOnlyLedger.accountExists(address)
# TODO: Why is `address` an argument in `getStorage`, `setStorage` and # TODO: Why is `address` an argument in `getStorage`, `setStorage` and
# `selfDestruct`, if an EVM is only allowed to do these things to its own # `selfDestruct`, if an EVM is only allowed to do these things to its own
# contract account and the host always knows which account? # contract account and the host always knows which account?
proc getStorage(host: TransactionHost, address: HostAddress, key: HostKey): HostValue {.show.} = proc getStorage(host: TransactionHost, address: HostAddress, key: HostKey): HostValue {.show.} =
host.vmState.readOnlyStateDB.getStorage(address, key) host.vmState.readOnlyLedger.getStorage(address, key)
proc setStorage(host: TransactionHost, address: HostAddress, proc setStorage(host: TransactionHost, address: HostAddress,
key: HostKey, newVal: HostValue): EvmcStorageStatus {.show.} = key: HostKey, newVal: HostValue): EvmcStorageStatus {.show.} =
let let
db = host.vmState.readOnlyStateDB db = host.vmState.readOnlyLedger
currentVal = db.getStorage(address, key) currentVal = db.getStorage(address, key)
if currentVal == newVal: if currentVal == newVal:
return EVMC_STORAGE_ASSIGNED return EVMC_STORAGE_ASSIGNED
host.vmState.mutateStateDB: host.vmState.mutateLedger:
db.setStorage(address, key, newVal) db.setStorage(address, key, newVal)
# https://eips.ethereum.org/EIPS/eip-1283 # https://eips.ethereum.org/EIPS/eip-1283
@ -174,15 +174,15 @@ proc setStorage(host: TransactionHost, address: HostAddress,
return EVMC_STORAGE_ASSIGNED return EVMC_STORAGE_ASSIGNED
proc getBalance(host: TransactionHost, address: HostAddress): HostBalance {.show.} = proc getBalance(host: TransactionHost, address: HostAddress): HostBalance {.show.} =
host.vmState.readOnlyStateDB.getBalance(address) host.vmState.readOnlyLedger.getBalance(address)
proc getCodeSize(host: TransactionHost, address: HostAddress): HostSize {.show.} = proc getCodeSize(host: TransactionHost, address: HostAddress): HostSize {.show.} =
# TODO: Check this `HostSize`, it was copied as `uint` from other code. # TODO: Check this `HostSize`, it was copied as `uint` from other code.
# Note: Old `evmc_host` uses `getCode(address).len` instead. # Note: Old `evmc_host` uses `getCode(address).len` instead.
host.vmState.readOnlyStateDB.getCodeSize(address).HostSize host.vmState.readOnlyLedger.getCodeSize(address).HostSize
proc getCodeHash(host: TransactionHost, address: HostAddress): HostHash {.show.} = proc getCodeHash(host: TransactionHost, address: HostAddress): HostHash {.show.} =
let db = host.vmState.readOnlyStateDB let db = host.vmState.readOnlyLedger
# TODO: Copied from `Computation`, but check if that code is wrong with # TODO: Copied from `Computation`, but check if that code is wrong with
# `FkSpurious`, as it has different calls from `accountExists` above. # `FkSpurious`, as it has different calls from `accountExists` above.
if not db.accountExists(address) or db.isEmptyAccount(address): if not db.accountExists(address) or db.isEmptyAccount(address):
@ -205,7 +205,7 @@ proc copyCode(host: TransactionHost, address: HostAddress,
# #
# Note, when there is no code, `getCode` result is empty `seq`. It was `nil` # Note, when there is no code, `getCode` result is empty `seq`. It was `nil`
# when the DB was first implemented, due to Nim language changes since then. # when the DB was first implemented, due to Nim language changes since then.
let code = host.vmState.readOnlyStateDB.getCode(address) let code = host.vmState.readOnlyLedger.getCode(address)
var safe_len: int = code.len # It's safe to assume >= 0. var safe_len: int = code.len # It's safe to assume >= 0.
if code_offset >= safe_len.HostSize: if code_offset >= safe_len.HostSize:
@ -221,7 +221,7 @@ proc copyCode(host: TransactionHost, address: HostAddress,
return safe_len.HostSize return safe_len.HostSize
proc selfDestruct(host: TransactionHost, address, beneficiary: HostAddress) {.show.} = proc selfDestruct(host: TransactionHost, address, beneficiary: HostAddress) {.show.} =
host.vmState.mutateStateDB: host.vmState.mutateLedger:
let localBalance = db.getBalance(address) let localBalance = db.getBalance(address)
if host.vmState.fork >= FkCancun: if host.vmState.fork >= FkCancun:
@ -274,10 +274,10 @@ proc emitLog(host: TransactionHost, address: HostAddress,
copyMem(log.data[0].addr, data, data_size.int) copyMem(log.data[0].addr, data, data_size.int)
log.address = address log.address = address
host.vmState.stateDB.addLogEntry(log) host.vmState.ledger.addLogEntry(log)
proc accessAccount(host: TransactionHost, address: HostAddress): EvmcAccessStatus {.show.} = proc accessAccount(host: TransactionHost, address: HostAddress): EvmcAccessStatus {.show.} =
host.vmState.mutateStateDB: host.vmState.mutateLedger:
if not db.inAccessList(address): if not db.inAccessList(address):
db.accessList(address) db.accessList(address)
return EVMC_ACCESS_COLD return EVMC_ACCESS_COLD
@ -286,7 +286,7 @@ proc accessAccount(host: TransactionHost, address: HostAddress): EvmcAccessStatu
proc accessStorage(host: TransactionHost, address: HostAddress, proc accessStorage(host: TransactionHost, address: HostAddress,
key: HostKey): EvmcAccessStatus {.show.} = key: HostKey): EvmcAccessStatus {.show.} =
host.vmState.mutateStateDB: host.vmState.mutateLedger:
if not db.inAccessList(address, key): if not db.inAccessList(address, key):
db.accessList(address, key) db.accessList(address, key)
return EVMC_ACCESS_COLD return EVMC_ACCESS_COLD
@ -295,15 +295,15 @@ proc accessStorage(host: TransactionHost, address: HostAddress,
proc getTransientStorage(host: TransactionHost, proc getTransientStorage(host: TransactionHost,
address: HostAddress, key: HostKey): HostValue {.show.} = address: HostAddress, key: HostKey): HostValue {.show.} =
host.vmState.readOnlyStateDB.getTransientStorage(address, key) host.vmState.readOnlyLedger.getTransientStorage(address, key)
proc setTransientStorage(host: TransactionHost, address: HostAddress, proc setTransientStorage(host: TransactionHost, address: HostAddress,
key: HostKey, newVal: HostValue) {.show.} = key: HostKey, newVal: HostValue) {.show.} =
host.vmState.mutateStateDB: host.vmState.mutateLedger:
db.setTransientStorage(address, key, newVal) db.setTransientStorage(address, key, newVal)
proc getDelegateAddress(host: TransactionHost, address: HostAddress): HostAddress {.show.} = proc getDelegateAddress(host: TransactionHost, address: HostAddress): HostAddress {.show.} =
let db = host.vmState.readOnlyStateDB let db = host.vmState.readOnlyLedger
db.getDelegateAddress(address) db.getDelegateAddress(address)
when use_evmc_glue: when use_evmc_glue:

View File

@ -61,23 +61,23 @@ proc debug*(h: Header): string =
result.add "blockHash : " & $blockHash(h) & "\n" result.add "blockHash : " & $blockHash(h) & "\n"
proc dumpAccounts*(vmState: BaseVMState): JsonNode = proc dumpAccounts*(vmState: BaseVMState): JsonNode =
%dumpAccounts(vmState.stateDB) %dumpAccounts(vmState.ledger)
proc debugAccounts*(stateDB: LedgerRef, addresses: openArray[string]): string = proc debugAccounts*(ledger: LedgerRef, addresses: openArray[string]): string =
var accountList = newSeq[Address]() var accountList = newSeq[Address]()
for address in addresses: for address in addresses:
accountList.add Address.fromHex(address) accountList.add Address.fromHex(address)
(%dumpAccounts(stateDB, accountList)).pretty (%dumpAccounts(ledger, accountList)).pretty
proc debugAccounts*(vmState: BaseVMState): string = proc debugAccounts*(vmState: BaseVMState): string =
var accountList = newSeq[Address]() var accountList = newSeq[Address]()
for address in vmState.stateDB.addresses: for address in vmState.ledger.addresses:
accountList.add address accountList.add address
let res = %{ let res = %{
"stateRoot": %($vmState.readOnlyStateDB.getStateRoot()), "stateRoot": %($vmState.readOnlyLedger.getStateRoot()),
"accounts": %dumpAccounts(vmState.stateDB, accountList), "accounts": %dumpAccounts(vmState.ledger, accountList),
} }
res.pretty res.pretty
@ -94,7 +94,7 @@ proc debug*(vms: BaseVMState): string =
result.add "excessBlobGas : " & $vms.blockCtx.excessBlobGas & "\n" result.add "excessBlobGas : " & $vms.blockCtx.excessBlobGas & "\n"
result.add "flags : " & $vms.flags & "\n" result.add "flags : " & $vms.flags & "\n"
result.add "receipts.len : " & $vms.receipts.len & "\n" result.add "receipts.len : " & $vms.receipts.len & "\n"
result.add "stateDB.root : " & $vms.stateDB.getStateRoot() & "\n" result.add "ledger.root : " & $vms.ledger.getStateRoot() & "\n"
result.add "cumulativeGasUsed: " & $vms.cumulativeGasUsed & "\n" result.add "cumulativeGasUsed: " & $vms.cumulativeGasUsed & "\n"
result.add "tx.origin : " & $vms.txCtx.origin & "\n" result.add "tx.origin : " & $vms.txCtx.origin & "\n"
result.add "tx.gasPrice : " & $vms.txCtx.gasPrice & "\n" result.add "tx.gasPrice : " & $vms.txCtx.gasPrice & "\n"

View File

@ -91,8 +91,8 @@ proc dumpState*(db: LedgerRef): StateDump =
accounts: dumpAccounts(db) accounts: dumpAccounts(db)
) )
proc dumpAccounts*(stateDB: LedgerRef, addresses: openArray[Address]): JsonNode = proc dumpAccounts*(ledger: LedgerRef, addresses: openArray[Address]): JsonNode =
result = newJObject() result = newJObject()
for ac in addresses: for ac in addresses:
result[ac.toHex] = %dumpAccount(stateDB, ac) result[ac.toHex] = %dumpAccount(ledger, ac)

View File

@ -322,8 +322,8 @@ proc verifyAsmResult(vmState: BaseVMState, boa: Assembler, asmResult: DebugCallR
error "different memory value", idx=i, expected=mem, actual=actual error "different memory value", idx=i, expected=mem, actual=actual
return false return false
var stateDB = vmState.stateDB var ledger = vmState.ledger
stateDB.persist() ledger.persist()
let let
al = com.db.ctx.getAccounts() al = com.db.ctx.getAccounts()
@ -392,7 +392,7 @@ proc createSignedTx(payload: seq[byte], chainId: ChainId): Transaction =
proc runVM*(vmState: BaseVMState, boa: Assembler): bool = proc runVM*(vmState: BaseVMState, boa: Assembler): bool =
let let
com = vmState.com com = vmState.com
vmState.mutateStateDB: vmState.mutateLedger:
db.setCode(codeAddress, boa.code) db.setCode(codeAddress, boa.code)
db.setBalance(codeAddress, 1_000_000.u256) db.setBalance(codeAddress, 1_000_000.u256)
let tx = createSignedTx(boa.data, com.chainId) let tx = createSignedTx(boa.data, com.chainId)

View File

@ -67,12 +67,12 @@ proc executeCase(node: JsonNode): bool =
let let
env = parseEnv(node) env = parseEnv(node)
memDB = newCoreDbRef DefaultDbMemory memDB = newCoreDbRef DefaultDbMemory
stateDB = LedgerRef.init(memDB) ledger = LedgerRef.init(memDB)
config = getChainConfig(env.network) config = getChainConfig(env.network)
com = CommonRef.new(memDB, nil, config) com = CommonRef.new(memDB, nil, config)
setupStateDB(env.pre, stateDB) setupLedger(env.pre, ledger)
stateDB.persist() ledger.persist()
com.db.persistHeaderAndSetHead(env.genesisHeader).isOkOr: com.db.persistHeaderAndSetHead(env.genesisHeader).isOkOr:
debugEcho "Failed to put genesis header into database: ", error debugEcho "Failed to put genesis header into database: ", error

View File

@ -357,7 +357,7 @@ proc runTestOverflow() =
com, com,
) )
s.stateDB.setCode(codeAddress, @data) s.ledger.setCode(codeAddress, @data)
let unsignedTx = Transaction( let unsignedTx = Transaction(
txType: TxLegacy, txType: TxLegacy,
nonce: 0, nonce: 0,

View File

@ -103,8 +103,8 @@ proc testFixtureIndexes(ctx: var TestCtx, testStatusIMPL: var TestStatus) =
var gasUsed: GasInt var gasUsed: GasInt
let sender = ctx.tx.recoverSender().expect("valid signature") let sender = ctx.tx.recoverSender().expect("valid signature")
vmState.mutateStateDB: vmState.mutateLedger:
setupStateDB(ctx.pre, db) setupLedger(ctx.pre, db)
# this is an important step when using `db/ledger` # this is an important step when using `db/ledger`
# it will affect the account storage's location # it will affect the account storage's location
@ -120,7 +120,7 @@ proc testFixtureIndexes(ctx: var TestCtx, testStatusIMPL: var TestStatus) =
coinbaseStateClearing(vmState, miner) coinbaseStateClearing(vmState, miner)
block post: block post:
let obtainedHash = vmState.readOnlyStateDB.getStateRoot() let obtainedHash = vmState.readOnlyLedger.getStateRoot()
check obtainedHash == ctx.expectedHash check obtainedHash == ctx.expectedHash
let logEntries = vmState.getAndClearLogEntries() let logEntries = vmState.getAndClearLogEntries()
let actualLogsHash = rlpHash(logEntries) let actualLogsHash = rlpHash(logEntries)

View File

@ -57,19 +57,19 @@ proc getGenesisAlloc(filePath: string): GenesisAlloc =
cn.genesis.alloc cn.genesis.alloc
proc setupStateDB(genAccounts: GenesisAlloc, stateDB: LedgerRef): Hash32 = proc setupLedger(genAccounts: GenesisAlloc, ledger: LedgerRef): Hash32 =
for address, genAccount in genAccounts: for address, genAccount in genAccounts:
for slotKey, slotValue in genAccount.storage: for slotKey, slotValue in genAccount.storage:
stateDB.setStorage(address, slotKey, slotValue) ledger.setStorage(address, slotKey, slotValue)
stateDB.setNonce(address, genAccount.nonce) ledger.setNonce(address, genAccount.nonce)
stateDB.setCode(address, genAccount.code) ledger.setCode(address, genAccount.code)
stateDB.setBalance(address, genAccount.balance) ledger.setBalance(address, genAccount.balance)
stateDB.persist() ledger.persist()
stateDB.getStateRoot() ledger.getStateRoot()
proc checkProofsForExistingLeafs( proc checkProofsForExistingLeafs(
genAccounts: GenesisAlloc, genAccounts: GenesisAlloc,
@ -129,8 +129,8 @@ proc getProofJsonMain*() =
let let
accounts = getGenesisAlloc("tests" / "customgenesis" / file) accounts = getGenesisAlloc("tests" / "customgenesis" / file)
coreDb = newCoreDbRef(DefaultDbMemory) coreDb = newCoreDbRef(DefaultDbMemory)
accountsCache = LedgerRef.init(coreDb) ledger = LedgerRef.init(coreDb)
stateRootHash = setupStateDB(accounts, accountsCache) stateRootHash = setupLedger(accounts, ledger)
accountDb = LedgerRef.init(coreDb) accountDb = LedgerRef.init(coreDb)
checkProofsForExistingLeafs(accounts, accountDb, stateRootHash) checkProofsForExistingLeafs(accounts, accountDb, stateRootHash)
@ -141,8 +141,8 @@ proc getProofJsonMain*() =
let let
accounts = getGenesisAlloc("tests" / "customgenesis" / file) accounts = getGenesisAlloc("tests" / "customgenesis" / file)
coreDb = newCoreDbRef(DefaultDbMemory) coreDb = newCoreDbRef(DefaultDbMemory)
accountsCache = LedgerRef.init(coreDb) ledger = LedgerRef.init(coreDb)
stateRootHash = setupStateDB(accounts, accountsCache) stateRootHash = setupLedger(accounts, ledger)
accountDb = LedgerRef.init(coreDb) accountDb = LedgerRef.init(coreDb)
checkProofsForMissingLeafs(accounts, accountDb, stateRootHash) checkProofsForMissingLeafs(accounts, accountDb, stateRootHash)

View File

@ -107,7 +107,7 @@ func getHexadecimalInt*(j: JsonNode): int64 =
data = fromHex(StUint[64], j.getStr) data = fromHex(StUint[64], j.getStr)
result = cast[int64](data) result = cast[int64](data)
proc verifyStateDB*(wantedState: JsonNode, stateDB: ReadOnlyStateDB) = proc verifyLedger*(wantedState: JsonNode, ledger: ReadOnlyLedger) =
for ac, accountData in wantedState: for ac, accountData in wantedState:
let account = EthAddress.fromHex(ac) let account = EthAddress.fromHex(ac)
for slot, value in accountData{"storage"}: for slot, value in accountData{"storage"}:
@ -115,7 +115,7 @@ proc verifyStateDB*(wantedState: JsonNode, stateDB: ReadOnlyStateDB) =
slotId = UInt256.fromHex slot slotId = UInt256.fromHex slot
wantedValue = UInt256.fromHex value.getStr wantedValue = UInt256.fromHex value.getStr
let actualValue = stateDB.getStorage(account, slotId) let actualValue = ledger.getStorage(account, slotId)
#if not found: #if not found:
# raise newException(ValidationError, "account not found: " & ac) # raise newException(ValidationError, "account not found: " & ac)
if actualValue != wantedValue: if actualValue != wantedValue:
@ -126,9 +126,9 @@ proc verifyStateDB*(wantedState: JsonNode, stateDB: ReadOnlyStateDB) =
wantedBalance = UInt256.fromHex accountData{"balance"}.getStr wantedBalance = UInt256.fromHex accountData{"balance"}.getStr
wantedNonce = accountData{"nonce"}.getHexadecimalInt.AccountNonce wantedNonce = accountData{"nonce"}.getHexadecimalInt.AccountNonce
actualCode = stateDB.getCode(account).bytes() actualCode = ledger.getCode(account).bytes()
actualBalance = stateDB.getBalance(account) actualBalance = ledger.getBalance(account)
actualNonce = stateDB.getNonce(account) actualNonce = ledger.getNonce(account)
if wantedCode != actualCode: if wantedCode != actualCode:
raise newException(ValidationError, &"{ac} codeDiff {wantedCode.toHex} != {actualCode.toHex}") raise newException(ValidationError, &"{ac} codeDiff {wantedCode.toHex} != {actualCode.toHex}")

View File

@ -391,31 +391,31 @@ proc runLedgerBasicOperationsTests() =
var var
memDB = newCoreDbRef DefaultDbMemory memDB = newCoreDbRef DefaultDbMemory
stateDB {.used.} = LedgerRef.init(memDB) ledger {.used.} = LedgerRef.init(memDB)
address {.used.} = address"0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" address {.used.} = address"0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6"
code {.used.} = hexToSeqByte("0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6") code {.used.} = hexToSeqByte("0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6")
stateRoot {.used.} : Hash32 stateRoot {.used.} : Hash32
test "accountExists and isDeadAccount": test "accountExists and isDeadAccount":
check stateDB.accountExists(address) == false check ledger.accountExists(address) == false
check stateDB.isDeadAccount(address) == true check ledger.isDeadAccount(address) == true
stateDB.setBalance(address, 1000.u256) ledger.setBalance(address, 1000.u256)
check stateDB.accountExists(address) == true check ledger.accountExists(address) == true
check stateDB.isDeadAccount(address) == false check ledger.isDeadAccount(address) == false
stateDB.setBalance(address, 0.u256) ledger.setBalance(address, 0.u256)
stateDB.setNonce(address, 1) ledger.setNonce(address, 1)
check stateDB.isDeadAccount(address) == false check ledger.isDeadAccount(address) == false
stateDB.setCode(address, code) ledger.setCode(address, code)
stateDB.setNonce(address, 0) ledger.setNonce(address, 0)
check stateDB.isDeadAccount(address) == false check ledger.isDeadAccount(address) == false
stateDB.setCode(address, newSeq[byte]()) ledger.setCode(address, newSeq[byte]())
check stateDB.isDeadAccount(address) == true check ledger.isDeadAccount(address) == true
check stateDB.accountExists(address) == true check ledger.accountExists(address) == true
test "clone storage": test "clone storage":
# give access to private fields of AccountRef # give access to private fields of AccountRef

View File

@ -213,7 +213,7 @@ proc opEnvMain*() =
assembler: # EXTCODECOPY OP assembler: # EXTCODECOPY OP
title: "EXTCODECOPY_1" title: "EXTCODECOPY_1"
setup: setup:
vmState.mutateStateDB: vmState.mutateLedger:
db.setCode(acc, code) db.setCode(acc, code)
code: code:
Push1 "0x04" # size Push1 "0x04" # size
@ -231,7 +231,7 @@ proc opEnvMain*() =
assembler: # EXTCODECOPY OP assembler: # EXTCODECOPY OP
title: "EXTCODECOPY_2" title: "EXTCODECOPY_2"
setup: setup:
vmState.mutateStateDB: vmState.mutateLedger:
db.setCode(acc, code) db.setCode(acc, code)
code: code:
Push1 "0x3E" Push1 "0x3E"
@ -251,7 +251,7 @@ proc opEnvMain*() =
assembler: # EXTCODECOPY OP assembler: # EXTCODECOPY OP
title: "EXTCODECOPY_3" title: "EXTCODECOPY_3"
setup: setup:
vmState.mutateStateDB: vmState.mutateLedger:
db.setCode(acc, code) db.setCode(acc, code)
code: code:
Push1 "0x5E" Push1 "0x5E"
@ -272,7 +272,7 @@ proc opEnvMain*() =
assembler: # EXTCODECOPY OP assembler: # EXTCODECOPY OP
title: "EXTCODECOPY_4" title: "EXTCODECOPY_4"
setup: setup:
vmState.mutateStateDB: vmState.mutateLedger:
db.setCode(acc, code) db.setCode(acc, code)
code: code:
Push2 "0x1234" Push2 "0x1234"
@ -327,7 +327,7 @@ proc opEnvMain*() =
assembler: # EXTCODESIZE OP assembler: # EXTCODESIZE OP
title: "EXTCODESIZE_1" title: "EXTCODESIZE_1"
setup: setup:
vmState.mutateStateDB: vmState.mutateLedger:
db.setCode(acc, code) db.setCode(acc, code)
code: code:
Push20 "0xfbe0afcd7658ba86be41922059dd879c192d4c73" Push20 "0xfbe0afcd7658ba86be41922059dd879c192d4c73"
@ -342,7 +342,7 @@ proc opEnvMain*() =
assembler: # EIP2929 EXTCODESIZE OP assembler: # EIP2929 EXTCODESIZE OP
title: "EIP2929 EXTCODESIZE_1" title: "EIP2929 EXTCODESIZE_1"
setup: setup:
vmState.mutateStateDB: vmState.mutateLedger:
db.setCode(acc, code) db.setCode(acc, code)
code: code:
Push20 "0xfbe0afcd7658ba86be41922059dd879c192d4c73" Push20 "0xfbe0afcd7658ba86be41922059dd879c192d4c73"
@ -355,7 +355,7 @@ proc opEnvMain*() =
assembler: # EIP2929 EXTCODEHASH OP assembler: # EIP2929 EXTCODEHASH OP
title: "EIP2929 EXTCODEHASH_1" title: "EIP2929 EXTCODEHASH_1"
setup: setup:
vmState.mutateStateDB: vmState.mutateLedger:
db.setCode(acc, code) db.setCode(acc, code)
code: code:
Push20 "0xfbe0afcd7658ba86be41922059dd879c192d4c73" Push20 "0xfbe0afcd7658ba86be41922059dd879c192d4c73"

View File

@ -110,24 +110,24 @@ proc setupEnv(signer, ks2: Address, ctx: EthContext, com: CommonRef): TestEnv =
vmState = BaseVMState() vmState = BaseVMState()
vmState.init(parent, vmHeader, com) vmState.init(parent, vmHeader, com)
vmState.stateDB.setCode(ks2, code) vmState.ledger.setCode(ks2, code)
vmState.stateDB.addBalance( vmState.ledger.addBalance(
signer, 1.u256 * 1_000_000_000.u256 * 1_000_000_000.u256) # 1 ETH signer, 1.u256 * 1_000_000_000.u256 * 1_000_000_000.u256) # 1 ETH
# Test data created for eth_getProof tests # Test data created for eth_getProof tests
let regularAcc = address"0x0000000000000000000000000000000000000001" let regularAcc = address"0x0000000000000000000000000000000000000001"
vmState.stateDB.addBalance(regularAcc, 2_000_000_000.u256) vmState.ledger.addBalance(regularAcc, 2_000_000_000.u256)
vmState.stateDB.setNonce(regularAcc, 1.uint64) vmState.ledger.setNonce(regularAcc, 1.uint64)
let contractAccWithStorage = address"0x0000000000000000000000000000000000000002" let contractAccWithStorage = address"0x0000000000000000000000000000000000000002"
vmState.stateDB.addBalance(contractAccWithStorage, 1_000_000_000.u256) vmState.ledger.addBalance(contractAccWithStorage, 1_000_000_000.u256)
vmState.stateDB.setNonce(contractAccWithStorage, 2.uint64) vmState.ledger.setNonce(contractAccWithStorage, 2.uint64)
vmState.stateDB.setCode(contractAccWithStorage, code) vmState.ledger.setCode(contractAccWithStorage, code)
vmState.stateDB.setStorage(contractAccWithStorage, u256(0), u256(1234)) vmState.ledger.setStorage(contractAccWithStorage, u256(0), u256(1234))
vmState.stateDB.setStorage(contractAccWithStorage, u256(1), u256(2345)) vmState.ledger.setStorage(contractAccWithStorage, u256(1), u256(2345))
let contractAccNoStorage = address"0x0000000000000000000000000000000000000003" let contractAccNoStorage = address"0x0000000000000000000000000000000000000003"
vmState.stateDB.setCode(contractAccNoStorage, code) vmState.ledger.setCode(contractAccNoStorage, code)
let let
@ -174,11 +174,11 @@ proc setupEnv(signer, ks2: Address, ctx: EthContext, com: CommonRef): TestEnv =
difficulty = com.calcDifficulty(timeStamp, parent) difficulty = com.calcDifficulty(timeStamp, parent)
# call persist() before we get the stateRoot # call persist() before we get the stateRoot
vmState.stateDB.persist() vmState.ledger.persist()
var header = Header( var header = Header(
parentHash : parentHash, parentHash : parentHash,
stateRoot : vmState.stateDB.getStateRoot, stateRoot : vmState.ledger.getStateRoot,
transactionsRoot: txRoot, transactionsRoot: txRoot,
receiptsRoot : calcReceiptsRoot(vmState.receipts), receiptsRoot : calcReceiptsRoot(vmState.receipts),
logsBloom : createBloom(vmState.receipts), logsBloom : createBloom(vmState.receipts),

View File

@ -26,7 +26,7 @@ proc coinbaseStateClearing*(vmState: BaseVMState,
# as well as conditionally cleaning up the coinbase account when left # as well as conditionally cleaning up the coinbase account when left
# empty in VMs after the state clearing rules came into effect. # empty in VMs after the state clearing rules came into effect.
vmState.mutateStateDB: vmState.mutateLedger:
if touched: if touched:
db.addBalance(miner, 0.u256) db.addBalance(miner, 0.u256)

View File

@ -122,12 +122,12 @@ proc runExecution(ctx: var StateContext, conf: StateConf, pre: JsonNode): StateR
var gasUsed: GasInt var gasUsed: GasInt
let sender = ctx.tx.recoverSender().expect("valid signature") let sender = ctx.tx.recoverSender().expect("valid signature")
vmState.mutateStateDB: vmState.mutateLedger:
setupStateDB(pre, db) setupLedger(pre, db)
db.persist(clearEmptyAccount = false) # settle accounts storage db.persist(clearEmptyAccount = false) # settle accounts storage
defer: defer:
let stateRoot = vmState.readOnlyStateDB.getStateRoot() let stateRoot = vmState.readOnlyLedger.getStateRoot()
ctx.verifyResult(vmState, stateRoot) ctx.verifyResult(vmState, stateRoot)
result = StateResult( result = StateResult(
name : ctx.name, name : ctx.name,
@ -137,7 +137,7 @@ proc runExecution(ctx: var StateContext, conf: StateConf, pre: JsonNode): StateR
error: ctx.error error: ctx.error
) )
if conf.dumpEnabled: if conf.dumpEnabled:
result.state = dumpState(vmState.stateDB) result.state = dumpState(vmState.ledger)
if conf.jsonEnabled: if conf.jsonEnabled:
writeRootHashToStderr(stateRoot) writeRootHashToStderr(stateRoot)

View File

@ -177,15 +177,15 @@ proc parseTx*(txData, index: JsonNode): Transaction =
valIndex = index["value"].getInt valIndex = index["value"].getInt
parseTx(txData, dataIndex, gasIndex, valIndex) parseTx(txData, dataIndex, gasIndex, valIndex)
proc setupStateDB*(wantedState: JsonNode, stateDB: LedgerRef) = proc setupLedger*(wantedState: JsonNode, ledger: LedgerRef) =
for ac, accountData in wantedState: for ac, accountData in wantedState:
let account = Address.fromHex(ac) let account = Address.fromHex(ac)
for slot, value in accountData{"storage"}: for slot, value in accountData{"storage"}:
stateDB.setStorage(account, fromHex(UInt256, slot), fromHex(UInt256, value.getStr)) ledger.setStorage(account, fromHex(UInt256, slot), fromHex(UInt256, value.getStr))
stateDB.setNonce(account, fromJson(AccountNonce, accountData["nonce"])) ledger.setNonce(account, fromJson(AccountNonce, accountData["nonce"]))
stateDB.setCode(account, fromJson(seq[byte], accountData["code"])) ledger.setCode(account, fromJson(seq[byte], accountData["code"]))
stateDB.setBalance(account, fromJson(UInt256, accountData["balance"])) ledger.setBalance(account, fromJson(UInt256, accountData["balance"]))
iterator postState*(node: JsonNode): (Address, GenesisAccount) = iterator postState*(node: JsonNode): (Address, GenesisAccount) =
for ac, accountData in node: for ac, accountData in node:

View File

@ -228,7 +228,7 @@ proc exec(ctx: TransContext,
if vmState.com.daoForkSupport and if vmState.com.daoForkSupport and
vmState.com.daoForkBlock.get == vmState.blockNumber: vmState.com.daoForkBlock.get == vmState.blockNumber:
vmState.mutateStateDB: vmState.mutateLedger:
db.applyDAOHardFork() db.applyDAOHardFork()
vmState.receipts = newSeqOfCap[Receipt](ctx.txList.len) vmState.receipts = newSeqOfCap[Receipt](ctx.txList.len)
@ -303,16 +303,16 @@ proc exec(ctx: TransContext,
var uncleReward = 8.u256 - uncle.delta.u256 var uncleReward = 8.u256 - uncle.delta.u256
uncleReward = uncleReward * blockReward uncleReward = uncleReward * blockReward
uncleReward = uncleReward div 8.u256 uncleReward = uncleReward div 8.u256
vmState.mutateStateDB: vmState.mutateLedger:
db.addBalance(uncle.address, uncleReward) db.addBalance(uncle.address, uncleReward)
mainReward += blockReward div 32.u256 mainReward += blockReward div 32.u256
vmState.mutateStateDB: vmState.mutateLedger:
db.addBalance(ctx.env.currentCoinbase, mainReward) db.addBalance(ctx.env.currentCoinbase, mainReward)
if ctx.env.withdrawals.isSome: if ctx.env.withdrawals.isSome:
for withdrawal in ctx.env.withdrawals.get: for withdrawal in ctx.env.withdrawals.get:
vmState.stateDB.addBalance(withdrawal.address, withdrawal.weiAmount) vmState.ledger.addBalance(withdrawal.address, withdrawal.weiAmount)
let miner = ctx.env.currentCoinbase let miner = ctx.env.currentCoinbase
coinbaseStateClearing(vmState, miner, stateReward.isSome()) coinbaseStateClearing(vmState, miner, stateReward.isSome())
@ -326,10 +326,10 @@ proc exec(ctx: TransContext,
withdrawalReqs = processDequeueWithdrawalRequests(vmState) withdrawalReqs = processDequeueWithdrawalRequests(vmState)
consolidationReqs = processDequeueConsolidationRequests(vmState) consolidationReqs = processDequeueConsolidationRequests(vmState)
let stateDB = vmState.stateDB let ledger = vmState.ledger
stateDB.postState(result.alloc) ledger.postState(result.alloc)
result.result = ExecutionResult( result.result = ExecutionResult(
stateRoot : stateDB.getStateRoot(), stateRoot : ledger.getStateRoot(),
txRoot : includedTx.calcTxRoot, txRoot : includedTx.calcTxRoot,
receiptsRoot: calcReceiptsRoot(vmState.receipts), receiptsRoot: calcReceiptsRoot(vmState.receipts),
logsHash : calcLogsHash(vmState.receipts), logsHash : calcLogsHash(vmState.receipts),
@ -389,14 +389,14 @@ template wrapException(body: untyped) =
else: else:
body body
proc setupAlloc(stateDB: LedgerRef, alloc: GenesisAlloc) = proc setupAlloc(ledger: LedgerRef, alloc: GenesisAlloc) =
for accAddr, acc in alloc: for accAddr, acc in alloc:
stateDB.setNonce(accAddr, acc.nonce) ledger.setNonce(accAddr, acc.nonce)
stateDB.setCode(accAddr, acc.code) ledger.setCode(accAddr, acc.code)
stateDB.setBalance(accAddr, acc.balance) ledger.setBalance(accAddr, acc.balance)
for slot, value in acc.storage: for slot, value in acc.storage:
stateDB.setStorage(accAddr, slot, value) ledger.setStorage(accAddr, slot, value)
method getAncestorHash(vmState: TestVMState; blockNumber: BlockNumber): Hash32 = method getAncestorHash(vmState: TestVMState; blockNumber: BlockNumber): Hash32 =
# we can't raise exception here, it'll mess with EVM exception handler. # we can't raise exception here, it'll mess with EVM exception handler.
@ -552,7 +552,7 @@ proc transitionAction*(ctx: var TransContext, conf: T8NConf) =
storeSlotHash = true storeSlotHash = true
) )
vmState.mutateStateDB: vmState.mutateLedger:
db.setupAlloc(ctx.alloc) db.setupAlloc(ctx.alloc)
db.persist(clearEmptyAccount = false) db.persist(clearEmptyAccount = false)