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 = method getBlockBody*(c: Chain, blockHash: KeccakHash): BlockBodyRef =
result = nil 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 # Run the VM here
if headers.len != bodies.len: if headers.len != bodies.len:
debug "Number of headers not matching number of bodies" 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 vmState.cumulativeGasUsed += result
let miner = vmState.getMinerAddress() let miner = vmState.coinbase()
vmState.mutateStateDB: vmState.mutateStateDB:
# miner fee # miner fee

View File

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

View File

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

View File

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