problem: starts subscription on init, may keep them forever
This commit is contained in:
@@ -2,6 +2,8 @@ package io.emeraldpay.dshackle.upstream
|
|||||||
|
|
||||||
import io.emeraldpay.grpc.Chain
|
import io.emeraldpay.grpc.Chain
|
||||||
import org.slf4j.LoggerFactory
|
import org.slf4j.LoggerFactory
|
||||||
|
import org.springframework.context.Lifecycle
|
||||||
|
import reactor.core.Disposable
|
||||||
import java.io.Closeable
|
import java.io.Closeable
|
||||||
import java.lang.IllegalStateException
|
import java.lang.IllegalStateException
|
||||||
import java.time.Duration
|
import java.time.Duration
|
||||||
@@ -10,26 +12,47 @@ class ChainUpstreams (
|
|||||||
val chain: Chain,
|
val chain: Chain,
|
||||||
private val upstreams: MutableList<Upstream>,
|
private val upstreams: MutableList<Upstream>,
|
||||||
targets: CallMethods
|
targets: CallMethods
|
||||||
) : AggregatedUpstream(targets) {
|
) : AggregatedUpstream(targets), Lifecycle {
|
||||||
|
|
||||||
|
|
||||||
private val log = LoggerFactory.getLogger(ChainUpstreams::class.java)
|
private val log = LoggerFactory.getLogger(ChainUpstreams::class.java)
|
||||||
private var seq = 0
|
private var seq = 0
|
||||||
private var head: EthereumHead?
|
private var head: EthereumHead?
|
||||||
private var lagObserver: HeadLagObserver? = null
|
private var lagObserver: HeadLagObserver? = null
|
||||||
|
private var subscription: Disposable? = null
|
||||||
|
|
||||||
init {
|
init {
|
||||||
head = updateHead()
|
head = updateHead()
|
||||||
observeStatus()
|
}
|
||||||
|
|
||||||
|
override fun isRunning(): Boolean {
|
||||||
|
return subscription != null
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun start() {
|
||||||
|
subscription = observeStatus()
|
||||||
.distinctUntilChanged()
|
.distinctUntilChanged()
|
||||||
.subscribe { printStatus() }
|
.subscribe { printStatus() }
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun updateHead(): EthereumHead {
|
override fun stop() {
|
||||||
val current = head
|
subscription?.dispose()
|
||||||
if (current != null && Closeable::class.java.isAssignableFrom(current.javaClass)) {
|
subscription = null
|
||||||
(current as Closeable).close()
|
head?.let {
|
||||||
|
if (it is Lifecycle) {
|
||||||
|
it.stop()
|
||||||
}
|
}
|
||||||
lagObserver?.close()
|
}
|
||||||
|
lagObserver?.stop()
|
||||||
|
}
|
||||||
|
|
||||||
|
internal fun updateHead(): EthereumHead {
|
||||||
|
head?.let {
|
||||||
|
if (it is Lifecycle) {
|
||||||
|
it.stop()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lagObserver?.stop()
|
||||||
lagObserver = null
|
lagObserver = null
|
||||||
return if (upstreams.size == 1) {
|
return if (upstreams.size == 1) {
|
||||||
val upstream = upstreams.first()
|
val upstream = upstreams.first()
|
||||||
@@ -37,6 +60,7 @@ class ChainUpstreams (
|
|||||||
upstream.getHead()
|
upstream.getHead()
|
||||||
} else {
|
} else {
|
||||||
val newHead = EthereumHeadMerge(upstreams.map { it.getHead() })
|
val newHead = EthereumHeadMerge(upstreams.map { it.getHead() })
|
||||||
|
newHead.start()
|
||||||
val lagObserver = HeadLagObserver(newHead, upstreams)
|
val lagObserver = HeadLagObserver(newHead, upstreams)
|
||||||
lagObserver.start()
|
lagObserver.start()
|
||||||
this.lagObserver = lagObserver
|
this.lagObserver = lagObserver
|
||||||
|
|||||||
@@ -132,7 +132,9 @@ open class ConfiguredUpstreams(
|
|||||||
}
|
}
|
||||||
if (rpcApi != null) {
|
if (rpcApi != null) {
|
||||||
log.info("Using ${chain.chainName} upstream, at ${urls.joinToString()}")
|
log.info("Using ${chain.chainName} upstream, at ${urls.joinToString()}")
|
||||||
addUpstream(chain, EthereumUpstream(chain, rpcApi!!, wsApi, options, NodeDetailsList.NodeDetails(1, labels), targetFor(chain)))
|
val ethereumUpstream = EthereumUpstream(chain, rpcApi!!, wsApi, options, NodeDetailsList.NodeDetails(1, labels), targetFor(chain))
|
||||||
|
ethereumUpstream.start()
|
||||||
|
addUpstream(chain, ethereumUpstream)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -165,6 +167,7 @@ open class ConfiguredUpstreams(
|
|||||||
if (current == null) {
|
if (current == null) {
|
||||||
val created = ChainUpstreams(chain, ArrayList<Upstream>(), targetFor(chain))
|
val created = ChainUpstreams(chain, ArrayList<Upstream>(), targetFor(chain))
|
||||||
created.addUpstream(up)
|
created.addUpstream(up)
|
||||||
|
created.start()
|
||||||
chainMapping[chain] = created
|
chainMapping[chain] = created
|
||||||
chainsBus.onNext(chain)
|
chainsBus.onNext(chain)
|
||||||
return created
|
return created
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package io.emeraldpay.dshackle.upstream
|
|||||||
import io.infinitape.etherjar.domain.TransactionId
|
import io.infinitape.etherjar.domain.TransactionId
|
||||||
import io.infinitape.etherjar.rpc.json.BlockJson
|
import io.infinitape.etherjar.rpc.json.BlockJson
|
||||||
import org.slf4j.LoggerFactory
|
import org.slf4j.LoggerFactory
|
||||||
|
import org.springframework.context.Lifecycle
|
||||||
import reactor.core.Disposable
|
import reactor.core.Disposable
|
||||||
import reactor.core.publisher.Flux
|
import reactor.core.publisher.Flux
|
||||||
import reactor.core.publisher.Mono
|
import reactor.core.publisher.Mono
|
||||||
@@ -10,13 +11,13 @@ import java.io.Closeable
|
|||||||
import java.util.concurrent.atomic.AtomicReference
|
import java.util.concurrent.atomic.AtomicReference
|
||||||
|
|
||||||
class EthereumHeadMerge(
|
class EthereumHeadMerge(
|
||||||
private val upstreams: List<EthereumHead>
|
upstreams: List<EthereumHead>
|
||||||
): EthereumHead, Closeable {
|
): EthereumHead, Lifecycle {
|
||||||
|
|
||||||
private val log = LoggerFactory.getLogger(EthereumHeadMerge::class.java)
|
private val log = LoggerFactory.getLogger(EthereumHeadMerge::class.java)
|
||||||
private val flux: Flux<BlockJson<TransactionId>>
|
private val flux: Flux<BlockJson<TransactionId>>
|
||||||
private val head = AtomicReference<BlockJson<TransactionId>>(null)
|
private val head = AtomicReference<BlockJson<TransactionId>>(null)
|
||||||
private val subscription: Disposable
|
private var subscription: Disposable? = null
|
||||||
|
|
||||||
init {
|
init {
|
||||||
val fluxes = upstreams.map { it.getFlux() }
|
val fluxes = upstreams.map { it.getFlux() }
|
||||||
@@ -30,13 +31,19 @@ class EthereumHeadMerge(
|
|||||||
}
|
}
|
||||||
.publish()
|
.publish()
|
||||||
.autoConnect()
|
.autoConnect()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun isRunning(): Boolean {
|
||||||
|
return subscription != null
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun start() {
|
||||||
subscription = Flux.from(flux).subscribe {
|
subscription = Flux.from(flux).subscribe {
|
||||||
head.set(it)
|
head.set(it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
override fun getHead(): Mono<BlockJson<TransactionId>> {
|
override fun getHead(): Mono<BlockJson<TransactionId>> {
|
||||||
val curr = head.get()
|
val curr = head.get()
|
||||||
if (curr != null) {
|
if (curr != null) {
|
||||||
@@ -50,10 +57,8 @@ class EthereumHeadMerge(
|
|||||||
.onBackpressureLatest()
|
.onBackpressureLatest()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun close() {
|
override fun stop() {
|
||||||
if (!subscription.isDisposed) {
|
subscription?.dispose()
|
||||||
subscription.dispose()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -5,6 +5,8 @@ import io.infinitape.etherjar.rpc.Batch
|
|||||||
import io.infinitape.etherjar.rpc.Commands
|
import io.infinitape.etherjar.rpc.Commands
|
||||||
import io.infinitape.etherjar.rpc.json.BlockJson
|
import io.infinitape.etherjar.rpc.json.BlockJson
|
||||||
import org.slf4j.LoggerFactory
|
import org.slf4j.LoggerFactory
|
||||||
|
import org.springframework.context.Lifecycle
|
||||||
|
import reactor.core.Disposable
|
||||||
import reactor.core.publisher.Flux
|
import reactor.core.publisher.Flux
|
||||||
import reactor.core.publisher.Mono
|
import reactor.core.publisher.Mono
|
||||||
import reactor.core.publisher.TopicProcessor
|
import reactor.core.publisher.TopicProcessor
|
||||||
@@ -13,15 +15,16 @@ import java.util.concurrent.atomic.AtomicReference
|
|||||||
|
|
||||||
class EthereumRpcHead(
|
class EthereumRpcHead(
|
||||||
private val api: EthereumApi
|
private val api: EthereumApi
|
||||||
): EthereumHead {
|
): EthereumHead, Lifecycle {
|
||||||
|
|
||||||
private val log = LoggerFactory.getLogger(EthereumRpcHead::class.java)
|
private val log = LoggerFactory.getLogger(EthereumRpcHead::class.java)
|
||||||
|
|
||||||
private val head = AtomicReference<BlockJson<TransactionId>>(null)
|
private val head = AtomicReference<BlockJson<TransactionId>>(null)
|
||||||
private val stream: TopicProcessor<BlockJson<TransactionId>> = TopicProcessor.create()
|
private val stream: TopicProcessor<BlockJson<TransactionId>> = TopicProcessor.create()
|
||||||
|
private var refreshSubscription: Disposable? = null
|
||||||
|
|
||||||
fun start() {
|
override fun start() {
|
||||||
Flux.interval(Duration.ofSeconds(7))
|
refreshSubscription = Flux.interval(Duration.ofSeconds(7))
|
||||||
.flatMap {
|
.flatMap {
|
||||||
val batch = Batch()
|
val batch = Batch()
|
||||||
val f = batch.add(Commands.eth().blockNumber)
|
val f = batch.add(Commands.eth().blockNumber)
|
||||||
@@ -48,6 +51,16 @@ class EthereumRpcHead(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun isRunning(): Boolean {
|
||||||
|
return refreshSubscription != null
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun stop() {
|
||||||
|
refreshSubscription?.dispose()
|
||||||
|
refreshSubscription = null
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
override fun getHead(): Mono<BlockJson<TransactionId>> {
|
override fun getHead(): Mono<BlockJson<TransactionId>> {
|
||||||
val current = head.get()
|
val current = head.get()
|
||||||
if (current != null) {
|
if (current != null) {
|
||||||
|
|||||||
@@ -3,6 +3,9 @@ package io.emeraldpay.dshackle.upstream
|
|||||||
import io.emeraldpay.dshackle.config.UpstreamsConfig
|
import io.emeraldpay.dshackle.config.UpstreamsConfig
|
||||||
import io.emeraldpay.grpc.Chain
|
import io.emeraldpay.grpc.Chain
|
||||||
import org.slf4j.LoggerFactory
|
import org.slf4j.LoggerFactory
|
||||||
|
import org.springframework.context.Lifecycle
|
||||||
|
import reactor.core.Disposable
|
||||||
|
import java.io.Closeable
|
||||||
|
|
||||||
open class EthereumUpstream(
|
open class EthereumUpstream(
|
||||||
val chain: Chain,
|
val chain: Chain,
|
||||||
@@ -11,7 +14,7 @@ open class EthereumUpstream(
|
|||||||
private val options: UpstreamsConfig.Options,
|
private val options: UpstreamsConfig.Options,
|
||||||
val node: NodeDetailsList.NodeDetails,
|
val node: NodeDetailsList.NodeDetails,
|
||||||
private val targets: CallMethods
|
private val targets: CallMethods
|
||||||
): DefaultUpstream() {
|
): DefaultUpstream(), Lifecycle {
|
||||||
|
|
||||||
constructor(chain: Chain, api: EthereumApi): this(chain, api, null,
|
constructor(chain: Chain, api: EthereumApi): this(chain, api, null,
|
||||||
UpstreamsConfig.Options.getDefaults(), NodeDetailsList.NodeDetails(1, UpstreamsConfig.Labels()),
|
UpstreamsConfig.Options.getDefaults(), NodeDetailsList.NodeDetails(1, UpstreamsConfig.Labels()),
|
||||||
@@ -24,21 +27,34 @@ open class EthereumUpstream(
|
|||||||
private val log = LoggerFactory.getLogger(EthereumUpstream::class.java)
|
private val log = LoggerFactory.getLogger(EthereumUpstream::class.java)
|
||||||
|
|
||||||
private val head: EthereumHead = this.createHead()
|
private val head: EthereumHead = this.createHead()
|
||||||
|
private var validatorSubscription: Disposable? = null
|
||||||
|
|
||||||
init {
|
init {
|
||||||
log.info("Configured for ${chain.chainName}")
|
|
||||||
api.upstream = this
|
api.upstream = this
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun start() {
|
||||||
|
log.info("Configured for ${chain.chainName}")
|
||||||
|
|
||||||
if (options.disableValidation != null && options.disableValidation!!) {
|
if (options.disableValidation != null && options.disableValidation!!) {
|
||||||
this.setLag(0)
|
this.setLag(0)
|
||||||
this.setStatus(UpstreamAvailability.OK)
|
this.setStatus(UpstreamAvailability.OK)
|
||||||
} else {
|
} else {
|
||||||
val validator = UpstreamValidator(this, options)
|
val validator = UpstreamValidator(this, options)
|
||||||
validator.start()
|
validatorSubscription = validator.start()
|
||||||
.subscribe(this::setStatus)
|
.subscribe(this::setStatus)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun isRunning(): Boolean {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun stop() {
|
||||||
|
validatorSubscription?.dispose()
|
||||||
|
validatorSubscription = null
|
||||||
|
}
|
||||||
|
|
||||||
open fun createHead(): EthereumHead {
|
open fun createHead(): EthereumHead {
|
||||||
return if (ethereumWs != null) {
|
return if (ethereumWs != null) {
|
||||||
EthereumWsHead(ethereumWs)
|
EthereumWsHead(ethereumWs)
|
||||||
|
|||||||
@@ -12,6 +12,8 @@ import io.infinitape.etherjar.domain.TransactionId
|
|||||||
import io.infinitape.etherjar.rpc.*
|
import io.infinitape.etherjar.rpc.*
|
||||||
import io.infinitape.etherjar.rpc.json.BlockJson
|
import io.infinitape.etherjar.rpc.json.BlockJson
|
||||||
import org.slf4j.LoggerFactory
|
import org.slf4j.LoggerFactory
|
||||||
|
import org.springframework.context.Lifecycle
|
||||||
|
import reactor.core.Disposable
|
||||||
import reactor.core.publisher.Flux
|
import reactor.core.publisher.Flux
|
||||||
import reactor.core.publisher.Mono
|
import reactor.core.publisher.Mono
|
||||||
import reactor.core.publisher.TopicProcessor
|
import reactor.core.publisher.TopicProcessor
|
||||||
@@ -28,21 +30,20 @@ open class GrpcUpstream(
|
|||||||
private val client: ReactorBlockchainGrpc.ReactorBlockchainStub,
|
private val client: ReactorBlockchainGrpc.ReactorBlockchainStub,
|
||||||
private val objectMapper: ObjectMapper,
|
private val objectMapper: ObjectMapper,
|
||||||
private val targets: CallMethods
|
private val targets: CallMethods
|
||||||
): DefaultUpstream() {
|
): DefaultUpstream(), Lifecycle {
|
||||||
|
|
||||||
|
|
||||||
private val log = LoggerFactory.getLogger(GrpcUpstream::class.java)
|
private val log = LoggerFactory.getLogger(GrpcUpstream::class.java)
|
||||||
|
|
||||||
private val options = UpstreamsConfig.Options.getDefaults()
|
private val options = UpstreamsConfig.Options.getDefaults()
|
||||||
private val headBlock = AtomicReference<BlockJson<TransactionId>>(null)
|
private val headBlock = AtomicReference<BlockJson<TransactionId>>(null)
|
||||||
private val streamBlocks: TopicProcessor<BlockJson<TransactionId>> = TopicProcessor.create()
|
private val streamBlocks: TopicProcessor<BlockJson<TransactionId>> = TopicProcessor.create()
|
||||||
private val status = AtomicReference<UpstreamAvailability>(UpstreamAvailability.UNAVAILABLE)
|
|
||||||
private val nodes = AtomicReference<NodeDetailsList>(NodeDetailsList())
|
private val nodes = AtomicReference<NodeDetailsList>(NodeDetailsList())
|
||||||
private val head = Head(this)
|
private val head = Head(this)
|
||||||
private val statusStream: TopicProcessor<UpstreamAvailability> = TopicProcessor.create()
|
|
||||||
private val supportedMethods = HashSet<String>()
|
private val supportedMethods = HashSet<String>()
|
||||||
private val grpcTransport = EthereumGrpcTransport(chain, client, objectMapper)
|
private val grpcTransport = EthereumGrpcTransport(chain, client, objectMapper)
|
||||||
|
|
||||||
|
private var headSubscription: Disposable? = null
|
||||||
|
|
||||||
open fun createApi(matcher: Selector.Matcher): EthereumApi {
|
open fun createApi(matcher: Selector.Matcher): EthereumApi {
|
||||||
val rpcClient = DefaultRpcClient(grpcTransport.withMatcher(matcher))
|
val rpcClient = DefaultRpcClient(grpcTransport.withMatcher(matcher))
|
||||||
return EthereumApi(rpcClient, objectMapper, chain, targets).let {
|
return EthereumApi(rpcClient, objectMapper, chain, targets).let {
|
||||||
@@ -51,7 +52,7 @@ open class GrpcUpstream(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
open fun connect() {
|
override fun start() {
|
||||||
val chainRef = Common.Chain.newBuilder()
|
val chainRef = Common.Chain.newBuilder()
|
||||||
.setTypeValue(chain.id)
|
.setTypeValue(chain.id)
|
||||||
.build()
|
.build()
|
||||||
@@ -64,11 +65,22 @@ open class GrpcUpstream(
|
|||||||
|
|
||||||
val flux = client.subscribeHead(chainRef)
|
val flux = client.subscribeHead(chainRef)
|
||||||
.compose(GrpcRetry.ManyToMany.retryAfter(retry, Duration.ofSeconds(5)))
|
.compose(GrpcRetry.ManyToMany.retryAfter(retry, Duration.ofSeconds(5)))
|
||||||
subscribe(flux)
|
observeHead(flux)
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun subscribe(flux: Flux<BlockchainOuterClass.ChainHead>) {
|
override fun isRunning(): Boolean {
|
||||||
flux.map { value ->
|
return headSubscription != null
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
override fun stop() {
|
||||||
|
headSubscription?.dispose()
|
||||||
|
headSubscription = null
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
internal fun observeHead(flux: Flux<BlockchainOuterClass.ChainHead>) {
|
||||||
|
headSubscription = flux.map { value ->
|
||||||
val block = BlockJson<TransactionId>()
|
val block = BlockJson<TransactionId>()
|
||||||
block.number = value.height
|
block.number = value.height
|
||||||
block.totalDifficulty = BigInteger(1, value.weight.toByteArray())
|
block.totalDifficulty = BigInteger(1, value.weight.toByteArray())
|
||||||
|
|||||||
@@ -94,7 +94,7 @@ class GrpcUpstreams(
|
|||||||
val created = GrpcUpstream(chain, client!!, objectMapper, upstreams.targetFor(chain))
|
val created = GrpcUpstream(chain, client!!, objectMapper, upstreams.targetFor(chain))
|
||||||
known[chain] = created
|
known[chain] = created
|
||||||
upstreams.addUpstream(chain, created)
|
upstreams.addUpstream(chain, created)
|
||||||
created.connect()
|
created.start()
|
||||||
created
|
created
|
||||||
} else {
|
} else {
|
||||||
current
|
current
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package io.emeraldpay.dshackle.upstream
|
|||||||
import io.infinitape.etherjar.domain.TransactionId
|
import io.infinitape.etherjar.domain.TransactionId
|
||||||
import io.infinitape.etherjar.rpc.json.BlockJson
|
import io.infinitape.etherjar.rpc.json.BlockJson
|
||||||
import org.slf4j.LoggerFactory
|
import org.slf4j.LoggerFactory
|
||||||
|
import org.springframework.context.Lifecycle
|
||||||
import reactor.core.Disposable
|
import reactor.core.Disposable
|
||||||
import reactor.core.publisher.Flux
|
import reactor.core.publisher.Flux
|
||||||
import reactor.core.publisher.toFlux
|
import reactor.core.publisher.toFlux
|
||||||
@@ -14,16 +15,25 @@ import java.time.Duration
|
|||||||
class HeadLagObserver (
|
class HeadLagObserver (
|
||||||
private val master: EthereumHead,
|
private val master: EthereumHead,
|
||||||
private val followers: Collection<Upstream>
|
private val followers: Collection<Upstream>
|
||||||
): Closeable {
|
): Lifecycle {
|
||||||
|
|
||||||
private val log = LoggerFactory.getLogger(HeadLagObserver::class.java)
|
private val log = LoggerFactory.getLogger(HeadLagObserver::class.java)
|
||||||
|
|
||||||
private var current: Disposable? = null
|
private var current: Disposable? = null
|
||||||
|
|
||||||
fun start() {
|
override fun start() {
|
||||||
current = subscription().subscribe { }
|
current = subscription().subscribe { }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun isRunning(): Boolean {
|
||||||
|
return current != null
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun stop() {
|
||||||
|
current?.dispose()
|
||||||
|
current = null
|
||||||
|
}
|
||||||
|
|
||||||
private fun subscription(): Flux<Unit> {
|
private fun subscription(): Flux<Unit> {
|
||||||
return master.getFlux()
|
return master.getFlux()
|
||||||
.flatMap(this::probeFollowers)
|
.flatMap(this::probeFollowers)
|
||||||
@@ -69,9 +79,4 @@ class HeadLagObserver (
|
|||||||
return 6
|
return 6
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun close() {
|
|
||||||
current?.dispose()
|
|
||||||
current = null
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -56,7 +56,7 @@ class GrpcUpstreamSpec extends Specification {
|
|||||||
def upstream = new GrpcUpstream(chain, client, objectMapper, ethereumTargets)
|
def upstream = new GrpcUpstream(chain, client, objectMapper, ethereumTargets)
|
||||||
upstream.setLag(0)
|
upstream.setLag(0)
|
||||||
when:
|
when:
|
||||||
upstream.connect()
|
upstream.start()
|
||||||
def h = upstream.head.head.block(Duration.ofSeconds(1))
|
def h = upstream.head.head.block(Duration.ofSeconds(1))
|
||||||
then:
|
then:
|
||||||
callData.chain == Chain.ETHEREUM.id
|
callData.chain == Chain.ETHEREUM.id
|
||||||
@@ -112,7 +112,7 @@ class GrpcUpstreamSpec extends Specification {
|
|||||||
def upstream = new GrpcUpstream(chain, client, objectMapper, ethereumTargets)
|
def upstream = new GrpcUpstream(chain, client, objectMapper, ethereumTargets)
|
||||||
upstream.setLag(0)
|
upstream.setLag(0)
|
||||||
when:
|
when:
|
||||||
upstream.connect()
|
upstream.start()
|
||||||
finished.get()
|
finished.get()
|
||||||
def h = upstream.head.head.block(Duration.ofSeconds(1))
|
def h = upstream.head.head.block(Duration.ofSeconds(1))
|
||||||
then:
|
then:
|
||||||
@@ -169,7 +169,7 @@ class GrpcUpstreamSpec extends Specification {
|
|||||||
def upstream = new GrpcUpstream(chain, client, objectMapper, ethereumTargets)
|
def upstream = new GrpcUpstream(chain, client, objectMapper, ethereumTargets)
|
||||||
upstream.setLag(0)
|
upstream.setLag(0)
|
||||||
when:
|
when:
|
||||||
upstream.connect()
|
upstream.start()
|
||||||
finished.get()
|
finished.get()
|
||||||
def h = upstream.head.head.block(Duration.ofSeconds(1))
|
def h = upstream.head.head.block(Duration.ofSeconds(1))
|
||||||
then:
|
then:
|
||||||
|
|||||||
Reference in New Issue
Block a user