Skip to content

Commit

Permalink
unit tests passing
Browse files Browse the repository at this point in the history
Signed-off-by: Justin Florentine <justin+github@florentine.us>
  • Loading branch information
jflo committed Jun 5, 2023
1 parent 3c5f2ec commit 5906c82
Show file tree
Hide file tree
Showing 6 changed files with 134 additions and 46 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
import org.hyperledger.besu.ethereum.vm.BlockHashLookup;
import org.hyperledger.besu.ethereum.vm.CachingBlockHashLookup;
import org.hyperledger.besu.evm.gascalculator.GasCalculator;
import org.hyperledger.besu.evm.log.Log;
import org.hyperledger.besu.evm.worldstate.WorldUpdater;
import org.hyperledger.besu.plugin.data.TransactionSelectionResult;
import org.hyperledger.besu.plugin.data.TransactionType;
Expand Down Expand Up @@ -471,28 +472,6 @@ private boolean isTransientValidationError(final TransactionInvalidReason invali
|| invalidReason.equals(TransactionInvalidReason.NONCE_TOO_HIGH);
}

/*
Responsible for updating the state maintained between transaction validation (i.e. receipts,
cumulative gas, world state root hash.).
*/
private void updateTransactionResultTracking(
final Transaction transaction, final TransactionProcessingResult result) {

final long gasUsedByTransaction = transaction.getGasLimit() - result.getGasRemaining();

final long cumulativeGasUsed =
transactionSelectionResult.getCumulativeGasUsed() + gasUsedByTransaction;

final long dataGasUsed = gasCalculator.dataGasCost(transaction.getBlobCount());

transactionSelectionResult.update(
transaction,
transactionReceiptFactory.create(
transaction.getType(), result, worldState, cumulativeGasUsed),
gasUsedByTransaction,
dataGasUsed);
}

