Skip to content

Commit

Permalink
refactor: Add GrandpaRpcClient to further split the rpc clients.
Browse files Browse the repository at this point in the history
  • Loading branch information
Zurcusa committed Aug 30, 2024
1 parent 2f98bd5 commit 76f2b45
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,15 @@

import com.limechain.polkaj.Hash256;
import com.limechain.rpc.dto.ChainGetHeaderResult;
import com.limechain.rpc.dto.GrandpaRoundStateResult;
import com.limechain.rpc.dto.RpcMethod;
import com.limechain.rpc.dto.RpcResponse;

import java.util.List;

public final class BlockRpcClient extends RpcClient {
/**
* An implementation of {@link RpcClient}, which implements RPC calls from the "chain" category.
*/
public final class ChainRpcClient extends RpcClient {

public static Hash256 getLastFinalizedBlockHash() {
RpcResponse response = sendRpcRequest(RpcMethod.CHAIN_GET_FINALIZED_HEAD, List.of());
Expand All @@ -19,9 +21,4 @@ public static ChainGetHeaderResult getHeader(String blockHash) {
RpcResponse response = sendRpcRequest(RpcMethod.CHAIN_GET_HEADER, List.of(blockHash));
return getResult(response, ChainGetHeaderResult.class);
}

public static GrandpaRoundStateResult getGrandpaRoundState() {
RpcResponse response = sendRpcRequest(RpcMethod.GRANDPA_ROUND_STATE, List.of());
return getResult(response, GrandpaRoundStateResult.class);
}
}
18 changes: 18 additions & 0 deletions src/main/java/com/limechain/rpc/GrandpaRpcClient.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.limechain.rpc;

import com.limechain.rpc.dto.GrandpaRoundStateResult;
import com.limechain.rpc.dto.RpcMethod;
import com.limechain.rpc.dto.RpcResponse;

import java.util.List;

/**
* An implementation of {@link RpcClient}, which implements RPC calls from the "grandpa" category.
*/
public final class GrandpaRpcClient extends RpcClient {

public static GrandpaRoundStateResult getGrandpaRoundState() {
RpcResponse response = sendRpcRequest(RpcMethod.GRANDPA_ROUND_STATE, List.of());
return getResult(response, GrandpaRoundStateResult.class);
}
}
43 changes: 34 additions & 9 deletions src/main/java/com/limechain/rpc/RpcClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,37 +14,62 @@
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;

/**
* Base class for executing RPC requests.
*/
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public sealed class RpcClient permits BlockRpcClient {
public sealed class RpcClient permits ChainRpcClient, GrandpaRpcClient {

private static final String POST = "POST";

private static final AtomicInteger ID_COUNTER = new AtomicInteger(1);
private static final LoadBalancer LOAD_BALANCER = new LoadBalancer(AppBean.getBean(HostConfig.class));
protected static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(false);

private static String createRpcRequestJson(String method, List<Object> params) {
RpcRequest request = new RpcRequest(ID_COUNTER.getAndAdd(1), method, params);
return JsonUtil.stringify(request);
}

/**
* Send an RPC request. Currently used only by the exported RPC client.
*
* @param method {@link String} representation of the RPC method name. For example "system_name".
* @param params An array of parameters for the sent RPC request.
* @return The {@link String} representation of the received RPC json result.
*/
public static String sendRpcRequest(String method, Object[] params) {
return HttpRequest.createHttpRequest(POST, LOAD_BALANCER.getNextEndpoint(),
createRpcRequestJson(method, List.of(params)));
}

/**
* Send an RPC request. Used by the specific implementations of the RpcClient.
*
* @param method Enum representation of an RPC method name.
* @param params An array of parameters for the sent RPC request.
* @return The {@link RpcResponse} representation of the received RPC json result.
*/
protected static RpcResponse sendRpcRequest(RpcMethod method, List<Object> params) {
String jsonResult = HttpRequest.asyncHttpRequest(POST, LOAD_BALANCER.getNextEndpoint(),
createRpcRequestJson(method.getMethod(), params));
return OBJECT_MAPPER.mapToClass(jsonResult, RpcResponse.class);
}

protected static <T> T getResult(RpcResponse response, Class<T> type) {
private static String createRpcRequestJson(String method, List<Object> params) {
RpcRequest request = new RpcRequest(ID_COUNTER.getAndAdd(1), method, params);
return JsonUtil.stringify(request);
}

/**
* Method used to map an {@link RpcResponse} result to a provided class type. This is needed because TeaVM does not
* support use of {@link java.lang.reflect.ParameterizedType} and we cannot use an object mapper with generics
* inside.
*
* @param response the {@link RpcResponse} whose result we have to map to an object.
* @param klazz the desired class for the mapping.
* @return a mapped version of the response result in the form of the provided {@code klazz} type.
*/
protected static <T> T getResult(RpcResponse response, Class<T> klazz) {
if (response.getError() != null) {
throw new IllegalStateException("RPC request resulted in an error with code:" + response.getError().getCode()
+ " and message:" + response.getError().getMessage());
}

return OBJECT_MAPPER.mapToClass(JsonUtil.stringify(response.getResult()), type);
return OBJECT_MAPPER.mapToClass(JsonUtil.stringify(response.getResult()), klazz);
}
}

0 comments on commit 76f2b45

Please sign in to comment.