Skip to content

Commit

Permalink
problem: eth_simulateV1 returns an array, and there is no standard wa…
Browse files Browse the repository at this point in the history
…y to handle this

solution: make RpcCall using JavaType instead of Class to support all types of data, including generics and arrays
  • Loading branch information
splix committed Nov 25, 2024
1 parent ebd238a commit 264aca1
Show file tree
Hide file tree
Showing 16 changed files with 247 additions and 155 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
*/
package io.emeraldpay.etherjar.rpc;

import com.fasterxml.jackson.databind.JavaType;

import java.io.IOException;
import java.io.InputStream;
import java.util.*;
Expand Down Expand Up @@ -46,7 +48,7 @@ public CompletableFuture<Iterable<RpcCallResponse>> execute(List<DefaultBatch.Fu
);
}
Map<Integer, DefaultBatch.FutureBatchItem> requests = new HashMap<>(items.size());
Map<Integer, Class> responseMapping = new HashMap<>(items.size());
Map<Integer, JavaType> responseMapping = new HashMap<>(items.size());
List<RequestJson<Integer>> rpcRequests = items.stream()
.map(item -> {
RequestJson<Integer> request = new RequestJson<>(
Expand Down Expand Up @@ -89,7 +91,7 @@ protected <JS, RES> Function<ResponseJson<?, Integer>, RpcCallResponse<JS, RES>>
return (resp) -> {
RpcCall<JS, RES> call = requests.get(resp.getId()).getCall();
if (call != null) {
ResponseJson<JS, Integer> castResp = resp.cast(call.getJsonType());
ResponseJson<JS, Integer> castResp = resp.cast((Class<JS>) call.getJsonType().getRawClass());
return responseJsonConverter.convert(call, castResp);
}
return null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
*/
package io.emeraldpay.etherjar.rpc;

import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.type.TypeFactory;
import io.emeraldpay.etherjar.domain.*;
import io.emeraldpay.etherjar.hex.Hex32;
import io.emeraldpay.etherjar.hex.HexData;
Expand All @@ -23,6 +25,9 @@

public class EthCommands {

private final JavaType blockWithTxJsonType = TypeFactory.defaultInstance().constructParametricType(BlockJson.class, TransactionJson.class);
private final JavaType blockWithTxIdType = TypeFactory.defaultInstance().constructParametricType(BlockJson.class, TransactionRefJson.class);

private final Class<BlockJson<TransactionJson>> blockWithTxJson = getBlockWithTx();
private final Class<BlockJson<TransactionRefJson>> blockWithTxId = getBlockWithRef();

Expand Down Expand Up @@ -73,7 +78,7 @@ public RpcCall<String, Wei> getBalance(Address address, long block) {
*/
public RpcCall<BlockJson<TransactionRefJson>, BlockJson<TransactionRefJson>> getBlock(long blockNumber) {
return RpcCall.create("eth_getBlockByNumber", blockWithTxId, HexQuantity.from(blockNumber).toHex(), false)
.withJsonType(blockWithTxId)
.withJsonType(blockWithTxIdType).castJsonType(blockWithTxId)
.withResultType(blockWithTxId);
}

Expand All @@ -85,7 +90,7 @@ public RpcCall<BlockJson<TransactionRefJson>, BlockJson<TransactionRefJson>> get
*/
public RpcCall<BlockJson<TransactionJson>, BlockJson<TransactionJson>> getBlockWithTransactions(long blockNumber) {
return RpcCall.create("eth_getBlockByNumber", blockWithTxJson, HexQuantity.from(blockNumber).toHex(), true)
.withJsonType(blockWithTxJson)
.withJsonType(blockWithTxJsonType).castJsonType(blockWithTxJson)
.withResultType(blockWithTxJson);
}

Expand All @@ -96,7 +101,7 @@ public RpcCall<BlockJson<TransactionJson>, BlockJson<TransactionJson>> getBlockW
*/
public RpcCall<BlockJson<TransactionRefJson>, BlockJson<TransactionRefJson>> getBlock(BlockHash hash) {
return RpcCall.create("eth_getBlockByHash", blockWithTxId, hash.toHex(), false)
.withJsonType(blockWithTxId)
.withJsonType(blockWithTxIdType).castJsonType(blockWithTxId)
.withResultType(blockWithTxId);
}

Expand All @@ -107,7 +112,7 @@ public RpcCall<BlockJson<TransactionRefJson>, BlockJson<TransactionRefJson>> get
*/
public RpcCall<BlockJson<TransactionJson>, BlockJson<TransactionJson>> getBlockWithTransactions(BlockHash hash) {
return RpcCall.create("eth_getBlockByHash", blockWithTxJson, hash.toHex(), true)
.withJsonType(blockWithTxJson)
.withJsonType(blockWithTxJsonType).castJsonType(blockWithTxJson)
.withResultType(blockWithTxJson);
}

Expand Down Expand Up @@ -355,8 +360,8 @@ public RpcCall<String, HexData> call(TransactionCallJson call, BlockTag block) {
* @param block The simulated blocks will be built on top of this. If null, the current block is used.
* @return simulated block
*/
public RpcCall<BlockSimulatedJson, BlockSimulatedJson> simulateV1(SimulateJson payload, BlockTag block) {
return RpcCall.create("eth_simulateV1", BlockSimulatedJson.class, payload, block.getCode());
public RpcCall<BlockSimulatedJson[], BlockSimulatedJson[]> simulateV1(SimulateJson payload, BlockTag block) {
return RpcCall.create("eth_simulateV1", BlockSimulatedJson.class, payload, block.getCode()).asArray();
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
package io.emeraldpay.etherjar.rpc;

import io.emeraldpay.etherjar.domain.TransactionId;
import io.emeraldpay.etherjar.rpc.json.TraceItemJson;

/**
* Commands specific for Parity Ethereum
Expand All @@ -28,7 +29,7 @@ public class ParityCommands {
* @param hash hash of the transaction
* @return trace list
*/
public RpcCall<TraceList, TraceList> traceTransaction(TransactionId hash) {
return RpcCall.create("trace_transaction", TraceList.class, hash.toHex());
public RpcCall<TraceItemJson[], TraceItemJson[]> traceTransaction(TransactionId hash) {
return RpcCall.create("trace_transaction", TraceItemJson.class, hash.toHex()).asArray();
}
}
Loading

0 comments on commit 264aca1

Please sign in to comment.