This is an automated email from the ASF dual-hosted git repository.
toulmean pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/incubator-tuweni.git
The following commit(s) were added to refs/heads/main by this push:
new 1df11c6 expose the evm execution changes
new d1c73e3 Merge pull request #377 from atoulme/evm_changes
1df11c6 is described below
commit 1df11c661ac6921931550b8f7e37eafc2b45f9fa
Author: Antoine Toulme <[email protected]>
AuthorDate: Sun Mar 13 15:01:50 2022 -0700
expose the evm execution changes
---
.../apache/tuweni/evm/EthereumVirtualMachine.kt | 30 +++++++++++++++++++++-
.../tuweni/evm/TransactionalEVMHostContext.kt | 17 +++++++++---
.../kotlin/org/apache/tuweni/evm/impl/EvmVmImpl.kt | 15 ++++++-----
.../org/apache/tuweni/evm/EVMReferenceTest.kt | 4 +--
4 files changed, 52 insertions(+), 14 deletions(-)
diff --git
a/evm/src/main/kotlin/org/apache/tuweni/evm/EthereumVirtualMachine.kt
b/evm/src/main/kotlin/org/apache/tuweni/evm/EthereumVirtualMachine.kt
index b9e3d33..f39de16 100644
--- a/evm/src/main/kotlin/org/apache/tuweni/evm/EthereumVirtualMachine.kt
+++ b/evm/src/main/kotlin/org/apache/tuweni/evm/EthereumVirtualMachine.kt
@@ -19,6 +19,7 @@ package org.apache.tuweni.evm
import org.apache.tuweni.bytes.Bytes
import org.apache.tuweni.bytes.Bytes32
import org.apache.tuweni.eth.Address
+import org.apache.tuweni.eth.Log
import org.apache.tuweni.eth.repository.BlockchainRepository
import org.apache.tuweni.evm.impl.GasManager
import org.apache.tuweni.units.bigints.UInt256
@@ -98,6 +99,7 @@ data class EVMResult(
val statusCode: EVMExecutionStatusCode,
val gasManager: GasManager,
val hostContext: HostContext,
+ val changes: ExecutionChanges,
val output: Bytes? = null,
)
@@ -312,7 +314,7 @@ interface HostContext {
* @param value The value to be stored.
* @return The effect on the storage item.
*/
- suspend fun setStorage(address: Address, key: Bytes, value: Bytes32): Int
+ suspend fun setStorage(address: Address, key: Bytes32, value: Bytes32): Int
/**
* Get balance function.
@@ -574,3 +576,29 @@ val opcodes = mapOf<Byte, String>(
Pair(0xfe.toByte(), "invalid"),
Pair(0xff.toByte(), "selfdestruct"),
)
+
+/**
+ * EVM transaction changes
+ */
+interface ExecutionChanges {
+
+ /**
+ * Changes made to account storage.
+ */
+ fun getAccountChanges(): Map<Address, HashMap<Bytes32, Bytes32>>
+
+ /**
+ * Logs emitted during execution
+ */
+ fun getLogs(): List<Log>
+
+ /**
+ * Lists of accounts to destroy
+ */
+ fun accountsToDestroy(): List<Address>
+
+ /**
+ * Lists of balance changes, with the final balances
+ */
+ fun getBalanceChanges(): Map<Address, Wei>
+}
diff --git
a/evm/src/main/kotlin/org/apache/tuweni/evm/TransactionalEVMHostContext.kt
b/evm/src/main/kotlin/org/apache/tuweni/evm/TransactionalEVMHostContext.kt
index 295f1bc..0c7a0af 100644
--- a/evm/src/main/kotlin/org/apache/tuweni/evm/TransactionalEVMHostContext.kt
+++ b/evm/src/main/kotlin/org/apache/tuweni/evm/TransactionalEVMHostContext.kt
@@ -47,17 +47,26 @@ class TransactionalEVMHostContext(
val currentTimestamp: Long,
val currentGasLimit: Long,
val currentDifficulty: UInt256
-) : HostContext {
+) : HostContext, ExecutionChanges {
companion object {
private val logger =
LoggerFactory.getLogger(TransactionalEVMHostContext::class.java)
}
- val accountChanges = HashMap<Address, HashMap<Bytes, Bytes32>>()
- val logs = mutableListOf<Log>()
+ private val accountChanges = mutableMapOf<Address, HashMap<Bytes32,
Bytes32>>()
+ private val logs = mutableListOf<Log>()
val accountsToDestroy = mutableListOf<Address>()
val balanceChanges = HashMap<Address, Wei>()
val warmedUpStorage = HashSet<Bytes>()
+
+ override fun getAccountChanges(): Map<Address, HashMap<Bytes32, Bytes32>> =
accountChanges
+
+ override fun getLogs(): List<Log> = logs
+
+ override fun accountsToDestroy(): List<Address> = accountsToDestroy
+
+ override fun getBalanceChanges(): Map<Address, Wei> = balanceChanges
+
/**
* Check account existence function.
*
@@ -125,7 +134,7 @@ class TransactionalEVMHostContext(
* A storage item has been deleted: X -> 0.
* EVMC_STORAGE_DELETED = 4
*/
- override suspend fun setStorage(address: Address, key: Bytes, value:
Bytes32): Int {
+ override suspend fun setStorage(address: Address, key: Bytes32, value:
Bytes32): Int {
logger.trace("Entering setStorage {} {} {}", address, key, value)
var newAccount = false
accountChanges.computeIfAbsent(address) {
diff --git a/evm/src/main/kotlin/org/apache/tuweni/evm/impl/EvmVmImpl.kt
b/evm/src/main/kotlin/org/apache/tuweni/evm/impl/EvmVmImpl.kt
index 7e1fd3d..0c9f90d 100644
--- a/evm/src/main/kotlin/org/apache/tuweni/evm/impl/EvmVmImpl.kt
+++ b/evm/src/main/kotlin/org/apache/tuweni/evm/impl/EvmVmImpl.kt
@@ -23,6 +23,7 @@ import org.apache.tuweni.evm.EVMResult
import org.apache.tuweni.evm.EvmVm
import org.apache.tuweni.evm.HardFork
import org.apache.tuweni.evm.HostContext
+import org.apache.tuweni.evm.TransactionalEVMHostContext
import org.apache.tuweni.evm.opcodes
import org.slf4j.LoggerFactory
@@ -72,7 +73,7 @@ class EvmVmImpl : EvmVm {
val opcode = registry.get(fork, code.get(current))
if (opcode == null) {
logger.error("Could not find opcode for ${code.slice(current, 1)} at
position $current")
- return EVMResult(EVMExecutionStatusCode.INVALID_INSTRUCTION,
gasManager, hostContext)
+ return EVMResult(EVMExecutionStatusCode.INVALID_INSTRUCTION,
gasManager, hostContext, hostContext as TransactionalEVMHostContext)
}
val currentOpcodeByte = code.get(current)
current++
@@ -87,27 +88,27 @@ class EvmVmImpl : EvmVm {
logger.trace(executionPath.map { opcodes[it] ?: it.toString(16)
}.joinToString(">"))
}
if (result.status == EVMExecutionStatusCode.SUCCESS &&
!gasManager.hasGasLeft()) {
- return EVMResult(EVMExecutionStatusCode.OUT_OF_GAS, gasManager,
hostContext)
+ return EVMResult(EVMExecutionStatusCode.OUT_OF_GAS, gasManager,
hostContext, hostContext as TransactionalEVMHostContext)
}
- return EVMResult(result.status, gasManager, hostContext, result.output)
+ return EVMResult(result.status, gasManager, hostContext, hostContext
as TransactionalEVMHostContext, result.output)
}
result?.newCodePosition?.let {
current = result.newCodePosition
}
if (!gasManager.hasGasLeft()) {
- return EVMResult(EVMExecutionStatusCode.OUT_OF_GAS, gasManager,
hostContext)
+ return EVMResult(EVMExecutionStatusCode.OUT_OF_GAS, gasManager,
hostContext, hostContext as TransactionalEVMHostContext)
}
if (stack.overflowed()) {
- return EVMResult(EVMExecutionStatusCode.STACK_OVERFLOW, gasManager,
hostContext)
+ return EVMResult(EVMExecutionStatusCode.STACK_OVERFLOW, gasManager,
hostContext, hostContext as TransactionalEVMHostContext)
}
if (result?.validationStatus != null) {
- return EVMResult(result.validationStatus, gasManager, hostContext)
+ return EVMResult(result.validationStatus, gasManager, hostContext,
hostContext as TransactionalEVMHostContext)
}
}
if (logger.isTraceEnabled) {
logger.trace(executionPath.map { opcodes[it] ?: it.toString(16)
}.joinToString(">"))
}
- return EVMResult(EVMExecutionStatusCode.SUCCESS, gasManager, hostContext)
+ return EVMResult(EVMExecutionStatusCode.SUCCESS, gasManager, hostContext,
hostContext as TransactionalEVMHostContext)
}
override fun capabilities(): Int {
diff --git a/evm/src/test/kotlin/org/apache/tuweni/evm/EVMReferenceTest.kt
b/evm/src/test/kotlin/org/apache/tuweni/evm/EVMReferenceTest.kt
index 9b90b4e..3e5a996 100644
--- a/evm/src/test/kotlin/org/apache/tuweni/evm/EVMReferenceTest.kt
+++ b/evm/src/test/kotlin/org/apache/tuweni/evm/EVMReferenceTest.kt
@@ -253,7 +253,7 @@ class EVMReferenceTest {
runBlocking {
assertTrue(
repository.accountsExists(address) ||
- (result.hostContext as
TransactionalEVMHostContext).accountChanges.containsKey(address)
+ (result.hostContext as
TransactionalEVMHostContext).getAccountChanges().containsKey(address)
)
val accountState = repository.getAccount(address)
val balance = accountState?.balance?.add(
@@ -270,7 +270,7 @@ class EVMReferenceTest {
}
test.logs?.let {
val logsTree = MerklePatriciaTrie.storingBytes()
- (result.hostContext as TransactionalEVMHostContext).logs.forEach {
+ (result.hostContext as
TransactionalEVMHostContext).getLogs().forEach {
runBlocking {
logsTree.put(Hash.hash(it.toBytes()), it.toBytes())
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]