Skip to content

Commit 361ac9c

Browse files
authored
Update protobuf extvm to 'Berlin' (#1123)
* Update protobuf extvm to 'Berlin' * Pass accessList in extenal EVM calls
1 parent 4ddead8 commit 361ac9c

File tree

6 files changed

+56
-10
lines changed

6 files changed

+56
-10
lines changed

nix/overlay.nix

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ rev: final: prev: {
1414
# ourselves instead.
1515
mantis-extvm-pb = builtins.fetchGit {
1616
url = "https://github.com/input-output-hk/mantis-extvm-pb";
17-
rev = "8f52caba70afc95ce669e9d61f773468db54557e";
17+
rev = "ae19e1fd9d3c0deba63c894be128d67e9519fe1f";
1818
};
1919

2020
writeBashChecked = final.writers.makeScriptWriter {

src/main/protobuf/extvm

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

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,17 @@ class VMClient(externalVmConfig: VmConfig.ExternalConfig, messageHandler: Messag
105105
resultMsg: msg.CallResult
106106
): ProgramResult[W, S] = {
107107
val updatedWorld = applyAccountChanges[W, S](world, resultMsg)
108+
109+
val accessedResultTuple = resultMsg.accessList
110+
.map { accessList =>
111+
val addresses: Set[Address] = accessList.addresses.map(a => a: Address).toSet
112+
val locations: Set[(Address, BigInt)] = accessList.storageLocations.map { loc =>
113+
(loc.address: Address, loc.storageLocation: BigInt)
114+
}.toSet
115+
(addresses, locations)
116+
}
117+
.getOrElse((Set.empty[Address], Set.empty[(Address, BigInt)]))
118+
108119
ProgramResult(
109120
resultMsg.returnData,
110121
resultMsg.gasRemaining,
@@ -114,9 +125,8 @@ class VMClient(externalVmConfig: VmConfig.ExternalConfig, messageHandler: Messag
114125
Nil,
115126
resultMsg.gasRefund,
116127
if (resultMsg.error) Some(OutOfGas) else None,
117-
// FIXME handle accessed addresses and storage in extVM
118-
Set.empty,
119-
Set.empty
128+
accessedResultTuple._1,
129+
accessedResultTuple._2
120130
)
121131
}
122132

@@ -155,6 +165,23 @@ class VMClient(externalVmConfig: VmConfig.ExternalConfig, messageHandler: Messag
155165
case _ => Config.Empty
156166
}
157167

168+
val txType =
169+
if (ctx.warmAddresses.isEmpty && ctx.warmStorage.isEmpty) msg.CallContext.TxType.LEGACY
170+
else msg.CallContext.TxType.ACCESSLIST
171+
172+
val extraData = txType match {
173+
case msg.CallContext.TxType.LEGACY => msg.CallContext.ExtraData.Empty
174+
case msg.CallContext.TxType.ACCESSLIST =>
175+
msg.CallContext.ExtraData.AccessList(
176+
msg
177+
.AccessListData()
178+
.withAddresses(ctx.warmAddresses.toSeq.map(_.bytes))
179+
.withStorageLocations(
180+
ctx.warmStorage.toSeq.map(x => msg.StorageEntry(address = x._1, storageLocation = x._2))
181+
)
182+
)
183+
}
184+
158185
msg.CallContext(
159186
callerAddr = ctx.callerAddr,
160187
recipientAddr = ctx.recipientAddr.map(_.bytes).getOrElse(ByteString.empty): ByteString,
@@ -163,7 +190,9 @@ class VMClient(externalVmConfig: VmConfig.ExternalConfig, messageHandler: Messag
163190
gasPrice = ctx.gasPrice,
164191
gasProvided = ctx.startGas,
165192
blockHeader = Some(blockHeader),
166-
config = config
193+
config = config,
194+
txType = txType,
195+
extraData = extraData
167196
)
168197
}
169198

@@ -178,6 +207,7 @@ class VMClient(externalVmConfig: VmConfig.ExternalConfig, messageHandler: Messag
178207
constantinopleBlockNumber = blockchainConfig.constantinopleBlockNumber,
179208
petersburgBlockNumber = blockchainConfig.petersburgBlockNumber,
180209
istanbulBlockNumber = blockchainConfig.istanbulBlockNumber,
210+
berlinBlockNumber = blockchainConfig.berlinBlockNumber,
181211
maxCodeSize = blockchainConfig.maxCodeSize.map(bigintToGByteString).getOrElse(ByteString()),
182212
accountStartNonce = blockchainConfig.accountStartNonce,
183213
chainId = ByteString(blockchainConfig.chainId)

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

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ import com.typesafe.config.ConfigFactory
2424
import io.iohk.ethereum.domain.Address
2525
import io.iohk.ethereum.domain.BlockHeader
2626
import io.iohk.ethereum.extvm.Implicits._
27+
import io.iohk.ethereum.extvm.msg.AccessListData
28+
import io.iohk.ethereum.extvm.msg.StorageEntry
2729
import io.iohk.ethereum.utils._
2830
import io.iohk.ethereum.vm.BlockchainConfigForEvm
2931
import io.iohk.ethereum.vm.EvmConfig
@@ -106,6 +108,7 @@ class VMServer(messageHandler: MessageHandler) extends Logger {
106108
messageHandler.close()
107109
}
108110

111+
// scalastyle:off method.length
109112
private def constructContextFromMsg(contextMsg: msg.CallContext): ProgramContext[World, Storage] = {
110113
import ByteString.{empty => irrelevant} // used for irrelevant BlockHeader fields
111114

@@ -136,6 +139,10 @@ class VMServer(messageHandler: MessageHandler) extends Logger {
136139
val recipientAddr: Option[Address] =
137140
Option(contextMsg.recipientAddr).filterNot(_.isEmpty).map(bytes => Address(bytes: ByteString))
138141

142+
val (warmAddresses: Set[Address], warmStorage: Set[(Address, BigInt)]) = contextMsg.extraData.accessList
143+
.map(extractWarmAccessList)
144+
.getOrElse((Set.empty[Address], Set.empty[(Address, BigInt)]))
145+
139146
ProgramContext(
140147
callerAddr = contextMsg.callerAddr,
141148
originAddr = contextMsg.callerAddr,
@@ -152,11 +159,19 @@ class VMServer(messageHandler: MessageHandler) extends Logger {
152159
initialAddressesToDelete = Set(),
153160
evmConfig = vmConfig,
154161
originalWorld = world,
155-
// TODO ETCM-1202 use access list from CallContext
156-
warmAddresses = Set.empty,
157-
warmStorage = Set.empty
162+
warmAddresses = warmAddresses,
163+
warmStorage = warmStorage
158164
)
159165
}
166+
// scalastyle:on method.length
167+
168+
private def extractWarmAccessList(ald: AccessListData): (Set[Address], Set[(Address, BigInt)]) = {
169+
val warmAddresses: Set[Address] = ald.addresses.toSet.map((bs: GByteString) => Address(bs: ByteString))
170+
val warmStorage: Set[(Address, BigInt)] = ald.storageLocations.toSet.map { (se: StorageEntry) =>
171+
(Address(se.address: ByteString), se.storageLocation: BigInt)
172+
}
173+
(warmAddresses, warmStorage)
174+
}
160175

161176
private def buildResultMsg(result: ProgramResult[World, Storage]): msg.CallResult = {
162177

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,7 @@ class VMClientSpec extends AnyFlatSpec with Matchers with MockFactory {
170170
constantinopleBlockNumber = forkBlockNumbers.constantinopleBlockNumber,
171171
petersburgBlockNumber = forkBlockNumbers.petersburgBlockNumber,
172172
istanbulBlockNumber = forkBlockNumbers.istanbulBlockNumber,
173+
berlinBlockNumber = forkBlockNumbers.berlinBlockNumber,
173174
maxCodeSize = blockchainConfig.maxCodeSize.get,
174175
accountStartNonce = blockchainConfig.accountStartNonce,
175176
chainId = ByteString(blockchainConfig.chainId)

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ class VMServerSpec extends AnyFlatSpec with Matchers with MockFactory {
122122
chainId = ByteString(blockchainConfig.chainId)
123123
)
124124
val ethereumConfigMsg: Hello.Config.EthereumConfig = msg.Hello.Config.EthereumConfig(ethereumConfig)
125-
val helloMsg: Hello = msg.Hello(version = "2.1", config = ethereumConfigMsg)
125+
val helloMsg: Hello = msg.Hello(version = "2.2", config = ethereumConfigMsg)
126126

127127
val messageHandler: MessageHandler = mock[MessageHandler]
128128
val vmServer = new VMServer(messageHandler)

0 commit comments

Comments
 (0)