Skip to content

Commit

Permalink
Add parameters to EVM library fluent API
Browse files Browse the repository at this point in the history
Add the ability to configure more parameters in the fluent API.
Specifically contract address, coinbase, difficulty, mixHash/prevRandao,
baseFee, block number, timestamp, gas limit, previous block hashes, and
versioned hashes.

Signed-off-by: Danno Ferrin <[email protected]>
  • Loading branch information
shemnon committed Sep 22, 2023
1 parent 9d7ee2b commit 349b4bf
Show file tree
Hide file tree
Showing 2 changed files with 227 additions and 5 deletions.
164 changes: 160 additions & 4 deletions evm/src/main/java/org/hyperledger/besu/evm/fluent/EVMExecutor.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

import org.hyperledger.besu.datatypes.Address;
import org.hyperledger.besu.datatypes.Hash;
import org.hyperledger.besu.datatypes.VersionedHash;
import org.hyperledger.besu.datatypes.Wei;
import org.hyperledger.besu.evm.Code;
import org.hyperledger.besu.evm.EVM;
Expand All @@ -40,7 +41,9 @@
import java.util.Deque;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.function.Function;

import com.google.common.collect.HashMultimap;
import com.google.common.collect.Multimap;
Expand All @@ -57,12 +60,16 @@ public class EVMExecutor {
private long gas = Long.MAX_VALUE;
private Address receiver = Address.ZERO;
private Address sender = Address.ZERO;
private Address contract = Address.ZERO;
private Address coinbase = Address.ZERO;
private Wei gasPriceGWei = Wei.ZERO;
private Wei blobGasPrice = Wei.ZERO;
private Bytes callData = Bytes.EMPTY;
private Wei ethValue = Wei.ZERO;
private Code code = CodeV0.EMPTY_CODE;
private BlockValues blockValues = new SimpleBlockValues();
private Function<Long, Hash> blockHashLookup = h -> null;
private Optional<List<VersionedHash>> versionedHashes = Optional.empty();
private OperationTracer tracer = OperationTracer.NO_TRACING;
private boolean requireDeposit = true;
private List<ContractValidationRule> contractValidationRules =
Expand Down Expand Up @@ -350,7 +357,7 @@ public Bytes execute() {
.type(MessageFrame.Type.MESSAGE_CALL)
.worldUpdater(worldUpdater.updater())
.initialGas(gas)
.contract(Address.ZERO)
.contract(contract)
.address(receiver)
.originator(sender)
.sender(sender)
Expand All @@ -361,11 +368,12 @@ public Bytes execute() {
.apparentValue(ethValue)
.code(code)
.blockValues(blockValues)
.completer(c -> {})
.miningBeneficiary(Address.ZERO)
.blockHashLookup(h -> null)
.miningBeneficiary(coinbase)
.blockHashLookup(blockHashLookup)
.accessListWarmAddresses(accessListWarmAddresses)
.accessListWarmStorage(accessListWarmStorage)
.versionedHashes(versionedHashes)
.completer(c -> {})
.build();

final Deque<MessageFrame> messageFrameStack = initialMessageFrame.getMessageFrameStack();
Expand Down Expand Up @@ -448,6 +456,28 @@ public EVMExecutor sender(final Address sender) {
return this;
}

/**
* Sets the address of the executing contract
*
* @param contract the contract
* @return the evm executor
*/
public EVMExecutor contract(final Address contract) {
this.contract = contract;
return this;
}

/**
* Sets the address of the coinbase aka mining beneficiary
*
* @param coinbase the coinbase
* @return the evm executor
*/
public EVMExecutor coinbase(final Address coinbase) {
this.coinbase = coinbase;
return this;
}

/**
* Sets Gas price GWei.
*
Expand Down Expand Up @@ -526,6 +556,132 @@ public EVMExecutor blockValues(final BlockValues blockValues) {
return this;
}

/**
* Sets the difficulty bytes on a SimpleBlockValues object
*
* @param difficulty the difficulty
* @return the evm executor
* @throws ClassCastException if the blockValues was set with a value that is not a {@link
* SimpleBlockValues}
*/
public EVMExecutor difficulty(final Bytes difficulty) {
((SimpleBlockValues) this.blockValues).setDifficultyBytes(difficulty);
return this;
}

/**
* Sets the mix hash bytes on a SimpleBlockValues object
*
* @param mixHash the mix hash
* @return the evm executor
* @throws ClassCastException if the blockValues was set with a value that is not a {@link
* SimpleBlockValues}
*/
public EVMExecutor mixHash(final Bytes32 mixHash) {
((SimpleBlockValues) this.blockValues).setMixHasOrPrevRandao(mixHash);
return this;
}

/**
* Sets the prev randao bytes on a SimpleBlockValues object
*
* @param prevRandao the prev randao
* @return the evm executor
* @throws ClassCastException if the blockValues was set with a value that is not a {@link
* SimpleBlockValues}
*/
public EVMExecutor prevRandao(final Bytes32 prevRandao) {
((SimpleBlockValues) this.blockValues).setMixHasOrPrevRandao(prevRandao);
return this;
}

/**
* Sets the baseFee for the block, directly.
*
* @param baseFee the baseFee
* @return the evm executor
* @throws ClassCastException if the blockValues was set with a value that is not a {@link
* SimpleBlockValues}
*/
public EVMExecutor baseFee(final Wei baseFee) {
((SimpleBlockValues) this.blockValues).setBaseFee(Optional.ofNullable(baseFee));
return this;
}

/**
* Sets the baseFee for the block, as an Optional.
*
* @param baseFee the baseFee
* @return the evm executor
* @throws ClassCastException if the blockValues was set with a value that is not a {@link
* SimpleBlockValues}
*/
public EVMExecutor baseFee(final Optional<Wei> baseFee) {
((SimpleBlockValues) this.blockValues).setBaseFee(baseFee);
return this;
}

/**
* Sets the block number for the block.
*
* @param number the block number
* @return the evm executor
* @throws ClassCastException if the blockValues was set with a value that is not a {@link
* SimpleBlockValues}
*/
public EVMExecutor number(final long number) {
((SimpleBlockValues) this.blockValues).setNumber(number);
return this;
}

/**
* Sets the timestamp for the block.
*
* @param timestamp the block timestamp
* @return the evm executor
* @throws ClassCastException if the blockValues was set with a value that is not a {@link
* SimpleBlockValues}
*/
public EVMExecutor timestamp(final long timestamp) {
((SimpleBlockValues) this.blockValues).setNumber(timestamp);
return this;
}

/**
* Sets the gas limit for the block.
*
* @param gasLimit the block gas limit
* @return the evm executor
* @throws ClassCastException if the blockValues was set with a value that is not a {@link
* SimpleBlockValues}
*/
public EVMExecutor gasLimit(final long gasLimit) {
((SimpleBlockValues) this.blockValues).setGasLimit(gasLimit);
return this;
}

/**
* Sets the block hash lookup function
*
* @param blockHashLookup the block hash lookup function
* @return the evm executor
*/
public EVMExecutor blockHashLookup(final Function<Long, Hash> blockHashLookup) {
this.blockHashLookup = blockHashLookup;
return this;
}

/**
* Sets Version Hashes for blobs. The blobs themselves are not accessible.
*
* @param versionedHashes the versioned hashes
* @return the evm executor
*/
public EVMExecutor versionedHashes(final Optional<List<VersionedHash>> versionedHashes) {
this.versionedHashes = versionedHashes;
return this;
}

/**
* Sets Operation Tracer.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,73 @@
*/
package org.hyperledger.besu.evm.fluent;

import org.hyperledger.besu.datatypes.Wei;
import org.hyperledger.besu.evm.frame.BlockValues;

import java.util.Optional;

import org.apache.tuweni.bytes.Bytes;
import org.apache.tuweni.bytes.Bytes32;

/** A concrete BlockValues object that takes all the defaults */
public class SimpleBlockValues implements BlockValues {}
public class SimpleBlockValues implements BlockValues {

Bytes difficultyBytes = Bytes32.ZERO;
Bytes32 mixHasOrPrevRandao = Bytes32.ZERO;
Optional<Wei> baseFee = Optional.empty();
long number = 1;
long timeStamp = 1;
long gasLimit = Long.MAX_VALUE;

@Override
public Bytes getDifficultyBytes() {
return difficultyBytes;
}

public void setDifficultyBytes(final Bytes difficultyBytes) {
this.difficultyBytes = difficultyBytes;
}

public Bytes32 getMixHasOrPrevRandao() {
return mixHasOrPrevRandao;
}

public void setMixHasOrPrevRandao(final Bytes32 mixHasOrPrevRandao) {
this.mixHasOrPrevRandao = mixHasOrPrevRandao;
}

@Override
public Optional<Wei> getBaseFee() {
return baseFee;
}

public void setBaseFee(final Optional<Wei> baseFee) {
this.baseFee = baseFee;
}

@Override
public long getNumber() {
return number;
}

public void setNumber(final long number) {
this.number = number;
}

public long getTimeStamp() {
return timeStamp;
}

public void setTimeStamp(final long timeStamp) {
this.timeStamp = timeStamp;
}

@Override
public long getGasLimit() {
return gasLimit;
}

public void setGasLimit(final long gasLimit) {
this.gasLimit = gasLimit;
}
}

0 comments on commit 349b4bf

Please sign in to comment.