Make use of the new transactional API offered by the Trie DB

This commit is contained in:
Zahary Karadjov 2018-09-18 02:56:10 +03:00
parent d484420f5b
commit d71ce6fb24
2 changed files with 32 additions and 24 deletions

View File

@ -86,8 +86,8 @@ proc prepareChildMessage*(
childOptions) childOptions)
proc applyMessage(computation: var BaseComputation) = proc applyMessage(computation: var BaseComputation) =
# TODO: Snapshots/Journaling, see: https://github.com/status-im/nimbus/issues/142 var transaction = computation.vmState.beginTransaction()
#let snapshot = computation.vmState.snapshot() defer: transaction.dispose()
if computation.msg.depth > STACK_DEPTH_LIMIT: if computation.msg.depth > STACK_DEPTH_LIMIT:
raise newException(StackDepthError, "Stack depth limit reached") raise newException(StackDepthError, "Stack depth limit reached")
@ -114,36 +114,43 @@ proc applyMessage(computation: var BaseComputation) =
computation.opcodeExec(computation) computation.opcodeExec(computation)
# TODO: Snapshots/Journaling if not computation.isError:
#[ transaction.commit()
if result.isError:
computation.vmState.revert(snapshot)
else:
computation.vmState.commit(snapshot)
]#
proc applyCreateMessage(fork: Fork, computation: var BaseComputation) = proc applyCreateMessage(fork: Fork, computation: var BaseComputation) =
computation.applyMessage() computation.applyMessage()
var transaction: DbTransaction
defer: transaction.safeDispose()
if fork >= FkFrontier: if fork >= FkFrontier:
# TODO: Take snapshot transaction = computation.vmState.beginTransaction()
discard
if computation.isError: if computation.isError:
if fork == FkSpurious:
# TODO: Revert snapshot
discard
return return
else: else:
let contractCode = computation.output let contractCode = computation.output
if contractCode.len > 0: if contractCode.len > 0:
if fork >= FkSpurious and contractCode.len >= EIP170_CODE_SIZE_LIMIT: if fork >= FkSpurious and contractCode.len >= EIP170_CODE_SIZE_LIMIT:
# TODO: Revert snapshot
raise newException(OutOfGas, &"Contract code size exceeds EIP170 limit of {EIP170_CODE_SIZE_LIMIT}. Got code of size: {contractCode.len}") raise newException(OutOfGas, &"Contract code size exceeds EIP170 limit of {EIP170_CODE_SIZE_LIMIT}. Got code of size: {contractCode.len}")
try: try:
computation.gasMeter.consumeGas( computation.gasMeter.consumeGas(
computation.gasCosts[Create].m_handler(0, 0, contractCode.len), computation.gasCosts[Create].m_handler(0, 0, contractCode.len),
reason = "Write contract code for CREATE") reason = "Write contract code for CREATE")
let storageAddr = computation.msg.storage_address
debug "SETTING CODE",
address = storageAddr.toHex,
length = len(contract_code),
hash = contractCode.rlpHash
computation.vmState.mutateStateDb:
db.setCode(storageAddr, contractCode.toRange)
if transaction != nil:
transaction.commit()
except OutOfGas: except OutOfGas:
if fork == FkFrontier: if fork == FkFrontier:
computation.output = @[] computation.output = @[]
@ -153,13 +160,8 @@ proc applyCreateMessage(fork: Fork, computation: var BaseComputation) =
# TODO: Revert snapshot # TODO: Revert snapshot
discard discard
else: else:
let storageAddr = computation.msg.storage_address if transaction != nil:
debug "SETTING CODE", transaction.commit()
address = storageAddr.toHex,
length = len(contract_code),
hash = contractCode.rlpHash
computation.vmState.mutateStateDB:
db.setCode(storageAddr, contractCode.toRange)
proc generateChildComputation*(fork: Fork, computation: BaseComputation, childMsg: Message): BaseComputation = proc generateChildComputation*(fork: Fork, computation: BaseComputation, childMsg: Message): BaseComputation =
var childComp = newBaseComputation( var childComp = newBaseComputation(

View File

@ -7,7 +7,7 @@
import import
macros, strformat, tables, macros, strformat, tables,
eth_common, eth_common, eth_trie/db,
./constants, ./errors, ./transaction, ./db/[db_chain, state_db], ./constants, ./errors, ./transaction, ./db/[db_chain, state_db],
./utils/header ./utils/header
@ -118,3 +118,9 @@ template mutateStateDB*(vmState: BaseVMState, body: untyped) =
proc readOnlyStateDB*(vmState: BaseVMState): AccountStateDB {.inline.}= proc readOnlyStateDB*(vmState: BaseVMState): AccountStateDB {.inline.}=
vmState.chaindb.getStateDb(vmState.blockHeader.stateRoot, readOnly = true) vmState.chaindb.getStateDb(vmState.blockHeader.stateRoot, readOnly = true)
export DbTransaction, commit, rollback, dispose, safeDispose
proc beginTransaction*(vmState: BaseVMState): DbTransaction =
vmState.chaindb.db.beginTransaction()