Skip to content

Commit 846e483

Browse files
authored
update eth_call error message (hyperledger#8129)
Signed-off-by: Karim Taam <karim.t2am@gmail.com>
1 parent b150b10 commit 846e483

File tree

21 files changed

+109
-53
lines changed

21 files changed

+109
-53
lines changed

ethereum/api/src/integration-test/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/fork/frontier/EthCallIntegrationTest.java

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,12 @@
2424
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext;
2525
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod;
2626
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonCallParameter;
27+
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcError;
2728
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse;
2829
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponse;
2930
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSuccessResponse;
30-
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType;
31+
import org.hyperledger.besu.ethereum.mainnet.ValidationResult;
32+
import org.hyperledger.besu.ethereum.transaction.TransactionInvalidReason;
3133
import org.hyperledger.besu.testutil.BlockTestUtil;
3234

3335
import java.util.Map;
@@ -132,7 +134,12 @@ public void shouldReturnErrorWithGasLimitTooLow() {
132134

133135
final JsonRpcRequestContext request = requestWithParams(callParameter, "latest");
134136
final JsonRpcResponse expectedResponse =
135-
new JsonRpcErrorResponse(null, RpcErrorType.INTRINSIC_GAS_EXCEEDS_LIMIT);
137+
new JsonRpcErrorResponse(
138+
null,
139+
JsonRpcError.from(
140+
ValidationResult.invalid(
141+
TransactionInvalidReason.INTRINSIC_GAS_EXCEEDS_GAS_LIMIT,
142+
"intrinsic gas cost 21272 exceeds gas limit 0")));
136143

137144
final JsonRpcResponse response = method.response(request);
138145

@@ -152,7 +159,12 @@ public void shouldReturnErrorWithGasPriceTooHighAndStrict() {
152159

153160
final JsonRpcRequestContext request = requestWithParams(callParameter, "latest");
154161
final JsonRpcResponse expectedResponse =
155-
new JsonRpcErrorResponse(null, RpcErrorType.TRANSACTION_UPFRONT_COST_EXCEEDS_BALANCE);
162+
new JsonRpcErrorResponse(
163+
null,
164+
JsonRpcError.from(
165+
ValidationResult.invalid(
166+
TransactionInvalidReason.UPFRONT_COST_EXCEEDS_BALANCE,
167+
"transaction up-front cost 0x2fefd80000000000000 exceeds transaction sender account balance 0x340ab63a0215af0d")));
156168

157169
final JsonRpcResponse response = method.response(request);
158170

@@ -192,7 +204,12 @@ public void shouldReturnErrorWithGasPriceTooHigh() {
192204

193205
final JsonRpcRequestContext request = requestWithParams(callParameter, "latest");
194206
final JsonRpcResponse expectedResponse =
195-
new JsonRpcErrorResponse(null, RpcErrorType.TRANSACTION_UPFRONT_COST_EXCEEDS_BALANCE);
207+
new JsonRpcErrorResponse(
208+
null,
209+
JsonRpcError.from(
210+
ValidationResult.invalid(
211+
TransactionInvalidReason.UPFRONT_COST_EXCEEDS_BALANCE,
212+
"transaction up-front cost 0x2fefd80000000000000 exceeds transaction sender account balance 0x340ab63a0215af0d")));
196213

197214
final JsonRpcResponse response = method.response(request);
198215

@@ -231,7 +248,12 @@ public void shouldReturnErrorWithGasPriceAndEmptyBalance() {
231248

232249
final JsonRpcRequestContext request = requestWithParams(callParameter, "latest");
233250
final JsonRpcResponse expectedResponse =
234-
new JsonRpcErrorResponse(null, RpcErrorType.TRANSACTION_UPFRONT_COST_EXCEEDS_BALANCE);
251+
new JsonRpcErrorResponse(
252+
null,
253+
JsonRpcError.from(
254+
ValidationResult.invalid(
255+
TransactionInvalidReason.UPFRONT_COST_EXCEEDS_BALANCE,
256+
"transaction up-front cost 0x2fefd80 exceeds transaction sender account balance 0x0")));
235257

236258
final JsonRpcResponse response = method.response(request);
237259

ethereum/api/src/integration-test/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/fork/london/EthCallIntegrationTest.java

Lines changed: 38 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,12 @@
2424
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext;
2525
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod;
2626
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonCallParameter;
27+
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcError;
2728
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse;
2829
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponse;
2930
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSuccessResponse;
30-
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType;
31+
import org.hyperledger.besu.ethereum.mainnet.ValidationResult;
32+
import org.hyperledger.besu.ethereum.transaction.TransactionInvalidReason;
3133
import org.hyperledger.besu.testutil.BlockTestUtil;
3234

3335
import java.math.BigInteger;
@@ -92,8 +94,13 @@ public void shouldReturnErrorWithGasPriceTooHigh() {
9294
.build();
9395

9496
final JsonRpcRequestContext request = requestWithParams(callParameter, "latest");
97+
98+
final ValidationResult<TransactionInvalidReason> validationResult =
99+
ValidationResult.invalid(
100+
TransactionInvalidReason.UPFRONT_COST_EXCEEDS_BALANCE,
101+
"transaction up-front cost 0x2000000000000000000000 exceeds transaction sender account balance 0x130ee8e7179044400000");
95102
final JsonRpcResponse expectedResponse =
96-
new JsonRpcErrorResponse(null, RpcErrorType.TRANSACTION_UPFRONT_COST_EXCEEDS_BALANCE);
103+
new JsonRpcErrorResponse(null, JsonRpcError.from(validationResult));
97104

98105
final JsonRpcResponse response = method.response(request);
99106

@@ -131,8 +138,13 @@ public void shouldReturnErrorWithGasPriceLessThanCurrentBaseFee() {
131138
.build();
132139

133140
final JsonRpcRequestContext request = requestWithParams(callParameter, "latest");
141+
142+
final ValidationResult<TransactionInvalidReason> validationResult =
143+
ValidationResult.invalid(
144+
TransactionInvalidReason.GAS_PRICE_BELOW_CURRENT_BASE_FEE,
145+
"gasPrice is less than the current BaseFee");
134146
final JsonRpcResponse expectedResponse =
135-
new JsonRpcErrorResponse(null, RpcErrorType.GAS_PRICE_BELOW_CURRENT_BASE_FEE);
147+
new JsonRpcErrorResponse(null, JsonRpcError.from(validationResult));
136148

137149
final JsonRpcResponse response = method.response(request);
138150

@@ -172,9 +184,12 @@ public void shouldReturnErrorWithInvalidChainId() {
172184
.build();
173185

174186
final JsonRpcRequestContext request = requestWithParams(callParameter, "latest");
187+
final ValidationResult<TransactionInvalidReason> validationResult =
188+
ValidationResult.invalid(
189+
TransactionInvalidReason.WRONG_CHAIN_ID,
190+
"transaction was meant for chain id 1983 and not this chain id 1982");
175191
final JsonRpcResponse expectedResponse =
176-
new JsonRpcErrorResponse(null, RpcErrorType.WRONG_CHAIN_ID);
177-
192+
new JsonRpcErrorResponse(null, JsonRpcError.from(validationResult));
178193
final JsonRpcResponse response = method.response(request);
179194

180195
assertThat(response).usingRecursiveComparison().isEqualTo(expectedResponse);
@@ -212,9 +227,13 @@ public void shouldReturnErrorWithValidMaxFeePerGasLessThanCurrentBaseFee() {
212227
.build();
213228

214229
final JsonRpcRequestContext request = requestWithParams(callParameter, "latest");
215-
final JsonRpcResponse expectedResponse =
216-
new JsonRpcErrorResponse(null, RpcErrorType.GAS_PRICE_BELOW_CURRENT_BASE_FEE);
217230

231+
final ValidationResult<TransactionInvalidReason> validationResult =
232+
ValidationResult.invalid(
233+
TransactionInvalidReason.GAS_PRICE_BELOW_CURRENT_BASE_FEE,
234+
"gasPrice is less than the current BaseFee");
235+
final JsonRpcResponse expectedResponse =
236+
new JsonRpcErrorResponse(null, JsonRpcError.from(validationResult));
218237
final JsonRpcResponse response = method.response(request);
219238

220239
assertThat(response).usingRecursiveComparison().isEqualTo(expectedResponse);
@@ -232,9 +251,13 @@ public void shouldReturnErrorWithValidMaxFeePerGasLessThanMaxPriorityFeePerGas()
232251
.build();
233252

234253
final JsonRpcRequestContext request = requestWithParams(callParameter, "latest");
254+
255+
final ValidationResult<TransactionInvalidReason> validationResult =
256+
ValidationResult.invalid(
257+
TransactionInvalidReason.MAX_PRIORITY_FEE_PER_GAS_EXCEEDS_MAX_FEE_PER_GAS,
258+
"max priority fee per gas cannot be greater than max fee per gas");
235259
final JsonRpcResponse expectedResponse =
236-
new JsonRpcErrorResponse(
237-
null, RpcErrorType.MAX_PRIORITY_FEE_PER_GAS_EXCEEDS_MAX_FEE_PER_GAS);
260+
new JsonRpcErrorResponse(null, JsonRpcError.from(validationResult));
238261

239262
final JsonRpcResponse response = method.response(request);
240263

@@ -252,8 +275,13 @@ public void shouldReturnErrorWithMaxFeePerGasAndEmptyBalance() {
252275
.build();
253276

254277
final JsonRpcRequestContext request = requestWithParams(callParameter, "latest");
278+
279+
final ValidationResult<TransactionInvalidReason> validationResult =
280+
ValidationResult.invalid(
281+
TransactionInvalidReason.UPFRONT_COST_EXCEEDS_BALANCE,
282+
"transaction up-front cost 0x7735940200000000 exceeds transaction sender account balance 0x0");
255283
final JsonRpcResponse expectedResponse =
256-
new JsonRpcErrorResponse(null, RpcErrorType.TRANSACTION_UPFRONT_COST_EXCEEDS_BALANCE);
284+
new JsonRpcErrorResponse(null, JsonRpcError.from(validationResult));
257285

258286
final JsonRpcResponse response = method.response(request);
259287

ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthCall.java

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
import org.hyperledger.besu.datatypes.Hash;
2121
import org.hyperledger.besu.datatypes.StateOverrideMap;
2222
import org.hyperledger.besu.datatypes.Wei;
23-
import org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcErrorConverter;
2423
import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod;
2524
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext;
2625
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters;
@@ -107,11 +106,7 @@ protected Object resultByBlockHeader(
107106
request.getRequest().getId(),
108107
result.getOutput().toString())
109108
: errorResponse(request, result)),
110-
reason ->
111-
errorResponse(
112-
request,
113-
JsonRpcErrorConverter.convertTransactionInvalidReason(
114-
reason)))),
109+
reason -> errorResponse(request, result))),
115110
header)
116111
.orElse(errorResponse(request, INTERNAL_ERROR));
117112
}
@@ -134,14 +129,10 @@ public JsonRpcResponse response(final JsonRpcRequestContext requestContext) {
134129

135130
private JsonRpcErrorResponse errorResponse(
136131
final JsonRpcRequestContext request, final TransactionSimulatorResult result) {
137-
138132
final ValidationResult<TransactionInvalidReason> validationResult =
139133
result.getValidationResult();
140134
if (validationResult != null && !validationResult.isValid()) {
141-
return errorResponse(
142-
request,
143-
JsonRpcErrorConverter.convertTransactionInvalidReason(
144-
validationResult.getInvalidReason()));
135+
return errorResponse(request, JsonRpcError.from(validationResult));
145136
} else {
146137
final TransactionProcessingResult resultTrx = result.result();
147138
if (resultTrx != null && resultTrx.getRevertReason().isPresent()) {

ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/AbstractEngineNewPayload.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,6 @@ public AbstractEngineNewPayload(
109109
@Override
110110
public JsonRpcResponse syncResponse(final JsonRpcRequestContext requestContext) {
111111
engineCallListener.executionEngineCalled();
112-
113112
final EnginePayloadParameter blockParam;
114113
try {
115114
blockParam = requestContext.getRequiredParameter(0, EnginePayloadParameter.class);

ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/response/JsonRpcError.java

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ public int getCode() {
7474

7575
@JsonGetter("message")
7676
public String getMessage() {
77-
return (reason == null ? message : message + ": " + reason);
77+
return (reason == null ? message : "%s (%s)".formatted(message, reason));
7878
}
7979

8080
@JsonGetter("data")
@@ -92,12 +92,29 @@ public boolean equals(final Object o) {
9292
}
9393
final JsonRpcError that = (JsonRpcError) o;
9494
return code == that.code
95-
&& Objects.equals(message.split(":", -1)[0], that.message.split(":", -1)[0])
95+
&& Objects.equals(message.split(" \\(", -1)[0], that.message.split(" \\(", -1)[0])
9696
&& Objects.equals(data, that.data);
9797
}
9898

99+
@Override
100+
public String toString() {
101+
return "JsonRpcError{"
102+
+ "code="
103+
+ code
104+
+ ", message='"
105+
+ message
106+
+ '\''
107+
+ ", data='"
108+
+ data
109+
+ '\''
110+
+ ", reason='"
111+
+ reason
112+
+ '\''
113+
+ '}';
114+
}
115+
99116
@Override
100117
public int hashCode() {
101-
return Objects.hash(code, message.split(":", -1)[0], data);
118+
return Objects.hash(code, message.split(" \\(", -1)[0], data);
102119
}
103120
}

ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/tracing/flat/FlatTraceGenerator.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -504,7 +504,6 @@ private static FlatTrace.Context handleHalt(
504504
return exceptionalHaltReason.getDescription();
505505
}
506506
}));
507-
508507
if (currentContext != null) {
509508
final Action.Builder actionBuilder = traceFrameBuilder.getActionBuilder();
510509
actionBuilder.value(Quantity.create(traceFrame.getValue()));

ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/PluginJsonRpcMethodTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ public void methodErrorWithDataShouldReturnErrorResponseWithDecodedData() throws
144144
try (final Response resp = client.newCall(buildPostRequest(body)).execute()) {
145145
assertThat(resp.code()).isEqualTo(200);
146146
final JsonObject json = new JsonObject(resp.body().string());
147-
testHelper.assertValidJsonRpcError(json, 1, -2, "Error with data: ABC", "abc");
147+
testHelper.assertValidJsonRpcError(json, 1, -2, "Error with data (ABC)", "abc");
148148
}
149149
}
150150
}

ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthCallTest.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -278,7 +278,7 @@ public void shouldReturnExecutionRevertErrorWithABIParseError() {
278278
final JsonRpcErrorResponse expectedResponse = new JsonRpcErrorResponse(null, expectedError);
279279

280280
assertThat(expectedResponse.getError().getMessage())
281-
.isEqualTo("Execution reverted: ABI decode error");
281+
.isEqualTo("Execution reverted (ABI decode error)");
282282

283283
mockTransactionProcessorSuccessResult(expectedResponse);
284284
when(blockchainQueries.getBlockchain()).thenReturn(blockchain);
@@ -304,7 +304,7 @@ public void shouldReturnExecutionRevertErrorWithABIParseError() {
304304

305305
assertThat(response).usingRecursiveComparison().isEqualTo(expectedResponse);
306306
assertThat(((JsonRpcErrorResponse) response).getError().getMessage())
307-
.isEqualTo("Execution reverted: ABI decode error");
307+
.isEqualTo("Execution reverted (ABI decode error)");
308308
}
309309

310310
@Test
@@ -319,7 +319,7 @@ public void shouldReturnExecutionRevertErrorWithParsedABI() {
319319
final JsonRpcErrorResponse expectedResponse = new JsonRpcErrorResponse(null, expectedError);
320320

321321
assertThat(expectedResponse.getError().getMessage())
322-
.isEqualTo("Execution reverted: ERC20: transfer from the zero address");
322+
.isEqualTo("Execution reverted (ERC20: transfer from the zero address)");
323323

324324
mockTransactionProcessorSuccessResult(expectedResponse);
325325
when(blockchainQueries.getBlockchain()).thenReturn(blockchain);
@@ -347,7 +347,7 @@ public void shouldReturnExecutionRevertErrorWithParsedABI() {
347347

348348
assertThat(response).usingRecursiveComparison().isEqualTo(expectedResponse);
349349
assertThat(((JsonRpcErrorResponse) response).getError().getMessage())
350-
.isEqualTo("Execution reverted: ERC20: transfer from the zero address");
350+
.isEqualTo("Execution reverted (ERC20: transfer from the zero address)");
351351
}
352352

353353
@Test

ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthEstimateGasTest.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -331,14 +331,14 @@ public void shouldReturnErrorReasonWhenTransactionReverted() {
331331
null, new JsonRpcError(RpcErrorType.REVERT_ERROR, executionRevertedReason));
332332

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

336336
final JsonRpcResponse actualResponse = method.response(request);
337337

338338
assertThat(actualResponse).usingRecursiveComparison().isEqualTo(expectedResponse);
339339

340340
assertThat(((JsonRpcErrorResponse) actualResponse).getError().getMessage())
341-
.isEqualTo("Execution reverted: ERC20: transfer from the zero address");
341+
.isEqualTo("Execution reverted (ERC20: transfer from the zero address)");
342342
}
343343

344344
@Test
@@ -359,14 +359,14 @@ public void shouldReturnABIDecodeErrorReasonWhenInvalidRevertReason() {
359359
null, new JsonRpcError(RpcErrorType.REVERT_ERROR, invalidRevertReason));
360360

361361
assertThat(((JsonRpcErrorResponse) expectedResponse).getError().getMessage())
362-
.isEqualTo("Execution reverted: ABI decode error");
362+
.isEqualTo("Execution reverted (ABI decode error)");
363363

364364
final JsonRpcResponse actualResponse = method.response(request);
365365

366366
assertThat(actualResponse).usingRecursiveComparison().isEqualTo(expectedResponse);
367367

368368
assertThat(((JsonRpcErrorResponse) actualResponse).getError().getMessage())
369-
.isEqualTo("Execution reverted: ABI decode error");
369+
.isEqualTo("Execution reverted (ABI decode error)");
370370
}
371371

372372
@Test

ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_call_blob_missing_maxFeePerBlobGas_strict.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
"response": {
2020
"jsonrpc": "2.0",
2121
"id": 4,
22-
"error":{"code":-32009,"message":"blob gas price below current blob base fee"}
22+
"error":{"code":-32009,"message":"blob gas price below current blob base fee (tx max fee per blob gas less than block blob gas fee: address 0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b blobGasFeeCap: 0 wei, blobBaseFee: 1 wei)"}
2323
},
2424
"statusCode": 200
2525
}

ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_call_blob_too_many_blobs.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
"response": {
1818
"jsonrpc": "2.0",
1919
"id": 4,
20-
"error":{"code":-32000,"message":"Total blob gas too high"}
20+
"error":{"code":-32000,"message":"Total blob gas too high (total blob gas 917504 exceeds max blob gas per block 786432)"}
2121
},
2222
"statusCode": 200
2323
}

ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_call_blob_without_to.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
"response": {
1717
"jsonrpc": "2.0",
1818
"id": 4,
19-
"error":{"code":-32602,"message":"Invalid transaction type"}
19+
"error":{"code":-32602,"message":"Invalid transaction type (transaction blob transactions must have a to address)"}
2020
},
2121
"statusCode": 200
2222
}

ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/eth/eth_call_gasLimitTooLow_block_8.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
"id": 4,
1818
"error" : {
1919
"code" : -32003,
20-
"message" : "Intrinsic gas exceeds gas limit"
20+
"message" : "Intrinsic gas exceeds gas limit (intrinsic gas cost 21000 exceeds gas limit 0)"
2121
}
2222
},
2323
"statusCode": 200

0 commit comments

Comments
 (0)