solution: use reactor-based rpc client

This commit is contained in:
Igor Artamonov
2019-10-11 22:54:12 -04:00
parent fd95aa4868
commit 77685c314a
16 changed files with 131 additions and 121 deletions

View File

@@ -26,7 +26,7 @@ import io.emeraldpay.dshackle.upstream.Selector
import io.emeraldpay.dshackle.upstream.Upstream
import io.emeraldpay.dshackle.upstream.Upstreams
import io.emeraldpay.grpc.Chain
import io.infinitape.etherjar.rpc.RpcClient
import io.infinitape.etherjar.rpc.ReactorRpcClient
import reactor.core.publisher.Mono
import reactor.test.StepVerifier
import spock.lang.Specification
@@ -42,7 +42,7 @@ class NativeCallSpec extends Specification {
setup:
def quorum = Spy(new AlwaysQuorum())
def upstreams = Stub(Upstreams)
RpcClient rpcClient = Stub(RpcClient)
ReactorRpcClient rpcClient = Stub(ReactorRpcClient)
def apiMock = TestingCommons.api(rpcClient)
apiMock.upstream = Stub(Upstream)
@@ -67,7 +67,7 @@ class NativeCallSpec extends Specification {
def quorum = Spy(new NonEmptyQuorum(TestingCommons.rpcConverter(), 3))
def upstreams = Stub(Upstreams)
RpcClient rpcClient = Stub(RpcClient)
ReactorRpcClient rpcClient = Stub(ReactorRpcClient)
def apiMock = TestingCommons.api(rpcClient)
apiMock.upstream = Stub(Upstream)
@@ -95,7 +95,7 @@ class NativeCallSpec extends Specification {
def quorum = Spy(new NonEmptyQuorum(TestingCommons.rpcConverter(), 3))
def upstreams = Stub(Upstreams)
RpcClient rpcClient = Stub(RpcClient)
ReactorRpcClient rpcClient = Stub(ReactorRpcClient)
def apiMock = TestingCommons.api(rpcClient)
apiMock.upstream = Stub(Upstream)
@@ -121,7 +121,7 @@ class NativeCallSpec extends Specification {
def quorum = Spy(new NonEmptyQuorum(TestingCommons.rpcConverter(), 3))
def upstreams = Stub(Upstreams)
RpcClient rpcClient = Stub(RpcClient)
ReactorRpcClient rpcClient = Stub(ReactorRpcClient)
def apiMock = TestingCommons.api(rpcClient)
apiMock.upstream = Stub(Upstream)
@@ -146,7 +146,7 @@ class NativeCallSpec extends Specification {
def quorum = Spy(new NonEmptyQuorum(TestingCommons.rpcConverter(), 3))
def upstreams = Stub(Upstreams)
RpcClient rpcClient = Stub(RpcClient)
ReactorRpcClient rpcClient = Stub(ReactorRpcClient)
def apiMock = TestingCommons.api(rpcClient)
apiMock.upstream = Stub(Upstream)
@@ -307,7 +307,7 @@ class NativeCallSpec extends Specification {
def quorum = Spy(new AlwaysQuorum())
def upstreams = Stub(Upstreams)
RpcClient rpcClient = Stub(RpcClient)
ReactorRpcClient rpcClient = Stub(ReactorRpcClient)
def apiMock = TestingCommons.api(rpcClient)
apiMock.upstream = Stub(Upstream)

View File

@@ -23,7 +23,7 @@ import io.emeraldpay.dshackle.upstream.Upstreams
import io.emeraldpay.grpc.Chain
import io.infinitape.etherjar.domain.Address
import io.infinitape.etherjar.domain.BlockHash
import io.infinitape.etherjar.rpc.RpcClient
import io.infinitape.etherjar.rpc.ReactorRpcClient
import io.infinitape.etherjar.rpc.json.BlockJson
import reactor.core.publisher.Mono
import reactor.core.publisher.TopicProcessor
@@ -56,7 +56,7 @@ class TrackAddressSpec extends Specification {
.setBalance("1234567890")
.build()
def apiMock = TestingCommons.api(Stub(RpcClient))
def apiMock = TestingCommons.api(Stub(ReactorRpcClient))
def upstreamMock = TestingCommons.upstream(apiMock)
Upstreams upstreams = new UpstreamsMock(Chain.ETHEREUM, upstreamMock)
TrackAddress trackAddress = new TrackAddress(upstreams, Schedulers.immediate())
@@ -98,7 +98,7 @@ class TrackAddressSpec extends Specification {
}
def blocksBus = TopicProcessor.create()
def apiMock = TestingCommons.api(Stub(RpcClient))
def apiMock = TestingCommons.api(Stub(ReactorRpcClient))
def upstreamMock = TestingCommons.upstream(apiMock)
Upstreams upstreams = new UpstreamsMock(Chain.ETHEREUM, upstreamMock)
TrackAddress trackAddress = new TrackAddress(upstreams, Schedulers.immediate())

View File

@@ -24,7 +24,7 @@ import io.emeraldpay.dshackle.upstream.Upstreams
import io.emeraldpay.grpc.Chain
import io.infinitape.etherjar.domain.BlockHash
import io.infinitape.etherjar.domain.TransactionId
import io.infinitape.etherjar.rpc.RpcClient
import io.infinitape.etherjar.rpc.ReactorRpcClient
import io.infinitape.etherjar.rpc.json.BlockJson
import io.infinitape.etherjar.rpc.json.TransactionJson
import reactor.core.publisher.Mono
@@ -87,7 +87,7 @@ class TrackTxSpec extends Specification {
.setTimestamp(blockJson.timestamp.getTime())
).build()
def apiMock = TestingCommons.api(Stub(RpcClient))
def apiMock = TestingCommons.api(Stub(ReactorRpcClient))
def upstreamMock = TestingCommons.upstream(apiMock)
Upstreams upstreams = new UpstreamsMock(Chain.ETHEREUM, upstreamMock)
TrackTx trackTx = new TrackTx(upstreams, Schedulers.immediate())
@@ -119,7 +119,7 @@ class TrackTxSpec extends Specification {
.setMined(false)
.build()
def apiMock = TestingCommons.api(Stub(RpcClient))
def apiMock = TestingCommons.api(Stub(ReactorRpcClient))
def upstreamMock = TestingCommons.upstream(apiMock)
Upstreams upstreams = new UpstreamsMock(Chain.ETHEREUM, upstreamMock)
TrackTx trackTx = new TrackTx(upstreams, Schedulers.immediate())
@@ -176,7 +176,7 @@ class TrackTxSpec extends Specification {
it
}
def apiMock = TestingCommons.api(Stub(RpcClient))
def apiMock = TestingCommons.api(Stub(ReactorRpcClient))
def upstreamMock = TestingCommons.upstream(apiMock)
Upstreams upstreams = new UpstreamsMock(Chain.ETHEREUM, upstreamMock)
TrackTx trackTx = new TrackTx(upstreams, Schedulers.immediate())
@@ -275,7 +275,7 @@ class TrackTxSpec extends Specification {
)
def apiMock = TestingCommons.api(Stub(RpcClient))
def apiMock = TestingCommons.api(Stub(ReactorRpcClient))
def upstreamMock = TestingCommons.upstream(apiMock)
Upstreams upstreams = new UpstreamsMock(Chain.ETHEREUM, upstreamMock)
TrackTx trackTx = new TrackTx(upstreams, Schedulers.immediate())
@@ -316,7 +316,7 @@ class TrackTxSpec extends Specification {
def "Tracked after first load"() {
setup:
def apiMock = TestingCommons.api(Stub(RpcClient))
def apiMock = TestingCommons.api(Stub(ReactorRpcClient))
def upstreamMock = TestingCommons.upstream(apiMock)
Upstreams upstreams = new UpstreamsMock(Chain.ETHEREUM, upstreamMock)
TrackTx trackTx = new TrackTx(upstreams, Schedulers.immediate())
@@ -337,7 +337,7 @@ class TrackTxSpec extends Specification {
def "Update of last notified keeps everything else"() {
setup:
def apiMock = TestingCommons.api(Stub(RpcClient))
def apiMock = TestingCommons.api(Stub(ReactorRpcClient))
def upstreamMock = TestingCommons.upstream(apiMock)
Upstreams upstreams = new UpstreamsMock(Chain.ETHEREUM, upstreamMock)
TrackTx trackTx = new TrackTx(upstreams, Schedulers.immediate())

View File

@@ -22,6 +22,7 @@ import io.emeraldpay.dshackle.upstream.DirectCallMethods
import io.emeraldpay.dshackle.upstream.ethereum.DirectEthereumApi
import io.emeraldpay.grpc.Chain
import io.grpc.stub.StreamObserver
import io.infinitape.etherjar.rpc.ReactorRpcClient
import io.infinitape.etherjar.rpc.RpcClient
import io.infinitape.etherjar.rpc.RpcResponseError
import io.infinitape.etherjar.rpc.json.ResponseJson
@@ -36,7 +37,7 @@ class EthereumApiMock extends DirectEthereumApi {
List<PredefinedResponse> predefined = []
private ObjectMapper objectMapper
EthereumApiMock(@NotNull RpcClient rpcClient, @NotNull ObjectMapper objectMapper, @NotNull Chain chain) {
EthereumApiMock(@NotNull ReactorRpcClient rpcClient, @NotNull ObjectMapper objectMapper, @NotNull Chain chain) {
super(rpcClient, objectMapper, new DirectCallMethods())
this.objectMapper = objectMapper
}

View File

@@ -16,14 +16,14 @@
package io.emeraldpay.dshackle.test
import com.fasterxml.jackson.databind.ObjectMapper
import io.emeraldpay.dshackle.upstream.CallMethods
import io.emeraldpay.dshackle.upstream.DirectCallMethods
import io.emeraldpay.dshackle.upstream.ethereum.DirectEthereumApi
import io.infinitape.etherjar.rpc.Batch
import io.infinitape.etherjar.rpc.ExecutableBatch
import io.infinitape.etherjar.rpc.ReactorBatch
import io.infinitape.etherjar.rpc.ReactorRpcClient
import io.infinitape.etherjar.rpc.RpcCall
import io.infinitape.etherjar.rpc.RpcClient
import io.infinitape.etherjar.rpc.transport.BatchStatus
import io.infinitape.etherjar.rpc.RpcCallResponse
import reactor.core.publisher.Flux
import reactor.core.publisher.Mono
import java.util.concurrent.CompletableFuture
@@ -31,7 +31,7 @@ class EthereumApiStub extends DirectEthereumApi {
private String id
private static ObjectMapper objectMapper = TestingCommons.objectMapper()
private static RpcClient rpcClient = new RpcClientMock();
private static ReactorRpcClient rpcClient = new RpcClientMock();
EthereumApiStub(Integer id) {
this(id.toString())
@@ -47,30 +47,16 @@ class EthereumApiStub extends DirectEthereumApi {
return "API Stub $id"
}
static class RpcClientMock implements RpcClient {
static class RpcClientMock implements ReactorRpcClient {
@Override
CompletableFuture<BatchStatus> execute(Batch batch) {
return null
Flux<RpcCallResponse> execute(ReactorBatch batch) {
return Flux.error(new Exception("Not implemented in mock"))
}
@Override
def <RES> CompletableFuture<RES> execute(RpcCall<?, RES> call) {
return null
}
@Override
ExecutableBatch batch() {
return null
}
@Override
EthCommands eth() {
return null
}
@Override
TraceCommands trace() {
return null
def <JS, RES> Mono<RES> execute(RpcCall<JS, RES> call) {
return Mono.error(new Exception("Not implemented in mock"))
}
}
}

View File

@@ -28,6 +28,7 @@ import io.emeraldpay.dshackle.upstream.ethereum.DirectEthereumApi
import io.emeraldpay.dshackle.upstream.ethereum.EthereumUpstream
import io.emeraldpay.grpc.Chain
import io.infinitape.etherjar.rpc.JacksonRpcConverter
import io.infinitape.etherjar.rpc.ReactorRpcClient
import io.infinitape.etherjar.rpc.RpcClient
import java.text.SimpleDateFormat
@@ -47,7 +48,7 @@ class TestingCommons {
return objectMapper
}
static EthereumApiMock api(RpcClient rpcClient) {
static EthereumApiMock api(ReactorRpcClient rpcClient) {
return new EthereumApiMock(rpcClient, objectMapper(), Chain.ETHEREUM)
}

View File

@@ -2,9 +2,8 @@ package io.emeraldpay.dshackle.upstream
import io.emeraldpay.dshackle.test.EthereumUpstreamMock
import io.emeraldpay.dshackle.test.TestingCommons
import io.emeraldpay.dshackle.upstream.ethereum.EthereumUpstream
import io.emeraldpay.grpc.Chain
import io.infinitape.etherjar.rpc.RpcClient
import io.infinitape.etherjar.rpc.ReactorRpcClient
import spock.lang.Specification
class CurrentUpstreamsSpec extends Specification {
@@ -12,7 +11,7 @@ class CurrentUpstreamsSpec extends Specification {
def "add upstream"() {
setup:
def current = new CurrentUpstreams(TestingCommons.objectMapper())
def up = new EthereumUpstreamMock("test", Chain.ETHEREUM, TestingCommons.api(Stub(RpcClient)))
def up = new EthereumUpstreamMock("test", Chain.ETHEREUM, TestingCommons.api(Stub(ReactorRpcClient)))
when:
current.update(new UpstreamChange(Chain.ETHEREUM, up, UpstreamChange.ChangeType.ADDED))
then:
@@ -23,9 +22,9 @@ class CurrentUpstreamsSpec extends Specification {
def "add multiple upstreams"() {
setup:
def current = new CurrentUpstreams(TestingCommons.objectMapper())
def up1 = new EthereumUpstreamMock("test1", Chain.ETHEREUM, TestingCommons.api(Stub(RpcClient)))
def up2 = new EthereumUpstreamMock("test2", Chain.ETHEREUM_CLASSIC, TestingCommons.api(Stub(RpcClient)))
def up3 = new EthereumUpstreamMock("test3", Chain.ETHEREUM, TestingCommons.api(Stub(RpcClient)))
def up1 = new EthereumUpstreamMock("test1", Chain.ETHEREUM, TestingCommons.api(Stub(ReactorRpcClient)))
def up2 = new EthereumUpstreamMock("test2", Chain.ETHEREUM_CLASSIC, TestingCommons.api(Stub(ReactorRpcClient)))
def up3 = new EthereumUpstreamMock("test3", Chain.ETHEREUM, TestingCommons.api(Stub(ReactorRpcClient)))
when:
current.update(new UpstreamChange(Chain.ETHEREUM, up1, UpstreamChange.ChangeType.ADDED))
current.update(new UpstreamChange(Chain.ETHEREUM_CLASSIC, up2, UpstreamChange.ChangeType.ADDED))
@@ -39,10 +38,10 @@ class CurrentUpstreamsSpec extends Specification {
def "remove upstream"() {
setup:
def current = new CurrentUpstreams(TestingCommons.objectMapper())
def up1 = new EthereumUpstreamMock("test1", Chain.ETHEREUM, TestingCommons.api(Stub(RpcClient)))
def up2 = new EthereumUpstreamMock("test2", Chain.ETHEREUM_CLASSIC, TestingCommons.api(Stub(RpcClient)))
def up3 = new EthereumUpstreamMock("test3", Chain.ETHEREUM, TestingCommons.api(Stub(RpcClient)))
def up1_del = new EthereumUpstreamMock("test1", Chain.ETHEREUM, TestingCommons.api(Stub(RpcClient)))
def up1 = new EthereumUpstreamMock("test1", Chain.ETHEREUM, TestingCommons.api(Stub(ReactorRpcClient)))
def up2 = new EthereumUpstreamMock("test2", Chain.ETHEREUM_CLASSIC, TestingCommons.api(Stub(ReactorRpcClient)))
def up3 = new EthereumUpstreamMock("test3", Chain.ETHEREUM, TestingCommons.api(Stub(ReactorRpcClient)))
def up1_del = new EthereumUpstreamMock("test1", Chain.ETHEREUM, TestingCommons.api(Stub(ReactorRpcClient)))
when:
current.update(new UpstreamChange(Chain.ETHEREUM, up1, UpstreamChange.ChangeType.ADDED))
current.update(new UpstreamChange(Chain.ETHEREUM_CLASSIC, up2, UpstreamChange.ChangeType.ADDED))

View File

@@ -22,8 +22,7 @@ import io.emeraldpay.dshackle.upstream.ethereum.DirectEthereumApi
import io.emeraldpay.dshackle.upstream.ethereum.EthereumUpstream
import io.emeraldpay.dshackle.upstream.ethereum.EthereumWs
import io.emeraldpay.grpc.Chain
import io.infinitape.etherjar.rpc.DefaultRpcClient
import io.infinitape.etherjar.rpc.RpcClient
import io.infinitape.etherjar.rpc.ReactorRpcClient
import reactor.test.StepVerifier
import spock.lang.Retry
import spock.lang.Specification
@@ -32,7 +31,7 @@ import java.time.Duration
class FilteredApisSpec extends Specification {
def rpcClient = new DefaultRpcClient(null)
def rpcClient = Stub(ReactorRpcClient)
def objectMapper = TestingCommons.objectMapper()
def ethereumTargets = new QuorumBasedMethods(objectMapper, Chain.ETHEREUM)
@@ -141,8 +140,8 @@ class FilteredApisSpec extends Specification {
def "Makes pause between batches"() {
when:
def api1 = TestingCommons.api(Stub(RpcClient))
def api2 = TestingCommons.api(Stub(RpcClient))
def api1 = TestingCommons.api(Stub(ReactorRpcClient))
def api2 = TestingCommons.api(Stub(ReactorRpcClient))
def up1 = TestingCommons.upstream(api1)
def up2 = TestingCommons.upstream(api2)
then:

View File

@@ -29,8 +29,8 @@ import io.emeraldpay.grpc.Chain
import io.grpc.stub.StreamObserver
import io.infinitape.etherjar.domain.BlockHash
import io.infinitape.etherjar.rpc.JacksonRpcConverter
import io.infinitape.etherjar.rpc.RpcClient
import io.infinitape.etherjar.rpc.emerald.EmeraldGrpcTransport
import io.infinitape.etherjar.rpc.ReactorRpcClient
import io.infinitape.etherjar.rpc.emerald.ReactorEmeraldClient
import io.infinitape.etherjar.rpc.json.BlockJson
import reactor.test.StepVerifier
import spock.lang.Specification
@@ -48,7 +48,7 @@ class GrpcUpstreamSpec extends Specification {
setup:
def callData = [:]
def chain = Chain.ETHEREUM
def api = TestingCommons.api(Stub(RpcClient))
def api = TestingCommons.api(Stub(ReactorRpcClient))
def block1 = new BlockJson().with {
it.number = 650246
it.hash = BlockHash.from("0x50d26e119968e791970d84a7bf5d0ec474d3ec2ef85d5ec8915210ac6bc09ad7")
@@ -74,7 +74,7 @@ class GrpcUpstreamSpec extends Specification {
)
}
})
def transport = EmeraldGrpcTransport.newBuilder().forChannel(client.channel).build()
def transport = ReactorEmeraldClient.newBuilder().forChannel(client.channel).build()
def upstream = new GrpcUpstream("test", chain, client, objectMapper, transport)
upstream.setLag(0)
upstream.init(BlockchainOuterClass.DescribeChain.newBuilder()
@@ -91,7 +91,7 @@ class GrpcUpstreamSpec extends Specification {
def "Follows difficulty, ignores less difficult"() {
setup:
def api = TestingCommons.api(Stub(RpcClient))
def api = TestingCommons.api(Stub(ReactorRpcClient))
def block1 = new BlockJson().with {
it.number = 650246
it.hash = BlockHash.from("0x50d26e119968e791970d84a7bf5d0ec474d3ec2ef85d5ec8915210ac6bc09ad7")
@@ -130,7 +130,7 @@ class GrpcUpstreamSpec extends Specification {
)
}
})
def transport = EmeraldGrpcTransport.newBuilder().forChannel(client.channel).build()
def transport = ReactorEmeraldClient.newBuilder().forChannel(client.channel).build()
def upstream = new GrpcUpstream("test", Chain.ETHEREUM, client, objectMapper, transport)
upstream.setLag(0)
upstream.init(BlockchainOuterClass.DescribeChain.newBuilder()
@@ -150,7 +150,7 @@ class GrpcUpstreamSpec extends Specification {
def callData = [:]
def finished = new CompletableFuture<Boolean>()
def chain = Chain.ETHEREUM
def api = TestingCommons.api(Stub(RpcClient))
def api = TestingCommons.api(Stub(ReactorRpcClient))
def block1 = new BlockJson().with {
it.number = 650246
it.hash = BlockHash.from("0x50d26e119968e791970d84a7bf5d0ec474d3ec2ef85d5ec8915210ac6bc09ad7")
@@ -190,7 +190,7 @@ class GrpcUpstreamSpec extends Specification {
finished.complete(true)
}
})
def transport = EmeraldGrpcTransport.newBuilder().forChannel(client.channel).build()
def transport = ReactorEmeraldClient.newBuilder().forChannel(client.channel).build()
def upstream = new GrpcUpstream("test", chain, client, objectMapper, transport)
upstream.setLag(0)
upstream.init(BlockchainOuterClass.DescribeChain.newBuilder()