From 5ffc7b378813ac6a60debf27702bb4f65e29ac6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aur=C3=A9lien=20Richez?= Date: Tue, 7 Sep 2021 11:50:30 +0200 Subject: [PATCH 1/6] compute initial access list price --- .../std/StdSignedTransactionValidator.scala | 3 ++- .../io/iohk/ethereum/domain/Transaction.scala | 7 ++++++ .../iohk/ethereum/extvm/ExtVMInterface.scala | 3 +-- .../io/iohk/ethereum/extvm/VMServer.scala | 4 ++- .../scala/io/iohk/ethereum/vm/EvmConfig.scala | 25 ++++++++++++++----- .../scala/io/iohk/ethereum/vm/OpCode.scala | 6 +++-- .../io/iohk/ethereum/vm/ProgramContext.scala | 10 +++++--- .../io/iohk/ethereum/vm/ProgramState.scala | 9 +++---- src/main/scala/io/iohk/ethereum/vm/VM.scala | 9 ++++--- 9 files changed, 50 insertions(+), 26 deletions(-) diff --git a/src/main/scala/io/iohk/ethereum/consensus/validators/std/StdSignedTransactionValidator.scala b/src/main/scala/io/iohk/ethereum/consensus/validators/std/StdSignedTransactionValidator.scala index 1726b696af..c240e132b2 100644 --- a/src/main/scala/io/iohk/ethereum/consensus/validators/std/StdSignedTransactionValidator.scala +++ b/src/main/scala/io/iohk/ethereum/consensus/validators/std/StdSignedTransactionValidator.scala @@ -117,7 +117,8 @@ object StdSignedTransactionValidator extends SignedTransactionValidator { )(implicit blockchainConfig: BlockchainConfig): Either[SignedTransactionError, SignedTransactionValid] = { import stx.tx val config = EvmConfig.forBlock(blockHeaderNumber, blockchainConfig) - val txIntrinsicGas = config.calcTransactionIntrinsicGas(tx.payload, tx.isContractInit) + val txIntrinsicGas = + config.calcTransactionIntrinsicGas(tx.payload, tx.isContractInit, Transaction.accessList(tx)) if (stx.tx.gasLimit >= txIntrinsicGas) Right(SignedTransactionValid) else Left(TransactionNotEnoughGasForIntrinsicError(stx.tx.gasLimit, txIntrinsicGas)) } diff --git a/src/main/scala/io/iohk/ethereum/domain/Transaction.scala b/src/main/scala/io/iohk/ethereum/domain/Transaction.scala index 0cb9e52c5c..e378d42a88 100644 --- a/src/main/scala/io/iohk/ethereum/domain/Transaction.scala +++ b/src/main/scala/io/iohk/ethereum/domain/Transaction.scala @@ -35,6 +35,12 @@ object Transaction { case tx: TransactionWithAccessList => tx.copy(gasLimit = gl) } + def accessList(tx: Transaction) = + tx match { + case transaction: TransactionWithAccessList => transaction.accessList + case LegacyTransaction(nonce, gasPrice, gasLimit, receivingAddress, value, payload) => Nil + } + implicit class TransactionTypeValidator(val transactionType: Byte) extends AnyVal { def isValidTransactionType: Boolean = transactionType >= MinAllowedType && transactionType <= MaxAllowedType } @@ -70,6 +76,7 @@ case class LegacyTransaction( value: BigInt, payload: ByteString ) extends Transaction { + override def toString: String = s"LegacyTransaction {" + s"nonce: $nonce " + diff --git a/src/main/scala/io/iohk/ethereum/extvm/ExtVMInterface.scala b/src/main/scala/io/iohk/ethereum/extvm/ExtVMInterface.scala index 9039a4a80c..ca2fa07f52 100644 --- a/src/main/scala/io/iohk/ethereum/extvm/ExtVMInterface.scala +++ b/src/main/scala/io/iohk/ethereum/extvm/ExtVMInterface.scala @@ -1,7 +1,6 @@ package io.iohk.ethereum.extvm import java.nio.ByteOrder - import akka.actor.ActorSystem import akka.stream.OverflowStrategy import akka.stream.scaladsl.Framing @@ -10,12 +9,12 @@ import akka.stream.scaladsl.Sink import akka.stream.scaladsl.Source import akka.stream.scaladsl.Tcp import akka.util.ByteString +import io.iohk.ethereum.domain.AccessListItem import scala.annotation.tailrec import scala.util.Failure import scala.util.Success import scala.util.Try - import io.iohk.ethereum.ledger.InMemoryWorldStateProxy import io.iohk.ethereum.ledger.InMemoryWorldStateProxyStorage import io.iohk.ethereum.utils.BlockchainConfig diff --git a/src/main/scala/io/iohk/ethereum/extvm/VMServer.scala b/src/main/scala/io/iohk/ethereum/extvm/VMServer.scala index b4702e230e..1cbf448102 100644 --- a/src/main/scala/io/iohk/ethereum/extvm/VMServer.scala +++ b/src/main/scala/io/iohk/ethereum/extvm/VMServer.scala @@ -151,7 +151,9 @@ class VMServer(messageHandler: MessageHandler) extends Logger { world = world, initialAddressesToDelete = Set(), evmConfig = vmConfig, - originalWorld = world + originalWorld = world, + // FIXME add access list to CallContext + accessList = Nil ) } diff --git a/src/main/scala/io/iohk/ethereum/vm/EvmConfig.scala b/src/main/scala/io/iohk/ethereum/vm/EvmConfig.scala index 04c658e233..4cd4dc96e8 100644 --- a/src/main/scala/io/iohk/ethereum/vm/EvmConfig.scala +++ b/src/main/scala/io/iohk/ethereum/vm/EvmConfig.scala @@ -1,13 +1,10 @@ package io.iohk.ethereum.vm import akka.util.ByteString - import io.iohk.ethereum - -import io.iohk.ethereum.domain.UInt256 +import io.iohk.ethereum.domain.{AccessListItem, TransactionWithAccessList, UInt256} import io.iohk.ethereum.utils.BlockchainConfig import io.iohk.ethereum.vm - import EvmConfig._ // scalastyle:off magic.number @@ -196,12 +193,20 @@ case class EvmConfig( /** Calculates transaction intrinsic gas. See YP section 6.2 */ - def calcTransactionIntrinsicGas(txData: ByteString, isContractCreation: Boolean): BigInt = { + def calcTransactionIntrinsicGas( + txData: ByteString, + isContractCreation: Boolean, + accessList: Seq[AccessListItem] + ): BigInt = { val txDataZero = txData.count(_ == 0) val txDataNonZero = txData.length - txDataZero + val accessListPrice = + accessList.size * G_access_list_address + + accessList.map(_.storageKeys.size).sum * G_access_list_storage + txDataZero * G_txdatazero + - txDataNonZero * G_txdatanonzero + + txDataNonZero * G_txdatanonzero + accessListPrice + (if (isContractCreation) G_txcreate else 0) + G_transaction } @@ -265,6 +270,10 @@ object FeeSchedule { override val G_cold_sload = 2100 override val G_cold_account_access = 2600 override val G_warm_storage_read = 100 + + // note: the access list does not exist until magneto hard fork + override val G_access_list_address = 2400 + override val G_access_list_storage = 1900 } class HomesteadFeeSchedule extends FrontierFeeSchedule { @@ -300,6 +309,8 @@ object FeeSchedule { class MagnetoFeeSchedule extends PhoenixFeeSchedule { override val G_sload: BigInt = G_warm_storage_read override val G_sreset: BigInt = 5000 - G_cold_sload + override val G_access_list_address: BigInt = 2400 + override val G_access_list_storage: BigInt = 1900 } } @@ -342,4 +353,6 @@ trait FeeSchedule { val G_cold_sload: BigInt val G_cold_account_access: BigInt val G_warm_storage_read: BigInt + val G_access_list_address: BigInt + val G_access_list_storage: BigInt } diff --git a/src/main/scala/io/iohk/ethereum/vm/OpCode.scala b/src/main/scala/io/iohk/ethereum/vm/OpCode.scala index 1c6532f06d..4f98fc3983 100644 --- a/src/main/scala/io/iohk/ethereum/vm/OpCode.scala +++ b/src/main/scala/io/iohk/ethereum/vm/OpCode.scala @@ -973,7 +973,8 @@ abstract class CreateOp(code: Int, delta: Int) extends OpCode(code, delta, 1, _. world = world1, initialAddressesToDelete = state.addressesToDelete, evmConfig = state.config, - originalWorld = state.originalWorld + originalWorld = state.originalWorld, + accessList = Nil ) val ((result, newAddress), stack2) = this match { @@ -1079,7 +1080,8 @@ abstract class CallOp(code: Int, delta: Int, alpha: Int) extends OpCode(code, de initialAddressesToDelete = state.addressesToDelete, evmConfig = state.config, staticCtx = static, - originalWorld = state.originalWorld + originalWorld = state.originalWorld, + accessList = Nil ) val result = state.vm.call(context, owner) diff --git a/src/main/scala/io/iohk/ethereum/vm/ProgramContext.scala b/src/main/scala/io/iohk/ethereum/vm/ProgramContext.scala index 6d05e03810..61ab459956 100644 --- a/src/main/scala/io/iohk/ethereum/vm/ProgramContext.scala +++ b/src/main/scala/io/iohk/ethereum/vm/ProgramContext.scala @@ -12,9 +12,9 @@ object ProgramContext { world: W, evmConfig: EvmConfig ): ProgramContext[W, S] = { - import stx.tx - val gasLimit = tx.gasLimit - evmConfig.calcTransactionIntrinsicGas(tx.payload, tx.isContractInit) + val gasLimit = + tx.gasLimit - evmConfig.calcTransactionIntrinsicGas(tx.payload, tx.isContractInit, Transaction.accessList(tx)) ProgramContext( callerAddr = senderAddress, @@ -31,7 +31,8 @@ object ProgramContext { world = world, initialAddressesToDelete = Set(), evmConfig = evmConfig, - originalWorld = world + originalWorld = world, + accessList = Transaction.accessList(tx) ) } } @@ -81,5 +82,6 @@ case class ProgramContext[W <: WorldStateProxy[W, S], S <: Storage[S]]( initialAddressesToDelete: Set[Address], evmConfig: EvmConfig, staticCtx: Boolean = false, - originalWorld: W + originalWorld: W, + accessList: Seq[AccessListItem] ) diff --git a/src/main/scala/io/iohk/ethereum/vm/ProgramState.scala b/src/main/scala/io/iohk/ethereum/vm/ProgramState.scala index 27dc19e0b4..5ea433deac 100644 --- a/src/main/scala/io/iohk/ethereum/vm/ProgramState.scala +++ b/src/main/scala/io/iohk/ethereum/vm/ProgramState.scala @@ -1,10 +1,7 @@ package io.iohk.ethereum.vm import akka.util.ByteString - -import io.iohk.ethereum.domain.Address -import io.iohk.ethereum.domain.TxLogEntry -import io.iohk.ethereum.domain.UInt256 +import io.iohk.ethereum.domain.{AccessListItem, Address, TxLogEntry, UInt256} object ProgramState { def apply[W <: WorldStateProxy[W, S], S <: Storage[S]]( @@ -23,8 +20,8 @@ object ProgramState { accessedAddresses = PrecompiledContracts.getContracts(context).keySet ++ Set( context.originAddr, context.recipientAddr.getOrElse(context.callerAddr) - ), - accessedStorageKeys = Set.empty + ) ++ context.accessList.map(_.address), + accessedStorageKeys = context.accessList.flatMap(i => i.storageKeys.map((i.address, _))).toSet ) } diff --git a/src/main/scala/io/iohk/ethereum/vm/VM.scala b/src/main/scala/io/iohk/ethereum/vm/VM.scala index 8517d915dd..936fb568e4 100644 --- a/src/main/scala/io/iohk/ethereum/vm/VM.scala +++ b/src/main/scala/io/iohk/ethereum/vm/VM.scala @@ -3,9 +3,7 @@ package io.iohk.ethereum.vm import akka.util.ByteString import scala.annotation.tailrec - -import io.iohk.ethereum.domain.Address -import io.iohk.ethereum.domain.UInt256 +import io.iohk.ethereum.domain.{AccessListItem, Address, UInt256} import io.iohk.ethereum.utils.Logger class VM[W <: WorldStateProxy[W, S], S <: Storage[S]] extends Logger { @@ -63,7 +61,10 @@ class VM[W <: WorldStateProxy[W, S], S <: Storage[S]] extends Logger { /** Contract creation - Λ function in YP * salt is used to create contract by CREATE2 opcode. See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1014.md */ - private[vm] def create(context: PC, salt: Option[UInt256] = None): (PR, Address) = + private[vm] def create( + context: PC, + salt: Option[UInt256] = None + ): (PR, Address) = if (!isValidCall(context)) (invalidCallResult(context), Address(0)) else { From 8328ea265bf00a5b7501f1bf7723d61bfb25a83a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aur=C3=A9lien=20Richez?= Date: Tue, 7 Sep 2021 15:02:55 +0200 Subject: [PATCH 2/6] keep initial warm status in context --- src/main/scala/io/iohk/ethereum/extvm/VMServer.scala | 3 ++- src/main/scala/io/iohk/ethereum/vm/OpCode.scala | 6 ++++-- src/main/scala/io/iohk/ethereum/vm/ProgramContext.scala | 9 ++++++--- src/main/scala/io/iohk/ethereum/vm/ProgramState.scala | 4 ++-- 4 files changed, 14 insertions(+), 8 deletions(-) diff --git a/src/main/scala/io/iohk/ethereum/extvm/VMServer.scala b/src/main/scala/io/iohk/ethereum/extvm/VMServer.scala index 1cbf448102..20d3a247f6 100644 --- a/src/main/scala/io/iohk/ethereum/extvm/VMServer.scala +++ b/src/main/scala/io/iohk/ethereum/extvm/VMServer.scala @@ -153,7 +153,8 @@ class VMServer(messageHandler: MessageHandler) extends Logger { evmConfig = vmConfig, originalWorld = world, // FIXME add access list to CallContext - accessList = Nil + warmAdresses = Set.empty, + warmStorage = Set.empty ) } diff --git a/src/main/scala/io/iohk/ethereum/vm/OpCode.scala b/src/main/scala/io/iohk/ethereum/vm/OpCode.scala index 4f98fc3983..18a4e64433 100644 --- a/src/main/scala/io/iohk/ethereum/vm/OpCode.scala +++ b/src/main/scala/io/iohk/ethereum/vm/OpCode.scala @@ -974,7 +974,8 @@ abstract class CreateOp(code: Int, delta: Int) extends OpCode(code, delta, 1, _. initialAddressesToDelete = state.addressesToDelete, evmConfig = state.config, originalWorld = state.originalWorld, - accessList = Nil + warmAdresses = state.accessedAddresses, + warmStorage = state.accessedStorageKeys ) val ((result, newAddress), stack2) = this match { @@ -1081,7 +1082,8 @@ abstract class CallOp(code: Int, delta: Int, alpha: Int) extends OpCode(code, de evmConfig = state.config, staticCtx = static, originalWorld = state.originalWorld, - accessList = Nil + warmAdresses = state.accessedAddresses, + warmStorage = state.accessedStorageKeys ) val result = state.vm.call(context, owner) diff --git a/src/main/scala/io/iohk/ethereum/vm/ProgramContext.scala b/src/main/scala/io/iohk/ethereum/vm/ProgramContext.scala index 61ab459956..33710cadc0 100644 --- a/src/main/scala/io/iohk/ethereum/vm/ProgramContext.scala +++ b/src/main/scala/io/iohk/ethereum/vm/ProgramContext.scala @@ -13,8 +13,9 @@ object ProgramContext { evmConfig: EvmConfig ): ProgramContext[W, S] = { import stx.tx + val accessList = Transaction.accessList(tx) val gasLimit = - tx.gasLimit - evmConfig.calcTransactionIntrinsicGas(tx.payload, tx.isContractInit, Transaction.accessList(tx)) + tx.gasLimit - evmConfig.calcTransactionIntrinsicGas(tx.payload, tx.isContractInit, accessList) ProgramContext( callerAddr = senderAddress, @@ -32,7 +33,8 @@ object ProgramContext { initialAddressesToDelete = Set(), evmConfig = evmConfig, originalWorld = world, - accessList = Transaction.accessList(tx) + warmAdresses = accessList.map(_.address).toSet, + warmStorage = accessList.flatMap(i => i.storageKeys.map((i.address, _))).toSet ) } } @@ -83,5 +85,6 @@ case class ProgramContext[W <: WorldStateProxy[W, S], S <: Storage[S]]( evmConfig: EvmConfig, staticCtx: Boolean = false, originalWorld: W, - accessList: Seq[AccessListItem] + warmAdresses: Set[Address], + warmStorage: Set[(Address, BigInt)] ) diff --git a/src/main/scala/io/iohk/ethereum/vm/ProgramState.scala b/src/main/scala/io/iohk/ethereum/vm/ProgramState.scala index 5ea433deac..1c012ca102 100644 --- a/src/main/scala/io/iohk/ethereum/vm/ProgramState.scala +++ b/src/main/scala/io/iohk/ethereum/vm/ProgramState.scala @@ -20,8 +20,8 @@ object ProgramState { accessedAddresses = PrecompiledContracts.getContracts(context).keySet ++ Set( context.originAddr, context.recipientAddr.getOrElse(context.callerAddr) - ) ++ context.accessList.map(_.address), - accessedStorageKeys = context.accessList.flatMap(i => i.storageKeys.map((i.address, _))).toSet + ) ++ context.warmAdresses, + accessedStorageKeys = context.warmStorage ) } From ad262e5b515350e298b14790f36d4358362a4b17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aur=C3=A9lien=20Richez?= Date: Tue, 7 Sep 2021 17:10:49 +0200 Subject: [PATCH 3/6] fix tests --- src/main/scala/io/iohk/ethereum/extvm/VMServer.scala | 2 +- src/main/scala/io/iohk/ethereum/vm/OpCode.scala | 4 ++-- src/main/scala/io/iohk/ethereum/vm/ProgramContext.scala | 4 ++-- src/main/scala/io/iohk/ethereum/vm/ProgramState.scala | 2 +- .../std/StdSignedLegacyTransactionValidatorSpec.scala | 2 +- src/test/scala/io/iohk/ethereum/vm/CallOpFixture.scala | 4 +++- src/test/scala/io/iohk/ethereum/vm/CreateOpcodeSpec.scala | 4 +++- src/test/scala/io/iohk/ethereum/vm/Generators.scala | 4 +++- .../scala/io/iohk/ethereum/vm/OpCodeGasSpecPostEip2929.scala | 4 +++- .../scala/io/iohk/ethereum/vm/PrecompiledContractsSpec.scala | 4 +++- .../ethereum/vm/SSTOREOpCodeGasPostConstantinopleSpec.scala | 4 +++- src/test/scala/io/iohk/ethereum/vm/ShiftingOpCodeSpec.scala | 4 +++- src/test/scala/io/iohk/ethereum/vm/VMSpec.scala | 4 +++- 13 files changed, 31 insertions(+), 15 deletions(-) diff --git a/src/main/scala/io/iohk/ethereum/extvm/VMServer.scala b/src/main/scala/io/iohk/ethereum/extvm/VMServer.scala index 20d3a247f6..385ce5a05a 100644 --- a/src/main/scala/io/iohk/ethereum/extvm/VMServer.scala +++ b/src/main/scala/io/iohk/ethereum/extvm/VMServer.scala @@ -153,7 +153,7 @@ class VMServer(messageHandler: MessageHandler) extends Logger { evmConfig = vmConfig, originalWorld = world, // FIXME add access list to CallContext - warmAdresses = Set.empty, + warmAddresses = Set.empty, warmStorage = Set.empty ) } diff --git a/src/main/scala/io/iohk/ethereum/vm/OpCode.scala b/src/main/scala/io/iohk/ethereum/vm/OpCode.scala index 18a4e64433..cb92c15701 100644 --- a/src/main/scala/io/iohk/ethereum/vm/OpCode.scala +++ b/src/main/scala/io/iohk/ethereum/vm/OpCode.scala @@ -974,7 +974,7 @@ abstract class CreateOp(code: Int, delta: Int) extends OpCode(code, delta, 1, _. initialAddressesToDelete = state.addressesToDelete, evmConfig = state.config, originalWorld = state.originalWorld, - warmAdresses = state.accessedAddresses, + warmAddresses = state.accessedAddresses, warmStorage = state.accessedStorageKeys ) @@ -1082,7 +1082,7 @@ abstract class CallOp(code: Int, delta: Int, alpha: Int) extends OpCode(code, de evmConfig = state.config, staticCtx = static, originalWorld = state.originalWorld, - warmAdresses = state.accessedAddresses, + warmAddresses = state.accessedAddresses, warmStorage = state.accessedStorageKeys ) diff --git a/src/main/scala/io/iohk/ethereum/vm/ProgramContext.scala b/src/main/scala/io/iohk/ethereum/vm/ProgramContext.scala index 33710cadc0..04c3eeb4ff 100644 --- a/src/main/scala/io/iohk/ethereum/vm/ProgramContext.scala +++ b/src/main/scala/io/iohk/ethereum/vm/ProgramContext.scala @@ -33,7 +33,7 @@ object ProgramContext { initialAddressesToDelete = Set(), evmConfig = evmConfig, originalWorld = world, - warmAdresses = accessList.map(_.address).toSet, + warmAddresses = accessList.map(_.address).toSet, warmStorage = accessList.flatMap(i => i.storageKeys.map((i.address, _))).toSet ) } @@ -85,6 +85,6 @@ case class ProgramContext[W <: WorldStateProxy[W, S], S <: Storage[S]]( evmConfig: EvmConfig, staticCtx: Boolean = false, originalWorld: W, - warmAdresses: Set[Address], + warmAddresses: Set[Address], warmStorage: Set[(Address, BigInt)] ) diff --git a/src/main/scala/io/iohk/ethereum/vm/ProgramState.scala b/src/main/scala/io/iohk/ethereum/vm/ProgramState.scala index 1c012ca102..39f3e66996 100644 --- a/src/main/scala/io/iohk/ethereum/vm/ProgramState.scala +++ b/src/main/scala/io/iohk/ethereum/vm/ProgramState.scala @@ -20,7 +20,7 @@ object ProgramState { accessedAddresses = PrecompiledContracts.getContracts(context).keySet ++ Set( context.originAddr, context.recipientAddr.getOrElse(context.callerAddr) - ) ++ context.warmAdresses, + ) ++ context.warmAddresses, accessedStorageKeys = context.warmStorage ) } diff --git a/src/test/scala/io/iohk/ethereum/consensus/validators/std/StdSignedLegacyTransactionValidatorSpec.scala b/src/test/scala/io/iohk/ethereum/consensus/validators/std/StdSignedLegacyTransactionValidatorSpec.scala index 288afa57c7..4d175c4f2d 100644 --- a/src/test/scala/io/iohk/ethereum/consensus/validators/std/StdSignedLegacyTransactionValidatorSpec.scala +++ b/src/test/scala/io/iohk/ethereum/consensus/validators/std/StdSignedLegacyTransactionValidatorSpec.scala @@ -200,7 +200,7 @@ class StdSignedLegacyTransactionValidatorSpec extends AnyFlatSpec with Matchers it should "report as invalid a tx with too low gas limit for intrinsic gas" in { val txIntrinsicGas = EvmConfig .forBlock(blockHeaderAfterHomestead.number, blockchainConfig) - .calcTransactionIntrinsicGas(txAfterHomestead.payload, txAfterHomestead.isContractInit) + .calcTransactionIntrinsicGas(txAfterHomestead.payload, txAfterHomestead.isContractInit, Nil) val txWithInvalidGasLimit = txAfterHomestead.copy(gasLimit = txIntrinsicGas / 2) val signedTxWithInvalidGasLimit = signedTxAfterHomestead.copy(tx = txWithInvalidGasLimit) validateStx(signedTxWithInvalidGasLimit, fromBeforeHomestead = false) match { diff --git a/src/test/scala/io/iohk/ethereum/vm/CallOpFixture.scala b/src/test/scala/io/iohk/ethereum/vm/CallOpFixture.scala index e07b54273b..332f1fe387 100644 --- a/src/test/scala/io/iohk/ethereum/vm/CallOpFixture.scala +++ b/src/test/scala/io/iohk/ethereum/vm/CallOpFixture.scala @@ -178,7 +178,9 @@ class CallOpFixture(val config: EvmConfig, val startState: MockWorldState) { world = worldWithExtAccount, initialAddressesToDelete = Set(), evmConfig = config, - originalWorld = worldWithExtAccount + originalWorld = worldWithExtAccount, + warmAddresses = Set.empty, + warmStorage = Set.empty ) case class ExecuteCall( diff --git a/src/test/scala/io/iohk/ethereum/vm/CreateOpcodeSpec.scala b/src/test/scala/io/iohk/ethereum/vm/CreateOpcodeSpec.scala index 5cdb7c286e..d48a088270 100644 --- a/src/test/scala/io/iohk/ethereum/vm/CreateOpcodeSpec.scala +++ b/src/test/scala/io/iohk/ethereum/vm/CreateOpcodeSpec.scala @@ -176,7 +176,9 @@ class CreateOpcodeSpec extends AnyWordSpec with Matchers with ScalaCheckProperty world = initWorld, initialAddressesToDelete = Set(), evmConfig = config, - originalWorld = initWorld + originalWorld = initWorld, + warmAddresses = Set.empty, + warmStorage = Set.empty ) } diff --git a/src/test/scala/io/iohk/ethereum/vm/Generators.scala b/src/test/scala/io/iohk/ethereum/vm/Generators.scala index cde8a5afed..d15239ff67 100644 --- a/src/test/scala/io/iohk/ethereum/vm/Generators.scala +++ b/src/test/scala/io/iohk/ethereum/vm/Generators.scala @@ -120,7 +120,9 @@ object Generators extends ObjectGenerators { world = world, initialAddressesToDelete = Set(), evmConfig = evmConfig, - originalWorld = world + originalWorld = world, + warmAddresses = Set.empty, + warmStorage = Set.empty ) env = ExecEnv(context, code, ownerAddr) diff --git a/src/test/scala/io/iohk/ethereum/vm/OpCodeGasSpecPostEip2929.scala b/src/test/scala/io/iohk/ethereum/vm/OpCodeGasSpecPostEip2929.scala index b1744609cc..be4b4e67c1 100644 --- a/src/test/scala/io/iohk/ethereum/vm/OpCodeGasSpecPostEip2929.scala +++ b/src/test/scala/io/iohk/ethereum/vm/OpCodeGasSpecPostEip2929.scala @@ -298,7 +298,9 @@ trait OpCodeGasSpecPostEip2929 extends AnyFunSuite with OpCodeTesting with Match world = defaultWorld, initialAddressesToDelete = Set(), evmConfig = config, - originalWorld = defaultWorld + originalWorld = defaultWorld, + warmAddresses = Set.empty, + warmStorage = Set.empty ) val env = ExecEnv(context, ByteString(Hex.decode(code)), context.originAddr) diff --git a/src/test/scala/io/iohk/ethereum/vm/PrecompiledContractsSpec.scala b/src/test/scala/io/iohk/ethereum/vm/PrecompiledContractsSpec.scala index 097d021f64..a7d8c17f9b 100644 --- a/src/test/scala/io/iohk/ethereum/vm/PrecompiledContractsSpec.scala +++ b/src/test/scala/io/iohk/ethereum/vm/PrecompiledContractsSpec.scala @@ -57,7 +57,9 @@ class PrecompiledContractsSpec world = world, initialAddressesToDelete = Set(), evmConfig = EvmConfig.PostEIP161ConfigBuilder(blockchainConfig), - originalWorld = world + originalWorld = world, + warmAddresses = Set.empty, + warmStorage = Set.empty ) } diff --git a/src/test/scala/io/iohk/ethereum/vm/SSTOREOpCodeGasPostConstantinopleSpec.scala b/src/test/scala/io/iohk/ethereum/vm/SSTOREOpCodeGasPostConstantinopleSpec.scala index 4afc84fa76..cdf866a844 100644 --- a/src/test/scala/io/iohk/ethereum/vm/SSTOREOpCodeGasPostConstantinopleSpec.scala +++ b/src/test/scala/io/iohk/ethereum/vm/SSTOREOpCodeGasPostConstantinopleSpec.scala @@ -131,7 +131,9 @@ trait TestSetup { world = world, initialAddressesToDelete = Set(), evmConfig = eipToCheck.config, - originalWorld = world + originalWorld = world, + warmAddresses = Set.empty, + warmStorage = Set.empty ) def prepareProgramState( diff --git a/src/test/scala/io/iohk/ethereum/vm/ShiftingOpCodeSpec.scala b/src/test/scala/io/iohk/ethereum/vm/ShiftingOpCodeSpec.scala index a0d54f2954..c3bdd4dbb5 100644 --- a/src/test/scala/io/iohk/ethereum/vm/ShiftingOpCodeSpec.scala +++ b/src/test/scala/io/iohk/ethereum/vm/ShiftingOpCodeSpec.scala @@ -188,7 +188,9 @@ class ShiftingOpCodeSpec extends AnyWordSpec with Matchers with ScalaCheckProper world = world, initialAddressesToDelete = Set(), evmConfig = config, - originalWorld = world + originalWorld = world, + warmAddresses = Set.empty, + warmStorage = Set.empty ) def prepareProgramState( diff --git a/src/test/scala/io/iohk/ethereum/vm/VMSpec.scala b/src/test/scala/io/iohk/ethereum/vm/VMSpec.scala index 76d2478029..e95910874f 100644 --- a/src/test/scala/io/iohk/ethereum/vm/VMSpec.scala +++ b/src/test/scala/io/iohk/ethereum/vm/VMSpec.scala @@ -195,7 +195,9 @@ class VMSpec extends AnyWordSpec with ScalaCheckPropertyChecks with Matchers { world = world, initialAddressesToDelete = Set(), evmConfig = evmConfig, - originalWorld = world + originalWorld = world, + warmAddresses = Set.empty, + warmStorage = Set.empty ) def recipientAddr: Option[Address] From a28f128355fd01e7a5ccadb7e6d8f085e34d9cd2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aur=C3=A9lien=20Richez?= Date: Wed, 15 Sep 2021 12:06:18 +0200 Subject: [PATCH 4/6] add ticket number in todo --- src/main/scala/io/iohk/ethereum/extvm/VMServer.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/scala/io/iohk/ethereum/extvm/VMServer.scala b/src/main/scala/io/iohk/ethereum/extvm/VMServer.scala index 385ce5a05a..91a6c9d1e3 100644 --- a/src/main/scala/io/iohk/ethereum/extvm/VMServer.scala +++ b/src/main/scala/io/iohk/ethereum/extvm/VMServer.scala @@ -152,7 +152,7 @@ class VMServer(messageHandler: MessageHandler) extends Logger { initialAddressesToDelete = Set(), evmConfig = vmConfig, originalWorld = world, - // FIXME add access list to CallContext + // TODO ETCM-1202 use access list from CallContext warmAddresses = Set.empty, warmStorage = Set.empty ) From 0d86c95f7d15f5186f295ef2921b33a626c32471 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aur=C3=A9lien=20Richez?= Date: Wed, 15 Sep 2021 12:16:37 +0200 Subject: [PATCH 5/6] move magneto comment up in fee schedule --- src/main/scala/io/iohk/ethereum/vm/EvmConfig.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/scala/io/iohk/ethereum/vm/EvmConfig.scala b/src/main/scala/io/iohk/ethereum/vm/EvmConfig.scala index 4cd4dc96e8..7b218f210d 100644 --- a/src/main/scala/io/iohk/ethereum/vm/EvmConfig.scala +++ b/src/main/scala/io/iohk/ethereum/vm/EvmConfig.scala @@ -267,11 +267,11 @@ object FeeSchedule { override val G_copy = 3 override val G_blockhash = 20 override val G_extcode = 20 + + // note: the access list and cold/warm access do not exist until magneto hard fork override val G_cold_sload = 2100 override val G_cold_account_access = 2600 override val G_warm_storage_read = 100 - - // note: the access list does not exist until magneto hard fork override val G_access_list_address = 2400 override val G_access_list_storage = 1900 } From 4cbabc52fede489972df137ab2265e76d5945323 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aur=C3=A9lien=20Richez?= Date: Wed, 15 Sep 2021 12:20:10 +0200 Subject: [PATCH 6/6] formatAll --- src/main/scala/io/iohk/ethereum/domain/Transaction.scala | 2 +- src/main/scala/io/iohk/ethereum/extvm/ExtVMInterface.scala | 4 +++- src/main/scala/io/iohk/ethereum/vm/EvmConfig.scala | 7 ++++++- src/main/scala/io/iohk/ethereum/vm/ProgramState.scala | 6 +++++- src/main/scala/io/iohk/ethereum/vm/VM.scala | 5 ++++- 5 files changed, 19 insertions(+), 5 deletions(-) diff --git a/src/main/scala/io/iohk/ethereum/domain/Transaction.scala b/src/main/scala/io/iohk/ethereum/domain/Transaction.scala index e378d42a88..56ed8f00e6 100644 --- a/src/main/scala/io/iohk/ethereum/domain/Transaction.scala +++ b/src/main/scala/io/iohk/ethereum/domain/Transaction.scala @@ -35,7 +35,7 @@ object Transaction { case tx: TransactionWithAccessList => tx.copy(gasLimit = gl) } - def accessList(tx: Transaction) = + def accessList(tx: Transaction): List[AccessListItem] = tx match { case transaction: TransactionWithAccessList => transaction.accessList case LegacyTransaction(nonce, gasPrice, gasLimit, receivingAddress, value, payload) => Nil diff --git a/src/main/scala/io/iohk/ethereum/extvm/ExtVMInterface.scala b/src/main/scala/io/iohk/ethereum/extvm/ExtVMInterface.scala index ca2fa07f52..d7e43fcb89 100644 --- a/src/main/scala/io/iohk/ethereum/extvm/ExtVMInterface.scala +++ b/src/main/scala/io/iohk/ethereum/extvm/ExtVMInterface.scala @@ -1,6 +1,7 @@ package io.iohk.ethereum.extvm import java.nio.ByteOrder + import akka.actor.ActorSystem import akka.stream.OverflowStrategy import akka.stream.scaladsl.Framing @@ -9,12 +10,13 @@ import akka.stream.scaladsl.Sink import akka.stream.scaladsl.Source import akka.stream.scaladsl.Tcp import akka.util.ByteString -import io.iohk.ethereum.domain.AccessListItem import scala.annotation.tailrec import scala.util.Failure import scala.util.Success import scala.util.Try + +import io.iohk.ethereum.domain.AccessListItem import io.iohk.ethereum.ledger.InMemoryWorldStateProxy import io.iohk.ethereum.ledger.InMemoryWorldStateProxyStorage import io.iohk.ethereum.utils.BlockchainConfig diff --git a/src/main/scala/io/iohk/ethereum/vm/EvmConfig.scala b/src/main/scala/io/iohk/ethereum/vm/EvmConfig.scala index 7b218f210d..3a5126c167 100644 --- a/src/main/scala/io/iohk/ethereum/vm/EvmConfig.scala +++ b/src/main/scala/io/iohk/ethereum/vm/EvmConfig.scala @@ -1,10 +1,15 @@ package io.iohk.ethereum.vm import akka.util.ByteString + import io.iohk.ethereum -import io.iohk.ethereum.domain.{AccessListItem, TransactionWithAccessList, UInt256} + +import io.iohk.ethereum.domain.AccessListItem +import io.iohk.ethereum.domain.TransactionWithAccessList +import io.iohk.ethereum.domain.UInt256 import io.iohk.ethereum.utils.BlockchainConfig import io.iohk.ethereum.vm + import EvmConfig._ // scalastyle:off magic.number diff --git a/src/main/scala/io/iohk/ethereum/vm/ProgramState.scala b/src/main/scala/io/iohk/ethereum/vm/ProgramState.scala index 39f3e66996..deef4b51f8 100644 --- a/src/main/scala/io/iohk/ethereum/vm/ProgramState.scala +++ b/src/main/scala/io/iohk/ethereum/vm/ProgramState.scala @@ -1,7 +1,11 @@ package io.iohk.ethereum.vm import akka.util.ByteString -import io.iohk.ethereum.domain.{AccessListItem, Address, TxLogEntry, UInt256} + +import io.iohk.ethereum.domain.AccessListItem +import io.iohk.ethereum.domain.Address +import io.iohk.ethereum.domain.TxLogEntry +import io.iohk.ethereum.domain.UInt256 object ProgramState { def apply[W <: WorldStateProxy[W, S], S <: Storage[S]]( diff --git a/src/main/scala/io/iohk/ethereum/vm/VM.scala b/src/main/scala/io/iohk/ethereum/vm/VM.scala index 936fb568e4..768cf0f958 100644 --- a/src/main/scala/io/iohk/ethereum/vm/VM.scala +++ b/src/main/scala/io/iohk/ethereum/vm/VM.scala @@ -3,7 +3,10 @@ package io.iohk.ethereum.vm import akka.util.ByteString import scala.annotation.tailrec -import io.iohk.ethereum.domain.{AccessListItem, Address, UInt256} + +import io.iohk.ethereum.domain.AccessListItem +import io.iohk.ethereum.domain.Address +import io.iohk.ethereum.domain.UInt256 import io.iohk.ethereum.utils.Logger class VM[W <: WorldStateProxy[W, S], S <: Storage[S]] extends Logger {