diff --git a/consensus/clique/src/test/java/tech/pegasys/pantheon/consensus/clique/jsonrpc/methods/CliqueGetSignerMetricsTest.java b/consensus/clique/src/test/java/tech/pegasys/pantheon/consensus/clique/jsonrpc/methods/CliqueGetSignerMetricsTest.java index 8463f70f53..c7344881ea 100644 --- a/consensus/clique/src/test/java/tech/pegasys/pantheon/consensus/clique/jsonrpc/methods/CliqueGetSignerMetricsTest.java +++ b/consensus/clique/src/test/java/tech/pegasys/pantheon/consensus/clique/jsonrpc/methods/CliqueGetSignerMetricsTest.java @@ -13,7 +13,10 @@ package tech.pegasys.pantheon.consensus.clique.jsonrpc.methods; import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.AdditionalMatchers.lt; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import tech.pegasys.pantheon.consensus.common.BlockInterface; @@ -141,6 +144,30 @@ public void getSignerMetrics() { .containsExactlyInAnyOrderElementsOf(signerMetricResultList); } + @Test + @SuppressWarnings("unchecked") + public void getSignerMetricsWhenThereAreFewerBlocksThanTheDefaultRange() { + final long startBlock = 0L; + final long headBlock = 2L; + + final List signerMetricResultList = new ArrayList<>(); + + when(blockchainQueries.headBlockNumber()).thenReturn(headBlock); + + LongStream.range(startBlock, headBlock) + .forEach(value -> signerMetricResultList.add(generateBlock(value))); + + final JsonRpcRequest request = requestWithParams(); + + final JsonRpcSuccessResponse response = (JsonRpcSuccessResponse) method.response(request); + + // verify getBlockHeaderByNumber is not called with negative values + verify(blockchainQueries, never()).getBlockHeaderByNumber(lt(0L)); + + assertThat((Collection) response.getResult()) + .containsExactlyInAnyOrderElementsOf(signerMetricResultList); + } + @Test @SuppressWarnings("unchecked") public void getSignerMetricsWithLatest() { diff --git a/consensus/common/src/main/java/tech/pegasys/pantheon/consensus/common/jsonrpc/AbstractGetSignerMetricsMethod.java b/consensus/common/src/main/java/tech/pegasys/pantheon/consensus/common/jsonrpc/AbstractGetSignerMetricsMethod.java index e80a6ca173..c65eafeaed 100644 --- a/consensus/common/src/main/java/tech/pegasys/pantheon/consensus/common/jsonrpc/AbstractGetSignerMetricsMethod.java +++ b/consensus/common/src/main/java/tech/pegasys/pantheon/consensus/common/jsonrpc/AbstractGetSignerMetricsMethod.java @@ -101,7 +101,7 @@ public JsonRpcResponse response(final JsonRpcRequest request) { private long getFromBlockNumber(final Optional startBlockParameter) { return startBlockParameter .map(this::resolveBlockNumber) - .orElseGet(() -> blockchainQueries.headBlockNumber() - DEFAULT_RANGE_BLOCK); + .orElseGet(() -> Math.max(0, blockchainQueries.headBlockNumber() - DEFAULT_RANGE_BLOCK)); } private long getEndBlockNumber(final Optional endBlockParameter) { diff --git a/consensus/ibft/src/test/java/tech/pegasys/pantheon/consensus/ibft/jsonrpc/methods/IbftGetSignerMetricsTest.java b/consensus/ibft/src/test/java/tech/pegasys/pantheon/consensus/ibft/jsonrpc/methods/IbftGetSignerMetricsTest.java index 212fcdff1c..8f13200b44 100644 --- a/consensus/ibft/src/test/java/tech/pegasys/pantheon/consensus/ibft/jsonrpc/methods/IbftGetSignerMetricsTest.java +++ b/consensus/ibft/src/test/java/tech/pegasys/pantheon/consensus/ibft/jsonrpc/methods/IbftGetSignerMetricsTest.java @@ -13,7 +13,10 @@ package tech.pegasys.pantheon.consensus.ibft.jsonrpc.methods; import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.AdditionalMatchers.lt; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import tech.pegasys.pantheon.consensus.common.BlockInterface; @@ -141,6 +144,30 @@ public void getSignerMetrics() { .containsExactlyInAnyOrderElementsOf(signerMetricResultList); } + @Test + @SuppressWarnings("unchecked") + public void getSignerMetricsWhenThereAreFewerBlocksThanTheDefaultRange() { + final long startBlock = 0L; + final long headBlock = 2L; + + final List signerMetricResultList = new ArrayList<>(); + + when(blockchainQueries.headBlockNumber()).thenReturn(headBlock); + + LongStream.range(startBlock, headBlock) + .forEach(value -> signerMetricResultList.add(generateBlock(value))); + + final JsonRpcRequest request = requestWithParams(); + + final JsonRpcSuccessResponse response = (JsonRpcSuccessResponse) method.response(request); + + // verify getBlockHeaderByNumber is not called with negative values + verify(blockchainQueries, never()).getBlockHeaderByNumber(lt(0L)); + + assertThat((Collection) response.getResult()) + .containsExactlyInAnyOrderElementsOf(signerMetricResultList); + } + @Test @SuppressWarnings("unchecked") public void getSignerMetricsWithLatest() {