Skip to content

Commit

Permalink
Fix merges
Browse files Browse the repository at this point in the history
Signed-off-by: Matthew Whitehead <[email protected]>
  • Loading branch information
matthew1001 committed Jul 28, 2023
1 parent 5b4cefd commit bd8fbe4
Show file tree
Hide file tree
Showing 6 changed files with 77 additions and 62 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public abstract class AbstractEstimateGas implements JsonRpcMethod {
protected final TransactionSimulator transactionSimulator;

public AbstractEstimateGas(
final BlockchainQueries blockchainQueries, final TransactionSimulator transactionSimulator) {
final BlockchainQueries blockchainQueries, final TransactionSimulator transactionSimulator) {
this.blockchainQueries = blockchainQueries;
this.transactionSimulator = transactionSimulator;
}
Expand All @@ -53,17 +53,17 @@ protected BlockHeader blockHeader() {
}

protected CallParameter overrideGasLimitAndPrice(
final JsonCallParameter callParams, final long gasLimit) {
final JsonCallParameter callParams, final long gasLimit) {
return new CallParameter(
callParams.getFrom(),
callParams.getTo(),
gasLimit,
Optional.ofNullable(callParams.getGasPrice()).orElse(Wei.ZERO),
callParams.getMaxPriorityFeePerGas(),
callParams.getMaxFeePerGas(),
callParams.getValue(),
callParams.getPayload(),
callParams.getAccessList());
callParams.getFrom(),
callParams.getTo(),
gasLimit,
Optional.ofNullable(callParams.getGasPrice()).orElse(Wei.ZERO),
callParams.getMaxPriorityFeePerGas(),
callParams.getMaxFeePerGas(),
callParams.getValue(),
callParams.getPayload(),
callParams.getAccessList());
}

