Skip to content

Commit

Permalink
Merge pull request #22 from HorizenOfficial/development
Browse files Browse the repository at this point in the history
version 1.0.0 to master
  • Loading branch information
paolocappelletti authored Nov 21, 2023
2 parents 6ec0a52 + b979a25 commit 8900a6a
Show file tree
Hide file tree
Showing 77 changed files with 1,917 additions and 836 deletions.
Empty file added .gitmodules
Empty file.
2 changes: 1 addition & 1 deletion .run/All in evm.run.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
<option name="METHOD_NAME" value="" />
<option name="TEST_OBJECT" value="package" />
<method v="2">
<option name="Make" enabled="true" />
<option name="RunConfigurationTask" enabled="true" run_configuration_name="build libevm for EVM package" run_configuration_type="ShConfigurationType" />
<option name="Make" enabled="true" />
</method>
</configuration>
</component>
2 changes: 1 addition & 1 deletion .run/build libevm for EVM package.run.xml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
<option name="INDEPENDENT_INTERPRETER_PATH" value="true" />
<option name="INTERPRETER_PATH" value="/usr/bin/zsh" />
<option name="INTERPRETER_OPTIONS" value="" />
<option name="EXECUTE_IN_TERMINAL" value="true" />
<option name="EXECUTE_IN_TERMINAL" value="false" />
<option name="EXECUTE_SCRIPT_FILE" value="true" />
<envs />
<method v="2" />
Expand Down
4 changes: 2 additions & 2 deletions .run/compile test contracts.run.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@
<option name="SCRIPT_PATH" value="" />
<option name="SCRIPT_OPTIONS" value="" />
<option name="INDEPENDENT_SCRIPT_WORKING_DIRECTORY" value="true" />
<option name="SCRIPT_WORKING_DIRECTORY" value="$PROJECT_DIR$/libevm" />
<option name="SCRIPT_WORKING_DIRECTORY" value="$PROJECT_DIR$/native" />
<option name="INDEPENDENT_INTERPRETER_PATH" value="true" />
<option name="INTERPRETER_PATH" value="/usr/bin/zsh" />
<option name="INTERPRETER_OPTIONS" value="" />
<option name="EXECUTE_IN_TERMINAL" value="true" />
<option name="EXECUTE_IN_TERMINAL" value="false" />
<option name="EXECUTE_SCRIPT_FILE" value="false" />
<envs />
<method v="2" />
Expand Down
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ env:
- IMAGE_NAME=sc-ci-base
# Separate branches by space
- PROD_RELEASE_BRANCHES='main'
- GOLANG_VERSION=1.18
- GOLANG_VERSION=1.21

script:
- source ci/setup_env.sh
Expand Down
10 changes: 9 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,16 @@
# Changelog

## 1.0.0

- Updated Go version to 1.21
- Based on [HorizenOfficial/go-ethereum](https://github.com/HorizenOfficial/go-ethereum) `v1.0.0`
- Support for interoperability between EVM and native smart contracts



## 0.1.0

Provides standlone access to go-ethereum features:
Provides standalone access to go-ethereum features:
- `StateDB` with underlying database:
- `MemoryDatabase`
- `LevelDBDatabase`
Expand Down
2 changes: 1 addition & 1 deletion libevm/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>io.horizen</groupId>
<artifactId>libevm</artifactId>
<version>0.1.0</version>
<version>1.0.0-SNAPSHOT</version>
<name>${project.groupId}:${project.artifactId}</name>
<description>This library provides access to a standalone version of the go-ethereum EVM and its state storage layer StateDB and underlying LevelDB.</description>
<url>https://github.com/${project.github.organization}/${project.artifactId}</url>
Expand Down
13 changes: 5 additions & 8 deletions libevm/src/main/java/io/horizen/evm/BlockHashCallback.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,14 @@ public abstract class BlockHashCallback extends LibEvmCallback {
public String invoke(String args) {
logger.debug("received block hash callback");
try {
if (!args.startsWith("0x")) {
logger.warn("received invalid block number: {}", args);
} else {
var blockNumber = new BigInteger(args.substring(2), 16);
return getBlockHash(blockNumber).toString();
}
var blockNumber = Converter.fromJson(args, BigInteger.class);
return Converter.toJson(getBlockHash(blockNumber));
} catch (Exception e) {
// note: make sure we do not throw any exception here because this callback is called by native code
// for diagnostics we log the exception here
logger.warn("received invalid block hash collback from libevm", e);
logger.warn("received invalid block hash callback", e);
}
return Hash.ZERO.toString();
return Converter.toJson(Hash.ZERO);
}
}

8 changes: 8 additions & 0 deletions libevm/src/main/java/io/horizen/evm/Converter.java
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,14 @@ public static <T> T fromJson(String json, JavaType type) {
}
}

