mirror of
https://github.com/status-im/nimbus-eth1.git
synced 2025-01-12 05:14:14 +00:00
RPC: Move EVM-calling function estimateGas to rpcEstimateGas
`estimateGas` used by JSON-RPC is another way to setup and call the EVM, also used by GraphQL. Move it to `transaction/call_evm`. This function has too much direct knowledge of details that shouldn't be used outside transaction handling code, details we need to change when changing the db and transaction memory layer. Moving this one exposed quite a bit of abstraction leakage, as it calls directly to the hexary trie db around `processTransaction`. It looks like the _intended_ functionality of `estimateGas` is similar to `rpcDoCall` with the only real difference being to not store the final state. It looks like the extra stuff in `estimateGas` compared with `doCall` is a messy workaround for computation not exposing the right API ("don't save final state") for RPC to use. Signed-off-by: Jamie Lokier <jamie@shareable.org>
This commit is contained in:
parent
2732af99eb
commit
8bda81496a
@ -778,7 +778,7 @@ proc blockEstimateGas(ud: RootRef, params: Args, parent: Node): RespResult {.api
|
|||||||
let param = params[0].val
|
let param = params[0].val
|
||||||
try:
|
try:
|
||||||
let (callData, gasLimit) = toCallData(param)
|
let (callData, gasLimit) = toCallData(param)
|
||||||
let gasUsed = estimateGas(callData, h.header, ctx.chainDB, gasLimit)
|
let gasUsed = rpcEstimateGas(callData, h.header, ctx.chainDB, gasLimit)
|
||||||
longNode(gasUsed)
|
longNode(gasUsed)
|
||||||
except Exception as em:
|
except Exception as em:
|
||||||
err("estimateGas error: " & em.msg)
|
err("estimateGas error: " & em.msg)
|
||||||
|
@ -275,7 +275,7 @@ proc setupEthRpc*(node: EthereumNode, chain: BaseChainDB , server: RpcServer) =
|
|||||||
let
|
let
|
||||||
header = chain.headerFromTag(quantityTag)
|
header = chain.headerFromTag(quantityTag)
|
||||||
callData = callData(call, false, chain)
|
callData = callData(call, false, chain)
|
||||||
gasUsed = estimateGas(callData, header, chain, call.gas.isSome)
|
gasUsed = rpcEstimateGas(callData, header, chain, call.gas.isSome)
|
||||||
result = encodeQuantity(gasUsed.uint64)
|
result = encodeQuantity(gasUsed.uint64)
|
||||||
|
|
||||||
server.rpc("eth_getBlockByHash") do(data: EthHashStr, fullTransactions: bool) -> Option[BlockObject]:
|
server.rpc("eth_getBlockByHash") do(data: EthHashStr, fullTransactions: bool) -> Option[BlockObject]:
|
||||||
|
@ -180,28 +180,6 @@ proc callData*(call: EthCall, callMode: bool = true, chain: BaseChainDB): RpcCal
|
|||||||
if call.data.isSome:
|
if call.data.isSome:
|
||||||
result.data = hexToSeqByte(call.data.get.string)
|
result.data = hexToSeqByte(call.data.get.string)
|
||||||
|
|
||||||
proc estimateGas*(call: RpcCallData, header: BlockHeader, chain: BaseChainDB, haveGasLimit: bool): GasInt =
|
|
||||||
var
|
|
||||||
# we use current header stateRoot, unlike block validation
|
|
||||||
# which use previous block stateRoot
|
|
||||||
vmState = newBaseVMState(header.stateRoot, header, chain)
|
|
||||||
fork = toFork(chain.config, header.blockNumber)
|
|
||||||
tx = Transaction(
|
|
||||||
accountNonce: vmState.accountdb.getNonce(call.source),
|
|
||||||
gasPrice: call.gasPrice,
|
|
||||||
gasLimit: if haveGasLimit: call.gas else: header.gasLimit - vmState.cumulativeGasUsed,
|
|
||||||
to : call.to,
|
|
||||||
value : call.value,
|
|
||||||
payload : call.data,
|
|
||||||
isContractCreation: call.contractCreation
|
|
||||||
)
|
|
||||||
|
|
||||||
var dbTx = chain.db.beginTransaction()
|
|
||||||
defer: dbTx.dispose()
|
|
||||||
result = processTransaction(tx, call.source, vmState, fork)
|
|
||||||
dbTx.dispose()
|
|
||||||
# TODO: handle revert and error
|
|
||||||
|
|
||||||
proc populateTransactionObject*(tx: Transaction, header: BlockHeader, txIndex: int): TransactionObject =
|
proc populateTransactionObject*(tx: Transaction, header: BlockHeader, txIndex: int): TransactionObject =
|
||||||
result.blockHash = some(header.hash)
|
result.blockHash = some(header.hash)
|
||||||
result.blockNumber = some(encodeQuantity(header.blockNumber))
|
result.blockNumber = some(encodeQuantity(header.blockNumber))
|
||||||
|
@ -9,7 +9,8 @@
|
|||||||
import
|
import
|
||||||
eth/common/eth_types, stint, options,
|
eth/common/eth_types, stint, options,
|
||||||
".."/[vm_types, vm_types2, vm_state, vm_computation],
|
".."/[vm_types, vm_types2, vm_state, vm_computation],
|
||||||
".."/[db/db_chain, config, vm_state_transactions, rpc/hexstrings]
|
".."/[db/db_chain, config, vm_state_transactions, rpc/hexstrings],
|
||||||
|
".."/[db/accounts_cache, p2p/executor], eth/trie/db
|
||||||
|
|
||||||
type
|
type
|
||||||
RpcCallData* = object
|
RpcCallData* = object
|
||||||
@ -53,3 +54,25 @@ proc rpcDoCall*(call: RpcCallData, header: BlockHeader, chain: BaseChainDB): Hex
|
|||||||
|
|
||||||
comp.execComputation()
|
comp.execComputation()
|
||||||
result = hexDataStr(comp.output)
|
result = hexDataStr(comp.output)
|
||||||
|
|
||||||
|
proc rpcEstimateGas*(call: RpcCallData, header: BlockHeader, chain: BaseChainDB, haveGasLimit: bool): GasInt =
|
||||||
|
# TODO: handle revert and error
|
||||||
|
var
|
||||||
|
# we use current header stateRoot, unlike block validation
|
||||||
|
# which use previous block stateRoot
|
||||||
|
vmState = newBaseVMState(header.stateRoot, header, chain)
|
||||||
|
fork = toFork(chain.config, header.blockNumber)
|
||||||
|
tx = Transaction(
|
||||||
|
accountNonce: vmState.accountdb.getNonce(call.source),
|
||||||
|
gasPrice: call.gasPrice,
|
||||||
|
gasLimit: if haveGasLimit: call.gas else: header.gasLimit - vmState.cumulativeGasUsed,
|
||||||
|
to : call.to,
|
||||||
|
value : call.value,
|
||||||
|
payload : call.data,
|
||||||
|
isContractCreation: call.contractCreation
|
||||||
|
)
|
||||||
|
|
||||||
|
var dbTx = chain.db.beginTransaction()
|
||||||
|
defer: dbTx.dispose()
|
||||||
|
result = processTransaction(tx, call.source, vmState, fork)
|
||||||
|
dbTx.dispose()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user