Skip to content

Commit 38cbba7

Browse files
author
Nicolas Tallar
committed
[ETCM-44] Treasury block reward distribution
1 parent 6a58490 commit 38cbba7

File tree

21 files changed

+177
-110
lines changed

21 files changed

+177
-110
lines changed

src/ets/scala/io/iohk/ethereum/ets/blockchain/BlockchainTestConfig.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,8 @@ object BlockchainTestConfig {
4343
atlantisBlockNumber = Long.MaxValue,
4444
aghartaBlockNumber = Long.MaxValue,
4545
phoenixBlockNumber = Long.MaxValue,
46-
ecip1098BlockNumber = Long.MaxValue
46+
ecip1098BlockNumber = Long.MaxValue,
47+
treasuryAddress = Address(0)
4748
)
4849

4950
val FrontierConfig = BaseBlockchainConfig.copy(

src/it/scala/io/iohk/ethereum/txExecTest/ECIP1017Test.scala

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@ package io.iohk.ethereum.txExecTest
22

33
import java.util.concurrent.Executors
44

5-
import io.iohk.ethereum.domain.{ BlockchainImpl, Receipt, UInt256 }
5+
import io.iohk.ethereum.domain.{Address, BlockchainImpl, Receipt, UInt256}
66
import io.iohk.ethereum.ledger._
77
import io.iohk.ethereum.txExecTest.util.FixtureProvider
8-
import io.iohk.ethereum.utils.{ BlockchainConfig, MonetaryPolicyConfig }
9-
import org.scalatest.{ FlatSpec, Matchers }
8+
import io.iohk.ethereum.utils.{BlockchainConfig, MonetaryPolicyConfig}
9+
import org.scalatest.{FlatSpec, Matchers}
1010

1111
import scala.concurrent.ExecutionContext
1212

@@ -47,7 +47,8 @@ class ECIP1017Test extends FlatSpec with Matchers {
4747
aghartaBlockNumber = Long.MaxValue,
4848
phoenixBlockNumber = Long.MaxValue,
4949
petersburgBlockNumber = Long.MaxValue,
50-
ecip1098BlockNumber = Long.MaxValue
50+
ecip1098BlockNumber = Long.MaxValue,
51+
treasuryAddress = Address(0)
5152
)
5253
val ec = ExecutionContext.fromExecutor(Executors.newFixedThreadPool(4))
5354

src/it/scala/io/iohk/ethereum/txExecTest/ForksTest.scala

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@ package io.iohk.ethereum.txExecTest
22

33
import java.util.concurrent.Executors
44

5-
import io.iohk.ethereum.domain.{ BlockchainImpl, Receipt, UInt256 }
6-
import io.iohk.ethereum.ledger.{ BlockExecution, BlockQueue, BlockValidation }
5+
import io.iohk.ethereum.domain.{Address, BlockchainImpl, Receipt, UInt256}
6+
import io.iohk.ethereum.ledger.{BlockExecution, BlockQueue, BlockValidation}
77
import io.iohk.ethereum.txExecTest.util.FixtureProvider
8-
import io.iohk.ethereum.utils.{ BlockchainConfig, MonetaryPolicyConfig }
9-
import org.scalatest.{ FlatSpec, Matchers }
8+
import io.iohk.ethereum.utils.{BlockchainConfig, MonetaryPolicyConfig}
9+
import org.scalatest.{FlatSpec, Matchers}
1010

1111
import scala.concurrent.ExecutionContext
1212

@@ -44,7 +44,8 @@ class ForksTest extends FlatSpec with Matchers {
4444
aghartaBlockNumber = Long.MaxValue,
4545
phoenixBlockNumber = Long.MaxValue,
4646
petersburgBlockNumber = Long.MaxValue,
47-
ecip1098BlockNumber = Long.MaxValue
47+
ecip1098BlockNumber = Long.MaxValue,
48+
treasuryAddress = Address(0)
4849
)
4950

5051
val noErrors = a[Right[_, Seq[Receipt]]]

src/main/resources/chains/etc-chain.conf

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@
8080

8181
# Proto-treasury fork block number (ETC only, but deactivated for now)
8282
# https://ecips.ethereumclassic.org/ECIPs/ecip-1098
83+
treasury-address = "0011223344556677889900112233445566778899"
8384
ecip1098-block-number = "1000000000000000000"
8485

8586
# DAO fork configuration (Ethereum HF/Classic split)

src/main/resources/chains/eth-chain.conf

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@
8080

8181
# Proto-treasury fork block number (ETC only, but deactivated for now)
8282
# https://ecips.ethereumclassic.org/ECIPs/ecip-1098
83+
treasury-address = "0011223344556677889900112233445566778899"
8384
ecip1098-block-number = "1000000000000000000"
8485

8586
# DAO fork configuration (Ethereum HF/Classic split)

src/main/resources/chains/mordor-chain.conf

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@
8080

8181
# Proto-treasury fork block number (ETC only, but deactivated for now)
8282
# https://ecips.ethereumclassic.org/ECIPs/ecip-1098
83+
treasury-address = "0011223344556677889900112233445566778899"
8384
ecip1098-block-number = "1000000000000000000"
8485

8586
# DAO fork configuration (Ethereum HF/Classic split)

src/main/resources/chains/ropsten-chain.conf

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@
8383

8484
# Proto-treasury fork block number (ETC only, but deactivated for now)
8585
# https://ecips.ethereumclassic.org/ECIPs/ecip-1098
86+
treasury-address = "0011223344556677889900112233445566778899"
8687
ecip1098-block-number = "1000000000000000000"
8788

8889
# DAO fork configuration (Ethereum HF/Classic split)

src/main/resources/chains/test-chain.conf

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@
8080

8181
# Proto-treasury fork block number (ETC only, but deactivated for now)
8282
# https://ecips.ethereumclassic.org/ECIPs/ecip-1098
83+
treasury-address = "0011223344556677889900112233445566778899"
8384
ecip1098-block-number = "1000000000000000000"
8485

8586
# DAO fork configuration (Ethereum HF/Classic split)

src/main/resources/chains/testnet-internal-chain.conf

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@
8080

8181
# Proto-treasury fork block number (ETC only, but deactivated for now)
8282
# https://ecips.ethereumclassic.org/ECIPs/ecip-1098
83+
treasury-address = "0011223344556677889900112233445566778899"
8384
ecip1098-block-number = "1000000000000000000"
8485

8586
# DAO fork configuration (Ethereum HF/Classic split)

src/main/scala/io/iohk/ethereum/ledger/BlockPreparator.scala

Lines changed: 45 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import io.iohk.ethereum.domain.UInt256._
66
import io.iohk.ethereum.domain._
77
import io.iohk.ethereum.ledger.BlockExecutionError.{StateBeforeFailure, TxsExecutionError}
88
import io.iohk.ethereum.ledger.Ledger._
9+
import io.iohk.ethereum.ledger.BlockPreparator._
910
import io.iohk.ethereum.utils.{BlockchainConfig, Logger}
1011
import 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

Comments
 (0)