miner address calculation for PoA consensus engine
This commit is contained in:
parent
2e583e9aa0
commit
2385df7bae
|
@ -26,16 +26,18 @@ proc processTransaction*(tx: Transaction, sender: EthAddress, vmState: BaseVMSta
|
|||
|
||||
vmState.cumulativeGasUsed += result
|
||||
|
||||
let miner = vmState.getMinerAddress()
|
||||
|
||||
vmState.mutateStateDB:
|
||||
# miner fee
|
||||
let txFee = result.u256 * tx.gasPrice.u256
|
||||
db.addBalance(vmState.blockHeader.coinbase, txFee)
|
||||
db.addBalance(miner, txFee)
|
||||
|
||||
for deletedAccount in vmState.suicides:
|
||||
db.deleteAccount deletedAccount
|
||||
|
||||
if fork >= FkSpurious:
|
||||
vmState.touchedAccounts.incl(vmState.blockHeader.coinbase)
|
||||
vmState.touchedAccounts.incl(miner)
|
||||
# EIP158/161 state clearing
|
||||
for account in vmState.touchedAccounts:
|
||||
if db.accountExists(account) and db.isEmptyAccount(account):
|
||||
|
@ -93,6 +95,25 @@ const
|
|||
eth2 # FkIstanbul
|
||||
]
|
||||
|
||||
proc calculateReward(fork: Fork, header: BlockHeader, body: BlockBody, vmState: BaseVMState) =
|
||||
# PoA consensus engine have no reward for miner
|
||||
if vmState.consensusEnginePoA: return
|
||||
|
||||
let blockReward = blockRewards[fork]
|
||||
var mainReward = blockReward
|
||||
|
||||
for uncle in body.uncles:
|
||||
var uncleReward = uncle.blockNumber.u256 + 8.u256
|
||||
uncleReward -= header.blockNumber.u256
|
||||
uncleReward = uncleReward * blockReward
|
||||
uncleReward = uncleReward div 8.u256
|
||||
vmState.mutateStateDB:
|
||||
db.addBalance(uncle.coinbase, uncleReward)
|
||||
mainReward += blockReward div 32.u256
|
||||
|
||||
vmState.mutateStateDB:
|
||||
db.addBalance(header.coinbase, mainReward)
|
||||
|
||||
proc processBlock*(chainDB: BaseChainDB, header: BlockHeader, body: BlockBody, vmState: BaseVMState): ValidationResult =
|
||||
var dbTx = chainDB.db.beginTransaction()
|
||||
defer: dbTx.dispose()
|
||||
|
@ -125,25 +146,16 @@ proc processBlock*(chainDB: BaseChainDB, header: BlockHeader, body: BlockBody, v
|
|||
return ValidationResult.Error
|
||||
vmState.receipts[txIndex] = makeReceipt(vmState, fork)
|
||||
|
||||
let blockReward = blockRewards[fork]
|
||||
var mainReward = blockReward
|
||||
if header.ommersHash != EMPTY_UNCLE_HASH:
|
||||
let h = chainDB.persistUncles(body.uncles)
|
||||
if h != header.ommersHash:
|
||||
debug "Uncle hash mismatch"
|
||||
return ValidationResult.Error
|
||||
for uncle in body.uncles:
|
||||
var uncleReward = uncle.blockNumber.u256 + 8.u256
|
||||
uncleReward -= header.blockNumber.u256
|
||||
uncleReward = uncleReward * blockReward
|
||||
uncleReward = uncleReward div 8.u256
|
||||
vmState.mutateStateDB:
|
||||
db.addBalance(uncle.coinbase, uncleReward)
|
||||
mainReward += blockReward div 32.u256
|
||||
|
||||
calculateReward(fork, header, body, vmState)
|
||||
|
||||
# Reward beneficiary
|
||||
vmState.mutateStateDB:
|
||||
db.addBalance(header.coinbase, mainReward)
|
||||
if vmState.generateWitness:
|
||||
db.collectWitnessData()
|
||||
db.persist(ClearCache in vmState.flags)
|
||||
|
|
|
@ -7,8 +7,8 @@
|
|||
|
||||
import
|
||||
macros, strformat, tables, sets, options,
|
||||
eth/common,
|
||||
vm/interpreter/[vm_forks, gas_costs],
|
||||
eth/[common, keys, rlp], nimcrypto/keccak,
|
||||
vm/interpreter/[vm_forks, gas_costs], ./errors,
|
||||
./constants, ./db/[db_chain, accounts_cache],
|
||||
./utils, json, vm_types, vm/transaction_tracer,
|
||||
./config, ../stateless/[multi_keys, witness_from_tree, witness_types]
|
||||
|
@ -61,6 +61,48 @@ proc setupTxContext*(vmState: BaseVMState, origin: EthAddress, gasPrice: GasInt,
|
|||
vmState.chainDB.config.toFork(vmState.blockHeader.blockNumber)
|
||||
vmState.gasCosts = vmState.fork.forkToSchedule
|
||||
|
||||
proc consensusEnginePoA*(vmState: BaseVMState): bool =
|
||||
let chainId = PublicNetwork(vmState.chainDB.config.chainId)
|
||||
# PoA consensus engine have no reward for miner
|
||||
result = chainId in {GoerliNet, RinkebyNet, KovanNet}
|
||||
|
||||
proc getSignature(bytes: openArray[byte], output: var Signature): bool =
|
||||
let sig = Signature.fromRaw(bytes)
|
||||
if sig.isOk:
|
||||
output = sig[]
|
||||
return true
|
||||
return false
|
||||
|
||||
proc headerHashOriExtraData(vmState: BaseVMState): Hash256 =
|
||||
var tmp = vmState.blockHeader
|
||||
tmp.extraData.setLen(tmp.extraData.len-65)
|
||||
result = keccak256.digest(rlp.encode(tmp))
|
||||
|
||||
proc getPubkey(sigRaw: openArray[byte], vmState: BaseVMState, output: var EthAddress): bool =
|
||||
var sig: Signature
|
||||
if sigRaw.getSignature(sig):
|
||||
let headerHash = headerHashOriExtraData(vmState)
|
||||
let pubkey = recover(sig, headerHash)
|
||||
if pubkey.isOk:
|
||||
output = pubkey[].toCanonicalAddress()
|
||||
result = true
|
||||
|
||||
proc getMinerAddress*(vmState: BaseVMState): EthAddress =
|
||||
if not vmState.consensusEnginePoA:
|
||||
return vmState.blockHeader.coinbase
|
||||
|
||||
template data: untyped =
|
||||
vmState.blockHeader.extraData
|
||||
|
||||
let len = data.len
|
||||
doAssert(len >= 65)
|
||||
|
||||
var miner: EthAddress
|
||||
if getPubkey(data.toOpenArray(len - 65, len-1), vmState, miner):
|
||||
result = miner
|
||||
else:
|
||||
raise newException(ValidationError, "Could not derive miner address from header extradata")
|
||||
|
||||
proc updateBlockHeader*(vmState: BaseVMState, header: BlockHeader) =
|
||||
vmState.blockHeader = header
|
||||
vmState.touchedAccounts.clear()
|
||||
|
|
Loading…
Reference in New Issue