public static <T> T fromJson(String json, Class<T> valueType) {
try {
return mapper.readValue(json, valueType);
} catch (IOException e) {
throw new IllegalArgumentException(e);
}
}

// Get byte array from hex string
public static byte[] fromHexString(String hex) {
return BaseEncoding.base16().lowerCase().decode(hex.toLowerCase());
Expand Down
4 changes: 2 additions & 2 deletions libevm/src/main/java/io/horizen/evm/Database.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ public Database(int handle) {
}

@Override
public void close() throws Exception {
LibEvm.invoke("CloseDatabase", new DatabaseParams(handle));
public void close() {
LibEvm.invoke("DatabaseClose", new DatabaseParams(handle));
}
}
21 changes: 4 additions & 17 deletions libevm/src/main/java/io/horizen/evm/Evm.java
Original file line number Diff line number Diff line change
@@ -1,26 +1,13 @@
package io.horizen.evm;

import io.horizen.evm.params.EvmParams;
import io.horizen.evm.results.EvmResult;

import java.math.BigInteger;
import io.horizen.evm.results.InvocationResult;

public final class Evm {
private Evm() { }

public static EvmResult Apply(
ResourceHandle stateDBHandle,
Address from,
Address to,
BigInteger value,
byte[] input,
BigInteger gasLimit,
BigInteger gasPrice,
EvmContext context,
TraceOptions traceOptions
) {
var params = new EvmParams(
stateDBHandle.handle, from, to, value, input, gasLimit, gasPrice, context, traceOptions);
return LibEvm.invoke("EvmApply", params, EvmResult.class);
public static InvocationResult Apply(ResourceHandle stateDBHandle, Invocation invocation, EvmContext context) {
var params = new EvmParams(stateDBHandle.handle, invocation, context);
return LibEvm.invoke("EvmApply", params, InvocationResult.class);
}
}
92 changes: 84 additions & 8 deletions libevm/src/main/java/io/horizen/evm/EvmContext.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,88 @@
import java.math.BigInteger;

public class EvmContext {
public BigInteger chainID;
public Address coinbase;
public BigInteger gasLimit;
public BigInteger blockNumber;
public BigInteger time;
public BigInteger baseFee;
public Hash random;
public BlockHashCallback blockHashCallback;
public final BigInteger chainID;
public final Address coinbase;
public final BigInteger gasLimit;
public final BigInteger gasPrice;
public final BigInteger blockNumber;
public final BigInteger time;
public final BigInteger baseFee;
public final Hash random;
private BlockHashCallback blockHashCallback;
private Address[] externalContracts;
private InvocationCallback externalCallback;
private Tracer tracer;
private int initialDepth;


public EvmContext(BigInteger chainID,
Address coinbase,
BigInteger gasLimit,
BigInteger gasPrice,
BigInteger blockNumber,
BigInteger time,
BigInteger baseFee,
Hash random) {
this.chainID = chainID;
this.coinbase = coinbase;
this.gasLimit = gasLimit;
this.gasPrice = gasPrice;
this.blockNumber = blockNumber;
this.time = time;
this.baseFee = baseFee;
this.random = random;
}

//This constructor is just for testing purposes
EvmContext() {
chainID = BigInteger.ZERO;
coinbase = Address.ZERO;
gasLimit = BigInteger.ZERO;
gasPrice = BigInteger.ZERO;
blockNumber = BigInteger.ZERO;
time = BigInteger.ZERO;
baseFee = BigInteger.ZERO;
random = Hash.ZERO;
};

public BlockHashCallback getBlockHashCallback() {
return blockHashCallback;
}

public void setBlockHashCallback(BlockHashCallback blockHashCallback) {
this.blockHashCallback = blockHashCallback;
}

public Address[] getExternalContracts() {
return externalContracts;
}

public void setExternalContracts(Address[] externalContracts) {
this.externalContracts = externalContracts;
}

public InvocationCallback getExternalCallback() {
return externalCallback;
}

public void setExternalCallback(InvocationCallback externalCallback) {
this.externalCallback = externalCallback;
}

public Tracer getTracer() {
return tracer;
}

public void setTracer(Tracer tracer) {
this.tracer = tracer;
}

public int getInitialDepth() {
return initialDepth;
}

public void setInitialDepth(int initialDepth) {
this.initialDepth = initialDepth;
}
}
22 changes: 22 additions & 0 deletions libevm/src/main/java/io/horizen/evm/ExternalInvocation.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package io.horizen.evm;

import com.fasterxml.jackson.annotation.JsonProperty;

import java.math.BigInteger;

public class ExternalInvocation extends Invocation {
public final int depth;

public ExternalInvocation(
@JsonProperty("caller") Address caller,
@JsonProperty("callee") Address callee,
@JsonProperty("value") BigInteger value,
@JsonProperty("input") byte[] input,
@JsonProperty("gas") BigInteger gas,
@JsonProperty("readOnly") boolean readOnly,
@JsonProperty("depth") int depth
) {
super(caller, callee, value, input, gas, readOnly);
this.depth = depth;
}
}
6 changes: 2 additions & 4 deletions libevm/src/main/java/io/horizen/evm/GlogCallback.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package io.horizen.evm;

import com.fasterxml.jackson.databind.type.TypeFactory;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.Logger;

Expand All @@ -16,8 +15,7 @@ class GlogCallback extends LibEvmCallback {
@Override
public String invoke(String args) {
try {
HashMap<String, Object> data =
Converter.fromJson(args, TypeFactory.defaultInstance().constructType(HashMap.class));
var data = Converter.fromJson(args, HashMap.class);
// parse and remove known properties from the map
var level = glogToLog4jLevel((String) data.remove("lvl"));
var file = data.remove("file");
Expand All @@ -32,7 +30,7 @@ public String invoke(String args) {
// note: make sure we do not throw any exception here because this callback is called by native code
// for diagnostics we log the exception here, if it is caused by malformed json it will also include
// the raw json string itself
logger.warn("received invalid log message data from libevm", e);
logger.warn("received invalid log message data", e);
}
return null;
}
Expand Down
30 changes: 30 additions & 0 deletions libevm/src/main/java/io/horizen/evm/Invocation.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package io.horizen.evm;

import com.fasterxml.jackson.annotation.JsonProperty;

import java.math.BigInteger;

public class Invocation {
public final Address caller;
public final Address callee;
public final BigInteger value;
public final byte[] input;
public final BigInteger gas;
public final boolean readOnly;

public Invocation(
@JsonProperty("caller") Address caller,
@JsonProperty("callee") Address callee,
@JsonProperty("value") BigInteger value,
@JsonProperty("input") byte[] input,
@JsonProperty("gas") BigInteger gas,
@JsonProperty("readOnly") boolean readOnly
) {
this.caller = caller;
this.callee = callee;
this.value = value;
this.input = input;
this.gas = gas;
this.readOnly = readOnly;
}
}
25 changes: 25 additions & 0 deletions libevm/src/main/java/io/horizen/evm/InvocationCallback.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package io.horizen.evm;

import io.horizen.evm.results.InvocationResult;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

public abstract class InvocationCallback extends LibEvmCallback {
private static final Logger logger = LogManager.getLogger();

protected abstract InvocationResult execute(ExternalInvocation args);

@Override
public String invoke(String args) {
logger.debug("received external contract callback");
try {
var invocation = Converter.fromJson(args, ExternalInvocation.class);
return Converter.toJson(execute(invocation));
} catch (Exception e) {
// note: make sure we do not throw any exception here because this callback is called by native code
// for diagnostics we log the exception here
logger.warn("received invalid external contract callback", e);
}
return null;
}
}
2 changes: 1 addition & 1 deletion libevm/src/main/java/io/horizen/evm/LevelDBDatabase.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ public class LevelDBDatabase extends Database {
* @param path data directory to pass to levelDB
*/
public LevelDBDatabase(String path) {
super(LibEvm.invoke("OpenLevelDB", new LevelDBParams(path), int.class));
super(LibEvm.invoke("DatabaseOpenLevelDB", new LevelDBParams(path), int.class));
}

@Override
Expand Down
2 changes: 1 addition & 1 deletion libevm/src/main/java/io/horizen/evm/LibEvm.java
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ public Pointer callback(int handle, Pointer msg) {
} catch (Exception e) {
// note: make sure we do not throw any exception here because this callback is called by native code
// for diagnostics we log the exception here
logger.warn("error while handling callback from libevm", e);
logger.warn("error while handling callback", e);
}
return null;
}
Expand Down
2 changes: 1 addition & 1 deletion libevm/src/main/java/io/horizen/evm/MemoryDatabase.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ public class MemoryDatabase extends Database {
* Open an ephemeral key-value database in memory.
*/
public MemoryDatabase() {
super(LibEvm.invoke("OpenMemoryDB", int.class));
super(LibEvm.invoke("DatabaseOpenMemoryDB", int.class));
}

@Override
Expand Down
3 changes: 3 additions & 0 deletions libevm/src/main/java/io/horizen/evm/ResourceHandle.java
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
package io.horizen.evm;

import com.fasterxml.jackson.annotation.JsonValue;

public abstract class ResourceHandle implements AutoCloseable {
/**
* Handle to a native resource that requires manual release.
*/
@JsonValue
final int handle;

public ResourceHandle(int handle) {
Expand Down
Loading

0 comments on commit 8900a6a

Please sign in to comment.