diff --git a/rskj-core/src/main/java/org/ethereum/rpc/parameters/CallArgumentsParam.java b/rskj-core/src/main/java/org/ethereum/rpc/parameters/CallArgumentsParam.java index 96134328f51..4982b25f0dc 100644 --- a/rskj-core/src/main/java/org/ethereum/rpc/parameters/CallArgumentsParam.java +++ b/rskj-core/src/main/java/org/ethereum/rpc/parameters/CallArgumentsParam.java @@ -24,7 +24,9 @@ import com.fasterxml.jackson.databind.deser.std.StdDeserializer; import org.ethereum.rpc.CallArguments; +import javax.annotation.Nullable; import java.io.IOException; +import java.util.function.Function; @JsonDeserialize(using = CallArgumentsParam.Deserializer.class) public class CallArgumentsParam { @@ -137,18 +139,28 @@ public static class Deserializer extends StdDeserializer { public CallArgumentsParam deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { JsonNode node = jp.getCodec().readTree(jp); - HexAddressParam from = node.has("from") ? new HexAddressParam(node.get("from").asText()) : null; - HexAddressParam to = node.has("to") ? new HexAddressParam(node.get("to").asText()) : null; - HexNumberParam gas = node.has("gas") ? new HexNumberParam(node.get("gas").asText()) : null; - HexNumberParam gasPrice = node.has("gasPrice") ? new HexNumberParam(node.get("gasPrice").asText()) : null; - HexNumberParam gasLimit = node.has("gasLimit") ? new HexNumberParam(node.get("gasLimit").asText()) : null; - HexNumberParam nonce = node.has("nonce") ? new HexNumberParam(node.get("nonce").asText()) : null; - HexNumberParam chainId = node.has("chainId") ? new HexNumberParam(node.get("chainId").asText()) : null; - HexNumberParam value = node.has("value") ? new HexNumberParam(node.get("value").asText()) : null; - HexDataParam data = node.has("data") ? new HexDataParam(node.get("data").asText()) : null; - HexDataParam input = node.has("input") ? new HexDataParam(node.get("input").asText()) : null; + HexAddressParam from = paramOrNull(node, "from", HexAddressParam::new); + HexAddressParam to = paramOrNull(node, "to", HexAddressParam::new); + HexNumberParam gas = paramOrNull(node, "gas", HexNumberParam::new); + HexNumberParam gasPrice = paramOrNull(node, "gasPrice", HexNumberParam::new); + HexNumberParam gasLimit = paramOrNull(node, "gasLimit", HexNumberParam::new); + HexNumberParam nonce = paramOrNull(node, "nonce", HexNumberParam::new); + HexNumberParam chainId = paramOrNull(node, "chainId", HexNumberParam::new); + HexNumberParam value = paramOrNull(node, "value", HexNumberParam::new); + HexDataParam data = paramOrNull(node, "data", HexDataParam::new); + HexDataParam input = paramOrNull(node, "input", HexDataParam::new); return new CallArgumentsParam(from, to, gas, gasPrice, gasLimit, nonce, chainId, value, data, input); } + + @Nullable + private static T paramOrNull(JsonNode node, String fieldName, Function paramFactory) { + JsonNode fieldNode = node.get(fieldName); + if (fieldNode == null || fieldNode.isNull()) { + return null; + } + + return paramFactory.apply(fieldNode.asText()); + } } } diff --git a/rskj-core/src/test/java/org/ethereum/rpc/parameters/CallArgumentsParamTest.java b/rskj-core/src/test/java/org/ethereum/rpc/parameters/CallArgumentsParamTest.java index 1a89239437f..a86d8a05f5b 100644 --- a/rskj-core/src/test/java/org/ethereum/rpc/parameters/CallArgumentsParamTest.java +++ b/rskj-core/src/test/java/org/ethereum/rpc/parameters/CallArgumentsParamTest.java @@ -13,14 +13,15 @@ public class CallArgumentsParamTest { private final ObjectMapper objectMapper = new ObjectMapper(); - private final String FROM = "0x7986b3df570230288501eea3d890bd66948c9b79"; - private final String TO = "0xe7b8e91401bf4d1669f54dc5f98109d7efbc4eea"; - private final String GAS = "0x76c0"; - private final String GAS_PRICE = "0x9184e72a000"; - private final String VALUE = "0x9184e72a"; - private final String DATA = "0xd46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f072445675"; - private final String NONCE = "0x1"; - private final String CHAIN_ID = "0x539"; + private static final String FROM = "0x7986b3df570230288501eea3d890bd66948c9b79"; + private static final String TO = "0xe7b8e91401bf4d1669f54dc5f98109d7efbc4eea"; + private static final String GAS = "0x76c0"; + private static final String GAS_PRICE = "0x9184e72a000"; + private static final String VALUE = "0x9184e72a"; + private static final String DATA = "0xd46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f072445675"; + private static final String NONCE = "0x1"; + private static final String CHAIN_ID = "0x539"; + private static final String NULL = "null"; @Test public void testValidCallArgumentsParam() throws JsonProcessingException { @@ -200,4 +201,50 @@ public void testToCallArgumentsWithInput() { assertEquals(DATA, callArguments.getData()); assertEquals(DATA, callArguments.getInput()); } + + @Test + public void testNullCallArgumentsParams() throws JsonProcessingException { + String callArgumentsInput = "{\n" + + " \"from\": " + NULL + ", " + + " \"to\" : " + NULL + ", " + + " \"gas\": " + NULL + ", " + + " \"gasPrice\": " + NULL + ", " + + " \"value\": " + NULL + ", " + + " \"data\": " + NULL + ", " + + " \"nonce\": " + NULL + ", " + + " \"chainId\": " + NULL + "}"; + + JsonNode jsonNode = objectMapper.readTree(callArgumentsInput); + CallArgumentsParam callArgumentsParam = objectMapper.convertValue(jsonNode, CallArgumentsParam.class); + + assertNotNull(callArgumentsParam); + + assertNull(callArgumentsParam.getFrom()); + assertNull(callArgumentsParam.getTo()); + assertNull(callArgumentsParam.getGas()); + assertNull(callArgumentsParam.getGasPrice()); + assertNull(callArgumentsParam.getValue()); + assertNull(callArgumentsParam.getData()); + assertNull(callArgumentsParam.getNonce()); + assertNull(callArgumentsParam.getChainId()); + } + + @Test + public void testNoCallArgumentsParams() throws JsonProcessingException { + String callArgumentsInput = "{ }"; + + JsonNode jsonNode = objectMapper.readTree(callArgumentsInput); + CallArgumentsParam callArgumentsParam = objectMapper.convertValue(jsonNode, CallArgumentsParam.class); + + assertNotNull(callArgumentsParam); + + assertNull(callArgumentsParam.getFrom()); + assertNull(callArgumentsParam.getTo()); + assertNull(callArgumentsParam.getGas()); + assertNull(callArgumentsParam.getGasPrice()); + assertNull(callArgumentsParam.getValue()); + assertNull(callArgumentsParam.getData()); + assertNull(callArgumentsParam.getNonce()); + assertNull(callArgumentsParam.getChainId()); + } }