From 48a42a4f06a9e2bfb3328890c8f5e4b14b999128 Mon Sep 17 00:00:00 2001 From: Angel Soto Date: Mon, 26 Feb 2024 20:35:41 +0100 Subject: [PATCH 1/5] Adding method by name filtering --- .../exception/JsonRpcMethodNotFoundError.java | 14 +++++++++++ .../co/rsk/rpc/netty/JsonRpcCustomServer.java | 23 ++++++++++++++++--- .../rpc/netty/JsonRpcWeb3ServerHandler.java | 2 -- 3 files changed, 34 insertions(+), 5 deletions(-) create mode 100644 rskj-core/src/main/java/co/rsk/rpc/exception/JsonRpcMethodNotFoundError.java diff --git a/rskj-core/src/main/java/co/rsk/rpc/exception/JsonRpcMethodNotFoundError.java b/rskj-core/src/main/java/co/rsk/rpc/exception/JsonRpcMethodNotFoundError.java new file mode 100644 index 00000000000..507ffb217bb --- /dev/null +++ b/rskj-core/src/main/java/co/rsk/rpc/exception/JsonRpcMethodNotFoundError.java @@ -0,0 +1,14 @@ +package co.rsk.rpc.exception; + +import co.rsk.jsonrpc.JsonRpcError; + +public class JsonRpcMethodNotFoundError extends JsonRpcThrowableError { + public JsonRpcMethodNotFoundError(String methodName) { + super("The method " + methodName + " does not exist/is not available"); + } + + @Override + public JsonRpcError getErrorResponse() { + return new JsonRpcError(JsonRpcError.METHOD_NOT_FOUND, getMessage()); + } +} diff --git a/rskj-core/src/main/java/co/rsk/rpc/netty/JsonRpcCustomServer.java b/rskj-core/src/main/java/co/rsk/rpc/netty/JsonRpcCustomServer.java index e298bde4d0f..150c1496b86 100644 --- a/rskj-core/src/main/java/co/rsk/rpc/netty/JsonRpcCustomServer.java +++ b/rskj-core/src/main/java/co/rsk/rpc/netty/JsonRpcCustomServer.java @@ -19,6 +19,7 @@ package co.rsk.rpc.netty; import co.rsk.rpc.ModuleDescription; +import co.rsk.rpc.exception.JsonRpcMethodNotFoundError; import com.fasterxml.jackson.core.JsonParseException; import com.fasterxml.jackson.databind.JsonMappingException; import com.fasterxml.jackson.databind.JsonNode; @@ -26,16 +27,18 @@ import com.googlecode.jsonrpc4j.JsonResponse; import com.googlecode.jsonrpc4j.JsonRpcBasicServer; -import java.util.ArrayList; -import java.util.List; -import java.util.Optional; +import java.lang.reflect.Method; +import java.util.*; +import java.util.stream.Collectors; public class JsonRpcCustomServer extends JsonRpcBasicServer { private final List modules; + private final Set methodNames; public JsonRpcCustomServer(final Object handler, final Class remoteInterface, List modules) { super(new ObjectMapper(), handler, remoteInterface); this.modules = new ArrayList<>(modules); + this.methodNames = extractMethodNames(remoteInterface); } @Override @@ -46,6 +49,10 @@ protected JsonResponse handleJsonNodeRequest(final JsonNode node) throws JsonPar String method = Optional.ofNullable(node.get("method")).map(JsonNode::asText).orElse(""); + if(!methodNames.contains(method)) { + throw new JsonRpcMethodNotFoundError(method); + } + String[] methodParts = method.split("_"); JsonResponse response; if (methodParts.length >= 2) { @@ -82,4 +89,14 @@ private long getTimeout(String moduleName, String methodName) { } return moduleDescription.getTimeout(methodName); } + + private Set extractMethodNames(Class remoteInterface) { + if (remoteInterface == null) { + return Collections.emptySet(); + } + + return Arrays.stream(remoteInterface.getMethods()) + .map(Method::getName) + .collect(Collectors.toSet()); + } } diff --git a/rskj-core/src/main/java/co/rsk/rpc/netty/JsonRpcWeb3ServerHandler.java b/rskj-core/src/main/java/co/rsk/rpc/netty/JsonRpcWeb3ServerHandler.java index d15decdc701..dbb8029ed5e 100644 --- a/rskj-core/src/main/java/co/rsk/rpc/netty/JsonRpcWeb3ServerHandler.java +++ b/rskj-core/src/main/java/co/rsk/rpc/netty/JsonRpcWeb3ServerHandler.java @@ -107,8 +107,6 @@ protected void channelRead0(ChannelHandlerContext ctx, ByteBufHolder request) th int errorCode = ErrorResolver.JsonError.CUSTOM_SERVER_ERROR_LOWER; responseContent = buildErrorContent(errorCode, unexpectedErrorMsg); responseCode = errorCode; - } finally { - ReflectionUtil.clearCache(); } ctx.fireChannelRead(new Web3Result( From ca9bb78743f4076dcd53c214c604dc8bba554338 Mon Sep 17 00:00:00 2001 From: Angel Soto Date: Tue, 27 Feb 2024 00:40:07 +0100 Subject: [PATCH 2/5] Updating error response format to match the standard jsonrpc error response --- .../exception/JsonRpcMethodNotFoundError.java | 8 +++++-- .../rpc/exception/JsonRpcThrowableError.java | 12 +++++++++- .../co/rsk/rpc/netty/JsonRpcCustomServer.java | 3 ++- .../rpc/netty/JsonRpcWeb3ServerHandler.java | 23 ++++++++++++++++++- 4 files changed, 41 insertions(+), 5 deletions(-) diff --git a/rskj-core/src/main/java/co/rsk/rpc/exception/JsonRpcMethodNotFoundError.java b/rskj-core/src/main/java/co/rsk/rpc/exception/JsonRpcMethodNotFoundError.java index 507ffb217bb..b4bad5ee4fd 100644 --- a/rskj-core/src/main/java/co/rsk/rpc/exception/JsonRpcMethodNotFoundError.java +++ b/rskj-core/src/main/java/co/rsk/rpc/exception/JsonRpcMethodNotFoundError.java @@ -3,8 +3,12 @@ import co.rsk.jsonrpc.JsonRpcError; public class JsonRpcMethodNotFoundError extends JsonRpcThrowableError { - public JsonRpcMethodNotFoundError(String methodName) { - super("The method " + methodName + " does not exist/is not available"); + + private static final long serialVersionUID = 2919587893031838269L; + private static final String MSG = "method not found"; + + public JsonRpcMethodNotFoundError(Object requestId) { + super(MSG, requestId); } @Override diff --git a/rskj-core/src/main/java/co/rsk/rpc/exception/JsonRpcThrowableError.java b/rskj-core/src/main/java/co/rsk/rpc/exception/JsonRpcThrowableError.java index c8aabb2a849..2ce8bf07895 100644 --- a/rskj-core/src/main/java/co/rsk/rpc/exception/JsonRpcThrowableError.java +++ b/rskj-core/src/main/java/co/rsk/rpc/exception/JsonRpcThrowableError.java @@ -22,10 +22,20 @@ public abstract class JsonRpcThrowableError extends Error { private static final long serialVersionUID = 5255618001502614914L; - + private final Object requestId; JsonRpcThrowableError(String msg) { super(msg); + this.requestId = null; + } + + JsonRpcThrowableError(String msg, Object requestId) { + super(msg); + this.requestId = requestId; } public abstract JsonRpcError getErrorResponse(); + + public Object requestId() { + return requestId; + } } diff --git a/rskj-core/src/main/java/co/rsk/rpc/netty/JsonRpcCustomServer.java b/rskj-core/src/main/java/co/rsk/rpc/netty/JsonRpcCustomServer.java index 150c1496b86..5764cf8560b 100644 --- a/rskj-core/src/main/java/co/rsk/rpc/netty/JsonRpcCustomServer.java +++ b/rskj-core/src/main/java/co/rsk/rpc/netty/JsonRpcCustomServer.java @@ -50,7 +50,8 @@ protected JsonResponse handleJsonNodeRequest(final JsonNode node) throws JsonPar String method = Optional.ofNullable(node.get("method")).map(JsonNode::asText).orElse(""); if(!methodNames.contains(method)) { - throw new JsonRpcMethodNotFoundError(method); + Object requestId = node.get("id"); + throw new JsonRpcMethodNotFoundError(requestId); } String[] methodParts = method.split("_"); diff --git a/rskj-core/src/main/java/co/rsk/rpc/netty/JsonRpcWeb3ServerHandler.java b/rskj-core/src/main/java/co/rsk/rpc/netty/JsonRpcWeb3ServerHandler.java index dbb8029ed5e..46d0c64da8f 100644 --- a/rskj-core/src/main/java/co/rsk/rpc/netty/JsonRpcWeb3ServerHandler.java +++ b/rskj-core/src/main/java/co/rsk/rpc/netty/JsonRpcWeb3ServerHandler.java @@ -29,6 +29,7 @@ import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.JsonNodeFactory; +import com.fasterxml.jackson.databind.node.ObjectNode; import com.googlecode.jsonrpc4j.*; import io.netty.buffer.*; import io.netty.channel.ChannelHandler; @@ -44,10 +45,13 @@ import java.util.List; import java.util.Map; +import static com.googlecode.jsonrpc4j.JsonRpcBasicServer.*; + @ChannelHandler.Sharable public class JsonRpcWeb3ServerHandler extends SimpleChannelInboundHandler { private static final Logger LOGGER = LoggerFactory.getLogger("jsonrpc"); + public static final String VERSION = "2.0"; private final ObjectMapper mapper = new ObjectMapper(); private final JsonNodeFactory jsonNodeFactory = JsonNodeFactory.instance; @@ -99,7 +103,9 @@ protected void channelRead0(ChannelHandlerContext ctx, ByteBufHolder request) th LOGGER.error(e.getMessage(), e); JsonRpcError error = e.getErrorResponse(); int errorCode = error.getCode(); - responseContent = buildErrorContent(errorCode, error.getMessage()); + Object id = e.requestId(); + //TODO update all exceptions to return standard JSONRPC response error format. + responseContent = id == null ? buildErrorContent(errorCode, error.getMessage()): buildError(e.requestId(), errorCode, error.getMessage()); responseCode = errorCode; } catch (Exception e) { String unexpectedErrorMsg = "Unexpected error"; @@ -130,4 +136,19 @@ private ByteBuf buildErrorContent(int errorCode, String errorMessage) throws Jso return Unpooled.wrappedBuffer(mapper.writeValueAsBytes(object)); } + + private ByteBuf buildError(Object id, int errorCode, String errorMessage) throws JsonProcessingException { + ObjectNode response = mapper.createObjectNode(); + response.put(JSONRPC, VERSION); + if(id != null) { + response.set(ID, mapper.valueToTree(id)); + } + ObjectNode error = mapper.createObjectNode(); + error.put(ERROR_CODE, errorCode); + error.put(ERROR_MESSAGE, errorMessage); + + response.set(ERROR, error); + return Unpooled.wrappedBuffer(mapper.writeValueAsBytes(response)); + + } } From 485f9d3b70fd37327d0fd80406f04498359bae9b Mon Sep 17 00:00:00 2001 From: Angel Soto Date: Wed, 28 Feb 2024 18:55:21 +0100 Subject: [PATCH 3/5] Update method not found error handling --- .../exception/JsonRpcMethodNotFoundError.java | 18 ---------- .../rpc/exception/JsonRpcThrowableError.java | 12 +------ .../co/rsk/rpc/netty/JsonRpcCustomServer.java | 33 +++++++++++++++---- .../rpc/netty/JsonRpcWeb3ServerHandler.java | 25 ++------------ .../rpc/netty/JsonRPCParamValidationTest.java | 2 +- .../rpc/netty/JsonRpcCustomServerTest.java | 14 ++++---- 6 files changed, 38 insertions(+), 66 deletions(-) delete mode 100644 rskj-core/src/main/java/co/rsk/rpc/exception/JsonRpcMethodNotFoundError.java diff --git a/rskj-core/src/main/java/co/rsk/rpc/exception/JsonRpcMethodNotFoundError.java b/rskj-core/src/main/java/co/rsk/rpc/exception/JsonRpcMethodNotFoundError.java deleted file mode 100644 index b4bad5ee4fd..00000000000 --- a/rskj-core/src/main/java/co/rsk/rpc/exception/JsonRpcMethodNotFoundError.java +++ /dev/null @@ -1,18 +0,0 @@ -package co.rsk.rpc.exception; - -import co.rsk.jsonrpc.JsonRpcError; - -public class JsonRpcMethodNotFoundError extends JsonRpcThrowableError { - - private static final long serialVersionUID = 2919587893031838269L; - private static final String MSG = "method not found"; - - public JsonRpcMethodNotFoundError(Object requestId) { - super(MSG, requestId); - } - - @Override - public JsonRpcError getErrorResponse() { - return new JsonRpcError(JsonRpcError.METHOD_NOT_FOUND, getMessage()); - } -} diff --git a/rskj-core/src/main/java/co/rsk/rpc/exception/JsonRpcThrowableError.java b/rskj-core/src/main/java/co/rsk/rpc/exception/JsonRpcThrowableError.java index 2ce8bf07895..c8aabb2a849 100644 --- a/rskj-core/src/main/java/co/rsk/rpc/exception/JsonRpcThrowableError.java +++ b/rskj-core/src/main/java/co/rsk/rpc/exception/JsonRpcThrowableError.java @@ -22,20 +22,10 @@ public abstract class JsonRpcThrowableError extends Error { private static final long serialVersionUID = 5255618001502614914L; - private final Object requestId; - JsonRpcThrowableError(String msg) { - super(msg); - this.requestId = null; - } - JsonRpcThrowableError(String msg, Object requestId) { + JsonRpcThrowableError(String msg) { super(msg); - this.requestId = requestId; } public abstract JsonRpcError getErrorResponse(); - - public Object requestId() { - return requestId; - } } diff --git a/rskj-core/src/main/java/co/rsk/rpc/netty/JsonRpcCustomServer.java b/rskj-core/src/main/java/co/rsk/rpc/netty/JsonRpcCustomServer.java index 5764cf8560b..4161e4a1255 100644 --- a/rskj-core/src/main/java/co/rsk/rpc/netty/JsonRpcCustomServer.java +++ b/rskj-core/src/main/java/co/rsk/rpc/netty/JsonRpcCustomServer.java @@ -19,11 +19,11 @@ package co.rsk.rpc.netty; import co.rsk.rpc.ModuleDescription; -import co.rsk.rpc.exception.JsonRpcMethodNotFoundError; import com.fasterxml.jackson.core.JsonParseException; import com.fasterxml.jackson.databind.JsonMappingException; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ObjectNode; import com.googlecode.jsonrpc4j.JsonResponse; import com.googlecode.jsonrpc4j.JsonRpcBasicServer; @@ -31,14 +31,19 @@ import java.util.*; import java.util.stream.Collectors; +import static co.rsk.jsonrpc.JsonRpcError.METHOD_NOT_FOUND; + public class JsonRpcCustomServer extends JsonRpcBasicServer { + public static final String METHOD_NOT_FOUND_MSG = "method not found"; private final List modules; private final Set methodNames; + private final ObjectMapper objectMapper; - public JsonRpcCustomServer(final Object handler, final Class remoteInterface, List modules) { - super(new ObjectMapper(), handler, remoteInterface); + public JsonRpcCustomServer(final Object handler, final Class remoteInterface, List modules, ObjectMapper objetMapper) { + super(objetMapper, handler, remoteInterface); this.modules = new ArrayList<>(modules); this.methodNames = extractMethodNames(remoteInterface); + this.objectMapper = objetMapper; } @Override @@ -47,11 +52,11 @@ protected JsonResponse handleJsonNodeRequest(final JsonNode node) throws JsonPar return super.handleJsonNodeRequest(node); } - String method = Optional.ofNullable(node.get("method")).map(JsonNode::asText).orElse(""); + String method = Optional.ofNullable(node.get(METHOD)).map(JsonNode::asText).orElse(""); if(!methodNames.contains(method)) { - Object requestId = node.get("id"); - throw new JsonRpcMethodNotFoundError(requestId); + Object requestId = node.get(ID); + return buildError(requestId, METHOD_NOT_FOUND, METHOD_NOT_FOUND_MSG); } String[] methodParts = method.split("_"); @@ -100,4 +105,20 @@ private Set extractMethodNames(Class remoteInterface) { .map(Method::getName) .collect(Collectors.toSet()); } + + private JsonResponse buildError(Object id, int errorCode, String errorMessage) { + ObjectMapper mapper = new ObjectMapper(); + ObjectNode response = mapper.createObjectNode(); + response.put(JSONRPC, VERSION); + if(id != null) { + response.set(ID, mapper.valueToTree(id)); + } + ObjectNode error = mapper.createObjectNode(); + error.put(ERROR_CODE, errorCode); + error.put(ERROR_MESSAGE, errorMessage); + + response.set(ERROR, error); + return new JsonResponse(response, errorCode); + } + } diff --git a/rskj-core/src/main/java/co/rsk/rpc/netty/JsonRpcWeb3ServerHandler.java b/rskj-core/src/main/java/co/rsk/rpc/netty/JsonRpcWeb3ServerHandler.java index 46d0c64da8f..02acbf4d19f 100644 --- a/rskj-core/src/main/java/co/rsk/rpc/netty/JsonRpcWeb3ServerHandler.java +++ b/rskj-core/src/main/java/co/rsk/rpc/netty/JsonRpcWeb3ServerHandler.java @@ -29,7 +29,6 @@ import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.JsonNodeFactory; -import com.fasterxml.jackson.databind.node.ObjectNode; import com.googlecode.jsonrpc4j.*; import io.netty.buffer.*; import io.netty.channel.ChannelHandler; @@ -45,13 +44,10 @@ import java.util.List; import java.util.Map; -import static com.googlecode.jsonrpc4j.JsonRpcBasicServer.*; - @ChannelHandler.Sharable public class JsonRpcWeb3ServerHandler extends SimpleChannelInboundHandler { private static final Logger LOGGER = LoggerFactory.getLogger("jsonrpc"); - public static final String VERSION = "2.0"; private final ObjectMapper mapper = new ObjectMapper(); private final JsonNodeFactory jsonNodeFactory = JsonNodeFactory.instance; @@ -60,7 +56,7 @@ public class JsonRpcWeb3ServerHandler extends SimpleChannelInboundHandler interceptors = new ArrayList<>(); interceptors.add(new JsonRpcRequestValidatorInterceptor(jsonRpcWeb3ServerProperties.getMaxBatchRequestsSize())); jsonRpcServer.setInterceptorList(interceptors); @@ -103,9 +99,7 @@ protected void channelRead0(ChannelHandlerContext ctx, ByteBufHolder request) th LOGGER.error(e.getMessage(), e); JsonRpcError error = e.getErrorResponse(); int errorCode = error.getCode(); - Object id = e.requestId(); - //TODO update all exceptions to return standard JSONRPC response error format. - responseContent = id == null ? buildErrorContent(errorCode, error.getMessage()): buildError(e.requestId(), errorCode, error.getMessage()); + responseContent = buildErrorContent(errorCode, error.getMessage()); responseCode = errorCode; } catch (Exception e) { String unexpectedErrorMsg = "Unexpected error"; @@ -136,19 +130,4 @@ private ByteBuf buildErrorContent(int errorCode, String errorMessage) throws Jso return Unpooled.wrappedBuffer(mapper.writeValueAsBytes(object)); } - - private ByteBuf buildError(Object id, int errorCode, String errorMessage) throws JsonProcessingException { - ObjectNode response = mapper.createObjectNode(); - response.put(JSONRPC, VERSION); - if(id != null) { - response.set(ID, mapper.valueToTree(id)); - } - ObjectNode error = mapper.createObjectNode(); - error.put(ERROR_CODE, errorCode); - error.put(ERROR_MESSAGE, errorMessage); - - response.set(ERROR, error); - return Unpooled.wrappedBuffer(mapper.writeValueAsBytes(response)); - - } } diff --git a/rskj-core/src/test/java/co/rsk/rpc/netty/JsonRPCParamValidationTest.java b/rskj-core/src/test/java/co/rsk/rpc/netty/JsonRPCParamValidationTest.java index a7bec0637a0..cf614eb6053 100644 --- a/rskj-core/src/test/java/co/rsk/rpc/netty/JsonRPCParamValidationTest.java +++ b/rskj-core/src/test/java/co/rsk/rpc/netty/JsonRPCParamValidationTest.java @@ -46,7 +46,7 @@ class JsonRPCParamValidationTest { @BeforeEach void setUp() { handler = mock(Web3EthModule.class); - this.jsonRpcServer = new JsonRpcCustomServer(handler, handler.getClass(), Collections.emptyList()); + this.jsonRpcServer = new JsonRpcCustomServer(handler, handler.getClass(), Collections.emptyList(), objectMapper); jsonRpcServer.setErrorResolver(new MultipleErrorResolver(new RskErrorResolver(), AnnotationsErrorResolver.INSTANCE, DefaultErrorResolver.INSTANCE)); } diff --git a/rskj-core/src/test/java/co/rsk/rpc/netty/JsonRpcCustomServerTest.java b/rskj-core/src/test/java/co/rsk/rpc/netty/JsonRpcCustomServerTest.java index 4f7b0523e98..5d0e12e8edd 100644 --- a/rskj-core/src/test/java/co/rsk/rpc/netty/JsonRpcCustomServerTest.java +++ b/rskj-core/src/test/java/co/rsk/rpc/netty/JsonRpcCustomServerTest.java @@ -57,7 +57,7 @@ void testHandleJsonNodeRequest() throws Exception { JsonNode request = objectMapper.readTree(FIRST_METHOD_REQUEST); String response = "test_method_response"; Web3Test handler = mock(Web3Test.class); - jsonRpcCustomServer = new JsonRpcCustomServer(handler, Web3Test.class, modules); + jsonRpcCustomServer = new JsonRpcCustomServer(handler, Web3Test.class, modules, objectMapper); when(handler.test_first(anyString())).thenReturn(response); @@ -72,7 +72,7 @@ void testHandleJsonNodeRequest_WithResponseLimit() throws Exception { Web3Test handler = mock(Web3Test.class); //expected response would be {"jsonrpc":"2.0","id":1,"result":"test_method_response"} with 56 bytes ResponseSizeLimitContext.createResponseSizeContext(55); - jsonRpcCustomServer = new JsonRpcCustomServer(handler, Web3Test.class, modules); + jsonRpcCustomServer = new JsonRpcCustomServer(handler, Web3Test.class, modules, objectMapper); when(handler.test_first(anyString())).thenReturn(response); @@ -83,7 +83,7 @@ void testHandleJsonNodeRequest_WithResponseLimit() throws Exception { void testHandleJsonNodeRequest_WithMethodModule() throws Exception { JsonNode request = objectMapper.readTree(SECOND_METHOD_REQUEST); Web3Test handler = mock(Web3Test.class); - jsonRpcCustomServer = new JsonRpcCustomServer(handler, Web3Test.class, getModulesWithMethodTimeout(0, 125)); + jsonRpcCustomServer = new JsonRpcCustomServer(handler, Web3Test.class, getModulesWithMethodTimeout(0, 125), objectMapper); String response = "test_method_response"; when(handler.test_second("param", "param2")).thenAnswer(invocation -> { @@ -99,7 +99,7 @@ void testHandleJsonNodeRequest_WithMethodModule() throws Exception { void testHandleJsonNodeRequest_WithMethodTimeout() throws Exception { JsonNode request = objectMapper.readTree(SECOND_METHOD_REQUEST); Web3Test handler = mock(Web3Test.class); - jsonRpcCustomServer = new JsonRpcCustomServer(handler, Web3Test.class, getModulesWithMethodTimeout(125, 0)); + jsonRpcCustomServer = new JsonRpcCustomServer(handler, Web3Test.class, getModulesWithMethodTimeout(125, 0), objectMapper); when(handler.test_second(anyString(), anyString())).thenAnswer(invocation -> { waitFor(150); @@ -113,7 +113,7 @@ void testHandleJsonNodeRequest_WithMethodTimeout() throws Exception { void testHandleJsonNodeRequest_methodTimeoutOverModule() throws Exception { JsonNode request = objectMapper.readTree(SECOND_METHOD_REQUEST); Web3Test handler = mock(Web3Test.class); - jsonRpcCustomServer = new JsonRpcCustomServer(handler, Web3Test.class, getModulesWithMethodTimeout(500, 100)); + jsonRpcCustomServer = new JsonRpcCustomServer(handler, Web3Test.class, getModulesWithMethodTimeout(500, 100), objectMapper); String response = "test_method_response"; when(handler.test_second("param", "param2")).thenAnswer(invocation -> { @@ -158,7 +158,7 @@ void testHandleJsonNodeRequest_WithMethodTimeout_BatchRequest_OK() throws Except JsonNode request = objectMapper.readTree(jsonRequest); Web3Test handler = mock(Web3Test.class); - jsonRpcCustomServer = new JsonRpcCustomServer(handler, Web3Test.class, getModulesWithMethodTimeout(timeoutPerMethod, 0)); + jsonRpcCustomServer = new JsonRpcCustomServer(handler, Web3Test.class, getModulesWithMethodTimeout(timeoutPerMethod, 0), objectMapper); when(handler.test_second(anyString(), anyString())).thenAnswer(invocation -> { waitFor(sleepTimePerRequest); @@ -198,7 +198,7 @@ void testHandleJsonNodeRequest_WithMethodTimeout_BatchRequest_FAIL() throws Exce JsonNode request = objectMapper.readTree(jsonRequest); Web3Test handler = mock(Web3Test.class); - jsonRpcCustomServer = new JsonRpcCustomServer(handler, Web3Test.class, getModulesWithMethodTimeout(timeoutPerMethod, 0)); + jsonRpcCustomServer = new JsonRpcCustomServer(handler, Web3Test.class, getModulesWithMethodTimeout(timeoutPerMethod, 0), objectMapper); when(handler.test_second(anyString(), anyString())).thenAnswer(invocation -> { waitFor(sleepTimePerRequest); From d89ee92e3f980a415bb92d0dea17128207bcc982 Mon Sep 17 00:00:00 2001 From: Angel Soto Date: Thu, 29 Feb 2024 18:51:28 +0100 Subject: [PATCH 4/5] Adding undifined method unit test --- .../rpc/netty/JsonRpcCustomServerTest.java | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/rskj-core/src/test/java/co/rsk/rpc/netty/JsonRpcCustomServerTest.java b/rskj-core/src/test/java/co/rsk/rpc/netty/JsonRpcCustomServerTest.java index 5d0e12e8edd..648a1024c37 100644 --- a/rskj-core/src/test/java/co/rsk/rpc/netty/JsonRpcCustomServerTest.java +++ b/rskj-core/src/test/java/co/rsk/rpc/netty/JsonRpcCustomServerTest.java @@ -209,6 +209,25 @@ void testHandleJsonNodeRequest_WithMethodTimeout_BatchRequest_FAIL() throws Exce verify(handler, times(1)).test_second(anyString(), anyString()); } + @Test + void sendingRequestWithNonDeclaredMethodShouldFail() throws Exception { + String jsonRequest = " {\n" + + " \"jsonrpc\": \"2.0\",\n" + + " \"method\": \"invalid_method\",\n" + + " \"params\": [],\n" + + " \"id\": 1\n" + + " }"; + + String expectedResponse = "{\"jsonrpc\":\"2.0\",\"id\":1,\"error\":{\"code\":-32601,\"message\":\"method not found\"}}"; + JsonNode request = objectMapper.readTree(jsonRequest); + Web3Test handler = mock(Web3Test.class); + + jsonRpcCustomServer = new JsonRpcCustomServer(handler, Web3Test.class, modules, objectMapper); + + JsonResponse actualResponse = jsonRpcCustomServer.handleJsonNodeRequest(request); + assertEquals(expectedResponse, actualResponse.getResponse().toString()); + } + public interface Web3Test { String test_first(String param1); From e869aa7da4242370b1c0a6fdcdc4238333680c29 Mon Sep 17 00:00:00 2001 From: Angel Soto Date: Mon, 4 Mar 2024 18:35:04 +0100 Subject: [PATCH 5/5] Updating objectMapper usage --- .../main/java/co/rsk/rpc/netty/JsonRpcCustomServer.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/rskj-core/src/main/java/co/rsk/rpc/netty/JsonRpcCustomServer.java b/rskj-core/src/main/java/co/rsk/rpc/netty/JsonRpcCustomServer.java index 4161e4a1255..58559b9ea70 100644 --- a/rskj-core/src/main/java/co/rsk/rpc/netty/JsonRpcCustomServer.java +++ b/rskj-core/src/main/java/co/rsk/rpc/netty/JsonRpcCustomServer.java @@ -107,13 +107,12 @@ private Set extractMethodNames(Class remoteInterface) { } private JsonResponse buildError(Object id, int errorCode, String errorMessage) { - ObjectMapper mapper = new ObjectMapper(); - ObjectNode response = mapper.createObjectNode(); + ObjectNode response = objectMapper.createObjectNode(); response.put(JSONRPC, VERSION); if(id != null) { - response.set(ID, mapper.valueToTree(id)); + response.set(ID, objectMapper.valueToTree(id)); } - ObjectNode error = mapper.createObjectNode(); + ObjectNode error = objectMapper.createObjectNode(); error.put(ERROR_CODE, errorCode); error.put(ERROR_MESSAGE, errorMessage);