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]

Reply via email to