Remove eventPublisher and locks (#336)

This commit is contained in:
KirillPamPam
2023-11-08 18:32:19 +04:00
committed by GitHub
parent e4c13ad1ad
commit ef48f8c89f
34 changed files with 741 additions and 805 deletions

View File

@@ -28,11 +28,13 @@ import io.emeraldpay.dshackle.quorum.AlwaysQuorum
import io.emeraldpay.dshackle.reader.Reader
import io.emeraldpay.dshackle.reader.RpcReader
import io.emeraldpay.dshackle.reader.RpcReaderFactory
import io.emeraldpay.dshackle.startup.UpstreamChangeEvent
import io.emeraldpay.dshackle.test.MultistreamHolderMock
import io.emeraldpay.dshackle.test.TestingCommons
import io.emeraldpay.dshackle.upstream.*
import io.emeraldpay.dshackle.upstream.calls.DefaultEthereumMethods
import io.emeraldpay.dshackle.upstream.calls.ManagedCallMethods
import io.emeraldpay.dshackle.upstream.generic.GenericUpstream
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcError
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcException
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcRequest
@@ -601,9 +603,10 @@ class NativeCallSpec extends Specification {
new DefaultEthereumMethods(Chain.ETHEREUM__MAINNET),
[] as Set, [] as Set, ["filter"] as Set, [] as Set
)
def multistream = new MultistreamHolderMock.EthereumMultistreamMock(Chain.ETHEREUM__MAINNET, TestingCommons.upstream(
TestingCommons.api(), methods
))
def multistream = new MultistreamHolderMock.EthereumMultistreamMock(Chain.ETHEREUM__MAINNET, new ArrayList<GenericUpstream>())
multistream.processUpstreamsEvents(
new UpstreamChangeEvent(Chain.ETHEREUM__MAINNET, TestingCommons.upstream(TestingCommons.api(), methods), UpstreamChangeEvent.ChangeType.ADDED)
)
multistream.customHead = Mock(Head)
def multistreamHolder = Mock(MultistreamHolder) {
_ * it.observeChains() >> Flux.empty()
@@ -636,9 +639,10 @@ class NativeCallSpec extends Specification {
new DefaultEthereumMethods(Chain.ETHEREUM__MAINNET),
[] as Set, [] as Set, ["filter"] as Set, [] as Set
)
def multistream = new MultistreamHolderMock.EthereumMultistreamMock(Chain.ETHEREUM__MAINNET, TestingCommons.upstream(
TestingCommons.api(), methods
))
def multistream = new MultistreamHolderMock.EthereumMultistreamMock(Chain.ETHEREUM__MAINNET, new ArrayList<GenericUpstream>())
multistream.processUpstreamsEvents(
new UpstreamChangeEvent(Chain.ETHEREUM__MAINNET, TestingCommons.upstream(TestingCommons.api(), methods), UpstreamChangeEvent.ChangeType.ADDED)
)
multistream.customHead = Mock(Head)
def multistreamHolder = Mock(MultistreamHolder) {
_ * it.observeChains() >> Flux.empty()

View File

@@ -1,191 +0,0 @@
package io.emeraldpay.dshackle.startup
import brave.Tracing
import brave.grpc.GrpcTracing
import io.emeraldpay.dshackle.Chain
import io.emeraldpay.dshackle.FileResolver
import io.emeraldpay.dshackle.config.AuthorizationConfig
import io.emeraldpay.dshackle.config.ChainsConfig
import io.emeraldpay.dshackle.config.CompressionConfig
import io.emeraldpay.dshackle.config.UpstreamsConfig
import io.emeraldpay.dshackle.quorum.NotNullQuorum
import io.emeraldpay.dshackle.upstream.CallTargetsHolder
import io.emeraldpay.dshackle.upstream.calls.ManagedCallMethods
import io.emeraldpay.dshackle.upstream.grpc.auth.GrpcAuthContext
import org.springframework.context.ApplicationEventPublisher
import reactor.core.scheduler.Schedulers
import spock.lang.Specification
import java.util.concurrent.Executors
class ConfiguredUpstreamsSpec extends Specification {
def "Applied quorum to extra methods"() {
setup:
def callTargetsHolder = new CallTargetsHolder()
def configurer = new ConfiguredUpstreams(
Stub(FileResolver),
new UpstreamsConfig(),
Stub(CompressionConfig),
callTargetsHolder,
Mock(ApplicationEventPublisher),
Executors.newFixedThreadPool(1),
ChainsConfig.default(),
GrpcTracing.create(Tracing.newBuilder().build()),
Schedulers.boundedElastic(),
null,
Schedulers.boundedElastic(),
Schedulers.boundedElastic(),
Schedulers.boundedElastic(),
AuthorizationConfig.default(),
new GrpcAuthContext()
)
def methods = new UpstreamsConfig.Methods(
[
new UpstreamsConfig.Method("foo_bar", null, null),
new UpstreamsConfig.Method("foo_bar", "not_empty", null)
] as Set,
[] as Set
)
def upstream = new UpstreamsConfig.Upstream()
upstream.methods = methods
when:
def act = configurer.buildMethods(upstream, Chain.ETHEREUM__MAINNET)
then:
act instanceof ManagedCallMethods
act.createQuorumFor("foo_bar") instanceof NotNullQuorum
}
def "Got static response from extra methods"() {
setup:
def callTargetsHolder = new CallTargetsHolder()
def configurer = new ConfiguredUpstreams(
Stub(FileResolver),
new UpstreamsConfig(),
Stub(CompressionConfig),
callTargetsHolder,
Mock(ApplicationEventPublisher),
Executors.newFixedThreadPool(1),
ChainsConfig.default(),
GrpcTracing.create(Tracing.newBuilder().build()),
Schedulers.boundedElastic(),
null,
Schedulers.boundedElastic(),
Schedulers.boundedElastic(),
Schedulers.boundedElastic(),
AuthorizationConfig.default(),
new GrpcAuthContext()
)
def methods = new UpstreamsConfig.Methods(
[
new UpstreamsConfig.Method("foo_bar", null, "static_response")
] as Set,
[] as Set
)
def upstream = new UpstreamsConfig.Upstream()
upstream.methods = methods
when:
def act = configurer.buildMethods(upstream, Chain.ETHEREUM__MAINNET)
then:
act instanceof ManagedCallMethods
new String(act.executeHardcoded("foo_bar")) == "\"static_response\""
}
def "Calculate node-id"() {
setup:
def callTargetsHolder = new CallTargetsHolder()
def configurer = new ConfiguredUpstreams(
Stub(FileResolver),
new UpstreamsConfig(),
Stub(CompressionConfig),
callTargetsHolder,
Mock(ApplicationEventPublisher),
Executors.newFixedThreadPool(1),
ChainsConfig.default(),
GrpcTracing.create(Tracing.newBuilder().build()),
Schedulers.boundedElastic(),
null,
Schedulers.boundedElastic(),
Schedulers.boundedElastic(),
Schedulers.boundedElastic(),
AuthorizationConfig.default(),
new GrpcAuthContext()
)
expect:
configurer.getHash(node, src) == expected
where:
node | src | expected
1 | "" | 1
9 | "hohoho" | 9
null | "hohoho" | 120
}
def "Calculate node-id conflicting results"() {
setup:
def callTargetsHolder = new CallTargetsHolder()
def configurer = new ConfiguredUpstreams(
Stub(FileResolver),
new UpstreamsConfig(),
Stub(CompressionConfig),
callTargetsHolder,
Mock(ApplicationEventPublisher),
Executors.newFixedThreadPool(1),
ChainsConfig.default(),
GrpcTracing.create(Tracing.newBuilder().build()),
Schedulers.boundedElastic(),
null,
Schedulers.boundedElastic(),
Schedulers.boundedElastic(),
Schedulers.boundedElastic(),
AuthorizationConfig.default(),
new GrpcAuthContext()
)
when:
def h1 = configurer.getHash(null, "hohoho")
def h2 = configurer.getHash(null, "hohoho")
def h3 = configurer.getHash(null, "hohoho")
def h4 = configurer.getHash(null, "hohoho")
def h5 = configurer.getHash(null, "hohoho")
then:
h1 == (byte)120
h2 == (byte)-120
h3 == (byte)-9
h4 == (byte)8
h5 == (byte)-128
}
def "Supporting method groups"() {
setup:
def callTargetsHolder = new CallTargetsHolder()
def configurer = new ConfiguredUpstreams(
Stub(FileResolver),
new UpstreamsConfig(),
Stub(CompressionConfig),
callTargetsHolder,
Mock(ApplicationEventPublisher),
Executors.newFixedThreadPool(1),
ChainsConfig.default(),
GrpcTracing.create(Tracing.newBuilder().build()),
Schedulers.boundedElastic(),
null,
Schedulers.boundedElastic(),
Schedulers.boundedElastic(),
Schedulers.boundedElastic(),
AuthorizationConfig.default(),
new GrpcAuthContext()
)
def methodsGroup = new UpstreamsConfig.MethodGroups(
["filter"] as Set,
[] as Set
)
def upstream = new UpstreamsConfig.Upstream()
upstream.methodGroups = methodsGroup
when:
def act = configurer.buildMethods(upstream, Chain.ETHEREUM__MAINNET)
then:
act instanceof ManagedCallMethods
act.supportedMethods.findAll {it.containsIgnoreCase("filter")}.size() == 6
}
}

View File

@@ -72,7 +72,6 @@ class GenericUpstreamMock extends GenericUpstream {
new QuorumForLabels.QuorumItem(1, UpstreamsConfig.Labels.fromMap(labels)),
ChainConfig.default(),
new ConnectorFactoryMock(api, new EthereumHeadMock()),
null,
io.emeraldpay.dshackle.upstream.starknet.StarknetChainSpecific.INSTANCE.&validator,
io.emeraldpay.dshackle.upstream.starknet.StarknetChainSpecific.INSTANCE.&labelDetector,
io.emeraldpay.dshackle.upstream.starknet.StarknetChainSpecific.INSTANCE.&subscriptionTopics,

View File

@@ -47,12 +47,13 @@ class MultistreamHolderMock implements MultistreamHolder {
upstreams[chain] = up
} else if (up instanceof GenericUpstream) {
upstreams[chain] = new GenericMultistream(
chain, [up as GenericUpstream], Caches.default(),
chain, Schedulers.immediate(), null, new ArrayList<Upstream>(), Caches.default(),
Schedulers.boundedElastic(),
EthereumChainSpecific.INSTANCE.makeCachingReaderBuilder(TestingCommons.tracerMock()),
EthereumChainSpecific.INSTANCE.&localReaderBuilder,
io.emeraldpay.dshackle.upstream.starknet.StarknetChainSpecific.INSTANCE.subscriptionBuilder(Schedulers.boundedElastic())
)
upstreams[chain].addUpstream(up)
} else {
throw new IllegalArgumentException("Unsupported upstream type ${up.class}")
}
@@ -100,7 +101,7 @@ class MultistreamHolderMock implements MultistreamHolder {
Head customHead = null
EthereumMultistreamMock(@NotNull Chain chain, @NotNull List<GenericUpstream> upstreams, @NotNull Caches caches) {
super(chain, upstreams, caches, Schedulers.boundedElastic(),
super(chain, Schedulers.immediate(), null, upstreams, caches, Schedulers.boundedElastic(),
EthereumChainSpecific.INSTANCE.makeCachingReaderBuilder(new BraveTracer(null, null, null)),
EthereumChainSpecific.INSTANCE.&localReaderBuilder,
EthereumChainSpecific.INSTANCE.subscriptionBuilder(Schedulers.boundedElastic()))

View File

@@ -25,15 +25,17 @@ import io.emeraldpay.dshackle.data.BlockContainer
import io.emeraldpay.dshackle.data.BlockId
import io.emeraldpay.dshackle.reader.EmptyReader
import io.emeraldpay.dshackle.reader.Reader
import io.emeraldpay.dshackle.startup.UpstreamChangeEvent
import io.emeraldpay.dshackle.upstream.Multistream
import io.emeraldpay.dshackle.upstream.Upstream
import io.emeraldpay.dshackle.upstream.calls.CallMethods
import io.emeraldpay.dshackle.upstream.calls.DirectCallMethods
import io.emeraldpay.dshackle.upstream.ethereum.EthereumChainSpecific
import io.emeraldpay.dshackle.upstream.ethereum.json.BlockJson
import io.emeraldpay.dshackle.upstream.generic.GenericMultistream
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcRequest
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcResponse
import io.emeraldpay.dshackle.upstream.ethereum.EthereumChainSpecific
import io.emeraldpay.etherjar.domain.BlockHash
import io.emeraldpay.dshackle.upstream.ethereum.json.BlockJson
import io.emeraldpay.etherjar.domain.TransactionId
import io.emeraldpay.etherjar.rpc.json.TransactionRefJson
import io.micrometer.core.instrument.MeterRegistry
@@ -91,13 +93,15 @@ class TestingCommons {
}
static Multistream multistream(GenericUpstreamMock up) {
return new GenericMultistream(Chain.ETHEREUM__MAINNET, [up], Caches.default(),
return new GenericMultistream(Chain.ETHEREUM__MAINNET, Schedulers.immediate(), null, new ArrayList<Upstream>(), Caches.default(),
Schedulers.boundedElastic(),
EthereumChainSpecific.INSTANCE.makeCachingReaderBuilder(tracerMock()),
EthereumChainSpecific.INSTANCE.&localReaderBuilder,
EthereumChainSpecific.INSTANCE.subscriptionBuilder(Schedulers.boundedElastic()),
).tap {
start()
it.processUpstreamsEvents(
new UpstreamChangeEvent(Chain.ETHEREUM__MAINNET, up, UpstreamChangeEvent.ChangeType.ADDED)
)
}
}
@@ -117,14 +121,14 @@ class TestingCommons {
}
static Multistream multistreamWithoutUpstreams(Chain chain) {
return new GenericMultistream(chain, [], emptyCaches().getCaches(chain), Schedulers.boundedElastic(),
return new GenericMultistream(chain, Schedulers.immediate(), null, [], emptyCaches().getCaches(chain), Schedulers.boundedElastic(),
EthereumChainSpecific.INSTANCE.makeCachingReaderBuilder(tracerMock()),
EthereumChainSpecific.INSTANCE.&localReaderBuilder,
EthereumChainSpecific.INSTANCE.subscriptionBuilder(Schedulers.boundedElastic()))
}
static Multistream multistreamClassicWithoutUpstreams(Chain chain) {
return new GenericMultistream(chain, [], emptyCaches().getCaches(chain), Schedulers.boundedElastic(),
return new GenericMultistream(chain, Schedulers.immediate(), null, [], emptyCaches().getCaches(chain), Schedulers.boundedElastic(),
EthereumChainSpecific.INSTANCE.makeCachingReaderBuilder(tracerMock()),
EthereumChainSpecific.INSTANCE.&localReaderBuilder,
EthereumChainSpecific.INSTANCE.subscriptionBuilder(Schedulers.boundedElastic()))

View File

@@ -28,7 +28,7 @@ class CurrentMultistreamHolderSpec extends Specification {
def current = new CurrentMultistreamHolder(TestingCommons.defaultMultistreams())
def up = new GenericUpstreamMock("test", Chain.ETHEREUM__MAINNET, TestingCommons.api())
when:
current.getUpstream(Chain.ETHEREUM__MAINNET).onUpstreamChange(new UpstreamChangeEvent(Chain.ETHEREUM__MAINNET, up, UpstreamChangeEvent.ChangeType.ADDED))
current.getUpstream(Chain.ETHEREUM__MAINNET).processUpstreamsEvents(new UpstreamChangeEvent(Chain.ETHEREUM__MAINNET, up, UpstreamChangeEvent.ChangeType.ADDED))
then:
current.getAvailable() == [Chain.ETHEREUM__MAINNET]
current.getUpstream(Chain.ETHEREUM__MAINNET).getAll()[0] == up
@@ -41,10 +41,10 @@ class CurrentMultistreamHolderSpec extends Specification {
def up2 = new GenericUpstreamMock("test2", Chain.ETHEREUM_CLASSIC__MAINNET, TestingCommons.api())
def up3 = new GenericUpstreamMock("test3", Chain.ETHEREUM__MAINNET, TestingCommons.api())
when:
current.getUpstream(Chain.ETHEREUM__MAINNET).onUpstreamChange(new UpstreamChangeEvent(Chain.ETHEREUM__MAINNET, up1, UpstreamChangeEvent.ChangeType.ADDED))
current.getUpstream(Chain.ETHEREUM_CLASSIC__MAINNET).onUpstreamChange(new UpstreamChangeEvent(Chain.ETHEREUM_CLASSIC__MAINNET, up2, UpstreamChangeEvent.ChangeType.ADDED))
current.getUpstream(Chain.ETHEREUM__MAINNET).onUpstreamChange(new UpstreamChangeEvent(Chain.ETHEREUM__MAINNET, up3, UpstreamChangeEvent.ChangeType.ADDED))
current.getUpstream(Chain.ETHEREUM_CLASSIC__MAINNET).onUpstreamChange(new UpstreamChangeEvent(Chain.ETHEREUM__MAINNET, up3, UpstreamChangeEvent.ChangeType.ADDED))
current.getUpstream(Chain.ETHEREUM__MAINNET).processUpstreamsEvents(new UpstreamChangeEvent(Chain.ETHEREUM__MAINNET, up1, UpstreamChangeEvent.ChangeType.ADDED))
current.getUpstream(Chain.ETHEREUM_CLASSIC__MAINNET).processUpstreamsEvents(new UpstreamChangeEvent(Chain.ETHEREUM_CLASSIC__MAINNET, up2, UpstreamChangeEvent.ChangeType.ADDED))
current.getUpstream(Chain.ETHEREUM__MAINNET).processUpstreamsEvents(new UpstreamChangeEvent(Chain.ETHEREUM__MAINNET, up3, UpstreamChangeEvent.ChangeType.ADDED))
current.getUpstream(Chain.ETHEREUM_CLASSIC__MAINNET).processUpstreamsEvents(new UpstreamChangeEvent(Chain.ETHEREUM__MAINNET, up3, UpstreamChangeEvent.ChangeType.ADDED))
then:
current.getAvailable().toSet() == [Chain.ETHEREUM__MAINNET, Chain.ETHEREUM_CLASSIC__MAINNET].toSet()
current.getUpstream(Chain.ETHEREUM__MAINNET).getAll().toSet() == [up1, up3].toSet()
@@ -59,10 +59,10 @@ class CurrentMultistreamHolderSpec extends Specification {
def up3 = new GenericUpstreamMock("test3", Chain.ETHEREUM__MAINNET, TestingCommons.api())
def up1_del = new GenericUpstreamMock("test1", Chain.ETHEREUM__MAINNET, TestingCommons.api())
when:
current.getUpstream(Chain.ETHEREUM__MAINNET).onUpstreamChange(new UpstreamChangeEvent(Chain.ETHEREUM__MAINNET, up1, UpstreamChangeEvent.ChangeType.ADDED))
current.getUpstream(Chain.ETHEREUM_CLASSIC__MAINNET).onUpstreamChange(new UpstreamChangeEvent(Chain.ETHEREUM_CLASSIC__MAINNET, up2, UpstreamChangeEvent.ChangeType.ADDED))
current.getUpstream(Chain.ETHEREUM__MAINNET).onUpstreamChange(new UpstreamChangeEvent(Chain.ETHEREUM__MAINNET, up3, UpstreamChangeEvent.ChangeType.ADDED))
current.getUpstream(Chain.ETHEREUM__MAINNET).onUpstreamChange(new UpstreamChangeEvent(Chain.ETHEREUM__MAINNET, up1_del, UpstreamChangeEvent.ChangeType.REMOVED))
current.getUpstream(Chain.ETHEREUM__MAINNET).processUpstreamsEvents(new UpstreamChangeEvent(Chain.ETHEREUM__MAINNET, up1, UpstreamChangeEvent.ChangeType.ADDED))
current.getUpstream(Chain.ETHEREUM_CLASSIC__MAINNET).processUpstreamsEvents(new UpstreamChangeEvent(Chain.ETHEREUM_CLASSIC__MAINNET, up2, UpstreamChangeEvent.ChangeType.ADDED))
current.getUpstream(Chain.ETHEREUM__MAINNET).processUpstreamsEvents(new UpstreamChangeEvent(Chain.ETHEREUM__MAINNET, up3, UpstreamChangeEvent.ChangeType.ADDED))
current.getUpstream(Chain.ETHEREUM__MAINNET).processUpstreamsEvents(new UpstreamChangeEvent(Chain.ETHEREUM__MAINNET, up1_del, UpstreamChangeEvent.ChangeType.REMOVED))
then:
current.getAvailable().toSet() == [Chain.ETHEREUM__MAINNET, Chain.ETHEREUM_CLASSIC__MAINNET].toSet()
current.getUpstream(Chain.ETHEREUM__MAINNET).getAll().toSet() == [up3].toSet()
@@ -80,7 +80,7 @@ class CurrentMultistreamHolderSpec extends Specification {
!act
when:
current.getUpstream(Chain.ETHEREUM__MAINNET).onUpstreamChange(new UpstreamChangeEvent(Chain.ETHEREUM__MAINNET, up1, UpstreamChangeEvent.ChangeType.ADDED))
current.getUpstream(Chain.ETHEREUM__MAINNET).processUpstreamsEvents(new UpstreamChangeEvent(Chain.ETHEREUM__MAINNET, up1, UpstreamChangeEvent.ChangeType.ADDED))
act = current.isAvailable(Chain.ETHEREUM__MAINNET)
then:

View File

@@ -77,7 +77,6 @@ class FilteredApisSpec extends Specification {
new QuorumForLabels.QuorumItem(1, UpstreamsConfig.Labels.fromMap(it)),
ChainsConfig.ChainConfig.default(),
connectorFactory,
null,
cs.&validator,
cs.&labelDetector,
cs.&subscriptionTopics,

View File

@@ -55,7 +55,7 @@ class MultistreamSpec extends Specification {
setup:
def up1 = new GenericUpstreamMock("test1", Chain.ETHEREUM__MAINNET, TestingCommons.api(), new DirectCallMethods(["eth_test1", "eth_test2"]))
def up2 = new GenericUpstreamMock("test1", Chain.ETHEREUM__MAINNET, TestingCommons.api(), new DirectCallMethods(["eth_test2", "eth_test3"]))
def aggr = new GenericMultistream(Chain.ETHEREUM__MAINNET, [up1, up2], Caches.default(),
def aggr = new GenericMultistream(Chain.ETHEREUM__MAINNET, Schedulers.immediate(), null, [up1, up2], Caches.default(),
Schedulers.boundedElastic(),
EthereumChainSpecific.INSTANCE.makeCachingReaderBuilder(TestingCommons.tracerMock()),
EthereumChainSpecific.INSTANCE.&localReaderBuilder,
@@ -190,7 +190,7 @@ class MultistreamSpec extends Specification {
def up1 = TestingCommons.upstream("test-1", "internal")
def up2 = TestingCommons.upstream("test-2", "external")
def up3 = TestingCommons.upstream("test-3", "external")
def multistream = new GenericMultistream(Chain.ETHEREUM__MAINNET, [up1, up2, up3], Caches.default(),
def multistream = new GenericMultistream(Chain.ETHEREUM__MAINNET, Schedulers.immediate(), null, [up1, up2, up3], Caches.default(),
Schedulers.boundedElastic(),
EthereumChainSpecific.INSTANCE.makeCachingReaderBuilder(TestingCommons.tracerMock()),
EthereumChainSpecific.INSTANCE.&localReaderBuilder,
@@ -263,16 +263,16 @@ class MultistreamSpec extends Specification {
setup:
def up1 = new GenericUpstreamMock("test1", Chain.ETHEREUM__MAINNET, TestingCommons.api(), new DirectCallMethods(["eth_test1", "eth_test2", "eth_test3"]))
def up2 = new GenericUpstreamMock("test2", Chain.ETHEREUM__MAINNET, TestingCommons.api(), new DirectCallMethods(["eth_test1", "eth_test2"]))
def ms = new GenericMultistream(Chain.ETHEREUM__MAINNET, new ArrayList<GenericMultistream>(), Caches.default(),
def ms = new GenericMultistream(Chain.ETHEREUM__MAINNET, Schedulers.immediate(), null, new ArrayList<GenericMultistream>(), Caches.default(),
Schedulers.boundedElastic(),
EthereumChainSpecific.INSTANCE.makeCachingReaderBuilder(TestingCommons.tracerMock()),
EthereumChainSpecific.INSTANCE.&localReaderBuilder,
EthereumChainSpecific.INSTANCE.subscriptionBuilder(Schedulers.boundedElastic()))
when:
ms.onUpstreamChange(
ms.processUpstreamsEvents(
new UpstreamChangeEvent(Chain.ETHEREUM__MAINNET, up1, UpstreamChangeEvent.ChangeType.ADDED)
)
ms.onUpstreamChange(
ms.processUpstreamsEvents(
new UpstreamChangeEvent(Chain.ETHEREUM__MAINNET, up2, UpstreamChangeEvent.ChangeType.ADDED)
)
up1.onStatus(status(Common.AvailabilityEnum.AVAIL_UNAVAILABLE))
@@ -294,7 +294,7 @@ class MultistreamSpec extends Specification {
setup:
def up1 = new GenericUpstreamMock("test1", Chain.ETHEREUM__MAINNET, TestingCommons.api(), new DirectCallMethods(["eth_test1", "eth_test2", "eth_test3"]))
def up2 = new GenericUpstreamMock("test2", Chain.ETHEREUM__MAINNET, TestingCommons.api(), new DirectCallMethods(["eth_test1", "eth_test2"]))
def ms = new GenericMultistream(Chain.ETHEREUM__MAINNET, new ArrayList<GenericMultistream>(), Caches.default(),
def ms = new GenericMultistream(Chain.ETHEREUM__MAINNET, Schedulers.immediate(), null, new ArrayList<GenericMultistream>(), Caches.default(),
Schedulers.boundedElastic(),
EthereumChainSpecific.INSTANCE.makeCachingReaderBuilder(TestingCommons.tracerMock()),
EthereumChainSpecific.INSTANCE.&localReaderBuilder,
@@ -303,10 +303,10 @@ class MultistreamSpec extends Specification {
def head2 = createBlock(270, "0x0d050c785de17179f935b9b93aca09c442964cc59972c71ae68e74731448402b")
def head3 = createBlock(100, "0x0d050c785de17179f935b9b93aca09c442964cc59972c71ae68e74731448412b")
when:
ms.onUpstreamChange(
ms.processUpstreamsEvents(
new UpstreamChangeEvent(Chain.ETHEREUM__MAINNET, up1, UpstreamChangeEvent.ChangeType.ADDED)
)
ms.onUpstreamChange(
ms.processUpstreamsEvents(
new UpstreamChangeEvent(Chain.ETHEREUM__MAINNET, up2, UpstreamChangeEvent.ChangeType.ADDED)
)
def head = ms.getHead()
@@ -329,25 +329,32 @@ class MultistreamSpec extends Specification {
def up1 = TestingCommons.upstream("test-1", "internal")
def up2 = TestingCommons.upstream("test-2", "external")
def up3 = TestingCommons.upstream("test-3", "external")
def multistream = new GenericMultistream(Chain.ETHEREUM__MAINNET, [up1, up2, up3], Caches.default(),
def multistream = new GenericMultistream(Chain.ETHEREUM__MAINNET, Schedulers.immediate(), null, new ArrayList<Upstream>(), Caches.default(),
Schedulers.boundedElastic(),
EthereumChainSpecific.INSTANCE.makeCachingReaderBuilder(TestingCommons.tracerMock()),
EthereumChainSpecific.INSTANCE.&localReaderBuilder,
EthereumChainSpecific.INSTANCE.subscriptionBuilder(Schedulers.boundedElastic()))
def observer = multistream.lagObserver
multistream.onUpstreamsUpdated()
multistream.processUpstreamsEvents(
new UpstreamChangeEvent(Chain.ETHEREUM__MAINNET, up1, UpstreamChangeEvent.ChangeType.ADDED)
)
multistream.processUpstreamsEvents(
new UpstreamChangeEvent(Chain.ETHEREUM__MAINNET, up2, UpstreamChangeEvent.ChangeType.ADDED)
)
multistream.processUpstreamsEvents(
new UpstreamChangeEvent(Chain.ETHEREUM__MAINNET, up3, UpstreamChangeEvent.ChangeType.ADDED)
)
expect:
multistream.getAll().size() == 3
observer.isRunning()
multistream.lagObserver.isRunning()
multistream.getAll().with {
remove(0)
remove(1)
}
multistream.processUpstreamsEvents(
new UpstreamChangeEvent(Chain.ETHEREUM__MAINNET, up1, UpstreamChangeEvent.ChangeType.REMOVED)
)
multistream.processUpstreamsEvents(
new UpstreamChangeEvent(Chain.ETHEREUM__MAINNET, up2, UpstreamChangeEvent.ChangeType.REMOVED)
)
multistream.getAll().size() == 1
multistream.onUpstreamsUpdated()
!observer.isRunning()
multistream.lagObserver == null
}
@@ -360,7 +367,7 @@ class MultistreamSpec extends Specification {
class TestEthereumPosMultistream extends GenericMultistream {
TestEthereumPosMultistream(@NotNull Chain chain, @NotNull List<GenericUpstream> upstreams, @NotNull Caches caches) {
super(chain, upstreams, caches,
super(chain, Schedulers.immediate(), null, upstreams, caches,
Schedulers.boundedElastic(),
EthereumChainSpecific.INSTANCE.makeCachingReaderBuilder(TestingCommons.tracerMock()),
EthereumChainSpecific.INSTANCE.&localReaderBuilder,
@@ -381,11 +388,6 @@ class MultistreamSpec extends Specification {
public <T extends Upstream> T cast(Class<T> selfType) {
return this
}
@Override
void init() {
}
}
BlockContainer createBlock(long number, String hash) {

View File

@@ -16,15 +16,12 @@ import io.emeraldpay.dshackle.upstream.Upstream
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.mockito.ArgumentCaptor
import org.mockito.kotlin.any
import org.mockito.kotlin.doReturn
import org.mockito.kotlin.mock
import org.mockito.kotlin.never
import org.mockito.kotlin.times
import org.mockito.kotlin.verify
import org.mockito.kotlin.whenever
import org.springframework.context.ApplicationEventPublisher
import org.springframework.util.ResourceUtils
import sun.misc.Signal
import java.io.File
@@ -38,7 +35,6 @@ class ReloadConfigTest {
private val config = mock<Config>()
private val reloadConfigService = ReloadConfigService(config, fileResolver, mainConfig)
private val applicationEventPublisher = mock<ApplicationEventPublisher>()
private val configuredUpstreams = mock<ConfiguredUpstreams>()
@BeforeEach
@@ -66,7 +62,6 @@ class ReloadConfigTest {
on { getUpstream(POLYGON__MAINNET) } doReturn msPoly
}
val reloadConfigUpstreamService = ReloadConfigUpstreamService(
applicationEventPublisher,
currentMultistreamHolder,
configuredUpstreams,
)
@@ -79,8 +74,8 @@ class ReloadConfigTest {
reloadConfig.handle(Signal("HUP"))
val captor = ArgumentCaptor.forClass(UpstreamChangeEvent::class.java)
verify(applicationEventPublisher, times(2)).publishEvent(captor.capture())
verify(msEth).processUpstreamsEvents(UpstreamChangeEvent(ETHEREUM__MAINNET, up1, UpstreamChangeEvent.ChangeType.REMOVED))
verify(msPoly).processUpstreamsEvents(UpstreamChangeEvent(POLYGON__MAINNET, up3, UpstreamChangeEvent.ChangeType.REMOVED))
verify(configuredUpstreams).processUpstreams(
UpstreamsConfig(
newConfig.defaultOptions,
@@ -90,14 +85,6 @@ class ReloadConfigTest {
assertEquals(3, mainConfig.upstreams!!.upstreams.size)
assertEquals(newConfig, mainConfig.upstreams)
assertEquals(
UpstreamChangeEvent(ETHEREUM__MAINNET, up1, UpstreamChangeEvent.ChangeType.REMOVED),
captor.allValues[0],
)
assertEquals(
UpstreamChangeEvent(POLYGON__MAINNET, up3, UpstreamChangeEvent.ChangeType.REMOVED),
captor.allValues[1],
)
}
@Test
@@ -123,7 +110,6 @@ class ReloadConfigTest {
on { getUpstream(POLYGON__MAINNET) } doReturn msPoly
}
val reloadConfigUpstreamService = ReloadConfigUpstreamService(
applicationEventPublisher,
currentMultistreamHolder,
configuredUpstreams,
)
@@ -135,8 +121,8 @@ class ReloadConfigTest {
reloadConfig.handle(Signal("HUP"))
val captor = ArgumentCaptor.forClass(UpstreamChangeEvent::class.java)
verify(applicationEventPublisher, times(2)).publishEvent(captor.capture())
verify(msEth).processUpstreamsEvents(UpstreamChangeEvent(ETHEREUM__MAINNET, up1, UpstreamChangeEvent.ChangeType.REMOVED))
verify(msEth).processUpstreamsEvents(UpstreamChangeEvent(ETHEREUM__MAINNET, up2, UpstreamChangeEvent.ChangeType.REMOVED))
verify(configuredUpstreams).processUpstreams(
UpstreamsConfig(
newConfig.defaultOptions,
@@ -146,14 +132,6 @@ class ReloadConfigTest {
verify(msEth).stop()
assertEquals(1, mainConfig.upstreams!!.upstreams.size)
assertEquals(newConfig, mainConfig.upstreams)
assertEquals(
UpstreamChangeEvent(ETHEREUM__MAINNET, up1, UpstreamChangeEvent.ChangeType.REMOVED),
captor.allValues[0],
)
assertEquals(
UpstreamChangeEvent(ETHEREUM__MAINNET, up2, UpstreamChangeEvent.ChangeType.REMOVED),
captor.allValues[1],
)
}
@Test

View File

@@ -0,0 +1,62 @@
package io.emeraldpay.dshackle.startup.configure
import io.emeraldpay.dshackle.BlockchainType
import io.emeraldpay.dshackle.config.UpstreamsConfig
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.params.ParameterizedTest
import org.junit.jupiter.params.provider.Arguments
import org.junit.jupiter.params.provider.MethodSource
import org.mockito.Mockito.reset
import org.mockito.kotlin.any
import org.mockito.kotlin.mock
import org.mockito.kotlin.verify
class UpstreamFactoryTest {
@BeforeEach
fun beforeEach() {
reset(genericUpstreamCreator, ethereumUpstreamCreator, bitcoinUpstreamCreator)
}
@ParameterizedTest
@MethodSource("data")
fun `create upstream based on chain`(
blockchain: BlockchainType,
verify: Runnable,
) {
upstreamFactory.createUpstream(blockchain, UpstreamsConfig.Upstream<UpstreamsConfig.UpstreamConnection>(), emptyMap())
verify.run()
}
companion object {
private val genericUpstreamCreator = mock<GenericUpstreamCreator>()
private val ethereumUpstreamCreator = mock<EthereumUpstreamCreator>()
private val bitcoinUpstreamCreator = mock<BitcoinUpstreamCreator>()
private val upstreamFactory = UpstreamFactory(genericUpstreamCreator, ethereumUpstreamCreator, bitcoinUpstreamCreator)
@JvmStatic
fun data() = listOf(
Arguments.of(
BlockchainType.ETHEREUM,
Runnable { verify(ethereumUpstreamCreator).createUpstream(any(), any()) },
),
Arguments.of(
BlockchainType.BITCOIN,
Runnable { verify(bitcoinUpstreamCreator).createUpstream(any(), any()) },
),
Arguments.of(
BlockchainType.POLKADOT,
Runnable { verify(genericUpstreamCreator).createUpstream(any(), any()) },
),
Arguments.of(
BlockchainType.STARKNET,
Runnable { verify(genericUpstreamCreator).createUpstream(any(), any()) },
),
Arguments.of(
BlockchainType.UNKNOWN,
Runnable { verify(genericUpstreamCreator).createUpstream(any(), any()) },
),
)
}
}