Skip to content

Commit ce5236d

Browse files
[ETCM-1049] Berlin config (#1111)
* [ETCM-1049] Add Berlin block height to config * [ETCM-1049] Handle Berlin fork in the EVM * [ETCM-1049] Add Berlin gas specs
1 parent 852133b commit ce5236d

17 files changed

+95
-40
lines changed

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,9 @@
109109
# https://ecips.ethereumclassic.org/ECIPs/ecip-1103
110110
magneto-block-number = "13189133"
111111

112+
# Berlin fork block number (ETH only)
113+
berlin-block-number = "1000000000000000000"
114+
112115
# ECIP-1049 soft fork block number
113116
# https://ecips.ethereumclassic.org/ECIPs/ecip-1049
114117
# https://github.com/ethereumclassic/ECIPs/issues/394

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,9 @@
106106
# https://ecips.ethereumclassic.org/ECIPs/ecip-1103
107107
magneto-block-number = "1000000000000000000"
108108

109+
# Berlin fork block number (ETH only)
110+
berlin-block-number = "12244000"
111+
109112
# DAO fork configuration (Ethereum HF/Classic split)
110113
# https://blog.ethereum.org/2016/07/20/hard-fork-completed/
111114
dao {

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,9 @@
107107
# https://ecips.ethereumclassic.org/ECIPs/ecip-1103
108108
magneto-block-number = "3985893"
109109

110+
# Berlin fork block number (ETH only)
111+
berlin-block-number = "1000000000000000000"
112+
110113
# DAO fork configuration (Ethereum HF/Classic split)
111114
# https://blog.ethereum.org/2016/07/20/hard-fork-completed/
112115
dao = null

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,9 @@
110110
# https://ecips.ethereumclassic.org/ECIPs/ecip-1103
111111
magneto-block-number = "1000000000000000000"
112112

113+
# Berlin fork block number (ETH only)
114+
berlin-block-number = "9812189"
115+
113116
# DAO fork configuration (Ethereum HF/Classic split)
114117
# https://blog.ethereum.org/2016/07/20/hard-fork-completed/
115118
dao {

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,9 @@
107107
# https://ecips.ethereumclassic.org/ECIPs/ecip-1103
108108
magneto-block-number = "1000000000000000000"
109109

110+
# Berlin fork block number (ETH only)
111+
berlin-block-number = "1000000000000000000"
112+
110113
# DAO fork configuration (Ethereum HF/Classic split)
111114
# https://blog.ethereum.org/2016/07/20/hard-fork-completed/
112115
dao {

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,9 @@
106106
# https://ecips.ethereumclassic.org/ECIPs/ecip-1103
107107
magneto-block-number = "1000000000000000000"
108108

109+
# Berlin fork block number (ETH only)
110+
berlin-block-number = "1000000000000000000"
111+
109112
# DAO fork configuration (Ethereum HF/Classic split)
110113
# https://blog.ethereum.org/2016/07/20/hard-fork-completed/
111114
dao = null

src/main/scala/io/iohk/ethereum/extvm/VMServer.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,7 @@ class VMServer(messageHandler: MessageHandler) extends Logger {
208208
petersburgBlockNumber = BigInt(10000000), //TODO include petersburg block number in protobuf
209209
phoenixBlockNumber = BigInt(10500839), //TODO include phoenix block number in protobuf
210210
magnetoBlockNumber = BigInt(13189133), //TODO include magneto block number in protobuf
211+
berlinBlockNumber = BigInt("1000000000000000000"), //TODO include berlin block number in protobuf
211212
chainId = 0x3d.toByte //TODO include chainId in protobuf
212213
)
213214
}

src/main/scala/io/iohk/ethereum/utils/BlockchainConfig.scala

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,8 @@ case class ForkBlockNumbers(
6161
ecip1049BlockNumber: Option[BigInt],
6262
ecip1099BlockNumber: BigInt,
6363
muirGlacierBlockNumber: BigInt,
64-
magnetoBlockNumber: BigInt
64+
magnetoBlockNumber: BigInt,
65+
berlinBlockNumber: BigInt
6566
) {
6667
def all: List[BigInt] = this.productIterator.toList.flatMap {
6768
case i: BigInt => Some(i)
@@ -98,7 +99,8 @@ object ForkBlockNumbers {
9899
ecip1099BlockNumber = Long.MaxValue,
99100
ecip1049BlockNumber = None,
100101
muirGlacierBlockNumber = Long.MaxValue,
101-
magnetoBlockNumber = Long.MaxValue
102+
magnetoBlockNumber = Long.MaxValue,
103+
berlinBlockNumber = Long.MaxValue
102104
)
103105
}
104106

@@ -171,6 +173,7 @@ object BlockchainConfig {
171173
val ecip1099BlockNumber: BigInt = BigInt(blockchainConfig.getString("ecip1099-block-number"))
172174
val muirGlacierBlockNumber: BigInt = BigInt(blockchainConfig.getString("muir-glacier-block-number"))
173175
val magnetoBlockNumber: BigInt = BigInt(blockchainConfig.getString("magneto-block-number"))
176+
val berlinBlockNumber: BigInt = BigInt(blockchainConfig.getString("berlin-block-number"))
174177

175178
val capabilities: List[Capability] =
176179
blockchainConfig.getStringList("capabilities").asScala.toList.map(Capability.parseUnsafe)
@@ -200,7 +203,8 @@ object BlockchainConfig {
200203
ecip1049BlockNumber = ecip1049BlockNumber,
201204
ecip1099BlockNumber = ecip1099BlockNumber,
202205
muirGlacierBlockNumber = muirGlacierBlockNumber,
203-
magnetoBlockNumber = magnetoBlockNumber
206+
magnetoBlockNumber = magnetoBlockNumber,
207+
berlinBlockNumber = berlinBlockNumber
204208
),
205209
treasuryAddress = treasuryAddress,
206210
maxCodeSize = maxCodeSize,

src/main/scala/io/iohk/ethereum/vm/BlockchainConfigForEvm.scala

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import io.iohk.ethereum.vm.BlockchainConfigForEvm.EtcForks.EtcFork
99
import io.iohk.ethereum.vm.BlockchainConfigForEvm.EtcForks.Magneto
1010
import io.iohk.ethereum.vm.BlockchainConfigForEvm.EtcForks.Phoenix
1111
import io.iohk.ethereum.vm.BlockchainConfigForEvm.EthForks.BeforeByzantium
12+
import io.iohk.ethereum.vm.BlockchainConfigForEvm.EthForks.Berlin
1213
import io.iohk.ethereum.vm.BlockchainConfigForEvm.EthForks.Byzantium
1314
import io.iohk.ethereum.vm.BlockchainConfigForEvm.EthForks.Constantinople
1415
import io.iohk.ethereum.vm.BlockchainConfigForEvm.EthForks.Istanbul
@@ -37,6 +38,7 @@ case class BlockchainConfigForEvm(
3738
petersburgBlockNumber: BigInt,
3839
phoenixBlockNumber: BigInt,
3940
magnetoBlockNumber: BigInt,
41+
berlinBlockNumber: BigInt,
4042
chainId: Byte
4143
) {
4244
def etcForkForBlockNumber(blockNumber: BigInt): EtcFork = blockNumber match {
@@ -52,7 +54,8 @@ case class BlockchainConfigForEvm(
5254
case _ if blockNumber < constantinopleBlockNumber => Byzantium
5355
case _ if blockNumber < petersburgBlockNumber => Constantinople
5456
case _ if blockNumber < istanbulBlockNumber => Petersburg
55-
case _ if blockNumber >= istanbulBlockNumber => Istanbul
57+
case _ if blockNumber < berlinBlockNumber => Istanbul
58+
case _ if blockNumber >= berlinBlockNumber => Berlin
5659
}
5760
}
5861

@@ -68,7 +71,8 @@ object BlockchainConfigForEvm {
6871
val BeforeByzantium, Byzantium, Constantinople, Petersburg, Istanbul, Berlin = Value
6972
}
7073

71-
def isEip2929Enabled(etcFork: EtcFork): Boolean = etcFork >= EtcForks.Magneto
74+
def isEip2929Enabled(etcFork: EtcFork, ethFork: BlockchainConfigForEvm.EthForks.Value): Boolean =
75+
etcFork >= EtcForks.Magneto || ethFork >= EthForks.Berlin
7276

7377
def apply(blockchainConfig: BlockchainConfig): BlockchainConfigForEvm = {
7478
import blockchainConfig._
@@ -88,6 +92,7 @@ object BlockchainConfigForEvm {
8892
petersburgBlockNumber = forkBlockNumbers.petersburgBlockNumber,
8993
phoenixBlockNumber = forkBlockNumbers.phoenixBlockNumber,
9094
magnetoBlockNumber = forkBlockNumbers.magnetoBlockNumber,
95+
berlinBlockNumber = forkBlockNumbers.berlinBlockNumber,
9196
chainId = chainId
9297
)
9398
}

src/main/scala/io/iohk/ethereum/vm/EvmConfig.scala

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,8 @@ object EvmConfig {
4343
(blockchainConfig.petersburgBlockNumber, 8, PetersburgConfigBuilder),
4444
(blockchainConfig.istanbulBlockNumber, 9, IstanbulConfigBuilder),
4545
(blockchainConfig.phoenixBlockNumber, 9, PhoenixConfigBuilder),
46-
(blockchainConfig.magnetoBlockNumber, 10, MagnetoConfigBuilder)
46+
(blockchainConfig.magnetoBlockNumber, 10, MagnetoConfigBuilder),
47+
(blockchainConfig.berlinBlockNumber, 10, BerlinConfigBuilder)
4748
)
4849

4950
// highest transition block that is less/equal to `blockNumber`
@@ -140,6 +141,8 @@ object EvmConfig {
140141
opCodeList = MagnetoOpCodes
141142
)
142143

144+
val BerlinConfigBuilder: EvmConfigBuilder = MagnetoConfigBuilder
145+
143146
case class OpCodeList(opCodes: List[OpCode]) {
144147
val byteToOpCode: Map[Byte, OpCode] =
145148
opCodes.map(op => op.code -> op).toMap

src/main/scala/io/iohk/ethereum/vm/OpCode.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -189,9 +189,9 @@ object OpCode {
189189
postWarmGasFn: FeeSchedule => BigInt
190190
): BigInt = {
191191
val currentBlockNumber = state.env.blockHeader.number
192-
// FIXME: handle ETH Berlin here as well
193192
val etcFork = state.config.blockchainConfig.etcForkForBlockNumber(currentBlockNumber)
194-
val eip2929Enabled = isEip2929Enabled(etcFork)
193+
val ethFork = state.config.blockchainConfig.ethForkForBlockNumber(currentBlockNumber)
194+
val eip2929Enabled = isEip2929Enabled(etcFork, ethFork)
195195
if (eip2929Enabled) {
196196
if (isWarm)
197197
postWarmGasFn(state.config.feeSchedule)

src/test/scala/io/iohk/ethereum/extvm/VMClientSpec.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,7 @@ class VMClientSpec extends AnyFlatSpec with Matchers with MockFactory {
196196
petersburgBlockNumber = 0,
197197
phoenixBlockNumber = 0,
198198
magnetoBlockNumber = 0,
199+
berlinBlockNumber = 0,
199200
chainId = 0x3d.toByte
200201
)
201202
val evmConfig: EvmConfig = EvmConfig.FrontierConfigBuilder(blockchainConfigForEvm)

src/test/scala/io/iohk/ethereum/forkid/ForkIdSpec.scala

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ class ForkIdSpec extends AnyWordSpec with Matchers {
2626

2727
"gatherForks for the eth chain correctly" in {
2828
val res = config.blockchains.map { case (name, conf) => (name, gatherForks(conf)) }
29-
res("eth") shouldBe List(1150000, 1920000, 2463000, 2675000, 4370000, 7280000, 9069000, 9200000)
29+
res("eth") shouldBe List(1150000, 1920000, 2463000, 2675000, 4370000, 7280000, 9069000, 9200000, 12244000)
3030
}
3131

3232
"create correct ForkId for ETH mainnet blocks" in {
@@ -53,9 +53,11 @@ class ForkIdSpec extends AnyWordSpec with Matchers {
5353
create(9068999) shouldBe ForkId(0x668db0afL, Some(9069000)) // Last Petersburg block
5454
create(9069000) shouldBe ForkId(0x879d6e30L, Some(9200000)) // First Istanbul block
5555
create(9200000 - 1) shouldBe ForkId(0x879d6e30L, Some(9200000)) // Last Istanbul block
56-
create(9200000) shouldBe ForkId(0xe029e991L, None) // First Muir Glacier block
57-
create(12644529) shouldBe ForkId(0xe029e991L, None) // Today Muir Glacier block
58-
// TODO: Add Berlin
56+
create(9200000) shouldBe ForkId(0xe029e991L, Some(12244000)) // First Muir Glacier block
57+
create(12243999) shouldBe ForkId(0xe029e991L, Some(12244000)) // Last Muir Glacier block
58+
create(12244000) shouldBe ForkId(0x0eb440f6L, None) // First Berlin block
59+
create(12644529) shouldBe ForkId(0x0eb440f6L, None) // Today Berlin block
60+
// TODO: Add London
5961
}
6062

6163
"create correct ForkId for ETC mainnet blocks" in {

src/test/scala/io/iohk/ethereum/vm/CallOpcodesPostEip2929Spec.scala

Lines changed: 25 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -7,40 +7,33 @@ import org.scalatest.wordspec.AnyWordSpec
77
import org.scalatestplus.scalacheck.ScalaCheckPropertyChecks
88

99
import io.iohk.ethereum.Fixtures.{Blocks => BlockFixtures}
10-
import io.iohk.ethereum.crypto._
1110
import io.iohk.ethereum.domain.Account
1211
import io.iohk.ethereum.domain.Address
1312
import io.iohk.ethereum.domain.BlockHeader
1413
import io.iohk.ethereum.domain.UInt256
15-
import io.iohk.ethereum.utils.ByteUtils
1614
import io.iohk.ethereum.vm.MockWorldState._
1715

1816
import Fixtures.blockchainConfig
1917

20-
class MagnetoCallOpFixture(config: EvmConfig)
21-
extends CallOpFixture(config, MockWorldState(touchedAccounts = Set.empty)) {
22-
23-
override val fakeHeader: BlockHeader =
24-
BlockFixtures.ValidBlock.header.copy(number = Fixtures.MagnetoBlockNumber, unixTimestamp = 0)
25-
26-
override val requiredGas: BigInt = {
27-
val storageCost = 3 * (config.feeSchedule.G_sset + config.feeSchedule.G_cold_sload)
28-
val memCost = config.calcMemCost(0, 0, 32)
29-
val copyCost = config.feeSchedule.G_copy * wordsForBytes(32)
18+
class CallOpcodesPostBerlin(val config: EvmConfig = EvmConfig.BerlinConfigBuilder(blockchainConfig))
19+
extends CallOpcodesPostEip2929Spec(config) {
20+
override val fxt = new Eip2929CallOpFixture(config, Fixtures.BerlinBlockNumber)
21+
}
3022

31-
extCode.linearConstGas(config) + storageCost + memCost + copyCost
32-
}
23+
class CallOpcodesPostMagneto(val config: EvmConfig = EvmConfig.MagnetoConfigBuilder(blockchainConfig))
24+
extends CallOpcodesPostEip2929Spec(config) {
25+
override val fxt = new Eip2929CallOpFixture(config, Fixtures.MagnetoBlockNumber)
3326
}
3427

35-
class CallOpcodesPostEip2929Spec
28+
abstract class CallOpcodesPostEip2929Spec(config: EvmConfig)
3629
extends AnyWordSpec
3730
with CallOpCodesBehaviors
3831
with Matchers
3932
with ScalaCheckPropertyChecks {
4033

41-
val config: EvmConfig = EvmConfig.MagnetoConfigBuilder(blockchainConfig)
4234
import config.feeSchedule._
43-
val fxt = new MagnetoCallOpFixture(config)
35+
36+
protected[this] val fxt: CallOpFixture
4437

4538
"CALL" when {
4639

@@ -555,3 +548,18 @@ class CallOpcodesPostEip2929Spec
555548
}
556549
}
557550
}
551+
552+
class Eip2929CallOpFixture(config: EvmConfig, forkBlockHeight: Int)
553+
extends CallOpFixture(config, MockWorldState(touchedAccounts = Set.empty)) {
554+
555+
override val fakeHeader: BlockHeader =
556+
BlockFixtures.ValidBlock.header.copy(number = forkBlockHeight, unixTimestamp = 0)
557+
558+
override val requiredGas: BigInt = {
559+
val storageCost = 3 * (config.feeSchedule.G_sset + config.feeSchedule.G_cold_sload)
560+
val memCost = config.calcMemCost(0, 0, 32)
561+
val copyCost = config.feeSchedule.G_copy * wordsForBytes(32)
562+
563+
extCode.linearConstGas(config) + storageCost + memCost + copyCost
564+
}
565+
}

src/test/scala/io/iohk/ethereum/vm/Fixtures.scala

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ object Fixtures {
77
val PhoenixBlockNumber = 600
88
val IstanbulBlockNumber = 600
99
val MagnetoBlockNumber = 700
10+
val BerlinBlockNumber = 700
1011

1112
val blockchainConfig: BlockchainConfigForEvm = BlockchainConfigForEvm(
1213
// block numbers are irrelevant
@@ -25,6 +26,7 @@ object Fixtures {
2526
petersburgBlockNumber = PetersburgBlockNumber,
2627
phoenixBlockNumber = PhoenixBlockNumber,
2728
magnetoBlockNumber = MagnetoBlockNumber,
29+
berlinBlockNumber = BerlinBlockNumber,
2830
chainId = 0x3d.toByte
2931
)
3032

0 commit comments

Comments
 (0)