You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tuweni.apache.org by to...@apache.org on 2023/01/30 07:11:55 UTC

[incubator-tuweni] branch main updated: add a simple test to check you can call the EVM from java

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 df21f7ba1 add a simple test to check you can call the EVM from java
     new 832158555 Merge pull request #506 from atoulme/add_evm_java_test
df21f7ba1 is described below

commit df21f7ba1f216c6a4ccb1b8a7ac7e2abbc0123a2
Author: Antoine Toulme <an...@lunar-ocean.com>
AuthorDate: Sun Jan 29 21:17:14 2023 -0800

    add a simple test to check you can call the EVM from java
---
 .../org/apache/tuweni/eth/precompiles/Registry.kt  |  5 ++
 .../tuweni/eth/repository/BlockchainRepository.kt  |  4 ++
 .../apache/tuweni/evm/EthereumVirtualMachine.kt    | 78 ++++++++++++++++++++++
 .../kotlin/org/apache/tuweni/evm/impl/EvmVmImpl.kt |  2 +
 .../test/java/org/apache/tuweni/evm/EVMTest.java   | 42 ++++++++++++
 .../kotlin/org/apache/tuweni/genesis/Genesis.kt    |  2 +
 6 files changed, 133 insertions(+)

diff --git a/eth-precompiles/src/main/kotlin/org/apache/tuweni/eth/precompiles/Registry.kt b/eth-precompiles/src/main/kotlin/org/apache/tuweni/eth/precompiles/Registry.kt
index 5da642caf..339d1f137 100644
--- a/eth-precompiles/src/main/kotlin/org/apache/tuweni/eth/precompiles/Registry.kt
+++ b/eth-precompiles/src/main/kotlin/org/apache/tuweni/eth/precompiles/Registry.kt
@@ -24,8 +24,13 @@ import org.hyperledger.besu.nativelib.bls12_381.LibEthPairings
  * Registry of precompiles organized by hard forks.
  */
 object Registry {
+  @JvmStatic
   val frontier: Map<Address, PrecompileContract>
+
+  @JvmStatic
   val bizantium: Map<Address, PrecompileContract>
+
+  @JvmStatic
   val istanbul: Map<Address, PrecompileContract>
 
   init {
diff --git a/eth-repository/src/main/kotlin/org/apache/tuweni/eth/repository/BlockchainRepository.kt b/eth-repository/src/main/kotlin/org/apache/tuweni/eth/repository/BlockchainRepository.kt
index f7e2035bf..061166966 100644
--- a/eth-repository/src/main/kotlin/org/apache/tuweni/eth/repository/BlockchainRepository.kt
+++ b/eth-repository/src/main/kotlin/org/apache/tuweni/eth/repository/BlockchainRepository.kt
@@ -78,6 +78,10 @@ class BlockchainRepository(
     internal val logger = LoggerFactory.getLogger(BlockchainRepository::class.java)
     internal val GENESIS_BLOCK = Bytes.wrap("genesisBlock".toByteArray())
 
+    fun inMemoryBlocking(genesisBlock: Block) = runBlocking {
+      inMemory(genesisBlock)
+    }
+
     /**
      * Constructs a blockchain repository that resides entirely in heap.
      *
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 2b6b3966c..82382f3c4 100644
--- a/evm/src/main/kotlin/org/apache/tuweni/evm/EthereumVirtualMachine.kt
+++ b/evm/src/main/kotlin/org/apache/tuweni/evm/EthereumVirtualMachine.kt
@@ -16,8 +16,13 @@
  */
 package org.apache.tuweni.evm
 
+import kotlinx.coroutines.runBlocking
 import org.apache.tuweni.bytes.Bytes
 import org.apache.tuweni.bytes.Bytes32
+import org.apache.tuweni.concurrent.AsyncCompletion
+import org.apache.tuweni.concurrent.AsyncResult
+import org.apache.tuweni.concurrent.coroutines.asyncCompletion
+import org.apache.tuweni.concurrent.coroutines.asyncResult
 import org.apache.tuweni.eth.Address
 import org.apache.tuweni.eth.Log
 import org.apache.tuweni.eth.precompiles.PrecompileContract
@@ -169,7 +174,9 @@ data class EVMMessage(
 /**
  * An Ethereum Virtual Machine.
  *
+ * @param transientRepository the state repository
  * @param repository the blockchain repository
+ * @param precompiles the registry of precompiled contracts
  * @param evmVmFactory factory to create the EVM
  * @param options the options to set on the EVM, specific to the library
  */
@@ -191,6 +198,12 @@ class EthereumVirtualMachine(
 
   private fun vm() = vm!!
 
+  fun startAsync(): AsyncCompletion = runBlocking {
+    asyncCompletion {
+      start()
+    }
+  }
+
   /**
    * Start the EVM
    */
@@ -208,6 +221,15 @@ class EthereumVirtualMachine(
    */
   fun version(): String = vm().version()
 
+  /**
+   * Stop the EVM
+   */
+  fun stopAsync() = runBlocking {
+    asyncCompletion {
+      vm().close()
+    }
+  }
+
   /**
    * Stop the EVM
    */
@@ -215,6 +237,62 @@ class EthereumVirtualMachine(
     vm().close()
   }
 
+  /**
+   * Execute an operation in the EVM asynchronously.
+   * @param sender the sender of the transaction
+   * @param destination the destination of the transaction
+   * @param code the code to execute
+   * @param inputData the execution input
+   * @param gas the gas available for the operation
+   * @param gasPrice current gas price
+   * @param currentCoinbase the coinbase address to reward
+   * @param currentNumber current block number
+   * @param currentTimestamp current block timestamp
+   * @param currentGasLimit current gas limit
+   * @param currentDifficulty block current total difficulty
+   * @param chainId the ID of the current chain
+   * @param callKind the type of call
+   * @param revision the hard fork revision in which to execute
+   * @return the result of the execution
+   */
+  fun executeAsync(
+    sender: Address,
+    destination: Address,
+    value: Bytes,
+    code: Bytes,
+    inputData: Bytes,
+    gas: Gas,
+    gasPrice: Wei,
+    currentCoinbase: Address,
+    currentNumber: UInt256,
+    currentTimestamp: UInt256,
+    currentGasLimit: Long,
+    currentDifficulty: UInt256,
+    chainId: UInt256,
+    callKind: CallKind,
+    revision: HardFork = latestHardFork
+  ): AsyncResult<EVMResult> = runBlocking {
+    asyncResult {
+      execute(
+        sender,
+        destination,
+        value,
+        code,
+        inputData,
+        gas,
+        gasPrice,
+        currentCoinbase,
+        currentNumber,
+        currentTimestamp,
+        currentGasLimit,
+        currentDifficulty,
+        chainId,
+        callKind,
+        revision
+      )
+    }
+  }
+
   /**
    * Execute an operation in the EVM.
    * @param sender the sender of the transaction
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 ae3512bac..5b2dd7278 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
@@ -52,6 +52,8 @@ interface StepListener {
 class EvmVmImpl(val stepListener: StepListener? = null) : EvmVm {
 
   companion object {
+    @JvmStatic
+    @JvmOverloads
     fun create(stepListener: StepListener? = null): EvmVm {
       return EvmVmImpl(stepListener)
     }
diff --git a/evm/src/test/java/org/apache/tuweni/evm/EVMTest.java b/evm/src/test/java/org/apache/tuweni/evm/EVMTest.java
new file mode 100644
index 000000000..97c681618
--- /dev/null
+++ b/evm/src/test/java/org/apache/tuweni/evm/EVMTest.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE
+ * file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file
+ * to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
+ * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ */
+package org.apache.tuweni.evm;
+
+import org.apache.tuweni.eth.precompiles.Registry;
+import org.apache.tuweni.eth.repository.BlockchainRepository;
+import org.apache.tuweni.evm.impl.EvmVmImpl;
+import org.apache.tuweni.genesis.Genesis;
+import org.apache.tuweni.junit.BouncyCastleExtension;
+
+import java.util.Collections;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+
+@ExtendWith(BouncyCastleExtension.class)
+public class EVMTest {
+
+  @Test
+  void testStartAndStop() {
+    BlockchainRepository repository = BlockchainRepository.Companion.inMemoryBlocking(Genesis.dev());
+
+    EthereumVirtualMachine vm = new EthereumVirtualMachine(
+        repository,
+        repository,
+        Registry.getIstanbul(),
+        EvmVmImpl::create,
+        Collections.singletonMap("DISABLE_TRANSFER_VALUE", "true"));
+    vm.startAsync();
+    vm.stopAsync();
+  }
+}
diff --git a/genesis/src/main/kotlin/org/apache/tuweni/genesis/Genesis.kt b/genesis/src/main/kotlin/org/apache/tuweni/genesis/Genesis.kt
index c05c25315..175f2c8d9 100644
--- a/genesis/src/main/kotlin/org/apache/tuweni/genesis/Genesis.kt
+++ b/genesis/src/main/kotlin/org/apache/tuweni/genesis/Genesis.kt
@@ -94,6 +94,8 @@ class Genesis(
      */
     val emptyTrieHash = Hash.hash(RLP.encodeValue(Bytes.EMPTY))
 
+    @JvmStatic
+    @JvmOverloads
     fun dev(
       genesis: Genesis = Genesis(
         Bytes.ofUnsignedLong(0),


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@tuweni.apache.org
For additional commands, e-mail: commits-help@tuweni.apache.org