Merge pull request #139 from status-im/callOpCodeWork
Flesh out call op
This commit is contained in:
commit
4f03c9cf2a
|
@ -52,3 +52,11 @@ const
|
||||||
|
|
||||||
MAX_PREV_HEADER_DEPTH* = 256.toBlockNumber
|
MAX_PREV_HEADER_DEPTH* = 256.toBlockNumber
|
||||||
MaxCallDepth* = 1024
|
MaxCallDepth* = 1024
|
||||||
|
|
||||||
|
## Fork specific constants
|
||||||
|
|
||||||
|
# See: https://github.com/ethereum/EIPs/blob/master/EIPS/eip-170.md
|
||||||
|
# and: https://github.com/ethereum/EIPs/issues/170
|
||||||
|
EIP170_CODE_SIZE_LIMIT* = 24577
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -238,8 +238,10 @@ proc persistBlockToDb*(self: BaseChainDB; blk: Block) =
|
||||||
# receiptDb[indexKey] = rlp.encode(receipt)
|
# receiptDb[indexKey] = rlp.encode(receipt)
|
||||||
# return receiptDb.rootHash
|
# return receiptDb.rootHash
|
||||||
|
|
||||||
# proc snapshot*(self: BaseChainDB): UUID =
|
#proc snapshot*(self: BaseChainDB): UUID =
|
||||||
# return self.db.snapshot()
|
# Snapshots are a combination of the state_root at the time of the
|
||||||
|
# snapshot and the id of the changeset from the journaled DB.
|
||||||
|
#return self.db.snapshot()
|
||||||
|
|
||||||
# proc commit*(self: BaseChainDB; checkpoint: UUID): void =
|
# proc commit*(self: BaseChainDB; checkpoint: UUID): void =
|
||||||
# self.db.commit(checkpoint)
|
# self.db.commit(checkpoint)
|
||||||
|
@ -248,6 +250,7 @@ proc persistBlockToDb*(self: BaseChainDB; blk: Block) =
|
||||||
# self.db.clear()
|
# self.db.clear()
|
||||||
|
|
||||||
proc getStateDb*(self: BaseChainDB; stateRoot: Hash256; readOnly: bool = false): AccountStateDB =
|
proc getStateDb*(self: BaseChainDB; stateRoot: Hash256; readOnly: bool = false): AccountStateDB =
|
||||||
|
# TODO: readOnly is not used.
|
||||||
result = newAccountStateDB(self.db, stateRoot)
|
result = newAccountStateDB(self.db, stateRoot)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,8 @@ import
|
||||||
eth_common,
|
eth_common,
|
||||||
../constants, ../errors, ../validation, ../vm_state, ../vm_types,
|
../constants, ../errors, ../validation, ../vm_state, ../vm_types,
|
||||||
./interpreter/[opcode_values, gas_meter, gas_costs, vm_forks],
|
./interpreter/[opcode_values, gas_meter, gas_costs, vm_forks],
|
||||||
./code_stream, ./memory, ./message, ./stack
|
./code_stream, ./memory, ./message, ./stack, ../db/[state_db, db_chain],
|
||||||
|
../utils/header, byteutils, ranges
|
||||||
|
|
||||||
logScope:
|
logScope:
|
||||||
topics = "vm computation"
|
topics = "vm computation"
|
||||||
|
@ -39,16 +40,30 @@ template isSuccess*(c: BaseComputation): bool =
|
||||||
template isError*(c: BaseComputation): bool =
|
template isError*(c: BaseComputation): bool =
|
||||||
not c.isSuccess
|
not c.isSuccess
|
||||||
|
|
||||||
proc shouldBurnGas*(c: BaseComputation): bool =
|
func shouldBurnGas*(c: BaseComputation): bool =
|
||||||
c.isError and c.error.burnsGas
|
c.isError and c.error.burnsGas
|
||||||
|
|
||||||
proc shouldEraseReturnData*(c: BaseComputation): bool =
|
func shouldEraseReturnData*(c: BaseComputation): bool =
|
||||||
c.isError and c.error.erasesReturnData
|
c.isError and c.error.erasesReturnData
|
||||||
|
|
||||||
func bytesToHex(x: openarray[byte]): string {.inline.} =
|
func bytesToHex(x: openarray[byte]): string {.inline.} =
|
||||||
## TODO: use seq[byte] for raw data and delete this proc
|
## TODO: use seq[byte] for raw data and delete this proc
|
||||||
foldl(x, a & b.int.toHex(2).toLowerAscii, "0x")
|
foldl(x, a & b.int.toHex(2).toLowerAscii, "0x")
|
||||||
|
|
||||||
|
func output*(c: BaseComputation): seq[byte] =
|
||||||
|
if c.shouldEraseReturnData:
|
||||||
|
@[]
|
||||||
|
else:
|
||||||
|
c.rawOutput
|
||||||
|
|
||||||
|
func `output=`*(c: var BaseComputation, value: openarray[byte]) =
|
||||||
|
c.rawOutput = @value
|
||||||
|
|
||||||
|
proc outputHex*(c: BaseComputation): string =
|
||||||
|
if c.shouldEraseReturnData:
|
||||||
|
return "0x"
|
||||||
|
c.rawOutput.bytesToHex
|
||||||
|
|
||||||
proc prepareChildMessage*(
|
proc prepareChildMessage*(
|
||||||
c: var BaseComputation,
|
c: var BaseComputation,
|
||||||
gas: GasInt,
|
gas: GasInt,
|
||||||
|
@ -70,19 +85,119 @@ proc prepareChildMessage*(
|
||||||
code,
|
code,
|
||||||
childOptions)
|
childOptions)
|
||||||
|
|
||||||
func output*(c: BaseComputation): seq[byte] =
|
proc applyMessage(computation: var BaseComputation) =
|
||||||
if c.shouldEraseReturnData:
|
var transaction = computation.vmState.beginTransaction()
|
||||||
@[]
|
defer: transaction.dispose()
|
||||||
|
|
||||||
|
if computation.msg.depth > STACK_DEPTH_LIMIT:
|
||||||
|
raise newException(StackDepthError, "Stack depth limit reached")
|
||||||
|
|
||||||
|
if computation.msg.value != 0:
|
||||||
|
let senderBalance =
|
||||||
|
computation.vmState.chainDb.getStateDb(
|
||||||
|
computation.vmState.blockHeader.hash, false).
|
||||||
|
getBalance(computation.msg.sender)
|
||||||
|
|
||||||
|
if sender_balance < computation.msg.value:
|
||||||
|
raise newException(InsufficientFunds,
|
||||||
|
&"Insufficient funds: {senderBalance} < {computation.msg.value}"
|
||||||
|
)
|
||||||
|
|
||||||
|
computation.vmState.mutateStateDb:
|
||||||
|
db.deltaBalance(computation.msg.sender, -1 * computation.msg.value)
|
||||||
|
db.deltaBalance(computation.msg.storage_address, computation.msg.value)
|
||||||
|
|
||||||
|
debug "Apply message",
|
||||||
|
value = computation.msg.value,
|
||||||
|
sender = computation.msg.sender.toHex,
|
||||||
|
address = computation.msg.storage_address.toHex
|
||||||
|
|
||||||
|
computation.opcodeExec(computation)
|
||||||
|
|
||||||
|
if not computation.isError:
|
||||||
|
transaction.commit()
|
||||||
|
|
||||||
|
proc applyCreateMessage(fork: Fork, computation: var BaseComputation) =
|
||||||
|
computation.applyMessage()
|
||||||
|
|
||||||
|
var transaction: DbTransaction
|
||||||
|
defer: transaction.safeDispose()
|
||||||
|
|
||||||
|
if fork >= FkFrontier:
|
||||||
|
transaction = computation.vmState.beginTransaction()
|
||||||
|
|
||||||
|
if computation.isError:
|
||||||
|
return
|
||||||
else:
|
else:
|
||||||
c.rawOutput
|
let contractCode = computation.output
|
||||||
|
if contractCode.len > 0:
|
||||||
|
if fork >= FkSpurious and contractCode.len >= EIP170_CODE_SIZE_LIMIT:
|
||||||
|
raise newException(OutOfGas, &"Contract code size exceeds EIP170 limit of {EIP170_CODE_SIZE_LIMIT}. Got code of size: {contractCode.len}")
|
||||||
|
|
||||||
func `output=`*(c: var BaseComputation, value: openarray[byte]) =
|
try:
|
||||||
c.rawOutput = @value
|
computation.gasMeter.consumeGas(
|
||||||
|
computation.gasCosts[Create].m_handler(0, 0, contractCode.len),
|
||||||
|
reason = "Write contract code for CREATE")
|
||||||
|
|
||||||
proc outputHex*(c: BaseComputation): string =
|
let storageAddr = computation.msg.storage_address
|
||||||
if c.shouldEraseReturnData:
|
debug "SETTING CODE",
|
||||||
return "0x"
|
address = storageAddr.toHex,
|
||||||
c.rawOutput.bytesToHex
|
length = len(contract_code),
|
||||||
|
hash = contractCode.rlpHash
|
||||||
|
|
||||||
|
computation.vmState.mutateStateDb:
|
||||||
|
db.setCode(storageAddr, contractCode.toRange)
|
||||||
|
|
||||||
|
if transaction != nil:
|
||||||
|
transaction.commit()
|
||||||
|
|
||||||
|
except OutOfGas:
|
||||||
|
if fork == FkFrontier:
|
||||||
|
computation.output = @[]
|
||||||
|
else:
|
||||||
|
# Different from Frontier:
|
||||||
|
# Reverts state on gas failure while writing contract code.
|
||||||
|
# TODO: Revert snapshot
|
||||||
|
discard
|
||||||
|
else:
|
||||||
|
if transaction != nil:
|
||||||
|
transaction.commit()
|
||||||
|
|
||||||
|
proc generateChildComputation*(fork: Fork, computation: BaseComputation, childMsg: Message): BaseComputation =
|
||||||
|
var childComp = newBaseComputation(
|
||||||
|
computation.vmState,
|
||||||
|
computation.vmState.blockHeader.blockNumber,
|
||||||
|
childMsg)
|
||||||
|
|
||||||
|
# Copy the fork op code executor proc (assumes child computation is in the same fork)
|
||||||
|
childComp.opCodeExec = computation.opCodeExec
|
||||||
|
|
||||||
|
if childMsg.isCreate:
|
||||||
|
fork.applyCreateMessage(childComp)
|
||||||
|
else:
|
||||||
|
applyMessage(childComp)
|
||||||
|
return childComp
|
||||||
|
|
||||||
|
proc addChildComputation(fork: Fork, computation: BaseComputation, child: BaseComputation) =
|
||||||
|
if child.isError:
|
||||||
|
if child.msg.isCreate:
|
||||||
|
computation.returnData = child.output
|
||||||
|
elif child.shouldBurnGas:
|
||||||
|
computation.returnData = @[]
|
||||||
|
else:
|
||||||
|
computation.returnData = child.output
|
||||||
|
else:
|
||||||
|
if child.msg.isCreate:
|
||||||
|
computation.returnData = @[]
|
||||||
|
else:
|
||||||
|
computation.returnData = child.output
|
||||||
|
computation.children.add(child)
|
||||||
|
|
||||||
|
proc applyChildComputation*(computation: BaseComputation, childMsg: Message): BaseComputation =
|
||||||
|
## Apply the vm message childMsg as a child computation.
|
||||||
|
let fork = computation.vmState.blockHeader.blockNumber.toFork
|
||||||
|
result = fork.generateChildComputation(computation, childMsg)
|
||||||
|
fork.addChildComputation(computation, result)
|
||||||
|
|
||||||
proc registerAccountForDeletion*(c: var BaseComputation, beneficiary: EthAddress) =
|
proc registerAccountForDeletion*(c: var BaseComputation, beneficiary: EthAddress) =
|
||||||
if c.msg.storageAddress in c.accountsToDelete:
|
if c.msg.storageAddress in c.accountsToDelete:
|
||||||
|
|
|
@ -168,6 +168,9 @@ template gasCosts(FeeSchedule: GasFeeSchedule, prefix, ResultGasCostsName: untyp
|
||||||
if not value.isZero:
|
if not value.isZero:
|
||||||
result += static(FeeSchedule[GasExpByte]) * (1 + log256(value))
|
result += static(FeeSchedule[GasExpByte]) * (1 + log256(value))
|
||||||
|
|
||||||
|
func `prefix gasCreate`(currentMemSize, memOffset, memLength: Natural): GasInt {.nimcall.} =
|
||||||
|
result = static(FeeSchedule[GasCodeDeposit]) * memLength
|
||||||
|
|
||||||
func `prefix gasSha3`(currentMemSize, memOffset, memLength: Natural): GasInt {.nimcall.} =
|
func `prefix gasSha3`(currentMemSize, memOffset, memLength: Natural): GasInt {.nimcall.} =
|
||||||
|
|
||||||
result = `prefix gasMemoryExpansion`(currentMemSize, memOffset, memLength)
|
result = `prefix gasMemoryExpansion`(currentMemSize, memOffset, memLength)
|
||||||
|
@ -494,7 +497,7 @@ template gasCosts(FeeSchedule: GasFeeSchedule, prefix, ResultGasCostsName: untyp
|
||||||
Log4: memExpansion `prefix gasLog4`,
|
Log4: memExpansion `prefix gasLog4`,
|
||||||
|
|
||||||
# f0s: System operations
|
# f0s: System operations
|
||||||
Create: fixed GasCreate, # TODO, dynamic cost
|
Create: memExpansion `prefix gasCreate`, # TODO: Change to dynamic?
|
||||||
Call: complex `prefix gasCall`,
|
Call: complex `prefix gasCall`,
|
||||||
CallCode: complex `prefix gasCall`,
|
CallCode: complex `prefix gasCall`,
|
||||||
Return: memExpansion `prefix gasHalt`,
|
Return: memExpansion `prefix gasHalt`,
|
||||||
|
|
|
@ -695,20 +695,20 @@ template genCall(callName: untyped): untyped =
|
||||||
computation.memory.extend(memInPos, memInLen)
|
computation.memory.extend(memInPos, memInLen)
|
||||||
computation.memory.extend(memOutPos, memOutLen)
|
computation.memory.extend(memOutPos, memOutLen)
|
||||||
|
|
||||||
let callData = computation.memory.read(memInPos, memInLen)
|
let
|
||||||
|
callData = computation.memory.read(memInPos, memInLen)
|
||||||
##### getBalance type error: expression 'db' is of type: proc (vmState: untyped, readOnly: untyped, handler: untyped): untyped{.noSideEffect, gcsafe, locks: <unknown>.}
|
senderBalance = computation.vmState.readOnlyStateDb.getBalance(computation.msg.storageAddress)
|
||||||
# computation.vmState.db(readOnly = true):
|
# TODO check gas balance rollover
|
||||||
# let senderBalance = db.getBalance(computation.msg.storageAddress) # TODO check gas balance rollover
|
# TODO: shouldTransferValue in py-evm is:
|
||||||
|
# True for call and callCode
|
||||||
let insufficientFunds = false # shouldTransferValue and senderBalance < value
|
# False for callDelegate and callStatic
|
||||||
let stackTooDeep = computation.msg.depth >= MaxCallDepth
|
insufficientFunds = senderBalance < value # TODO: and shouldTransferValue
|
||||||
|
stackTooDeep = computation.msg.depth >= MaxCallDepth
|
||||||
|
|
||||||
if insufficientFunds or stackTooDeep:
|
if insufficientFunds or stackTooDeep:
|
||||||
computation.returnData = @[]
|
computation.returnData = @[]
|
||||||
var errMessage: string
|
var errMessage: string
|
||||||
if insufficientFunds:
|
if insufficientFunds:
|
||||||
let senderBalance = -1 # TODO workaround
|
|
||||||
# Note: for some reason we can't use strformat here, we get undeclared identifiers
|
# Note: for some reason we can't use strformat here, we get undeclared identifiers
|
||||||
errMessage = &"Insufficient Funds: have: " & $senderBalance & "need: " & $value
|
errMessage = &"Insufficient Funds: have: " & $senderBalance & "need: " & $value
|
||||||
elif stackTooDeep:
|
elif stackTooDeep:
|
||||||
|
@ -721,11 +721,11 @@ template genCall(callName: untyped): untyped =
|
||||||
push: 0
|
push: 0
|
||||||
return
|
return
|
||||||
|
|
||||||
##### getCode type error: expression 'db' is of type: proc (vmState: untyped, readOnly: untyped, handler: untyped): untyped{.noSideEffect, gcsafe, locks: <unknown>.}
|
let code =
|
||||||
# computation.vmState.db(readOnly = true):
|
if codeAddress != ZERO_ADDRESS:
|
||||||
# let code = if codeAddress != ZERO_ADDRESS: db.getCode(codeAddress)
|
computation.vmState.readOnlyStateDb.getCode(codeAddress)
|
||||||
# else: db.getCode(to)
|
else:
|
||||||
let code: seq[byte] = @[]
|
computation.vmState.readOnlyStateDb.getCode(to)
|
||||||
|
|
||||||
var childMsg = prepareChildMessage(
|
var childMsg = prepareChildMessage(
|
||||||
computation,
|
computation,
|
||||||
|
@ -733,17 +733,14 @@ template genCall(callName: untyped): untyped =
|
||||||
to,
|
to,
|
||||||
value,
|
value,
|
||||||
callData,
|
callData,
|
||||||
code,
|
code.toSeq,
|
||||||
MessageOptions(flags: flags)
|
MessageOptions(flags: flags)
|
||||||
)
|
)
|
||||||
|
|
||||||
if sender != ZERO_ADDRESS:
|
if sender != ZERO_ADDRESS:
|
||||||
childMsg.sender = sender
|
childMsg.sender = sender
|
||||||
|
|
||||||
# let childComputation = applyChildBaseComputation(computation, childMsg)
|
var childComputation = applyChildComputation(computation, childMsg)
|
||||||
var childComputation: BaseComputation # TODO - stub
|
|
||||||
new childComputation
|
|
||||||
childComputation.gasMeter.init(0)
|
|
||||||
|
|
||||||
if childComputation.isError:
|
if childComputation.isError:
|
||||||
push: 0
|
push: 0
|
||||||
|
|
|
@ -48,3 +48,15 @@ proc toFork*(blockNumber: UInt256): Fork =
|
||||||
elif blockNumber < forkBlocks[FkByzantium]: FkSpurious
|
elif blockNumber < forkBlocks[FkByzantium]: FkSpurious
|
||||||
else:
|
else:
|
||||||
FkByzantium # Update for constantinople when announced
|
FkByzantium # Update for constantinople when announced
|
||||||
|
|
||||||
|
proc `$`*(fork: Fork): string =
|
||||||
|
case fork
|
||||||
|
of FkFrontier: result = "Frontier"
|
||||||
|
of FkThawing: result = "Thawing"
|
||||||
|
of FkHomestead: result = "Homestead"
|
||||||
|
of FkDao: result = "Dao"
|
||||||
|
of FkTangerine: result = "Tangerine Whistle"
|
||||||
|
of FkSpurious: result = "Spurious Dragon"
|
||||||
|
of FkByzantium: result = "Byzantium"
|
||||||
|
else: result = "UNKNOWN FORK"
|
||||||
|
|
||||||
|
|
|
@ -222,12 +222,22 @@ macro genFrontierDispatch(computation: BaseComputation): untyped =
|
||||||
proc frontierVM(computation: var BaseComputation) =
|
proc frontierVM(computation: var BaseComputation) =
|
||||||
genFrontierDispatch(computation)
|
genFrontierDispatch(computation)
|
||||||
|
|
||||||
|
proc updateOpcodeExec*(computation: var BaseComputation, fork: Fork) =
|
||||||
|
case fork
|
||||||
|
of FkFrontier:
|
||||||
|
computation.opCodeExec = frontierVM
|
||||||
|
computation.frontierVM()
|
||||||
|
else:
|
||||||
|
raise newException(VMError, "Unknown or not implemented fork: " & $fork)
|
||||||
|
|
||||||
|
proc updateOpcodeExec*(computation: var BaseComputation) =
|
||||||
|
let fork = computation.vmState.blockHeader.blockNumber.toFork
|
||||||
|
computation.updateOpcodeExec(fork)
|
||||||
|
|
||||||
proc executeOpcodes*(computation: var BaseComputation) =
|
proc executeOpcodes*(computation: var BaseComputation) =
|
||||||
|
# TODO: Optimise getting fork and updating opCodeExec only when necessary
|
||||||
let fork = computation.vmState.blockHeader.blockNumber.toFork
|
let fork = computation.vmState.blockHeader.blockNumber.toFork
|
||||||
try:
|
try:
|
||||||
case fork
|
computation.updateOpcodeExec(fork)
|
||||||
of FkFrontier: computation.frontierVM()
|
|
||||||
else:
|
|
||||||
raise newException(ValueError, "not implemented fork: " & $fork)
|
|
||||||
except VMError:
|
except VMError:
|
||||||
computation.error = Error(info: getCurrentExceptionMsg())
|
computation.error = Error(info: getCurrentExceptionMsg())
|
||||||
|
|
|
@ -83,5 +83,5 @@ proc `storageAddress`*(message: Message): EthAddress =
|
||||||
else:
|
else:
|
||||||
message.destination
|
message.destination
|
||||||
|
|
||||||
proc isCreate(message: Message): bool =
|
proc isCreate*(message: Message): bool =
|
||||||
message.destination == CREATE_CONTRACT_ADDRESS
|
message.destination == CREATE_CONTRACT_ADDRESS
|
||||||
|
|
|
@ -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()
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,8 @@ import
|
||||||
|
|
||||||
|
|
||||||
type
|
type
|
||||||
|
OpcodeExecutor* = proc(computation: var BaseComputation)
|
||||||
|
|
||||||
BaseComputation* = ref object of RootObj
|
BaseComputation* = ref object of RootObj
|
||||||
# The execution computation
|
# The execution computation
|
||||||
vmState*: BaseVMState
|
vmState*: BaseVMState
|
||||||
|
@ -32,6 +34,7 @@ type
|
||||||
opcodes*: Table[Op, proc(computation: var BaseComputation){.nimcall.}]
|
opcodes*: Table[Op, proc(computation: var BaseComputation){.nimcall.}]
|
||||||
precompiles*: Table[string, Opcode]
|
precompiles*: Table[string, Opcode]
|
||||||
gasCosts*: GasCosts # TODO - will be hidden at a lower layer
|
gasCosts*: GasCosts # TODO - will be hidden at a lower layer
|
||||||
|
opCodeExec*: OpcodeExecutor
|
||||||
|
|
||||||
Error* = ref object
|
Error* = ref object
|
||||||
info*: string
|
info*: string
|
||||||
|
|
|
@ -52,7 +52,7 @@ proc testFixture(fixtures: JsonNode, testStatusIMPL: var TestStatus) =
|
||||||
let gas_cost = transaction.gasLimit.u256 * transaction.gasPrice.u256
|
let gas_cost = transaction.gasLimit.u256 * transaction.gasPrice.u256
|
||||||
|
|
||||||
var memDb = newMemDB()
|
var memDb = newMemDB()
|
||||||
var vmState = newBaseVMState(header, newBaseChainDB(trieDB memDb))
|
var vmState = newBaseVMState(header, newBaseChainDB(newMemoryDb()))
|
||||||
vmState.mutateStateDB:
|
vmState.mutateStateDB:
|
||||||
setupStateDB(fixture{"pre"}, db)
|
setupStateDB(fixture{"pre"}, db)
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,7 @@ from eth_common import GasInt
|
||||||
proc testCode(code: string, initialGas: GasInt, blockNum: UInt256): BaseComputation =
|
proc testCode(code: string, initialGas: GasInt, blockNum: UInt256): BaseComputation =
|
||||||
let header = BlockHeader(blockNumber: blockNum)
|
let header = BlockHeader(blockNumber: blockNum)
|
||||||
var memDb = newMemDB()
|
var memDb = newMemDB()
|
||||||
var vmState = newBaseVMState(header, newBaseChainDB(trieDB memDb))
|
var vmState = newBaseVMState(header, newBaseChainDB(newMemoryDb()))
|
||||||
|
|
||||||
# coinbase: "",
|
# coinbase: "",
|
||||||
# difficulty: fixture{"env"}{"currentDifficulty"}.getHexadecimalInt.u256,
|
# difficulty: fixture{"env"}{"currentDifficulty"}.getHexadecimalInt.u256,
|
||||||
|
|
|
@ -45,7 +45,7 @@ proc doTests =
|
||||||
emptyRlpHash = keccak256.digest(rlp.encode("").toOpenArray)
|
emptyRlpHash = keccak256.digest(rlp.encode("").toOpenArray)
|
||||||
header = BlockHeader(stateRoot: emptyRlpHash)
|
header = BlockHeader(stateRoot: emptyRlpHash)
|
||||||
var
|
var
|
||||||
chain = newBaseChainDB(trieDB newMemDB())
|
chain = newBaseChainDB(newMemoryDb())
|
||||||
state = newBaseVMState(header, chain)
|
state = newBaseVMState(header, chain)
|
||||||
ethNode.chain = chain
|
ethNode.chain = chain
|
||||||
|
|
||||||
|
|
|
@ -40,7 +40,7 @@ proc testFixture(fixtures: JsonNode, testStatusIMPL: var TestStatus) =
|
||||||
)
|
)
|
||||||
|
|
||||||
var memDb = newMemDB()
|
var memDb = newMemDB()
|
||||||
var vmState = newBaseVMState(header, newBaseChainDB(trieDB memDb))
|
var vmState = newBaseVMState(header, newBaseChainDB(newMemoryDB()))
|
||||||
let fexec = fixture["exec"]
|
let fexec = fixture["exec"]
|
||||||
var code: seq[byte]
|
var code: seq[byte]
|
||||||
vmState.mutateStateDB:
|
vmState.mutateStateDB:
|
||||||
|
|
Loading…
Reference in New Issue