integrate snapshot with computation
This commit is contained in:
parent
90924eef47
commit
527891cdb8
|
@ -7,7 +7,7 @@
|
|||
|
||||
import
|
||||
chronicles, strformat, strutils, sequtils, macros, terminal, math, tables, options,
|
||||
eth/[common, keys],
|
||||
eth/[common, keys], eth/trie/db as triedb,
|
||||
../constants, ../errors, ../validation, ../vm_state, ../vm_types,
|
||||
./interpreter/[opcode_values, gas_meter, gas_costs, vm_forks],
|
||||
./code_stream, ./memory, ./message, ./stack, ../db/[state_db, db_chain],
|
||||
|
@ -93,24 +93,23 @@ proc prepareChildMessage*(
|
|||
code,
|
||||
childOptions)
|
||||
|
||||
type
|
||||
ComputationSnapshot* = object
|
||||
snapshot: Snapshot
|
||||
computation: BaseComputation
|
||||
proc snapshot*(comp: BaseComputation) =
|
||||
comp.dbsnapshot.transaction = comp.vmState.chaindb.db.beginTransaction()
|
||||
comp.dbsnapshot.intermediateRoot = comp.vmState.accountDb.rootHash
|
||||
comp.vmState.blockHeader.stateRoot = comp.vmState.accountDb.rootHash
|
||||
|
||||
proc snapshot*(computation: BaseComputation): ComputationSnapshot =
|
||||
result.snapshot = computation.vmState.snapshot()
|
||||
result.computation = computation
|
||||
proc revert*(comp: BaseComputation, burnsGas = false) =
|
||||
comp.dbsnapshot.transaction.rollback()
|
||||
comp.vmState.accountDb.rootHash = comp.dbsnapshot.intermediateRoot
|
||||
comp.vmState.blockHeader.stateRoot = comp.dbsnapshot.intermediateRoot
|
||||
comp.error = Error(info: getCurrentExceptionMsg(), burnsGas: burnsGas)
|
||||
|
||||
proc revert*(snapshot: var ComputationSnapshot, burnsGas: bool = false) =
|
||||
snapshot.snapshot.revert()
|
||||
snapshot.computation.error = Error(info: getCurrentExceptionMsg(), burnsGas: burnsGas)
|
||||
proc commit*(comp: BaseComputation) =
|
||||
comp.dbsnapshot.transaction.commit()
|
||||
comp.vmState.accountDb.rootHash = comp.vmState.blockHeader.stateRoot
|
||||
|
||||
proc commit*(snapshot: var ComputationSnapshot) {.inline.} =
|
||||
snapshot.snapshot.commit()
|
||||
|
||||
proc dispose*(snapshot: var ComputationSnapshot) {.inline.} =
|
||||
snapshot.snapshot.dispose()
|
||||
proc dispose*(comp: BaseComputation) {.inline.} =
|
||||
comp.dbsnapshot.transaction.dispose()
|
||||
|
||||
proc getFork*(computation: BaseComputation): Fork =
|
||||
result =
|
||||
|
@ -165,16 +164,16 @@ proc transferBalance(computation: var BaseComputation, opCode: static[Op]): bool
|
|||
proc executeOpcodes*(computation: var BaseComputation) {.gcsafe.}
|
||||
|
||||
proc applyMessage*(computation: var BaseComputation, opCode: static[Op]): bool =
|
||||
var snapshot = computation.snapshot()
|
||||
defer: snapshot.dispose()
|
||||
computation.snapshot()
|
||||
defer: computation.dispose()
|
||||
|
||||
when opCode in {CallCode, Call, Create}:
|
||||
if not computation.transferBalance(opCode):
|
||||
snapshot.revert()
|
||||
computation.revert()
|
||||
return
|
||||
|
||||
if computation.gasMeter.gasRemaining < 0:
|
||||
snapshot.commit()
|
||||
computation.commit()
|
||||
return
|
||||
|
||||
try:
|
||||
|
@ -197,9 +196,9 @@ proc applyMessage*(computation: var BaseComputation, opCode: static[Op]): bool =
|
|||
result = not(contractFailed and fork == FkHomestead)
|
||||
|
||||
if result:
|
||||
snapshot.commit()
|
||||
computation.commit()
|
||||
else:
|
||||
snapshot.revert(true)
|
||||
computation.revert(true)
|
||||
|
||||
proc addChildComputation(computation: var BaseComputation, child: BaseComputation) =
|
||||
if child.isError:
|
||||
|
|
|
@ -132,33 +132,6 @@ template mutateStateDB*(vmState: BaseVMState, body: untyped) =
|
|||
if finalStateRoot != initialStateRoot:
|
||||
vmState.blockHeader.stateRoot = finalStateRoot
|
||||
|
||||
export DbTransaction, commit, rollback, dispose, safeDispose
|
||||
|
||||
type
|
||||
Snapshot* = object
|
||||
transaction: DbTransaction
|
||||
intermediateRoot: Hash256
|
||||
vmState: BaseVMState
|
||||
|
||||
proc snapshot*(vmState: BaseVMState): Snapshot =
|
||||
# TODO: use AccountStateDB revert/commit after JournalDB implemented
|
||||
result.transaction = vmState.chaindb.db.beginTransaction()
|
||||
result.intermediateRoot = vmState.accountDb.rootHash
|
||||
vmState.blockHeader.stateRoot = vmState.accountDb.rootHash
|
||||
result.vmState = vmState
|
||||
|
||||
proc revert*(s: var Snapshot) =
|
||||
s.transaction.rollback()
|
||||
s.vmState.accountDb.rootHash = s.intermediateRoot
|
||||
s.vmState.blockHeader.stateRoot = s.intermediateRoot
|
||||
|
||||
proc commit*(s: var Snapshot) =
|
||||
s.transaction.commit()
|
||||
s.vmState.accountDb.rootHash = s.vmState.blockHeader.stateRoot
|
||||
|
||||
proc dispose*(s: var Snapshot) {.inline.} =
|
||||
s.transaction.dispose()
|
||||
|
||||
proc getTracingResult*(vmState: BaseVMState): JsonNode =
|
||||
doAssert(vmState.tracingEnabled)
|
||||
vmState.tracer.trace
|
||||
|
@ -189,4 +162,3 @@ iterator tracedAccountsPairs*(vmState: BaseVMState): (int, EthAddress) =
|
|||
proc removeTracedAccounts*(vmState: BaseVMState, accounts: varargs[EthAddress]) =
|
||||
for acc in accounts:
|
||||
vmState.tracer.accounts.excl acc
|
||||
|
||||
|
|
|
@ -6,8 +6,8 @@
|
|||
# at your option. This file may not be copied, modified, or distributed except according to those terms.
|
||||
|
||||
import
|
||||
tables, eth/common, options,
|
||||
./constants, json, sets,
|
||||
tables, eth/common, eth/trie/db,
|
||||
options, ./constants, json, sets,
|
||||
./vm/[memory, stack, code_stream],
|
||||
./vm/interpreter/[gas_costs, opcode_values, vm_forks], # TODO - will be hidden at a lower layer
|
||||
./db/[db_chain, state_db]
|
||||
|
@ -44,6 +44,10 @@ type
|
|||
accounts*: HashSet[EthAddress]
|
||||
storageKeys*: seq[HashSet[Uint256]]
|
||||
|
||||
Snapshot* = object
|
||||
transaction*: DbTransaction
|
||||
intermediateRoot*: Hash256
|
||||
|
||||
BaseComputation* = ref object of RootObj
|
||||
# The execution computation
|
||||
vmState*: BaseVMState
|
||||
|
@ -56,12 +60,11 @@ type
|
|||
rawOutput*: seq[byte]
|
||||
returnData*: seq[byte]
|
||||
error*: Error
|
||||
shouldEraseReturnData*: bool
|
||||
accountsToDelete*: Table[EthAddress, EthAddress]
|
||||
opcodes*: Table[Op, proc(computation: var BaseComputation){.nimcall.}]
|
||||
gasCosts*: GasCosts # TODO - will be hidden at a lower layer
|
||||
forkOverride*: Option[Fork]
|
||||
logEntries*: seq[Log]
|
||||
dbsnapshot*: Snapshot
|
||||
|
||||
Error* = ref object
|
||||
info*: string
|
||||
|
|
Loading…
Reference in New Issue