diff --git a/ethereum/jsonrpc/src/main/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/JsonRpcRequest.java b/ethereum/jsonrpc/src/main/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/JsonRpcRequest.java index 58c15421b8..abfa3b50cb 100644 --- a/ethereum/jsonrpc/src/main/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/JsonRpcRequest.java +++ b/ethereum/jsonrpc/src/main/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/JsonRpcRequest.java @@ -12,6 +12,7 @@ */ package tech.pegasys.pantheon.ethereum.jsonrpc.internal; +import tech.pegasys.pantheon.ethereum.jsonrpc.internal.exception.InvalidJsonRpcParameters; import tech.pegasys.pantheon.ethereum.jsonrpc.internal.exception.InvalidJsonRpcRequestException; import java.util.Arrays; @@ -69,6 +70,15 @@ public Object[] getParams() { return params; } + @JsonIgnore + public void assertMaxLength(final int expectedLength) { + final int length = getParamLength(); + if (length > expectedLength) { + throw new InvalidJsonRpcParameters( + "Too many parameters, expected " + expectedLength + ", got " + length + " ."); + } + } + @JsonIgnore public boolean isNotification() { return isNotification; diff --git a/ethereum/jsonrpc/src/main/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/methods/EthGetUncleCountByBlockNumber.java b/ethereum/jsonrpc/src/main/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/methods/EthGetUncleCountByBlockNumber.java index 626e25aa0a..076dd45d4c 100644 --- a/ethereum/jsonrpc/src/main/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/methods/EthGetUncleCountByBlockNumber.java +++ b/ethereum/jsonrpc/src/main/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/methods/EthGetUncleCountByBlockNumber.java @@ -33,6 +33,7 @@ public String getName() { @Override protected BlockParameter blockParameter(final JsonRpcRequest request) { + request.assertMaxLength(1); return getParameters().required(request.getParams(), 0, BlockParameter.class); } diff --git a/ethereum/jsonrpc/src/main/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/privacy/methods/eea/EeaGetTransactionCount.java b/ethereum/jsonrpc/src/main/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/privacy/methods/eea/EeaGetTransactionCount.java index c84118c848..a4c9aa9294 100644 --- a/ethereum/jsonrpc/src/main/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/privacy/methods/eea/EeaGetTransactionCount.java +++ b/ethereum/jsonrpc/src/main/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/privacy/methods/eea/EeaGetTransactionCount.java @@ -47,9 +47,7 @@ public String getName() { @Override public JsonRpcResponse response(final JsonRpcRequest request) { - if (request.getParamLength() != 3) { - return new JsonRpcErrorResponse(request.getId(), JsonRpcError.INVALID_PARAMS); - } + request.assertMaxLength(3); final Address address = parameters.required(request.getParams(), 0, Address.class); final String privateFrom = parameters.required(request.getParams(), 1, String.class); diff --git a/ethereum/jsonrpc/src/main/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/privacy/methods/eea/EeaGetTransactionReceipt.java b/ethereum/jsonrpc/src/main/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/privacy/methods/eea/EeaGetTransactionReceipt.java index f4bd7a2c39..a9877aff50 100644 --- a/ethereum/jsonrpc/src/main/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/privacy/methods/eea/EeaGetTransactionReceipt.java +++ b/ethereum/jsonrpc/src/main/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/privacy/methods/eea/EeaGetTransactionReceipt.java @@ -73,6 +73,7 @@ public String getName() { @Override public JsonRpcResponse response(final JsonRpcRequest request) { + request.assertMaxLength(1); LOG.trace("Executing {}", RpcMethod.EEA_GET_TRANSACTION_RECEIPT.getMethodName()); final Hash transactionHash = parameters.required(request.getParams(), 0, Hash.class); final Optional maybeLocation = diff --git a/ethereum/jsonrpc/src/main/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/privacy/methods/eea/EeaSendRawTransaction.java b/ethereum/jsonrpc/src/main/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/privacy/methods/eea/EeaSendRawTransaction.java index 68970b779b..4d567798ab 100644 --- a/ethereum/jsonrpc/src/main/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/privacy/methods/eea/EeaSendRawTransaction.java +++ b/ethereum/jsonrpc/src/main/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/privacy/methods/eea/EeaSendRawTransaction.java @@ -60,9 +60,7 @@ public String getName() { @Override public JsonRpcResponse response(final JsonRpcRequest request) { - if (request.getParamLength() != 1) { - return new JsonRpcErrorResponse(request.getId(), JsonRpcError.INVALID_PARAMS); - } + request.assertMaxLength(1); final String rawPrivateTransaction = parameters.required(request.getParams(), 0, String.class); final PrivateTransaction privateTransaction; diff --git a/ethereum/jsonrpc/src/main/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/privacy/methods/priv/PrivCreatePrivacyGroup.java b/ethereum/jsonrpc/src/main/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/privacy/methods/priv/PrivCreatePrivacyGroup.java index 95cf57f79b..1959ddcbd0 100644 --- a/ethereum/jsonrpc/src/main/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/privacy/methods/priv/PrivCreatePrivacyGroup.java +++ b/ethereum/jsonrpc/src/main/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/privacy/methods/priv/PrivCreatePrivacyGroup.java @@ -53,6 +53,7 @@ public String getName() { @Override public JsonRpcResponse response(final JsonRpcRequest request) { + request.assertMaxLength(3); LOG.trace("Executing {}", RpcMethod.PRIV_CREATE_PRIVACY_GROUP.getMethodName()); final CreatePrivacyGroupParameter parameter = diff --git a/ethereum/jsonrpc/src/main/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/privacy/methods/priv/PrivGetPrivacyPrecompileAddress.java b/ethereum/jsonrpc/src/main/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/privacy/methods/priv/PrivGetPrivacyPrecompileAddress.java index 336b268dba..59ea50b5ec 100644 --- a/ethereum/jsonrpc/src/main/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/privacy/methods/priv/PrivGetPrivacyPrecompileAddress.java +++ b/ethereum/jsonrpc/src/main/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/privacy/methods/priv/PrivGetPrivacyPrecompileAddress.java @@ -39,7 +39,7 @@ public String getName() { @Override public JsonRpcResponse response(final JsonRpcRequest request) { - + request.assertMaxLength(1); if (privacyEnabled) { return new JsonRpcSuccessResponse( request.getId(), Address.privacyPrecompiled(privacyAddress).toString()); diff --git a/ethereum/jsonrpc/src/main/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/privacy/methods/priv/PrivGetPrivateTransaction.java b/ethereum/jsonrpc/src/main/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/privacy/methods/priv/PrivGetPrivateTransaction.java index a75a4bdcca..d7ba167f88 100644 --- a/ethereum/jsonrpc/src/main/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/privacy/methods/priv/PrivGetPrivateTransaction.java +++ b/ethereum/jsonrpc/src/main/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/privacy/methods/priv/PrivGetPrivateTransaction.java @@ -62,6 +62,7 @@ public String getName() { @Override public JsonRpcResponse response(final JsonRpcRequest request) { + request.assertMaxLength(1); LOG.trace("Executing {}", RpcMethod.PRIV_GET_PRIVATE_TRANSACTION.getMethodName()); final Hash hash = parameters.required(request.getParams(), 0, Hash.class); diff --git a/ethereum/jsonrpc/src/main/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/privacy/methods/priv/PrivGetTransactionCount.java b/ethereum/jsonrpc/src/main/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/privacy/methods/priv/PrivGetTransactionCount.java index 89216c095e..3fa0772f3b 100644 --- a/ethereum/jsonrpc/src/main/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/privacy/methods/priv/PrivGetTransactionCount.java +++ b/ethereum/jsonrpc/src/main/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/privacy/methods/priv/PrivGetTransactionCount.java @@ -17,8 +17,6 @@ import tech.pegasys.pantheon.ethereum.jsonrpc.internal.JsonRpcRequest; import tech.pegasys.pantheon.ethereum.jsonrpc.internal.methods.JsonRpcMethod; import tech.pegasys.pantheon.ethereum.jsonrpc.internal.parameters.JsonRpcParameter; -import tech.pegasys.pantheon.ethereum.jsonrpc.internal.response.JsonRpcError; -import tech.pegasys.pantheon.ethereum.jsonrpc.internal.response.JsonRpcErrorResponse; import tech.pegasys.pantheon.ethereum.jsonrpc.internal.response.JsonRpcResponse; import tech.pegasys.pantheon.ethereum.jsonrpc.internal.response.JsonRpcSuccessResponse; import tech.pegasys.pantheon.ethereum.jsonrpc.internal.results.Quantity; @@ -43,9 +41,7 @@ public String getName() { @Override public JsonRpcResponse response(final JsonRpcRequest request) { - if (request.getParamLength() != 2) { - return new JsonRpcErrorResponse(request.getId(), JsonRpcError.INVALID_PARAMS); - } + request.assertMaxLength(2); final Address address = parameters.required(request.getParams(), 0, Address.class); final String privacyGroupId = parameters.required(request.getParams(), 1, String.class); diff --git a/ethereum/jsonrpc/src/test/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/methods/privacy/eea/EeaGetTransactionCountTest.java b/ethereum/jsonrpc/src/test/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/methods/privacy/eea/EeaGetTransactionCountTest.java index 1e60cb8eb6..31b37dd369 100644 --- a/ethereum/jsonrpc/src/test/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/methods/privacy/eea/EeaGetTransactionCountTest.java +++ b/ethereum/jsonrpc/src/test/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/methods/privacy/eea/EeaGetTransactionCountTest.java @@ -13,6 +13,7 @@ package tech.pegasys.pantheon.ethereum.jsonrpc.internal.methods.privacy.eea; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -91,4 +92,19 @@ public void nonceProviderThrowsAnExceptionProducesErrorResponse() { assertThat(errorResponse.getError()) .isEqualTo(JsonRpcError.GET_PRIVATE_TRANSACTION_NONCE_ERROR); } + + @Test + public void tooManyParamsThrowsAnException() { + final long reportedNonce = 8L; + final EeaGetTransactionCount method = + new EeaGetTransactionCount(new JsonRpcParameter(), nonceProvider); + + when(nonceProvider.determineNonce(privateFrom, privateFor, address)).thenReturn(reportedNonce); + + final Object[] jsonBody = new Object[] {address.toString(), privateFrom, privateFor, "tooMany"}; + final JsonRpcRequest tooManyParamsReq = + new JsonRpcRequest("2.0", "eea_getTransactionCount", jsonBody); + assertThatExceptionOfType(RuntimeException.class) + .isThrownBy(() -> method.response(tooManyParamsReq)); + } } diff --git a/ethereum/jsonrpc/src/test/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/privacy/methods/eea/EeaGetTransactionReceiptTest.java b/ethereum/jsonrpc/src/test/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/privacy/methods/eea/EeaGetTransactionReceiptTest.java index c8049ab5ca..e429b11052 100644 --- a/ethereum/jsonrpc/src/test/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/privacy/methods/eea/EeaGetTransactionReceiptTest.java +++ b/ethereum/jsonrpc/src/test/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/privacy/methods/eea/EeaGetTransactionReceiptTest.java @@ -13,6 +13,7 @@ package tech.pegasys.pantheon.ethereum.jsonrpc.internal.privacy.methods.eea; import static java.nio.charset.StandardCharsets.UTF_8; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; import static org.junit.Assert.assertEquals; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.nullable; @@ -184,4 +185,61 @@ public void createsPrivateTransactionReceipt() throws Exception { assertEquals("0x0bac79b78b9866ef11c989ad21a7fcf15f7a18d7", result.getContractAddress()); } + + @Test + public void tooManyParamsThrowsException() { + final BytesValue mockBytesValue = mock(BytesValue.class); + final Block chainBlock = mock(Block.class); + final long mockLong = 10; + final BlockBody blockBody = mock(BlockBody.class); + final Transaction mockTx = mock(Transaction.class); + final BlockHeader mockBlockHeader = mock(BlockHeader.class); + + final Log mockLog = mock(Log.class); + final Address mockAddress = mock(Address.class); + when(mockLog.getLogger()).thenReturn(mockAddress); + final LogTopic mockLogTopic = mock(LogTopic.class); + final List listLogTopic = Arrays.asList(mockLogTopic); + when(mockLog.getTopics()).thenReturn(listLogTopic); + when(mockLog.getData()).thenReturn(mockBytesValue); + final List mockLogList = Arrays.asList(mockLog); + final PrivateTransactionStorage privateTransactionStorage = + mock(PrivateTransactionStorage.class); + final List mockListTx = Arrays.asList(mockTx, transaction); + final TransactionLocation transactionLocation = new TransactionLocation(mockBlockHash, 1); + + doReturn(privateTransactionStorage).when(privacyParameters).getPrivateTransactionStorage(); + when(privateTransactionStorage.getEvents(any(Bytes32.class))) + .thenReturn(Optional.of(mockLogList)); + when(privateTransactionStorage.getOutput(any(Bytes32.class))) + .thenReturn(Optional.of(mockBytesValue)); + + final EeaGetTransactionReceipt eeaGetTransactionReceipt = + new EeaGetTransactionReceipt(blockchainQueries, enclave, parameters, privacyParameters); + final Object[] params = new Object[] {transaction.hash(), "tooManyParams"}; + final JsonRpcRequest tooManyParamsReq = + new JsonRpcRequest("1", "eea_getTransactionReceipt", params); + + when(blockchainQueries.getBlockchain()).thenReturn(blockchain); + when(blockchain.getTransactionByHash(transaction.hash())).thenReturn(Optional.of(transaction)); + when(blockchain.getTransactionLocation(nullable(Hash.class))) + .thenReturn(Optional.of(transactionLocation)); + final BytesValueRLPOutput bvrlp = new BytesValueRLPOutput(); + privateTransaction.writeTo(bvrlp); + when(enclave.receive(any(ReceiveRequest.class))) + .thenReturn( + new ReceiveResponse( + Base64.getEncoder().encodeToString(bvrlp.encoded().extractArray()).getBytes(UTF_8), + "")); + + when(blockchain.getChainHeadBlock()).thenReturn(chainBlock); + when(chainBlock.getHash()).thenReturn(mockTransactionHash); + when(blockchainQueries.getBlockchain().getChainHeadBlockNumber()).thenReturn(mockLong); + when(blockBody.getTransactions()).thenReturn(mockListTx); + when(blockchain.getBlockHeader(mockBlockHash)).thenReturn(Optional.of(mockBlockHeader)); + when(mockBlockHeader.getHash()).thenReturn(mockTransactionHash); + when(blockchain.getBlockBody(mockBlockHash)).thenReturn(Optional.of(blockBody)); + assertThatExceptionOfType(RuntimeException.class) + .isThrownBy(() -> eeaGetTransactionReceipt.response(tooManyParamsReq)); + } } diff --git a/ethereum/jsonrpc/src/test/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/privacy/methods/eea/EeaSendRawTransactionTest.java b/ethereum/jsonrpc/src/test/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/privacy/methods/eea/EeaSendRawTransactionTest.java index bd788ef5f0..62de350574 100644 --- a/ethereum/jsonrpc/src/test/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/privacy/methods/eea/EeaSendRawTransactionTest.java +++ b/ethereum/jsonrpc/src/test/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/privacy/methods/eea/EeaSendRawTransactionTest.java @@ -13,6 +13,7 @@ package tech.pegasys.pantheon.ethereum.jsonrpc.internal.privacy.methods.eea; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.Mockito.verify; @@ -125,24 +126,14 @@ public void requestIsMissingParameter() { final JsonRpcRequest request = new JsonRpcRequest("2.0", "eea_sendRawTransaction", new String[] {}); - final JsonRpcResponse expectedResponse = - new JsonRpcErrorResponse(request.getId(), JsonRpcError.INVALID_PARAMS); - - final JsonRpcResponse actualResponse = method.response(request); - - assertThat(actualResponse).isEqualToComparingFieldByField(expectedResponse); + assertThatExceptionOfType(RuntimeException.class).isThrownBy(() -> method.response(request)); } @Test public void requestHasNullObjectParameter() { final JsonRpcRequest request = new JsonRpcRequest("2.0", "eea_sendRawTransaction", null); - final JsonRpcResponse expectedResponse = - new JsonRpcErrorResponse(request.getId(), JsonRpcError.INVALID_PARAMS); - - final JsonRpcResponse actualResponse = method.response(request); - - assertThat(actualResponse).isEqualToComparingFieldByField(expectedResponse); + assertThatExceptionOfType(RuntimeException.class).isThrownBy(() -> method.response(request)); } @Test @@ -150,12 +141,7 @@ public void requestHasNullArrayParameter() { final JsonRpcRequest request = new JsonRpcRequest("2.0", "eea_sendRawTransaction", new String[] {null}); - final JsonRpcResponse expectedResponse = - new JsonRpcErrorResponse(request.getId(), JsonRpcError.INVALID_PARAMS); - - final JsonRpcResponse actualResponse = method.response(request); - - assertThat(actualResponse).isEqualToComparingFieldByField(expectedResponse); + assertThatExceptionOfType(RuntimeException.class).isThrownBy(() -> method.response(request)); } @Test @@ -386,4 +372,16 @@ private void verifyErrorForInvalidTransaction( public void getMethodReturnsExpectedName() { assertThat(method.getName()).matches("eea_sendRawTransaction"); } + + @Test + public void tooManyParamsThrowsException() { + + final Object[] params = new Object[] {VALID_PRIVATE_TRANSACTION_RLP, "tooManyParams"}; + + final JsonRpcRequest tooManyParamsReq = + new JsonRpcRequest("2.0", "eea_sendRawTransaction", params); + + assertThatExceptionOfType(RuntimeException.class) + .isThrownBy(() -> method.response(tooManyParamsReq)); + } } diff --git a/ethereum/jsonrpc/src/test/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/privacy/methods/priv/PrivCreatePrivacyGroupTest.java b/ethereum/jsonrpc/src/test/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/privacy/methods/priv/PrivCreatePrivacyGroupTest.java index 1d8e4ca489..e31e646221 100644 --- a/ethereum/jsonrpc/src/test/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/privacy/methods/priv/PrivCreatePrivacyGroupTest.java +++ b/ethereum/jsonrpc/src/test/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/privacy/methods/priv/PrivCreatePrivacyGroupTest.java @@ -13,6 +13,7 @@ package tech.pegasys.pantheon.ethereum.jsonrpc.internal.privacy.methods.priv; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; import static org.assertj.core.api.Assertions.catchThrowableOfType; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.mock; @@ -246,4 +247,20 @@ public void returnsCorrectErrorEnclaveError() { assertThat(result).isEqualTo(JsonRpcError.CREATE_PRIVACY_GROUP_ERROR); } + + @Test + public void tooManyParamsThrowsException() { + + final PrivCreatePrivacyGroup privCreatePrivacyGroup = + new PrivCreatePrivacyGroup(enclave, privacyParameters, parameters); + + final CreatePrivacyGroupParameter param = + new CreatePrivacyGroupParameter(ADDRESSES, NAME, DESCRIPTION); + final Object[] params = new Object[] {param, "tooManyParams"}; + + final JsonRpcRequest tooManyParamsReq = + new JsonRpcRequest("1", "priv_createPrivacyGroup", params); + assertThatExceptionOfType(RuntimeException.class) + .isThrownBy(() -> privCreatePrivacyGroup.response(tooManyParamsReq)); + } } diff --git a/ethereum/jsonrpc/src/test/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/privacy/methods/priv/PrivGetPrivacyPrecompileAddressTest.java b/ethereum/jsonrpc/src/test/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/privacy/methods/priv/PrivGetPrivacyPrecompileAddressTest.java index 3e26269f29..69722671f6 100644 --- a/ethereum/jsonrpc/src/test/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/privacy/methods/priv/PrivGetPrivacyPrecompileAddressTest.java +++ b/ethereum/jsonrpc/src/test/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/privacy/methods/priv/PrivGetPrivacyPrecompileAddressTest.java @@ -12,6 +12,7 @@ */ package tech.pegasys.pantheon.ethereum.jsonrpc.internal.privacy.methods.priv; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; import static org.junit.Assert.assertEquals; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -66,4 +67,21 @@ public void verifyErrorPrivacyDisabled() { assertEquals(JsonRpcResponseType.ERROR, response.getType()); assertEquals(JsonRpcError.PRIVACY_NOT_ENABLED, ((JsonRpcErrorResponse) response).getError()); } + + @Test + public void tooManyParamsThrowsException() { + when(privacyParameters.getPrivacyAddress()).thenReturn(rawPrivacyAddress); + when(privacyParameters.isEnabled()).thenReturn(true); + + final PrivGetPrivacyPrecompileAddress privGetPrivacyPrecompileAddress = + new PrivGetPrivacyPrecompileAddress(privacyParameters); + + final Object[] params = new Object[] {new Object[0], "tooManyParams"}; + + final JsonRpcRequest tooManyParamsReq = + new JsonRpcRequest("1", "priv_getPrivacyPrecompileAddress", params); + + assertThatExceptionOfType(RuntimeException.class) + .isThrownBy(() -> privGetPrivacyPrecompileAddress.response(tooManyParamsReq)); + } } diff --git a/ethereum/jsonrpc/src/test/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/privacy/methods/priv/PrivGetPrivateTransactionTest.java b/ethereum/jsonrpc/src/test/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/privacy/methods/priv/PrivGetPrivateTransactionTest.java index 7dbcb7aea5..f893e817db 100644 --- a/ethereum/jsonrpc/src/test/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/privacy/methods/priv/PrivGetPrivateTransactionTest.java +++ b/ethereum/jsonrpc/src/test/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/privacy/methods/priv/PrivGetPrivateTransactionTest.java @@ -14,6 +14,7 @@ import static java.nio.charset.StandardCharsets.UTF_8; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -168,4 +169,21 @@ public void returnsPrivateTransactionGroup() throws Exception { assertThat(result).isEqualToComparingFieldByField(privateTransactionGroupResult); } + + @Test + public void tooManyParamsThrowsException() { + when(blockchain.transactionByHash(any(Hash.class))) + .thenReturn(Optional.of(returnedTransaction)); + when(returnedTransaction.getTransaction()).thenReturn(justTransaction); + when(justTransaction.getPayload()).thenReturn(BytesValues.fromBase64("")); + + final PrivGetPrivateTransaction privGetPrivateTransaction = + new PrivGetPrivateTransaction(blockchain, enclave, parameters, privacyParameters); + + final Object[] params = new Object[] {enclaveKey, "tooManyParams"}; + final JsonRpcRequest tooManyParamsReq = + new JsonRpcRequest("1", "priv_getPrivateTransaction", params); + assertThatExceptionOfType(RuntimeException.class) + .isThrownBy(() -> privGetPrivateTransaction.response(tooManyParamsReq)); + } } diff --git a/ethereum/jsonrpc/src/test/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/privacy/methods/priv/PrivGetTransactionCountTest.java b/ethereum/jsonrpc/src/test/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/privacy/methods/priv/PrivGetTransactionCountTest.java index 864fb30c0d..a9cb808a26 100644 --- a/ethereum/jsonrpc/src/test/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/privacy/methods/priv/PrivGetTransactionCountTest.java +++ b/ethereum/jsonrpc/src/test/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/privacy/methods/priv/PrivGetTransactionCountTest.java @@ -13,6 +13,7 @@ package tech.pegasys.pantheon.ethereum.jsonrpc.internal.privacy.methods.priv; import static java.nio.charset.StandardCharsets.UTF_8; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; import static org.junit.Assert.assertEquals; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -54,4 +55,21 @@ public void verifyTransactionCount() { assertEquals(String.format("0x%X", NONCE), response.getResult()); } + + @Test + public void tooManyParamsThrowsException() { + final PrivateTransactionHandler privateTransactionHandler = + mock(PrivateTransactionHandler.class); + when(privateTransactionHandler.getSenderNonce(senderAddress, privacyGroupId)).thenReturn(NONCE); + + final PrivGetTransactionCount privGetTransactionCount = + new PrivGetTransactionCount(parameters, privateTransactionHandler); + + final Object[] params = new Object[] {senderAddress, privacyGroupId, "tooManyParams"}; + final JsonRpcRequest tooManyParamsReq = + new JsonRpcRequest("1", "priv_getTransactionCount", params); + + assertThatExceptionOfType(RuntimeException.class) + .isThrownBy(() -> privGetTransactionCount.response(tooManyParamsReq)); + } } diff --git a/ethereum/jsonrpc/src/test/resources/tech/pegasys/pantheon/ethereum/jsonrpc/eth/eth_getUncleCountByBlockNumber_tooManyParams.json b/ethereum/jsonrpc/src/test/resources/tech/pegasys/pantheon/ethereum/jsonrpc/eth/eth_getUncleCountByBlockNumber_tooManyParams.json new file mode 100644 index 0000000000..cd0dbc7301 --- /dev/null +++ b/ethereum/jsonrpc/src/test/resources/tech/pegasys/pantheon/ethereum/jsonrpc/eth/eth_getUncleCountByBlockNumber_tooManyParams.json @@ -0,0 +1,20 @@ +{ + "request": { + "id": 42, + "jsonrpc": "2.0", + "method": "eth_getUncleCountByBlockNumber", + "params": [ + "0xe8", + "0xe8" + ] + }, + "response": { + "jsonrpc": "2.0", + "id": 42, + "error": { + "code": -32602, + "message": "Invalid params" + } + }, + "statusCode": 400 +}