cache miner address instead of recalculation

This commit is contained in:
jangko 2020-06-22 07:48:23 +07:00
parent 9d0b399213
commit f401622782
No known key found for this signature in database
GPG Key ID: 31702AE10541E6B9
5 changed files with 22 additions and 13 deletions

View File

@ -36,7 +36,7 @@ method getAncestorHeader*(c: Chain, h: BlockHeader, output: var BlockHeader, ski
method getBlockBody*(c: Chain, blockHash: KeccakHash): BlockBodyRef =
result = nil
method persistBlocks*(c: Chain, headers: openarray[BlockHeader], bodies: openarray[BlockBody]): ValidationResult =
method persistBlocks*(c: Chain, headers: openarray[BlockHeader], bodies: openarray[BlockBody]): ValidationResult {.gcsafe.} =
# Run the VM here
if headers.len != bodies.len:
debug "Number of headers not matching number of bodies"

View File

@ -26,7 +26,7 @@ proc processTransaction*(tx: Transaction, sender: EthAddress, vmState: BaseVMSta
vmState.cumulativeGasUsed += result
let miner = vmState.getMinerAddress()
let miner = vmState.coinbase()
vmState.mutateStateDB:
# miner fee

View File

@ -103,7 +103,9 @@ proc traceTransaction*(chainDB: BaseChainDB, header: BlockHeader,
stateDiff = %{"before": before, "after": after}
beforeRoot: Hash256
let fork = chainDB.config.toFork(header.blockNumber)
let
fork = chainDB.config.toFork(header.blockNumber)
miner = vmState.coinbase()
for idx, tx in body.transactions:
let sender = tx.getSender
@ -113,7 +115,7 @@ proc traceTransaction*(chainDB: BaseChainDB, header: BlockHeader,
vmState.enableTracing()
before.captureAccount(stateDb, sender, senderName)
before.captureAccount(stateDb, recipient, recipientName)
before.captureAccount(stateDb, header.coinbase, minerName)
before.captureAccount(stateDb, miner, minerName)
stateDb.persist()
stateDiff["beforeRoot"] = %($stateDb.rootHash)
beforeRoot = stateDb.rootHash
@ -123,8 +125,8 @@ proc traceTransaction*(chainDB: BaseChainDB, header: BlockHeader,
if idx == txIndex:
after.captureAccount(stateDb, sender, senderName)
after.captureAccount(stateDb, recipient, recipientName)
after.captureAccount(stateDb, header.coinbase, minerName)
vmState.removeTracedAccounts(sender, recipient, header.coinbase)
after.captureAccount(stateDb, miner, minerName)
vmState.removeTracedAccounts(sender, recipient, miner)
stateDb.persist()
stateDiff["afterRoot"] = %($stateDb.rootHash)
break
@ -156,6 +158,7 @@ proc dumpBlockState*(db: BaseChainDB, header: BlockHeader, body: BlockBody, dump
captureChainDB = newBaseChainDB(captureTrieDB, false, PublicNetWork(db.config.chainId))
# we only need stack dump if we want to scan for internal transaction address
vmState = newBaseVMState(parent.stateRoot, header, captureChainDB, {EnableTracing, DisableMemory, DisableStorage, EnableAccount})
miner = vmState.coinbase()
var
before = newJArray()
@ -168,7 +171,7 @@ proc dumpBlockState*(db: BaseChainDB, header: BlockHeader, body: BlockBody, dump
before.captureAccount(stateBefore, sender, senderName & $idx)
before.captureAccount(stateBefore, recipient, recipientName & $idx)
before.captureAccount(stateBefore, header.coinbase, minerName)
before.captureAccount(stateBefore, miner, minerName)
for idx, uncle in body.uncles:
before.captureAccount(stateBefore, uncle.coinbase, uncleName & $idx)
@ -184,8 +187,8 @@ proc dumpBlockState*(db: BaseChainDB, header: BlockHeader, body: BlockBody, dump
after.captureAccount(stateAfter, recipient, recipientName & $idx)
vmState.removeTracedAccounts(sender, recipient)
after.captureAccount(stateAfter, header.coinbase, minerName)
vmState.removeTracedAccounts(header.coinbase)
after.captureAccount(stateAfter, miner, minerName)
vmState.removeTracedAccounts(miner)
for idx, uncle in body.uncles:
after.captureAccount(stateAfter, uncle.coinbase, uncleName & $idx)

View File

@ -26,6 +26,8 @@ proc `$`*(vmState: BaseVMState): string =
else:
result = &"VMState {vmState.name}:\n header: {vmState.blockHeader}\n chaindb: {vmState.chaindb}"
proc getMinerAddress(vmState: BaseVMState): EthAddress
proc init*(self: BaseVMState, prevStateRoot: Hash256, header: BlockHeader,
chainDB: BaseChainDB, tracerFlags: set[TracerFlags] = {}) =
self.prevHeaders = @[]
@ -37,6 +39,8 @@ proc init*(self: BaseVMState, prevStateRoot: Hash256, header: BlockHeader,
self.logEntries = @[]
self.accountDb = AccountsCache.init(chainDB.db, prevStateRoot, chainDB.pruneTrie)
self.touchedAccounts = initHashSet[EthAddress]()
{.gcsafe.}:
self.minerAddress = self.getMinerAddress()
proc newBaseVMState*(prevStateRoot: Hash256, header: BlockHeader,
chainDB: BaseChainDB, tracerFlags: set[TracerFlags] = {}): BaseVMState =
@ -78,7 +82,7 @@ proc headerHashOriExtraData(vmState: BaseVMState): Hash256 =
tmp.extraData.setLen(tmp.extraData.len-65)
result = keccak256.digest(rlp.encode(tmp))
proc getPubkey(sigRaw: openArray[byte], vmState: BaseVMState, output: var EthAddress): bool =
proc calcMinerAddress(sigRaw: openArray[byte], vmState: BaseVMState, output: var EthAddress): bool =
var sig: Signature
if sigRaw.getSignature(sig):
let headerHash = headerHashOriExtraData(vmState)
@ -87,7 +91,7 @@ proc getPubkey(sigRaw: openArray[byte], vmState: BaseVMState, output: var EthAdd
output = pubkey[].toCanonicalAddress()
result = true
proc getMinerAddress*(vmState: BaseVMState): EthAddress =
proc getMinerAddress(vmState: BaseVMState): EthAddress =
if not vmState.consensusEnginePoA:
return vmState.blockHeader.coinbase
@ -98,7 +102,7 @@ proc getMinerAddress*(vmState: BaseVMState): EthAddress =
doAssert(len >= 65)
var miner: EthAddress
if getPubkey(data.toOpenArray(len - 65, len-1), vmState, miner):
if calcMinerAddress(data.toOpenArray(len - 65, len-1), vmState, miner):
result = miner
else:
raise newException(ValidationError, "Could not derive miner address from header extradata")
@ -111,12 +115,13 @@ proc updateBlockHeader*(vmState: BaseVMState, header: BlockHeader) =
vmState.tracer.initTracer(vmState.tracer.flags)
vmState.logEntries = @[]
vmState.receipts = @[]
vmState.minerAddress = vmState.getMinerAddress()
method blockhash*(vmState: BaseVMState): Hash256 {.base, gcsafe.} =
vmState.blockHeader.hash
method coinbase*(vmState: BaseVMState): EthAddress {.base, gcsafe.} =
vmState.blockHeader.coinbase
vmState.minerAddress
method timestamp*(vmState: BaseVMState): EthTime {.base, gcsafe.} =
vmState.blockHeader.timestamp

View File

@ -39,6 +39,7 @@ type
txGasPrice* : GasInt
gasCosts* : GasCosts
fork* : Fork
minerAddress* : EthAddress
AccessLogs* = ref object
reads*: Table[string, string]