integrate snapshot with computation

This commit is contained in:
andri lim 2019-03-20 17:52:42 +07:00
parent 90924eef47
commit 527891cdb8
No known key found for this signature in database
GPG Key ID: 31702AE10541E6B9
3 changed files with 28 additions and 54 deletions

View File

@ -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:

View File

@ -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

View File

@ -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