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
|
vmState.cumulativeGasUsed += result
|
||||||
|
|
||||||
|
let miner = vmState.getMinerAddress()
|
||||||
|
|
||||||
vmState.mutateStateDB:
|
vmState.mutateStateDB:
|
||||||
# miner fee
|
# miner fee
|
||||||
let txFee = result.u256 * tx.gasPrice.u256
|
let txFee = result.u256 * tx.gasPrice.u256
|
||||||
db.addBalance(vmState.blockHeader.coinbase, txFee)
|
db.addBalance(miner, txFee)
|
||||||
|
|
||||||
for deletedAccount in vmState.suicides:
|
for deletedAccount in vmState.suicides:
|
||||||
db.deleteAccount deletedAccount
|
db.deleteAccount deletedAccount
|
||||||
|
|
||||||
if fork >= FkSpurious:
|
if fork >= FkSpurious:
|
||||||
vmState.touchedAccounts.incl(vmState.blockHeader.coinbase)
|
vmState.touchedAccounts.incl(miner)
|
||||||
# EIP158/161 state clearing
|
# EIP158/161 state clearing
|
||||||
for account in vmState.touchedAccounts:
|
for account in vmState.touchedAccounts:
|
||||||
if db.accountExists(account) and db.isEmptyAccount(account):
|
if db.accountExists(account) and db.isEmptyAccount(account):
|
||||||
|
@ -93,6 +95,25 @@ const
|
||||||
eth2 # FkIstanbul
|
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 =
|
proc processBlock*(chainDB: BaseChainDB, header: BlockHeader, body: BlockBody, vmState: BaseVMState): ValidationResult =
|
||||||
var dbTx = chainDB.db.beginTransaction()
|
var dbTx = chainDB.db.beginTransaction()
|
||||||
defer: dbTx.dispose()
|
defer: dbTx.dispose()
|
||||||
|
@ -125,25 +146,16 @@ proc processBlock*(chainDB: BaseChainDB, header: BlockHeader, body: BlockBody, v
|
||||||
return ValidationResult.Error
|
return ValidationResult.Error
|
||||||
vmState.receipts[txIndex] = makeReceipt(vmState, fork)
|
vmState.receipts[txIndex] = makeReceipt(vmState, fork)
|
||||||
|
|
||||||
let blockReward = blockRewards[fork]
|
|
||||||
var mainReward = blockReward
|
|
||||||
if header.ommersHash != EMPTY_UNCLE_HASH:
|
if header.ommersHash != EMPTY_UNCLE_HASH:
|
||||||
let h = chainDB.persistUncles(body.uncles)
|
let h = chainDB.persistUncles(body.uncles)
|
||||||
if h != header.ommersHash:
|
if h != header.ommersHash:
|
||||||
debug "Uncle hash mismatch"
|
debug "Uncle hash mismatch"
|
||||||
return ValidationResult.Error
|
return ValidationResult.Error
|
||||||
for uncle in body.uncles:
|
|
||||||
var uncleReward = uncle.blockNumber.u256 + 8.u256
|
calculateReward(fork, header, body, vmState)
|
||||||
uncleReward -= header.blockNumber.u256
|
|
||||||
uncleReward = uncleReward * blockReward
|
|
||||||
uncleReward = uncleReward div 8.u256
|
|
||||||
vmState.mutateStateDB:
|
|
||||||
db.addBalance(uncle.coinbase, uncleReward)
|
|
||||||
mainReward += blockReward div 32.u256
|
|
||||||
|
|
||||||
# Reward beneficiary
|
# Reward beneficiary
|
||||||
vmState.mutateStateDB:
|
vmState.mutateStateDB:
|
||||||
db.addBalance(header.coinbase, mainReward)
|
|
||||||
if vmState.generateWitness:
|
if vmState.generateWitness:
|
||||||
db.collectWitnessData()
|
db.collectWitnessData()
|
||||||
db.persist(ClearCache in vmState.flags)
|
db.persist(ClearCache in vmState.flags)
|
||||||
|
|
|
@ -7,8 +7,8 @@
|
||||||
|
|
||||||
import
|
import
|
||||||
macros, strformat, tables, sets, options,
|
macros, strformat, tables, sets, options,
|
||||||
eth/common,
|
eth/[common, keys, rlp], nimcrypto/keccak,
|
||||||
vm/interpreter/[vm_forks, gas_costs],
|
vm/interpreter/[vm_forks, gas_costs], ./errors,
|
||||||
./constants, ./db/[db_chain, accounts_cache],
|
./constants, ./db/[db_chain, accounts_cache],
|
||||||
./utils, json, vm_types, vm/transaction_tracer,
|
./utils, json, vm_types, vm/transaction_tracer,
|
||||||
./config, ../stateless/[multi_keys, witness_from_tree, witness_types]
|
./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.chainDB.config.toFork(vmState.blockHeader.blockNumber)
|
||||||
vmState.gasCosts = vmState.fork.forkToSchedule
|
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) =
|
proc updateBlockHeader*(vmState: BaseVMState, header: BlockHeader) =
|
||||||
vmState.blockHeader = header
|
vmState.blockHeader = header
|
||||||
vmState.touchedAccounts.clear()
|
vmState.touchedAccounts.clear()
|
||||||
|
|
Loading…
Reference in New Issue