From 6deca4b2be2acba72440470f91ec374274cf8c83 Mon Sep 17 00:00:00 2001 From: tau3 Date: Thu, 16 Apr 2020 15:46:17 +0000 Subject: [PATCH] [Bugfix] NPE in JsonRpc2_0Rx (#1183) * fix NPE in JsonRpc2_0Rx#replayBlocksFlowableSync; refactor Collection class * refactor JsonRpc2_0Rx#replayBlocksFlowableSync and Collection#join * rename unit test * run spotless on sources * rename parameter after code review --- .../org/web3j/protocol/rx/JsonRpc2_0Rx.java | 33 ++++++------------- .../main/java/org/web3j/utils/Collection.java | 26 ++------------- .../web3j/protocol/rx/JsonRpc2_0RxTest.java | 25 ++++++++++++++ .../java/org/web3j/utils/CollectionTest.java | 10 ------ 4 files changed, 38 insertions(+), 56 deletions(-) diff --git a/core/src/main/java/org/web3j/protocol/rx/JsonRpc2_0Rx.java b/core/src/main/java/org/web3j/protocol/rx/JsonRpc2_0Rx.java index dd6570d5d..5fed2cebd 100644 --- a/core/src/main/java/org/web3j/protocol/rx/JsonRpc2_0Rx.java +++ b/core/src/main/java/org/web3j/protocol/rx/JsonRpc2_0Rx.java @@ -28,6 +28,7 @@ import org.web3j.protocol.core.DefaultBlockParameter; import org.web3j.protocol.core.DefaultBlockParameterName; import org.web3j.protocol.core.DefaultBlockParameterNumber; +import org.web3j.protocol.core.Request; import org.web3j.protocol.core.filters.BlockFilter; import org.web3j.protocol.core.filters.LogFilter; import org.web3j.protocol.core.filters.PendingTransactionFilter; @@ -138,35 +139,21 @@ private Flowable replayBlocksFlowableSync( private Flowable replayBlocksFlowableSync( DefaultBlockParameter startBlock, DefaultBlockParameter endBlock, - boolean fullTransactionObjects, - boolean ascending) { - - BigInteger startBlockNumber = null; - BigInteger endBlockNumber = null; + boolean containsFullTransactionObjects, + boolean isAscending) { + BigInteger startBlockNumber; + BigInteger endBlockNumber; try { startBlockNumber = getBlockNumber(startBlock); endBlockNumber = getBlockNumber(endBlock); } catch (IOException e) { - Flowable.error(e); + return Flowable.error(e); } - if (ascending) { - return Flowables.range(startBlockNumber, endBlockNumber) - .flatMap( - i -> - web3j.ethGetBlockByNumber( - new DefaultBlockParameterNumber(i), - fullTransactionObjects) - .flowable()); - } else { - return Flowables.range(startBlockNumber, endBlockNumber, false) - .flatMap( - i -> - web3j.ethGetBlockByNumber( - new DefaultBlockParameterNumber(i), - fullTransactionObjects) - .flowable()); - } + return Flowables.range(startBlockNumber, endBlockNumber, isAscending) + .map(DefaultBlockParameterNumber::new) + .map(number -> web3j.ethGetBlockByNumber(number, containsFullTransactionObjects)) + .flatMap(Request::flowable); } public Flowable replayTransactionsFlowable( diff --git a/core/src/main/java/org/web3j/utils/Collection.java b/core/src/main/java/org/web3j/utils/Collection.java index 3dce78f2b..081282b6a 100644 --- a/core/src/main/java/org/web3j/utils/Collection.java +++ b/core/src/main/java/org/web3j/utils/Collection.java @@ -14,6 +14,8 @@ import java.util.Arrays; import java.util.List; +import java.util.function.Function; +import java.util.stream.Collectors; /** Utility functions for working with Collections. */ public class Collection { @@ -36,28 +38,6 @@ public static T[] create(T... args) { } public static String join(List list, String separator, Function function) { - String result = ""; - for (int i = 0; i < list.size(); i++) { - result += function.apply(list.get(i)).trim(); - if (i + 1 < list.size()) { - result += separator; - } - } - return result; - } - - public static String join(List list, String separator) { - String result = ""; - for (int i = 0; i < list.size(); i++) { - result += list.get(i).trim(); - if (i + 1 < list.size()) { - result += separator; - } - } - return result; - } - - public interface Function { - S apply(R r); + return list.stream().map(function).map(String::trim).collect(Collectors.joining(separator)); } } diff --git a/core/src/test/java/org/web3j/protocol/rx/JsonRpc2_0RxTest.java b/core/src/test/java/org/web3j/protocol/rx/JsonRpc2_0RxTest.java index b9b5f96f6..504079039 100644 --- a/core/src/test/java/org/web3j/protocol/rx/JsonRpc2_0RxTest.java +++ b/core/src/test/java/org/web3j/protocol/rx/JsonRpc2_0RxTest.java @@ -12,6 +12,7 @@ */ package org.web3j.protocol.rx; +import java.io.IOException; import java.math.BigInteger; import java.util.ArrayList; import java.util.Arrays; @@ -31,6 +32,7 @@ import org.web3j.protocol.ObjectMapperFactory; import org.web3j.protocol.Web3j; import org.web3j.protocol.Web3jService; +import org.web3j.protocol.core.DefaultBlockParameter; import org.web3j.protocol.core.DefaultBlockParameterNumber; import org.web3j.protocol.core.Request; import org.web3j.protocol.core.methods.response.EthBlock; @@ -41,10 +43,13 @@ import org.web3j.utils.Numeric; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertSame; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.fail; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.RETURNS_DEEP_STUBS; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -386,4 +391,24 @@ private Transaction createTransaction(String transactionHash) { transaction.setHash(transactionHash); return transaction; } + + @Test + void testReplayBlocksFlowableWhenIOExceptionOnBlockResolving() throws IOException { + Web3j web3j = mock(Web3j.class, RETURNS_DEEP_STUBS); + when(web3j.ethGetBlockByNumber(any(), anyBoolean()).send()) + .thenThrow(new IOException("fail")); + + JsonRpc2_0Rx rpc = new JsonRpc2_0Rx(web3j, Executors.newSingleThreadScheduledExecutor()); + + Flowable flowable = + rpc.replayBlocksFlowable( + mock(DefaultBlockParameter.class), + mock(DefaultBlockParameter.class), + false, + false); + EthBlock expected = mock(EthBlock.class); + EthBlock actual = flowable.onErrorReturnItem(expected).blockingFirst(); + + assertSame(expected, actual, "unexpected returned block"); + } } diff --git a/core/src/test/java/org/web3j/utils/CollectionTest.java b/core/src/test/java/org/web3j/utils/CollectionTest.java index 325817eff..e25d21474 100644 --- a/core/src/test/java/org/web3j/utils/CollectionTest.java +++ b/core/src/test/java/org/web3j/utils/CollectionTest.java @@ -20,7 +20,6 @@ import static org.junit.jupiter.api.Assertions.assertArrayEquals; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.web3j.utils.Collection.EMPTY_STRING_ARRAY; -import static org.web3j.utils.Collection.Function; import static org.web3j.utils.Collection.create; import static org.web3j.utils.Collection.join; import static org.web3j.utils.Collection.tail; @@ -41,14 +40,6 @@ public void testCreate() { assertArrayEquals(create("a", "b"), (new String[] {"a", "b"})); } - @Test - public void testJoin() { - assertEquals(join(Arrays.asList("a ", "b ", " c "), ","), ("a,b,c")); - assertEquals(join(Arrays.asList("a", "b", "c", "d"), ","), ("a,b,c,d")); - assertEquals(join(Arrays.asList("a ", "b ", " c "), ", "), ("a, b, c")); - assertEquals(join(Arrays.asList("a", "b", "c", "d"), ", "), ("a, b, c, d")); - } - @Test public void testJoinWithFunction() { final List specs1 = @@ -68,7 +59,6 @@ public void testJoinWithFunction() { assertEquals(join(specs4, ", ", FakeSpec::getName), ("a, b, c")); } - /** Fake object to test {@link Collection#join(List, String, Function)}. */ private final class FakeSpec { private final String name;