put traceTransaction into action
This commit is contained in:
parent
3570dd60ad
commit
157415fb44
|
@ -1,6 +1,6 @@
|
||||||
import ../db/[db_chain, state_db], eth_common, chronicles, ../vm_state, ../vm_types, ../transaction, ranges,
|
import ../db/[db_chain, state_db], eth_common, chronicles, ../vm_state, ../vm_types, ../transaction, ranges,
|
||||||
../vm/[computation, interpreter_dispatch, message], ../constants, stint, nimcrypto,
|
../vm/[computation, interpreter_dispatch, message], ../constants, stint, nimcrypto,
|
||||||
../vm_state_transactions, sugar, ../utils, eth_trie/db
|
../vm_state_transactions, sugar, ../utils, eth_trie/db, ../tracer, ./executor, json
|
||||||
|
|
||||||
type
|
type
|
||||||
Chain* = ref object of AbstractChainDB
|
Chain* = ref object of AbstractChainDB
|
||||||
|
@ -30,72 +30,6 @@ method getSuccessorHeader*(c: Chain, h: BlockHeader, output: var BlockHeader): b
|
||||||
method getBlockBody*(c: Chain, blockHash: KeccakHash): BlockBodyRef =
|
method getBlockBody*(c: Chain, blockHash: KeccakHash): BlockBodyRef =
|
||||||
result = nil
|
result = nil
|
||||||
|
|
||||||
proc processTransaction*(db: var AccountStateDB, t: Transaction, sender: EthAddress, vmState: BaseVMState): UInt256 =
|
|
||||||
## Process the transaction, write the results to db.
|
|
||||||
## Returns amount of ETH to be rewarded to miner
|
|
||||||
echo "Sender: ", sender
|
|
||||||
echo "txHash: ", t.rlpHash
|
|
||||||
# Inct nonce:
|
|
||||||
db.setNonce(sender, db.getNonce(sender) + 1)
|
|
||||||
var transactionFailed = false
|
|
||||||
|
|
||||||
#t.dump
|
|
||||||
|
|
||||||
# TODO: combine/refactor re validate
|
|
||||||
let upfrontGasCost = t.gasLimit.u256 * t.gasPrice.u256
|
|
||||||
let upfrontCost = upfrontGasCost + t.value
|
|
||||||
var balance = db.getBalance(sender)
|
|
||||||
if balance < upfrontCost:
|
|
||||||
if balance <= upfrontGasCost:
|
|
||||||
result = balance
|
|
||||||
balance = 0.u256
|
|
||||||
else:
|
|
||||||
result = upfrontGasCost
|
|
||||||
balance -= upfrontGasCost
|
|
||||||
transactionFailed = true
|
|
||||||
else:
|
|
||||||
balance -= upfrontCost
|
|
||||||
|
|
||||||
db.setBalance(sender, balance)
|
|
||||||
if transactionFailed:
|
|
||||||
return
|
|
||||||
|
|
||||||
var gasUsed = t.payload.intrinsicGas.GasInt # += 32000 appears in Homestead when contract create
|
|
||||||
|
|
||||||
if gasUsed > t.gasLimit:
|
|
||||||
echo "Transaction failed. Out of gas."
|
|
||||||
transactionFailed = true
|
|
||||||
else:
|
|
||||||
if t.isContractCreation:
|
|
||||||
# TODO: re-derive sender in callee for cleaner interface, perhaps
|
|
||||||
return applyCreateTransaction(db, t, vmState, sender)
|
|
||||||
|
|
||||||
else:
|
|
||||||
let code = db.getCode(t.to)
|
|
||||||
if code.len == 0:
|
|
||||||
# Value transfer
|
|
||||||
echo "Transfer ", t.value, " from ", sender, " to ", t.to
|
|
||||||
|
|
||||||
db.addBalance(t.to, t.value)
|
|
||||||
else:
|
|
||||||
# Contract call
|
|
||||||
echo "Contract call"
|
|
||||||
|
|
||||||
debug "Transaction", sender, to = t.to, value = t.value, hasCode = code.len != 0
|
|
||||||
let msg = newMessage(t.gasLimit, t.gasPrice, t.to, sender, t.value, t.payload, code.toSeq)
|
|
||||||
# TODO: Run the vm
|
|
||||||
|
|
||||||
if gasUsed > t.gasLimit:
|
|
||||||
gasUsed = t.gasLimit
|
|
||||||
|
|
||||||
var refund = (t.gasLimit - gasUsed).u256 * t.gasPrice.u256
|
|
||||||
if transactionFailed:
|
|
||||||
refund += t.value
|
|
||||||
|
|
||||||
db.addBalance(sender, refund)
|
|
||||||
|
|
||||||
return gasUsed.u256 * t.gasPrice.u256
|
|
||||||
|
|
||||||
method persistBlocks*(c: Chain, headers: openarray[BlockHeader], bodies: openarray[BlockBody]) =
|
method persistBlocks*(c: Chain, headers: openarray[BlockHeader], bodies: openarray[BlockBody]) =
|
||||||
# Run the VM here
|
# Run the VM here
|
||||||
assert(headers.len == bodies.len)
|
assert(headers.len == bodies.len)
|
||||||
|
@ -149,6 +83,10 @@ method persistBlocks*(c: Chain, headers: openarray[BlockHeader], bodies: openarr
|
||||||
|
|
||||||
if headers[i].stateRoot != stateDb.rootHash:
|
if headers[i].stateRoot != stateDb.rootHash:
|
||||||
echo "Wrong state root in block ", headers[i].blockNumber, ". Expected: ", headers[i].stateRoot, ", Actual: ", stateDb.rootHash, " arrived from ", c.db.getCanonicalHead().stateRoot
|
echo "Wrong state root in block ", headers[i].blockNumber, ". Expected: ", headers[i].stateRoot, ", Actual: ", stateDb.rootHash, " arrived from ", c.db.getCanonicalHead().stateRoot
|
||||||
|
let trace = traceTransaction(c.db, headers[i], bodies[i], bodies[i].transactions.len - 1, {})
|
||||||
|
echo "NIMBUS TRACE"
|
||||||
|
echo trace.pretty()
|
||||||
|
|
||||||
assert(headers[i].stateRoot == stateDb.rootHash)
|
assert(headers[i].stateRoot == stateDb.rootHash)
|
||||||
|
|
||||||
discard c.db.persistHeaderToDb(headers[i])
|
discard c.db.persistHeaderToDb(headers[i])
|
||||||
|
|
|
@ -0,0 +1,69 @@
|
||||||
|
import ../db/[db_chain, state_db], ../transaction, eth_common,
|
||||||
|
../vm_state, ../vm_types, ../vm_state_transactions, ranges,
|
||||||
|
chronicles, ../vm/[computation, interpreter_dispatch, message]
|
||||||
|
|
||||||
|
proc processTransaction*(db: var AccountStateDB, t: Transaction, sender: EthAddress, vmState: BaseVMState): UInt256 =
|
||||||
|
## Process the transaction, write the results to db.
|
||||||
|
## Returns amount of ETH to be rewarded to miner
|
||||||
|
echo "Sender: ", sender
|
||||||
|
echo "txHash: ", t.rlpHash
|
||||||
|
# Inct nonce:
|
||||||
|
db.setNonce(sender, db.getNonce(sender) + 1)
|
||||||
|
var transactionFailed = false
|
||||||
|
|
||||||
|
#t.dump
|
||||||
|
|
||||||
|
# TODO: combine/refactor re validate
|
||||||
|
let upfrontGasCost = t.gasLimit.u256 * t.gasPrice.u256
|
||||||
|
let upfrontCost = upfrontGasCost + t.value
|
||||||
|
var balance = db.getBalance(sender)
|
||||||
|
if balance < upfrontCost:
|
||||||
|
if balance <= upfrontGasCost:
|
||||||
|
result = balance
|
||||||
|
balance = 0.u256
|
||||||
|
else:
|
||||||
|
result = upfrontGasCost
|
||||||
|
balance -= upfrontGasCost
|
||||||
|
transactionFailed = true
|
||||||
|
else:
|
||||||
|
balance -= upfrontCost
|
||||||
|
|
||||||
|
db.setBalance(sender, balance)
|
||||||
|
if transactionFailed:
|
||||||
|
return
|
||||||
|
|
||||||
|
var gasUsed = t.payload.intrinsicGas.GasInt # += 32000 appears in Homestead when contract create
|
||||||
|
|
||||||
|
if gasUsed > t.gasLimit:
|
||||||
|
echo "Transaction failed. Out of gas."
|
||||||
|
transactionFailed = true
|
||||||
|
else:
|
||||||
|
if t.isContractCreation:
|
||||||
|
# TODO: re-derive sender in callee for cleaner interface, perhaps
|
||||||
|
return applyCreateTransaction(db, t, vmState, sender)
|
||||||
|
|
||||||
|
else:
|
||||||
|
let code = db.getCode(t.to)
|
||||||
|
if code.len == 0:
|
||||||
|
# Value transfer
|
||||||
|
echo "Transfer ", t.value, " from ", sender, " to ", t.to
|
||||||
|
|
||||||
|
db.addBalance(t.to, t.value)
|
||||||
|
else:
|
||||||
|
# Contract call
|
||||||
|
echo "Contract call"
|
||||||
|
|
||||||
|
debug "Transaction", sender, to = t.to, value = t.value, hasCode = code.len != 0
|
||||||
|
let msg = newMessage(t.gasLimit, t.gasPrice, t.to, sender, t.value, t.payload, code.toSeq)
|
||||||
|
# TODO: Run the vm
|
||||||
|
|
||||||
|
if gasUsed > t.gasLimit:
|
||||||
|
gasUsed = t.gasLimit
|
||||||
|
|
||||||
|
var refund = (t.gasLimit - gasUsed).u256 * t.gasPrice.u256
|
||||||
|
if transactionFailed:
|
||||||
|
refund += t.value
|
||||||
|
|
||||||
|
db.addBalance(sender, refund)
|
||||||
|
|
||||||
|
return gasUsed.u256 * t.gasPrice.u256
|
|
@ -1,6 +1,6 @@
|
||||||
import
|
import
|
||||||
db/[db_chain, state_db, capturedb], eth_common, utils, json,
|
db/[db_chain, state_db, capturedb], eth_common, utils, json,
|
||||||
constants, vm_state, vm_types, transaction, p2p/chain,
|
constants, vm_state, vm_types, transaction, p2p/executor,
|
||||||
eth_trie/db, nimcrypto
|
eth_trie/db, nimcrypto
|
||||||
|
|
||||||
proc getParentHeader(self: BaseChainDB, header: BlockHeader): BlockHeader =
|
proc getParentHeader(self: BaseChainDB, header: BlockHeader): BlockHeader =
|
||||||
|
@ -10,7 +10,7 @@ proc prefixHex(x: openArray[byte]): string =
|
||||||
"0x" & toHex(x, true)
|
"0x" & toHex(x, true)
|
||||||
|
|
||||||
proc traceTransaction*(db: BaseChainDB, header: BlockHeader,
|
proc traceTransaction*(db: BaseChainDB, header: BlockHeader,
|
||||||
body: BlockBody, txIndex: int, tracerFlags: set[TracerFlags]): JsonNode =
|
body: BlockBody, txIndex: int, tracerFlags: set[TracerFlags] = {}): JsonNode =
|
||||||
let
|
let
|
||||||
parent = db.getParentHeader(header)
|
parent = db.getParentHeader(header)
|
||||||
# we add a memory layer between backend/lower layer db
|
# we add a memory layer between backend/lower layer db
|
||||||
|
|
Loading…
Reference in New Issue