moved validateTransaction() to executor
why: not part of VM (see andri's requested change at #573)
This commit is contained in:
parent
a72f6ed6e0
commit
dfc93a74ad
|
@ -7,6 +7,39 @@ import options, sets,
|
|||
../vm_types2,
|
||||
./dao, ../config
|
||||
|
||||
proc validateTransaction*(vmState: BaseVMState, tx: Transaction,
|
||||
sender: EthAddress, fork: Fork): bool =
|
||||
let balance = vmState.readOnlyStateDB.getBalance(sender)
|
||||
let nonce = vmState.readOnlyStateDB.getNonce(sender)
|
||||
|
||||
if vmState.cumulativeGasUsed + tx.gasLimit > vmState.blockHeader.gasLimit:
|
||||
debug "invalid tx: block header gasLimit reached",
|
||||
maxLimit=vmState.blockHeader.gasLimit,
|
||||
gasUsed=vmState.cumulativeGasUsed,
|
||||
addition=tx.gasLimit
|
||||
return
|
||||
|
||||
let totalCost = tx.gasLimit.u256 * tx.gasPrice.u256 + tx.value
|
||||
if totalCost > balance:
|
||||
debug "invalid tx: not enough cash",
|
||||
available=balance,
|
||||
require=totalCost
|
||||
return
|
||||
|
||||
if tx.gasLimit < tx.intrinsicGas(fork):
|
||||
debug "invalid tx: not enough gas to perform calculation",
|
||||
available=tx.gasLimit,
|
||||
require=tx.intrinsicGas(fork)
|
||||
return
|
||||
|
||||
if tx.accountNonce != nonce:
|
||||
debug "invalid tx: account nonce mismatch",
|
||||
txNonce=tx.accountnonce,
|
||||
accountNonce=nonce
|
||||
return
|
||||
|
||||
result = true
|
||||
|
||||
proc processTransaction*(tx: Transaction, sender: EthAddress, vmState: BaseVMState, fork: Fork): GasInt =
|
||||
## Process the transaction, write the results to db.
|
||||
## Returns amount of ETH to be rewarded to miner
|
||||
|
@ -196,3 +229,67 @@ proc processBlock*(chainDB: BaseChainDB, header: BlockHeader, body: BlockBody, v
|
|||
# rather than destroyed by trie pruning. But the current block will still get a pruned trie.
|
||||
# If trie pruning deactivated, `applyDeletes` have no effects.
|
||||
dbTx.commit(applyDeletes = false)
|
||||
|
||||
|
||||
#[
|
||||
method executeTransaction(vmState: BaseVMState, transaction: Transaction): (Computation, BlockHeader) {.base.}=
|
||||
# Execute the transaction in the vm
|
||||
# TODO: introduced here: https://github.com/ethereum/py-evm/commit/21c57f2d56ab91bb62723c3f9ebe291d0b132dde
|
||||
# Refactored/Removed here: https://github.com/ethereum/py-evm/commit/cc991bf
|
||||
# Deleted here: https://github.com/ethereum/py-evm/commit/746defb6f8e83cee2c352a0ab8690e1281c4227c
|
||||
raise newException(ValueError, "Must be implemented by subclasses")
|
||||
|
||||
|
||||
method addTransaction*(vmState: BaseVMState, transaction: Transaction, c: Computation, b: Block): (Block, Table[string, string]) =
|
||||
# Add a transaction to the given block and
|
||||
# return `trieData` to store the transaction data in chaindb in VM layer
|
||||
# Update the bloomFilter, transaction trie and receipt trie roots, bloom_filter,
|
||||
# bloom, and usedGas of the block
|
||||
# transaction: the executed transaction
|
||||
# computation: the Computation object with executed result
|
||||
# block: the Block which the transaction is added in
|
||||
# var receipt = vmState.makeReceipt(transaction, computation)
|
||||
# vmState.add_receipt(receipt)
|
||||
|
||||
# block.transactions.append(transaction)
|
||||
|
||||
# # Get trie roots and changed key-values.
|
||||
# tx_root_hash, tx_kv_nodes = make_trie_root_and_nodes(block.transactions)
|
||||
# receipt_root_hash, receipt_kv_nodes = make_trie_root_and_nodes(self.receipts)
|
||||
|
||||
# trie_data = merge(tx_kv_nodes, receipt_kv_nodes)
|
||||
|
||||
# block.bloom_filter |= receipt.bloom
|
||||
|
||||
# block.header.transaction_root = tx_root_hash
|
||||
# block.header.receipt_root = receipt_root_hash
|
||||
# block.header.bloom = int(block.bloom_filter)
|
||||
# block.header.gas_used = receipt.gas_used
|
||||
|
||||
# return block, trie_data
|
||||
result = (b, initTable[string, string]())
|
||||
|
||||
method applyTransaction*(
|
||||
vmState: BaseVMState,
|
||||
transaction: Transaction,
|
||||
b: Block,
|
||||
isStateless: bool): (Computation, Block, Table[string, string]) =
|
||||
# Apply transaction to the given block
|
||||
# transaction: the transaction need to be applied
|
||||
# b: the block which the transaction applies on
|
||||
# isStateless: if isStateless, call vmState.addTransaction to set block
|
||||
|
||||
if isStateless:
|
||||
var ourBlock = b # deepcopy
|
||||
vmState.blockHeader = b.header
|
||||
var (computation, blockHeader) = vmState.executeTransaction(transaction)
|
||||
|
||||
ourBlock.header = blockHeader
|
||||
var trieData: Table[string, string]
|
||||
(ourBlock, trieData) = vmState.addTransaction(transaction, computation, ourBlock)
|
||||
|
||||
result = (computation, ourBlock, trieData)
|
||||
else:
|
||||
var (computation, blockHeader) = vmState.executeTransaction(transaction)
|
||||
return (computation, nil, initTable[string, string]())
|
||||
]#
|
||||
|
|
|
@ -11,38 +11,6 @@ import
|
|||
../transaction,
|
||||
./computation, ./interpreter, ./state, ./types
|
||||
|
||||
proc validateTransaction*(vmState: BaseVMState, tx: Transaction, sender: EthAddress, fork: Fork): bool =
|
||||
let balance = vmState.readOnlyStateDB.getBalance(sender)
|
||||
let nonce = vmState.readOnlyStateDB.getNonce(sender)
|
||||
|
||||
if vmState.cumulativeGasUsed + tx.gasLimit > vmState.blockHeader.gasLimit:
|
||||
debug "invalid tx: block header gasLimit reached",
|
||||
maxLimit=vmState.blockHeader.gasLimit,
|
||||
gasUsed=vmState.cumulativeGasUsed,
|
||||
addition=tx.gasLimit
|
||||
return
|
||||
|
||||
let totalCost = tx.gasLimit.u256 * tx.gasPrice.u256 + tx.value
|
||||
if totalCost > balance:
|
||||
debug "invalid tx: not enough cash",
|
||||
available=balance,
|
||||
require=totalCost
|
||||
return
|
||||
|
||||
if tx.gasLimit < tx.intrinsicGas(fork):
|
||||
debug "invalid tx: not enough gas to perform calculation",
|
||||
available=tx.gasLimit,
|
||||
require=tx.intrinsicGas(fork)
|
||||
return
|
||||
|
||||
if tx.accountNonce != nonce:
|
||||
debug "invalid tx: account nonce mismatch",
|
||||
txNonce=tx.accountnonce,
|
||||
accountNonce=nonce
|
||||
return
|
||||
|
||||
result = true
|
||||
|
||||
proc setupComputation*(vmState: BaseVMState, tx: Transaction, sender: EthAddress, fork: Fork) : Computation =
|
||||
var gas = tx.gasLimit - tx.intrinsicGas(fork)
|
||||
assert gas >= 0
|
||||
|
@ -88,66 +56,3 @@ proc refundGas*(c: Computation, tx: Transaction, sender: EthAddress) =
|
|||
c.gasMeter.returnGas min(c.getGasRefund(), maxRefund)
|
||||
c.vmState.mutateStateDB:
|
||||
db.addBalance(sender, c.gasMeter.gasRemaining.u256 * tx.gasPrice.u256)
|
||||
|
||||
#[
|
||||
method executeTransaction(vmState: BaseVMState, transaction: Transaction): (Computation, BlockHeader) {.base.}=
|
||||
# Execute the transaction in the vm
|
||||
# TODO: introduced here: https://github.com/ethereum/py-evm/commit/21c57f2d56ab91bb62723c3f9ebe291d0b132dde
|
||||
# Refactored/Removed here: https://github.com/ethereum/py-evm/commit/cc991bf
|
||||
# Deleted here: https://github.com/ethereum/py-evm/commit/746defb6f8e83cee2c352a0ab8690e1281c4227c
|
||||
raise newException(ValueError, "Must be implemented by subclasses")
|
||||
|
||||
|
||||
method addTransaction*(vmState: BaseVMState, transaction: Transaction, c: Computation, b: Block): (Block, Table[string, string]) =
|
||||
# Add a transaction to the given block and
|
||||
# return `trieData` to store the transaction data in chaindb in VM layer
|
||||
# Update the bloomFilter, transaction trie and receipt trie roots, bloom_filter,
|
||||
# bloom, and usedGas of the block
|
||||
# transaction: the executed transaction
|
||||
# computation: the Computation object with executed result
|
||||
# block: the Block which the transaction is added in
|
||||
# var receipt = vmState.makeReceipt(transaction, computation)
|
||||
# vmState.add_receipt(receipt)
|
||||
|
||||
# block.transactions.append(transaction)
|
||||
|
||||
# # Get trie roots and changed key-values.
|
||||
# tx_root_hash, tx_kv_nodes = make_trie_root_and_nodes(block.transactions)
|
||||
# receipt_root_hash, receipt_kv_nodes = make_trie_root_and_nodes(self.receipts)
|
||||
|
||||
# trie_data = merge(tx_kv_nodes, receipt_kv_nodes)
|
||||
|
||||
# block.bloom_filter |= receipt.bloom
|
||||
|
||||
# block.header.transaction_root = tx_root_hash
|
||||
# block.header.receipt_root = receipt_root_hash
|
||||
# block.header.bloom = int(block.bloom_filter)
|
||||
# block.header.gas_used = receipt.gas_used
|
||||
|
||||
# return block, trie_data
|
||||
result = (b, initTable[string, string]())
|
||||
|
||||
method applyTransaction*(
|
||||
vmState: BaseVMState,
|
||||
transaction: Transaction,
|
||||
b: Block,
|
||||
isStateless: bool): (Computation, Block, Table[string, string]) =
|
||||
# Apply transaction to the given block
|
||||
# transaction: the transaction need to be applied
|
||||
# b: the block which the transaction applies on
|
||||
# isStateless: if isStateless, call vmState.addTransaction to set block
|
||||
|
||||
if isStateless:
|
||||
var ourBlock = b # deepcopy
|
||||
vmState.blockHeader = b.header
|
||||
var (computation, blockHeader) = vmState.executeTransaction(transaction)
|
||||
|
||||
ourBlock.header = blockHeader
|
||||
var trieData: Table[string, string]
|
||||
(ourBlock, trieData) = vmState.addTransaction(transaction, computation, ourBlock)
|
||||
|
||||
result = (computation, ourBlock, trieData)
|
||||
else:
|
||||
var (computation, blockHeader) = vmState.executeTransaction(transaction)
|
||||
return (computation, nil, initTable[string, string]())
|
||||
]#
|
||||
|
|
|
@ -14,7 +14,6 @@ import
|
|||
export
|
||||
vmx.execComputation,
|
||||
vmx.refundGas,
|
||||
vmx.setupComputation,
|
||||
vmx.validateTransaction
|
||||
vmx.setupComputation
|
||||
|
||||
# End
|
||||
|
|
Loading…
Reference in New Issue