/**
Expand All @@ -75,10 +75,10 @@ protected CallParameter overrideGasLimitAndPrice(
* @return estimate gas
*/
protected long processEstimateGas(
final TransactionSimulatorResult result, final EstimateGasOperationTracer operationTracer) {
final TransactionSimulatorResult result, final EstimateGasOperationTracer operationTracer) {
// no more than 63/64s of the remaining gas can be passed to the sub calls
final double subCallMultiplier =
Math.pow(SUB_CALL_REMAINING_GAS_RATIO, operationTracer.getMaxDepth());
Math.pow(SUB_CALL_REMAINING_GAS_RATIO, operationTracer.getMaxDepth());
// and minimum gas remaining is necessary for some operation (additionalStipend)
final long gasStipend = operationTracer.getStipendNeeded();
final long gasUsedByTransaction = result.getResult().getEstimateGasUsedByTransaction();
Expand All @@ -88,44 +88,42 @@ protected long processEstimateGas(
protected JsonCallParameter validateAndGetCallParams(final JsonRpcRequestContext request) {
final JsonCallParameter callParams = request.getRequiredParameter(0, JsonCallParameter.class);
if (callParams.getGasPrice() != null
&& (callParams.getMaxFeePerGas().isPresent()
&& (callParams.getMaxFeePerGas().isPresent()
|| callParams.getMaxPriorityFeePerGas().isPresent())) {
throw new InvalidJsonRpcParameters("gasPrice cannot be used with baseFee or maxFeePerGas");
}
return callParams;
}

protected JsonRpcErrorResponse errorResponse(
final JsonRpcRequestContext request, final TransactionSimulatorResult result) {
final JsonRpcRequestContext request, final TransactionSimulatorResult result) {

final ValidationResult<TransactionInvalidReason> validationResult =
result.getValidationResult();
result.getValidationResult();
if (validationResult != null && !validationResult.isValid()) {
return errorResponse(
request,
JsonRpcErrorConverter.convertTransactionInvalidReason(
validationResult.getInvalidReason()));
request,
JsonRpcErrorConverter.convertTransactionInvalidReason(
validationResult.getInvalidReason()));
} else {
final TransactionProcessingResult resultTrx = result.getResult();
if (resultTrx != null && resultTrx.getRevertReason().isPresent()) {
JsonRpcErrorResponse.decodeRevertReason(resultTrx.getRevertReason().get())
.ifPresent(jsonRpcError::setReason);
return errorResponse(
request,
new JsonRpcError(
RpcErrorType.REVERT_ERROR, resultTrx.getRevertReason().get().toHexString()));
JsonRpcError rpcErr =
new JsonRpcError(
RpcErrorType.REVERT_ERROR, resultTrx.getRevertReason().get().toHexString());
return errorResponse(request, rpcErr);
}
return errorResponse(request, RpcErrorType.INTERNAL_ERROR);
}
}

protected JsonRpcErrorResponse errorResponse(
final JsonRpcRequestContext request, final RpcErrorType rpcErrorType) {
final JsonRpcRequestContext request, final RpcErrorType rpcErrorType) {
return errorResponse(request, new JsonRpcError(rpcErrorType));
}

protected JsonRpcErrorResponse errorResponse(
final JsonRpcRequestContext request, final JsonRpcError jsonRpcError) {
final JsonRpcRequestContext request, final JsonRpcError jsonRpcError) {
return new JsonRpcErrorResponse(request.getRequest().getId(), jsonRpcError);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,6 @@ public JsonRpcResponse response(final JsonRpcRequestContext requestContext) {

private JsonRpcErrorResponse errorResponse(
final JsonRpcRequestContext request, final TransactionSimulatorResult result) {
final JsonRpcError jsonRpcError;

final ValidationResult<TransactionInvalidReason> validationResult =
result.getValidationResult();
Expand All @@ -120,16 +119,13 @@ private JsonRpcErrorResponse errorResponse(
} else {
final TransactionProcessingResult resultTrx = result.getResult();
if (resultTrx != null && resultTrx.getRevertReason().isPresent()) {
JsonRpcErrorResponse.decodeRevertReason(resultTrx.getRevertReason().get())
.ifPresent(jsonRpcError::setReason);
return errorResponse(
request,
JsonRpcError rpcErr =
new JsonRpcError(
RpcErrorType.REVERT_ERROR, resultTrx.getRevertReason().get().toHexString()));
RpcErrorType.REVERT_ERROR, resultTrx.getRevertReason().get().toHexString());
return errorResponse(request, rpcErr);
}
return errorResponse(request, RpcErrorType.INTERNAL_ERROR);
}
return errorResponse(request, jsonRpcError);
}

private JsonRpcErrorResponse errorResponse(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,33 +15,40 @@
package org.hyperledger.besu.ethereum.api.jsonrpc.internal.response;

import java.util.Objects;
import java.util.Optional;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonGetter;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.apache.tuweni.bytes.Bytes;

@JsonInclude(value = JsonInclude.Include.NON_NULL)
@JsonFormat(shape = JsonFormat.Shape.OBJECT)
public class JsonRpcError {
private final int code;
private final String message;
private final String data;
private final String reason;
private String reason;

@JsonCreator
public JsonRpcError(
@JsonProperty("code") final int code,
@JsonProperty("message") final String message,
@JsonProperty("data") final String data) {
@JsonProperty("code") final int code,
@JsonProperty("message") final String message,
@JsonProperty("data") final String data) {
this.code = code;
this.message = message;
this.data = data;
}

public JsonRpcError(final RpcErrorType errorType, final String data) {
this(errorType.getCode(), errorType.getMessage(), data);

// For execution reverted errors decode the data (if present)
if (errorType == RpcErrorType.REVERT_ERROR && data != null) {
JsonRpcErrorResponse.decodeRevertReason(Bytes.fromHexString(data)).ifPresent((decodedReason) -> {this.reason = decodedReason;});
}
}

public JsonRpcError(final RpcErrorType errorType) {
Expand All @@ -63,10 +70,6 @@ public String getData() {
return data;
}

public void setReason(final String reason) {
this.reason = reason;
}

@Override
public boolean equals(final Object o) {
if (this == o) {
Expand All @@ -77,12 +80,12 @@ public boolean equals(final Object o) {
}
final JsonRpcError that = (JsonRpcError) o;
return code == that.code
&& Objects.equals(message, that.message)
&& Objects.equals(data, that.data);
&& Objects.equals(message.split(":", -1)[0], that.message.split(":", -1)[0])
&& Objects.equals(data, that.data);
}

@Override
public int hashCode() {
return Objects.hash(code, message, data);
return Objects.hash(code, message.split(":", -1)[0], data);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,6 @@
import org.web3j.abi.datatypes.AbiTypes;
import org.web3j.abi.datatypes.Type;
import org.web3j.abi.datatypes.Utf8String;
import org.apache.tuweni.bytes.Bytes;
import org.web3j.abi.FunctionReturnDecoder;
import org.web3j.abi.TypeReference;
import org.web3j.abi.datatypes.AbiTypes;
import org.web3j.abi.datatypes.Type;
import org.web3j.abi.datatypes.Utf8String;

@JsonPropertyOrder({"jsonrpc", "id", "error"})
public class JsonRpcErrorResponse implements JsonRpcResponse {
Expand Down Expand Up @@ -102,7 +96,7 @@ public RpcErrorType getErrorType() {

private RpcErrorType findErrorType(final int code, final String message) {
return Arrays.stream(RpcErrorType.values())
.filter(e -> e.getCode() == code && e.getMessage().equals(message))
.filter(e -> e.getCode() == code && message.startsWith(e.getMessage()))
.findFirst()
.get();
}
Expand All @@ -112,12 +106,12 @@ public static Optional<String> decodeRevertReason(final Bytes revertReason) {
if (revertReason.toHexString().startsWith(errorMethodABI)) {
// Remove the "Error(string)" prefix
final String encodedReasonText =
revertReason.toHexString().substring(errorMethodABI.length());
revertReason.toHexString().substring(errorMethodABI.length());

try {
List<TypeReference<Type>> revertReasonTypes =
Collections.singletonList(
TypeReference.create((Class<Type>) AbiTypes.getType("string")));
Collections.singletonList(
TypeReference.create((Class<Type>) AbiTypes.getType("string")));
List<Type> decoded = FunctionReturnDecoder.decode(encodedReasonText, revertReasonTypes);

// Expect a single decoded string
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequest;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonCallParameter;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcError;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponse;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSuccessResponse;
Expand All @@ -45,6 +46,7 @@
import org.hyperledger.besu.ethereum.mainnet.ImmutableTransactionValidationParams;
import org.hyperledger.besu.ethereum.mainnet.TransactionValidationParams;
import org.hyperledger.besu.ethereum.mainnet.ValidationResult;
import org.hyperledger.besu.ethereum.processing.TransactionProcessingResult;
import org.hyperledger.besu.ethereum.transaction.CallParameter;
import org.hyperledger.besu.ethereum.transaction.PreCloseStateHandler;
import org.hyperledger.besu.ethereum.transaction.TransactionSimulator;
Expand Down Expand Up @@ -170,10 +172,13 @@ public void shouldReturnBasicExecutionRevertErrorWithoutReason() {
final JsonRpcRequestContext request = ethCallRequest(callParameter(), "latest");

// Expect a revert error with no decoded reason (error doesn't begin "Error(string)" so ignored)
final JsonRpcError expectedError = REVERT_ERROR;
final String abiHexString = "0x1234";
final JsonRpcError expectedError = new JsonRpcError(REVERT_ERROR, abiHexString);
final JsonRpcResponse expectedResponse = new JsonRpcErrorResponse(null, expectedError);

assertThat(((JsonRpcErrorResponse) expectedResponse).getError().getMessage())
.isEqualTo("Execution reverted");

mockTransactionProcessorSuccessResult(expectedResponse);
when(blockchainQueries.getBlockchain()).thenReturn(blockchain);
when(blockchain.getChainHead()).thenReturn(chainHead);
Expand Down Expand Up @@ -208,9 +213,12 @@ public void shouldReturnExecutionRevertErrorWithABIParseError() {
// Expect a revert error with no decoded reason (error begins with "Error(string)" but trailing
// bytes are invalid ABI)
final String abiHexString = "0x08c379a002d36d";
final JsonRpcError expectedError = REVERT_ERROR;
final JsonRpcError expectedError = new JsonRpcError(REVERT_ERROR, abiHexString);
final JsonRpcResponse expectedResponse = new JsonRpcErrorResponse(null, expectedError);

assertThat(((JsonRpcErrorResponse) expectedResponse).getError().getMessage())
.isEqualTo("Execution reverted: ABI decode error");

mockTransactionProcessorSuccessResult(expectedResponse);
when(blockchainQueries.getBlockchain()).thenReturn(blockchain);
when(blockchain.getChainHead()).thenReturn(chainHead);
Expand Down Expand Up @@ -245,9 +253,12 @@ public void shouldReturnExecutionRevertErrorWithParsedABI() {
// = "ERC20: transfer from the zero address")
final String abiHexString =
"0x08c379a00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002545524332303a207472616e736665722066726f6d20746865207a65726f2061646472657373000000000000000000000000000000000000000000000000000000";
final JsonRpcError expectedError = REVERT_ERROR;
final JsonRpcError expectedError = new JsonRpcError(REVERT_ERROR, abiHexString);
final JsonRpcResponse expectedResponse = new JsonRpcErrorResponse(null, expectedError);

assertThat(((JsonRpcErrorResponse) expectedResponse).getError().getMessage())
.isEqualTo("Execution reverted: ERC20: transfer from the zero address");

mockTransactionProcessorSuccessResult(expectedResponse);
when(blockchainQueries.getBlockchain()).thenReturn(blockchain);
when(blockchain.getChainHead()).thenReturn(chainHead);
Expand All @@ -257,15 +268,19 @@ public void shouldReturnExecutionRevertErrorWithParsedABI() {
when(chainHead.getBlockHeader()).thenReturn(blockHeader);

final JsonRpcResponse response = method.response(request);

final TransactionProcessingResult processingResult =
new TransactionProcessingResult(
null, null, 0, 0, null, null, Optional.of(Bytes.fromHexString(abiHexString)));
new TransactionProcessingResult(
null, null, 0, 0, null, null, Optional.of(Bytes.fromHexString(abiHexString)));

final TransactionSimulatorResult result = mock(TransactionSimulatorResult.class);
when(result.isSuccessful()).thenReturn(false);
when(result.getValidationResult()).thenReturn(ValidationResult.valid());
when(result.getResult()).thenReturn(processingResult);

verify(transactionSimulator).process(any(), any(), any(), mapperCaptor.capture(), any());
System.out.println(result);
System.out.println(expectedResponse);
assertThat(mapperCaptor.getValue().apply(mock(MutableWorldState.class), Optional.of(result)))
.isEqualTo(Optional.of(expectedResponse));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,9 @@ public void shouldReturnErrorWhenTransactionReverted() {
final JsonRpcResponse expectedResponse =
new JsonRpcErrorResponse(null, new JsonRpcError(RpcErrorType.REVERT_ERROR, "0x00"));

assertThat(((JsonRpcErrorResponse) expectedResponse).getError().getMessage())
.isEqualTo("Execution reverted");

final JsonRpcResponse actualResponse = method.response(request);

Assertions.assertThat(actualResponse).usingRecursiveComparison().isEqualTo(expectedResponse);
Expand All @@ -280,7 +283,10 @@ public void shouldReturnErrorReasonWhenTransactionReverted() {
mockTransientProcessorTxReverted(1L, false, Bytes.fromHexString(executionRevertedReason));

final JsonRpcResponse expectedResponse =
new JsonRpcErrorResponse(null, JsonRpcError.REVERT_ERROR);
new JsonRpcErrorResponse(null, new JsonRpcError(RpcErrorType.REVERT_ERROR, executionRevertedReason));

assertThat(((JsonRpcErrorResponse) expectedResponse).getError().getMessage())
.isEqualTo("Execution reverted: ERC20: transfer from the zero address");

final JsonRpcResponse actualResponse = method.response(request);

Expand All @@ -303,7 +309,10 @@ public void shouldReturnABIDecodeErrorReasonWhenInvalidRevertReason() {
mockTransientProcessorTxReverted(1L, false, Bytes.fromHexString(invalidRevertReason));

final JsonRpcResponse expectedResponse =
new JsonRpcErrorResponse(null, JsonRpcError.REVERT_ERROR);
new JsonRpcErrorResponse(null, new JsonRpcError(RpcErrorType.REVERT_ERROR, invalidRevertReason));

assertThat(((JsonRpcErrorResponse) expectedResponse).getError().getMessage())
.isEqualTo("Execution reverted: ABI decode error");

final JsonRpcResponse actualResponse = method.response(request);

Expand Down

0 comments on commit bd8fbe4

Please sign in to comment.