private boolean isIncorrectNonce(final ValidationResult<TransactionInvalidReason> result) {
return result.getInvalidReason().equals(TransactionInvalidReason.NONCE_TOO_HIGH);
}
Expand Down Expand Up @@ -530,7 +509,8 @@ private boolean blockOccupancyAboveThreshold() {

private boolean blockFull() {
final long gasAvailable = processableBlockHeader.getGasLimit();
final long gasUsed = transactionSelectionResult.getCumulativeGasUsed();
final long gasUsed = transactionSelectionResults.getCumulativeGasUsed();

final long gasRemaining = gasAvailable - gasUsed;

if (gasRemaining < gasCalculator.getMinimumTransactionCost()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

import java.util.Objects;

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

public class VersionedHash {
Expand Down Expand Up @@ -66,4 +67,7 @@ public boolean equals(final Object o) {
public int hashCode() {
return Objects.hash(getVersionId(), hashish);
}

public static final VersionedHash DEFAULT_VERSIONED_HASH =
new VersionedHash((byte) 0x01, Hash.wrap(Bytes32.wrap(Bytes.repeat((byte) 42, 32))));
}
Original file line number Diff line number Diff line change
Expand Up @@ -443,7 +443,7 @@ private Transaction blobTransaction(final Bytes payload, final Address to) {
.payload(payload)
.chainId(BigInteger.ONE)
.maxFeePerDataGas(Wei.of(1))
.versionedHashes(List.of(new VersionedHash(Bytes32.fromHexStringLenient("0x29"))))
.versionedHashes(List.of(VersionedHash.DEFAULT_VERSIONED_HASH))
.signAndBuild(generateKeyPair());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public class TransactionTestFixture {

private long nonce = 0;

private Wei gasPrice = Wei.of(5000);
private Optional<Wei> gasPrice = Optional.empty();

private long gasLimit = 5000;

Expand All @@ -52,7 +52,7 @@ public class TransactionTestFixture {

private Optional<Wei> maxFeePerDataGas = Optional.empty();

private List<AccessListEntry> accessList = null;
private Optional<List<AccessListEntry>> accessListEntries = Optional.empty();
private Optional<List<VersionedHash>> versionedHashes = Optional.empty();

private Optional<BlobsWithCommitments> blobs = Optional.empty();
Expand All @@ -62,24 +62,41 @@ public Transaction createTransaction(final KeyPair keys) {
builder
.type(transactionType)
.gasLimit(gasLimit)
.gasPrice(gasPrice)
.nonce(nonce)
.payload(payload)
.value(value)
.sender(sender)
.accessList(accessList);
.sender(sender);

switch (transactionType) {
case FRONTIER:
builder.gasPrice(gasPrice.orElse(Wei.of(5000)));
break;
case ACCESS_LIST:
builder.gasPrice(gasPrice.orElse(Wei.of(5000)));
builder.accessList(accessListEntries.orElse(List.of()));
break;
case EIP1559:
builder.maxPriorityFeePerGas(maxPriorityFeePerGas.orElse(Wei.of(500)));
builder.maxFeePerGas(maxFeePerGas.orElse(Wei.of(5000)));
builder.accessList(accessListEntries.orElse(List.of()));
break;
case BLOB:
builder.maxPriorityFeePerGas(maxPriorityFeePerGas.orElse(Wei.of(500)));
builder.maxFeePerGas(maxFeePerGas.orElse(Wei.of(5000)));
builder.accessList(accessListEntries.orElse(List.of()));
builder.maxFeePerDataGas(maxFeePerDataGas.orElse(Wei.ONE));
builder.versionedHashes(
versionedHashes.orElse(List.of(VersionedHash.DEFAULT_VERSIONED_HASH)));
blobs.ifPresent(
bwc -> {
builder.kzgBlobs(bwc.getKzgCommitments(), bwc.getBlobs(), bwc.getKzgProofs());
});
break;
}

to.ifPresent(builder::to);
chainId.ifPresent(builder::chainId);

maxPriorityFeePerGas.ifPresent(builder::maxPriorityFeePerGas);
maxFeePerGas.ifPresent(builder::maxFeePerGas);
maxFeePerDataGas.ifPresent(builder::maxFeePerDataGas);
versionedHashes.ifPresent(builder::versionedHashes);
blobs.ifPresent(
bwc -> {
builder.kzgBlobs(bwc.getKzgCommitments(), bwc.getBlobs(), bwc.getKzgProofs());
});
return builder.signAndBuild(keys);
}

Expand All @@ -94,7 +111,7 @@ public TransactionTestFixture nonce(final long nonce) {
}

public TransactionTestFixture gasPrice(final Wei gasPrice) {
this.gasPrice = gasPrice;
this.gasPrice = Optional.ofNullable(gasPrice);
return this;
}

Expand Down Expand Up @@ -143,13 +160,8 @@ public TransactionTestFixture maxFeePerDataGas(final Optional<Wei> maxFeePerData
return this;
}

public TransactionTestFixture blobsWithCommitments(final Optional<BlobsWithCommitments> blobs) {
this.blobs = blobs;
return this;
}

public TransactionTestFixture accessList(final List<AccessListEntry> accessList) {
this.accessList = accessList;
public TransactionTestFixture accessList(final List<AccessListEntry> accessListEntries) {
this.accessListEntries = Optional.ofNullable(accessListEntries);
return this;
}

Expand All @@ -158,4 +170,9 @@ public TransactionTestFixture versionedHashes(
this.versionedHashes = versionedHashes;
return this;
}

public TransactionTestFixture blobsWithCommitments(final Optional<BlobsWithCommitments> blobs) {
this.blobs = blobs;
return this;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
/*
* Copyright Hyperledger Besu Contributors.
*
* Licensed 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.
*
* SPDX-License-Identifier: Apache-2.0
*/
package org.hyperledger.besu.evm.precompile;

import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;

import org.hyperledger.besu.evm.frame.MessageFrame;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import org.apache.tuweni.bytes.Bytes;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;

public class KZGPointEvalPrecompileContractTest {
private static KZGPointEvalPrecompiledContract contract;
private final MessageFrame toRun = mock(MessageFrame.class);

@BeforeAll
public static void init() {
KZGPointEvalPrecompiledContract.init("foo");
contract = new KZGPointEvalPrecompiledContract();
}

@AfterAll
public static void tearDown() {
contract.tearDown();
}

@ParameterizedTest(name = "{index}")
@MethodSource("getPointEvaluationPrecompileTestVectors")
public void testComputePrecompile(final PrecompileTestParameters parameters) {
PrecompiledContract.PrecompileContractResult result =
contract.computePrecompile(parameters.input, toRun);
if (parameters.valid) {
assertThat(result.getState()).isEqualTo(MessageFrame.State.COMPLETED_SUCCESS);
assertThat(result.getOutput()).isEqualTo(parameters.returnValue);
} else {
assertThat(result.getState()).isNotEqualTo(MessageFrame.State.COMPLETED_SUCCESS);
}
}

public static List<PrecompileTestParameters> getPointEvaluationPrecompileTestVectors()
throws IOException {
final JsonNode jsonNode;
try (final InputStream testVectors =
KZGPointEvalPrecompileContractTest.class.getResourceAsStream(
"pointEvaluationPrecompile.json")) {
jsonNode = new ObjectMapper().readTree(testVectors);
}
final ArrayNode testCases = (ArrayNode) jsonNode.get("TestCases");
final Bytes returnValue = Bytes.fromHexString(jsonNode.get("PrecompileReturnValue").asText());
return IntStream.range(0, testCases.size())
.mapToObj(
i -> {
final JsonNode testCase = testCases.get(i);
final Bytes input = Bytes.fromHexString(testCase.get("Input").asText());
final boolean valid = testCase.get("Valid").asBoolean();
return new PrecompileTestParameters(input, valid, returnValue);
})
.collect(Collectors.toList());
}

record PrecompileTestParameters(Bytes input, boolean valid, Bytes returnValue) {}
}
2 changes: 1 addition & 1 deletion plugin-api/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ Calculated : ${currentHash}
tasks.register('checkAPIChanges', FileStateChecker) {
description = "Checks that the API for the Plugin-API project does not change without deliberate thought"
files = sourceSets.main.allJava.files
knownHash = 'qPEwwqc/bjDvFqYBVq+qjxoQbQilRiyIoG0ltRDqItY='
knownHash = 'ef5MBjA2GKpl/WYEOxVgfzKspuIpK504kXWcl8aBmB8='
}
check.dependsOn('checkAPIChanges')

Expand Down

0 comments on commit 5906c82

Please sign in to comment.