diff --git a/src/main/scala/io/iohk/ethereum/extvm/VMServer.scala b/src/main/scala/io/iohk/ethereum/extvm/VMServer.scala index f372a0d54e..4f94c96270 100644 --- a/src/main/scala/io/iohk/ethereum/extvm/VMServer.scala +++ b/src/main/scala/io/iohk/ethereum/extvm/VMServer.scala @@ -188,7 +188,8 @@ class VMServer(messageHandler: MessageHandler) accountStartNonce = conf.accountStartNonce, atlantisBlockNumber = BigInt(8772000), //TODO include atlantis block number in protobuf aghartaBlockNumber = BigInt(9573000), //TODO include agharta block number in protobuf - phoenixBlockNumber = BigInt(10500839) //TODO include phoenix block number in protobuf + phoenixBlockNumber = BigInt(10500839), //TODO include phoenix block number in protobuf + chainId = 0x3d.toByte //TODO include chainId in protobuf ) } } diff --git a/src/main/scala/io/iohk/ethereum/vm/BlockchainConfigForEvm.scala b/src/main/scala/io/iohk/ethereum/vm/BlockchainConfigForEvm.scala index 58b64881ff..940e579b61 100644 --- a/src/main/scala/io/iohk/ethereum/vm/BlockchainConfigForEvm.scala +++ b/src/main/scala/io/iohk/ethereum/vm/BlockchainConfigForEvm.scala @@ -20,7 +20,8 @@ case class BlockchainConfigForEvm( accountStartNonce: UInt256, atlantisBlockNumber: BigInt, aghartaBlockNumber: BigInt, - phoenixBlockNumber: BigInt + phoenixBlockNumber: BigInt, + chainId: Byte ) object BlockchainConfigForEvm { @@ -38,7 +39,8 @@ object BlockchainConfigForEvm { accountStartNonce = accountStartNonce, atlantisBlockNumber = atlantisBlockNumber, aghartaBlockNumber = aghartaBlockNumber, - phoenixBlockNumber = phoenixBlockNumber + phoenixBlockNumber = phoenixBlockNumber, + chainId = chainId ) } diff --git a/src/main/scala/io/iohk/ethereum/vm/EvmConfig.scala b/src/main/scala/io/iohk/ethereum/vm/EvmConfig.scala index 5f0fa639fd..93a7327366 100644 --- a/src/main/scala/io/iohk/ethereum/vm/EvmConfig.scala +++ b/src/main/scala/io/iohk/ethereum/vm/EvmConfig.scala @@ -4,6 +4,7 @@ import akka.util.ByteString import io.iohk.ethereum.domain.UInt256 import io.iohk.ethereum.utils.BlockchainConfig import EvmConfig._ +import io.iohk.ethereum import io.iohk.ethereum.vm // scalastyle:off number.of.methods @@ -36,7 +37,8 @@ object EvmConfig { blockchainConfig.byzantiumBlockNumber -> ByzantiumConfigBuilder, blockchainConfig.constantinopleBlockNumber -> ConstantinopleConfigBuilder, blockchainConfig.atlantisBlockNumber -> AtlantisConfigBuilder, - blockchainConfig.aghartaBlockNumber -> AghartaConfigBuilder + blockchainConfig.aghartaBlockNumber -> AghartaConfigBuilder, + blockchainConfig.phoenixBlockNumber -> PhoenixConfigBuilder ) // highest transition block that is less/equal to `blockNumber` @@ -53,6 +55,7 @@ object EvmConfig { val AtlantisOpCodes = ByzantiumOpCodes val ConstantinopleOpCodes = OpCodeList(OpCodes.ConstantinopleOpCodes) val AghartaOpCodes = ConstantinopleOpCodes + val PhoenixOpCodes = OpCodeList(OpCodes.PhoenixOpCodes) val FrontierConfigBuilder: EvmConfigBuilder = config => EvmConfig( blockchainConfig = config, @@ -105,6 +108,11 @@ object EvmConfig { opCodeList = AghartaOpCodes ) + val PhoenixConfigBuilder: EvmConfigBuilder = config => AghartaConfigBuilder(config).copy( + feeSchedule = new ethereum.vm.FeeSchedule.PhoenixFeeSchedule, + opCodeList = PhoenixOpCodes + ) + case class OpCodeList(opCodes: List[OpCode]) { val byteToOpCode: Map[Byte, OpCode] = opCodes.map(op => op.code -> op).toMap @@ -253,6 +261,8 @@ object FeeSchedule { class AghartaFeeSchedule extends ByzantiumFeeSchedule + class PhoenixFeeSchedule extends AghartaFeeSchedule + } trait FeeSchedule { diff --git a/src/main/scala/io/iohk/ethereum/vm/OpCode.scala b/src/main/scala/io/iohk/ethereum/vm/OpCode.scala index f47e54fc5f..87c9e52edc 100644 --- a/src/main/scala/io/iohk/ethereum/vm/OpCode.scala +++ b/src/main/scala/io/iohk/ethereum/vm/OpCode.scala @@ -166,6 +166,9 @@ object OpCodes { val ConstantinopleOpCodes: List[OpCode] = List(EXTCODEHASH, CREATE2, SHL, SHR, SAR) ++ ByzantiumOpCodes + + val PhoenixOpCodes: List[OpCode] = + List(CHAINID) ++ ConstantinopleOpCodes } object OpCode { @@ -1149,3 +1152,5 @@ case object SELFDESTRUCT extends OpCode(0xff, 1, 0, _.G_selfdestruct) { override protected def availableInContext[W <: WorldStateProxy[W, S], S <: Storage[S]]: ProgramState[W, S] => Boolean = !_.staticCtx } + +case object CHAINID extends ConstOp(0x46)(state => UInt256(state.env.evmConfig.blockchainConfig.chainId)) diff --git a/src/test/scala/io/iohk/ethereum/extvm/VMClientSpec.scala b/src/test/scala/io/iohk/ethereum/extvm/VMClientSpec.scala index a86be52437..44c70d89c2 100644 --- a/src/test/scala/io/iohk/ethereum/extvm/VMClientSpec.scala +++ b/src/test/scala/io/iohk/ethereum/extvm/VMClientSpec.scala @@ -177,7 +177,8 @@ class VMClientSpec extends FlatSpec with Matchers with MockFactory { accountStartNonce = 0, atlantisBlockNumber = 0, aghartaBlockNumber = 0, - phoenixBlockNumber = 0 + phoenixBlockNumber = 0, + chainId = 0x3d.toByte ) val evmConfig = EvmConfig.FrontierConfigBuilder(blockchainConfigForEvm) diff --git a/src/test/scala/io/iohk/ethereum/vm/Fixtures.scala b/src/test/scala/io/iohk/ethereum/vm/Fixtures.scala index e3cfa3628a..62418f8a27 100644 --- a/src/test/scala/io/iohk/ethereum/vm/Fixtures.scala +++ b/src/test/scala/io/iohk/ethereum/vm/Fixtures.scala @@ -17,7 +17,8 @@ object Fixtures { accountStartNonce = 0, atlantisBlockNumber = 0, aghartaBlockNumber = 0, - phoenixBlockNumber = 0 + phoenixBlockNumber = 0, + chainId = 0x3d.toByte ) } diff --git a/src/test/scala/io/iohk/ethereum/vm/OpCodeFunSpec.scala b/src/test/scala/io/iohk/ethereum/vm/OpCodeFunSpec.scala index 833ea58c30..34062c09cd 100644 --- a/src/test/scala/io/iohk/ethereum/vm/OpCodeFunSpec.scala +++ b/src/test/scala/io/iohk/ethereum/vm/OpCodeFunSpec.scala @@ -14,7 +14,7 @@ class OpCodeFunSpec extends FunSuite with OpCodeTesting with Matchers with Prope import MockWorldState.PS - override val config = EvmConfig.ByzantiumConfigBuilder(blockchainConfig) + override val config = EvmConfig.PhoenixConfigBuilder(blockchainConfig) def executeOp(op: OpCode, stateIn: PS): PS = { // gas is not tested in this spec @@ -819,7 +819,7 @@ class OpCodeFunSpec extends FunSuite with OpCodeTesting with Matchers with Prope } } - verifyAllOpCodesRegistered(except = CREATE, CREATE2, CALL, CALLCODE, DELEGATECALL, STATICCALL) + verifyAllOpCodesRegistered(except = CREATE, CREATE2, CALL, CALLCODE, DELEGATECALL, STATICCALL, SHL, SHR, SAR) test("sliceBytes helper") { def zeroes(i: Int): ByteString = diff --git a/src/test/scala/io/iohk/ethereum/vm/VMSpec.scala b/src/test/scala/io/iohk/ethereum/vm/VMSpec.scala index 20da7200c5..e8b73a4242 100644 --- a/src/test/scala/io/iohk/ethereum/vm/VMSpec.scala +++ b/src/test/scala/io/iohk/ethereum/vm/VMSpec.scala @@ -157,7 +157,8 @@ class VMSpec extends WordSpec with PropertyChecks with Matchers { accountStartNonce = 0, atlantisBlockNumber = Long.MaxValue, aghartaBlockNumber = Long.MaxValue, - phoenixBlockNumber = Long.MaxValue + phoenixBlockNumber = Long.MaxValue, + chainId = 0x3d.toByte ) val homesteadConfig = EvmConfig.forBlock(0, evmBlockchainConfig.copy(homesteadBlockNumber = 0))