@@ -6,6 +6,7 @@ import io.iohk.ethereum.domain.UInt256._
66import io .iohk .ethereum .domain ._
77import io .iohk .ethereum .ledger .BlockExecutionError .{StateBeforeFailure , TxsExecutionError }
88import io .iohk .ethereum .ledger .Ledger ._
9+ import io .iohk .ethereum .ledger .BlockPreparator ._
910import io .iohk .ethereum .utils .{BlockchainConfig , Logger }
1011import io .iohk .ethereum .vm .{PC => _ , _ }
1112
@@ -45,26 +46,47 @@ class BlockPreparator(
4546 * @return
4647 */
4748 private [ledger] def payBlockReward (block : Block , worldStateProxy : InMemoryWorldStateProxy ): InMemoryWorldStateProxy = {
48- def getAccountToPay (address : Address , ws : InMemoryWorldStateProxy ): Account =
49- ws.getAccount(address).getOrElse(Account .empty(blockchainConfig.accountStartNonce))
50-
5149 val blockNumber = block.header.number
5250
51+ val rewardForBlock = blockRewardCalculator.calculateMiningRewardForBlock(blockNumber)
52+ val minerRewardForOmmers = blockRewardCalculator.calculateMiningRewardForOmmers(blockNumber, block.body.uncleNodesList.size)
53+
5354 val minerAddress = Address (block.header.beneficiary)
54- val minerAccount = getAccountToPay(minerAddress, worldStateProxy)
55- val minerReward = blockRewardCalculator.calcBlockMinerReward(blockNumber, block.body.uncleNodesList.size)
55+ val treasuryAddress = blockchainConfig.treasuryAddress
56+ val existsTreasuryContract = worldStateProxy.getAccount(treasuryAddress).isDefined
5657
57- val afterMinerReward = worldStateProxy.saveAccount(minerAddress, minerAccount.increaseBalance(UInt256 (minerReward)))
58- log.debug(s " Paying block $blockNumber reward of $minerReward to miner with account address $minerAddress" )
58+ val worldAfterPayingBlockReward =
59+ if (block.header.treasuryOptOut.isEmpty || ! existsTreasuryContract) {
60+ val minerReward = minerRewardForOmmers + rewardForBlock
61+ val worldAfterMinerReward = pay(minerAddress, UInt256 (minerReward), withTouch = false )(worldStateProxy)
62+ log.debug(s " Paying block $blockNumber reward of $minerReward to miner with address $minerAddress" )
5963
60- block.body.uncleNodesList.foldLeft(afterMinerReward) { (ws, ommer) =>
61- val ommerAddress = Address (ommer.beneficiary)
62- val account = getAccountToPay(ommerAddress, ws)
64+ worldAfterMinerReward
65+ } else if (block.header.treasuryOptOut.get) {
66+ val minerReward = minerRewardForOmmers + rewardForBlock * MinerRewardPercentageAfterECIP1098 / 100
67+ val worldAfterMinerReward = increaseAccountBalance(minerAddress, UInt256 (minerReward))(worldStateProxy)
68+ log.debug(s " Paying block $blockNumber reward of $minerReward to miner with address $minerAddress, miner opted-out of treasury " )
69+
70+ worldAfterMinerReward
71+ } else {
72+ val minerReward = minerRewardForOmmers + rewardForBlock * MinerRewardPercentageAfterECIP1098 / 100
73+ val worldAfterMinerReward = increaseAccountBalance(minerAddress, UInt256 (minerReward))(worldStateProxy)
6374
64- val ommerReward = blockRewardCalculator.calcOmmerMinerReward(blockNumber, ommer.number)
75+ val treasuryReward = rewardForBlock * TreasuryRewardPercentageAfterECIP1098 / 100
76+ val worldAfterTreasuryReward = increaseAccountBalance(treasuryAddress, UInt256 (treasuryReward))(worldAfterMinerReward)
77+
78+ log.debug(s " Paying block $blockNumber reward of $minerReward to miner with address $minerAddress" +
79+ s " paying treasury reward of $treasuryReward to treasury with address $treasuryAddress" )
80+
81+ worldAfterTreasuryReward
82+ }
83+
84+ block.body.uncleNodesList.foldLeft(worldAfterPayingBlockReward) { (ws, ommer) =>
85+ val ommerAddress = Address (ommer.beneficiary)
86+ val ommerReward = blockRewardCalculator.calculateOmmerRewardForInclusion(blockNumber, ommer.number)
6587
6688 log.debug(s " Paying block $blockNumber reward of $ommerReward to ommer with account address $ommerAddress" )
67- ws.saveAccount (ommerAddress, account.increaseBalance( UInt256 (ommerReward)))
89+ increaseAccountBalance (ommerAddress, UInt256 (ommerReward))(ws )
6890 }
6991 }
7092
@@ -120,13 +142,16 @@ class BlockPreparator(
120142 }
121143 }
122144
145+ private [ledger] def increaseAccountBalance (address : Address , value : UInt256 )(world : InMemoryWorldStateProxy ): InMemoryWorldStateProxy = {
146+ val account = world.getAccount(address).getOrElse(Account .empty(blockchainConfig.accountStartNonce)).increaseBalance(value)
147+ world.saveAccount(address, account)
148+ }
149+
123150 private [ledger] def pay (address : Address , value : UInt256 , withTouch : Boolean )(world : InMemoryWorldStateProxy ): InMemoryWorldStateProxy = {
124151 if (world.isZeroValueTransferToNonExistentAccount(address, value)) {
125152 world
126153 } else {
127- val account = world.getAccount(address).getOrElse(Account .empty(blockchainConfig.accountStartNonce)).increaseBalance(value)
128- val savedWorld = world.saveAccount(address, account)
129-
154+ val savedWorld = increaseAccountBalance(address, value)(world)
130155 if (withTouch) savedWorld.touchAccounts(address) else savedWorld
131156 }
132157 }
@@ -320,3 +345,8 @@ class BlockPreparator(
320345 }
321346 }
322347}
348+
349+ object BlockPreparator {
350+ val TreasuryRewardPercentageAfterECIP1098 = 20
351+ val MinerRewardPercentageAfterECIP1098 = 100 - TreasuryRewardPercentageAfterECIP1098
352+ }
0 commit comments