Fix setting unavailable status (#308)
This commit is contained in:
@@ -24,9 +24,9 @@ class EthereumWsConnectionPoolFactory(
|
|||||||
private val ethereumWsConnectionFactory: EthereumWsConnectionFactory
|
private val ethereumWsConnectionFactory: EthereumWsConnectionFactory
|
||||||
) {
|
) {
|
||||||
|
|
||||||
fun create(upstream: DefaultUpstream?): WsConnectionPool {
|
fun create(upstream: DefaultUpstream): WsConnectionPool {
|
||||||
require(upstream == null || upstream.getId() == id) {
|
require(upstream.getId() == id) {
|
||||||
"Creating instance for different upstream. ${upstream?.getId()} != id"
|
"Creating instance for different upstream. ${upstream.getId()} != id"
|
||||||
}
|
}
|
||||||
return if (connections > 1) {
|
return if (connections > 1) {
|
||||||
WsConnectionMultiPool(ethereumWsConnectionFactory, upstream, connections)
|
WsConnectionMultiPool(ethereumWsConnectionFactory, upstream, connections)
|
||||||
|
|||||||
@@ -23,7 +23,9 @@ import io.emeraldpay.dshackle.data.BlockContainer
|
|||||||
import io.emeraldpay.dshackle.reader.JsonRpcReader
|
import io.emeraldpay.dshackle.reader.JsonRpcReader
|
||||||
import io.emeraldpay.dshackle.reader.Reader
|
import io.emeraldpay.dshackle.reader.Reader
|
||||||
import io.emeraldpay.dshackle.upstream.BlockValidator
|
import io.emeraldpay.dshackle.upstream.BlockValidator
|
||||||
|
import io.emeraldpay.dshackle.upstream.DefaultUpstream
|
||||||
import io.emeraldpay.dshackle.upstream.Lifecycle
|
import io.emeraldpay.dshackle.upstream.Lifecycle
|
||||||
|
import io.emeraldpay.dshackle.upstream.UpstreamAvailability
|
||||||
import io.emeraldpay.dshackle.upstream.ethereum.json.BlockJson
|
import io.emeraldpay.dshackle.upstream.ethereum.json.BlockJson
|
||||||
import io.emeraldpay.dshackle.upstream.forkchoice.ForkChoice
|
import io.emeraldpay.dshackle.upstream.forkchoice.ForkChoice
|
||||||
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcRequest
|
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcRequest
|
||||||
@@ -38,7 +40,6 @@ import reactor.core.scheduler.Scheduler
|
|||||||
import java.time.Duration
|
import java.time.Duration
|
||||||
|
|
||||||
class EthereumWsHead(
|
class EthereumWsHead(
|
||||||
upstreamId: String,
|
|
||||||
forkChoice: ForkChoice,
|
forkChoice: ForkChoice,
|
||||||
blockValidator: BlockValidator,
|
blockValidator: BlockValidator,
|
||||||
private val api: JsonRpcReader,
|
private val api: JsonRpcReader,
|
||||||
@@ -46,7 +47,8 @@ class EthereumWsHead(
|
|||||||
private val skipEnhance: Boolean,
|
private val skipEnhance: Boolean,
|
||||||
private val wsConnectionResubscribeScheduler: Scheduler,
|
private val wsConnectionResubscribeScheduler: Scheduler,
|
||||||
private val headScheduler: Scheduler,
|
private val headScheduler: Scheduler,
|
||||||
) : DefaultEthereumHead(upstreamId, forkChoice, blockValidator, headScheduler), Lifecycle {
|
private val upstream: DefaultUpstream
|
||||||
|
) : DefaultEthereumHead(upstream.getId(), forkChoice, blockValidator, headScheduler), Lifecycle {
|
||||||
|
|
||||||
private var connectionId: String? = null
|
private var connectionId: String? = null
|
||||||
private var subscribed = false
|
private var subscribed = false
|
||||||
@@ -89,6 +91,9 @@ class EthereumWsHead(
|
|||||||
|
|
||||||
fun listenNewHeads(): Flux<BlockContainer> {
|
fun listenNewHeads(): Flux<BlockContainer> {
|
||||||
return subscribe()
|
return subscribe()
|
||||||
|
.transform {
|
||||||
|
Flux.concat(it.next().doOnNext { upstream.setStatus(UpstreamAvailability.OK) }, it)
|
||||||
|
}
|
||||||
.map {
|
.map {
|
||||||
val block = Global.objectMapper.readValue(it, BlockJson::class.java) as BlockJson<TransactionRefJson>
|
val block = Global.objectMapper.readValue(it, BlockJson::class.java) as BlockJson<TransactionRefJson>
|
||||||
if (!block.checkExtraData() && skipEnhance) {
|
if (!block.checkExtraData() && skipEnhance) {
|
||||||
@@ -137,6 +142,8 @@ class EthereumWsHead(
|
|||||||
}
|
}
|
||||||
.timeout(Duration.ofSeconds(60), Mono.error(RuntimeException("No response from subscribe to newHeads")))
|
.timeout(Duration.ofSeconds(60), Mono.error(RuntimeException("No response from subscribe to newHeads")))
|
||||||
.onErrorResume {
|
.onErrorResume {
|
||||||
|
log.error("Error getting heads for $upstreamId - ${it.message}")
|
||||||
|
upstream.setStatus(UpstreamAvailability.UNAVAILABLE)
|
||||||
subscribed = false
|
subscribed = false
|
||||||
Mono.empty()
|
Mono.empty()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ import kotlin.concurrent.write
|
|||||||
*/
|
*/
|
||||||
class WsConnectionMultiPool(
|
class WsConnectionMultiPool(
|
||||||
private val ethereumWsConnectionFactory: EthereumWsConnectionFactory,
|
private val ethereumWsConnectionFactory: EthereumWsConnectionFactory,
|
||||||
private val upstream: DefaultUpstream?,
|
private val upstream: DefaultUpstream,
|
||||||
private val connections: Int,
|
private val connections: Int,
|
||||||
) : WsConnectionPool {
|
) : WsConnectionPool {
|
||||||
|
|
||||||
@@ -112,7 +112,7 @@ class WsConnectionMultiPool(
|
|||||||
current.add(
|
current.add(
|
||||||
ethereumWsConnectionFactory.createWsConnection(connIndex++) {
|
ethereumWsConnectionFactory.createWsConnection(connIndex++) {
|
||||||
if (isUnavailable()) {
|
if (isUnavailable()) {
|
||||||
upstream?.setStatus(UpstreamAvailability.UNAVAILABLE)
|
upstream.setStatus(UpstreamAvailability.UNAVAILABLE)
|
||||||
}
|
}
|
||||||
}.also {
|
}.also {
|
||||||
it.connect()
|
it.connect()
|
||||||
|
|||||||
@@ -21,10 +21,10 @@ import reactor.core.publisher.Flux
|
|||||||
|
|
||||||
class WsConnectionSinglePool(
|
class WsConnectionSinglePool(
|
||||||
ethereumWsConnectionFactory: EthereumWsConnectionFactory,
|
ethereumWsConnectionFactory: EthereumWsConnectionFactory,
|
||||||
private val upstream: DefaultUpstream?,
|
private val upstream: DefaultUpstream,
|
||||||
) : WsConnectionPool {
|
) : WsConnectionPool {
|
||||||
private val connection = ethereumWsConnectionFactory.createWsConnection {
|
private val connection = ethereumWsConnectionFactory.createWsConnection {
|
||||||
upstream?.setStatus(UpstreamAvailability.UNAVAILABLE)
|
upstream.setStatus(UpstreamAvailability.UNAVAILABLE)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun connect() {
|
override fun connect() {
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ open class EthereumConnectorFactory(
|
|||||||
connectorType,
|
connectorType,
|
||||||
httpFactory.create(upstream.getId(), chain),
|
httpFactory.create(upstream.getId(), chain),
|
||||||
wsFactory,
|
wsFactory,
|
||||||
upstream.getId(),
|
upstream,
|
||||||
forkChoice,
|
forkChoice,
|
||||||
blockValidator,
|
blockValidator,
|
||||||
skipEnhance,
|
skipEnhance,
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import io.emeraldpay.dshackle.cache.Caches
|
|||||||
import io.emeraldpay.dshackle.cache.CachesEnabled
|
import io.emeraldpay.dshackle.cache.CachesEnabled
|
||||||
import io.emeraldpay.dshackle.reader.JsonRpcReader
|
import io.emeraldpay.dshackle.reader.JsonRpcReader
|
||||||
import io.emeraldpay.dshackle.upstream.BlockValidator
|
import io.emeraldpay.dshackle.upstream.BlockValidator
|
||||||
|
import io.emeraldpay.dshackle.upstream.DefaultUpstream
|
||||||
import io.emeraldpay.dshackle.upstream.Head
|
import io.emeraldpay.dshackle.upstream.Head
|
||||||
import io.emeraldpay.dshackle.upstream.Lifecycle
|
import io.emeraldpay.dshackle.upstream.Lifecycle
|
||||||
import io.emeraldpay.dshackle.upstream.MergedHead
|
import io.emeraldpay.dshackle.upstream.MergedHead
|
||||||
@@ -31,7 +32,7 @@ class EthereumRpcConnector(
|
|||||||
connectorType: ConnectorMode,
|
connectorType: ConnectorMode,
|
||||||
private val directReader: JsonRpcReader,
|
private val directReader: JsonRpcReader,
|
||||||
wsFactory: EthereumWsConnectionPoolFactory?,
|
wsFactory: EthereumWsConnectionPoolFactory?,
|
||||||
id: String,
|
upstream: DefaultUpstream,
|
||||||
forkChoice: ForkChoice,
|
forkChoice: ForkChoice,
|
||||||
blockValidator: BlockValidator,
|
blockValidator: BlockValidator,
|
||||||
skipEnhance: Boolean,
|
skipEnhance: Boolean,
|
||||||
@@ -39,6 +40,7 @@ class EthereumRpcConnector(
|
|||||||
headScheduler: Scheduler,
|
headScheduler: Scheduler,
|
||||||
expectedBlockTime: Duration
|
expectedBlockTime: Duration
|
||||||
) : EthereumConnector, CachesEnabled {
|
) : EthereumConnector, CachesEnabled {
|
||||||
|
private val id = upstream.getId()
|
||||||
private val pool: WsConnectionPool?
|
private val pool: WsConnectionPool?
|
||||||
private val head: Head
|
private val head: Head
|
||||||
private val liveness: HeadLivenessValidator
|
private val liveness: HeadLivenessValidator
|
||||||
@@ -52,7 +54,7 @@ class EthereumRpcConnector(
|
|||||||
}
|
}
|
||||||
|
|
||||||
init {
|
init {
|
||||||
pool = wsFactory?.create(null)
|
pool = wsFactory?.create(upstream)
|
||||||
|
|
||||||
head = when (connectorType) {
|
head = when (connectorType) {
|
||||||
RPC_ONLY -> {
|
RPC_ONLY -> {
|
||||||
@@ -67,14 +69,14 @@ class EthereumRpcConnector(
|
|||||||
RPC_REQUESTS_WITH_MIXED_HEAD -> {
|
RPC_REQUESTS_WITH_MIXED_HEAD -> {
|
||||||
val wsHead =
|
val wsHead =
|
||||||
EthereumWsHead(
|
EthereumWsHead(
|
||||||
id,
|
|
||||||
AlwaysForkChoice(),
|
AlwaysForkChoice(),
|
||||||
blockValidator,
|
blockValidator,
|
||||||
getIngressReader(),
|
getIngressReader(),
|
||||||
WsSubscriptionsImpl(pool!!),
|
WsSubscriptionsImpl(pool!!),
|
||||||
skipEnhance,
|
skipEnhance,
|
||||||
wsConnectionResubscribeScheduler,
|
wsConnectionResubscribeScheduler,
|
||||||
headScheduler
|
headScheduler,
|
||||||
|
upstream
|
||||||
)
|
)
|
||||||
// receive all new blocks through WebSockets, but also periodically verify with RPC in case if WS failed
|
// receive all new blocks through WebSockets, but also periodically verify with RPC in case if WS failed
|
||||||
val rpcHead =
|
val rpcHead =
|
||||||
@@ -91,11 +93,11 @@ class EthereumRpcConnector(
|
|||||||
|
|
||||||
RPC_REQUESTS_WITH_WS_HEAD -> {
|
RPC_REQUESTS_WITH_WS_HEAD -> {
|
||||||
EthereumWsHead(
|
EthereumWsHead(
|
||||||
id,
|
|
||||||
AlwaysForkChoice(),
|
AlwaysForkChoice(),
|
||||||
blockValidator, getIngressReader(),
|
blockValidator, getIngressReader(),
|
||||||
WsSubscriptionsImpl(pool!!), skipEnhance, wsConnectionResubscribeScheduler,
|
WsSubscriptionsImpl(pool!!), skipEnhance, wsConnectionResubscribeScheduler,
|
||||||
headScheduler
|
headScheduler,
|
||||||
|
upstream
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,14 +37,14 @@ class EthereumWsConnector(
|
|||||||
reader = JsonRpcWsClient(pool)
|
reader = JsonRpcWsClient(pool)
|
||||||
val wsSubscriptions = WsSubscriptionsImpl(pool)
|
val wsSubscriptions = WsSubscriptionsImpl(pool)
|
||||||
head = EthereumWsHead(
|
head = EthereumWsHead(
|
||||||
upstream.getId(),
|
|
||||||
forkChoice,
|
forkChoice,
|
||||||
blockValidator,
|
blockValidator,
|
||||||
reader,
|
reader,
|
||||||
wsSubscriptions,
|
wsSubscriptions,
|
||||||
skipEnhance,
|
skipEnhance,
|
||||||
wsConnectionResubscribeScheduler,
|
wsConnectionResubscribeScheduler,
|
||||||
headScheduler
|
headScheduler,
|
||||||
|
upstream
|
||||||
)
|
)
|
||||||
liveness = HeadLivenessValidator(head, expectedBlockTime, headScheduler, upstream.getId())
|
liveness = HeadLivenessValidator(head, expectedBlockTime, headScheduler, upstream.getId())
|
||||||
subscriptions = EthereumWsIngressSubscription(wsSubscriptions)
|
subscriptions = EthereumWsIngressSubscription(wsSubscriptions)
|
||||||
|
|||||||
@@ -15,14 +15,17 @@
|
|||||||
*/
|
*/
|
||||||
package io.emeraldpay.dshackle.upstream.ethereum
|
package io.emeraldpay.dshackle.upstream.ethereum
|
||||||
|
|
||||||
|
import io.emeraldpay.dshackle.Chain
|
||||||
import io.emeraldpay.dshackle.Global
|
import io.emeraldpay.dshackle.Global
|
||||||
import io.emeraldpay.dshackle.data.BlockContainer
|
import io.emeraldpay.dshackle.data.BlockContainer
|
||||||
|
import io.emeraldpay.dshackle.test.EthereumPosRpcUpstreamMock
|
||||||
import io.emeraldpay.dshackle.test.TestingCommons
|
import io.emeraldpay.dshackle.test.TestingCommons
|
||||||
import io.emeraldpay.dshackle.upstream.BlockValidator
|
import io.emeraldpay.dshackle.upstream.BlockValidator
|
||||||
|
import io.emeraldpay.dshackle.upstream.DefaultUpstream
|
||||||
|
import io.emeraldpay.dshackle.upstream.ethereum.json.BlockJson
|
||||||
import io.emeraldpay.dshackle.upstream.forkchoice.AlwaysForkChoice
|
import io.emeraldpay.dshackle.upstream.forkchoice.AlwaysForkChoice
|
||||||
import io.emeraldpay.etherjar.domain.BlockHash
|
import io.emeraldpay.etherjar.domain.BlockHash
|
||||||
import io.emeraldpay.etherjar.domain.TransactionId
|
import io.emeraldpay.etherjar.domain.TransactionId
|
||||||
import io.emeraldpay.dshackle.upstream.ethereum.json.BlockJson
|
|
||||||
import io.emeraldpay.etherjar.rpc.json.TransactionRefJson
|
import io.emeraldpay.etherjar.rpc.json.TransactionRefJson
|
||||||
import reactor.core.publisher.Flux
|
import reactor.core.publisher.Flux
|
||||||
import reactor.core.publisher.Mono
|
import reactor.core.publisher.Mono
|
||||||
@@ -38,6 +41,7 @@ import java.time.temporal.ChronoUnit
|
|||||||
class EthereumWsHeadSpec extends Specification {
|
class EthereumWsHeadSpec extends Specification {
|
||||||
|
|
||||||
BlockHash parent = BlockHash.from("0x3ec2ebf5d0ec474d0ac6bc50d2770d8409ad76e119968e7919f85d5ec8915200")
|
BlockHash parent = BlockHash.from("0x3ec2ebf5d0ec474d0ac6bc50d2770d8409ad76e119968e7919f85d5ec8915200")
|
||||||
|
DefaultUpstream upstream = new EthereumPosRpcUpstreamMock(Chain.ETHEREUM__MAINNET, TestingCommons.api())
|
||||||
|
|
||||||
def "Fetch block"() {
|
def "Fetch block"() {
|
||||||
setup:
|
setup:
|
||||||
@@ -66,7 +70,7 @@ class EthereumWsHeadSpec extends Specification {
|
|||||||
1 * it.connectionInfoFlux() >> Flux.empty()
|
1 * it.connectionInfoFlux() >> Flux.empty()
|
||||||
}
|
}
|
||||||
|
|
||||||
def head = new EthereumWsHead("fake", new AlwaysForkChoice(), BlockValidator.ALWAYS_VALID, apiMock, ws, false, Schedulers.boundedElastic(), Schedulers.boundedElastic())
|
def head = new EthereumWsHead(new AlwaysForkChoice(), BlockValidator.ALWAYS_VALID, apiMock, ws, false, Schedulers.boundedElastic(), Schedulers.boundedElastic(), upstream)
|
||||||
|
|
||||||
when:
|
when:
|
||||||
def act = head.listenNewHeads().blockFirst()
|
def act = head.listenNewHeads().blockFirst()
|
||||||
@@ -107,7 +111,7 @@ class EthereumWsHeadSpec extends Specification {
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
def head = new EthereumWsHead("fake", new AlwaysForkChoice(), BlockValidator.ALWAYS_VALID, apiMock, ws, true, Schedulers.boundedElastic(), Schedulers.boundedElastic())
|
def head = new EthereumWsHead(new AlwaysForkChoice(), BlockValidator.ALWAYS_VALID, apiMock, ws, true, Schedulers.boundedElastic(), Schedulers.boundedElastic(), upstream)
|
||||||
|
|
||||||
when:
|
when:
|
||||||
def act = head.getFlux()
|
def act = head.getFlux()
|
||||||
@@ -161,7 +165,7 @@ class EthereumWsHeadSpec extends Specification {
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
def head = new EthereumWsHead("fake", new AlwaysForkChoice(), BlockValidator.ALWAYS_VALID, apiMock, ws, true, Schedulers.boundedElastic(), Schedulers.boundedElastic())
|
def head = new EthereumWsHead(new AlwaysForkChoice(), BlockValidator.ALWAYS_VALID, apiMock, ws, true, Schedulers.boundedElastic(), Schedulers.boundedElastic(), upstream)
|
||||||
|
|
||||||
when:
|
when:
|
||||||
def act = head.getFlux()
|
def act = head.getFlux()
|
||||||
@@ -201,7 +205,7 @@ class EthereumWsHeadSpec extends Specification {
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
def head = new EthereumWsHead("fake", new AlwaysForkChoice(), BlockValidator.ALWAYS_VALID, apiMock, ws, true, Schedulers.boundedElastic(), Schedulers.boundedElastic())
|
def head = new EthereumWsHead( new AlwaysForkChoice(), BlockValidator.ALWAYS_VALID, apiMock, ws, true, Schedulers.boundedElastic(), Schedulers.boundedElastic(), upstream)
|
||||||
|
|
||||||
when:
|
when:
|
||||||
def act = head.getFlux()
|
def act = head.getFlux()
|
||||||
@@ -240,7 +244,7 @@ class EthereumWsHeadSpec extends Specification {
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
def head = new EthereumWsHead("fake", new AlwaysForkChoice(), BlockValidator.ALWAYS_VALID, apiMock, ws, true, Schedulers.boundedElastic(), Schedulers.boundedElastic())
|
def head = new EthereumWsHead(new AlwaysForkChoice(), BlockValidator.ALWAYS_VALID, apiMock, ws, true, Schedulers.boundedElastic(), Schedulers.boundedElastic(), upstream)
|
||||||
|
|
||||||
when:
|
when:
|
||||||
def act = head.getFlux()
|
def act = head.getFlux()
|
||||||
@@ -293,7 +297,7 @@ class EthereumWsHeadSpec extends Specification {
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
def head = new EthereumWsHead("fake", new AlwaysForkChoice(), BlockValidator.ALWAYS_VALID, apiMock, ws, true, Schedulers.boundedElastic(), Schedulers.boundedElastic())
|
def head = new EthereumWsHead(new AlwaysForkChoice(), BlockValidator.ALWAYS_VALID, apiMock, ws, true, Schedulers.boundedElastic(), Schedulers.boundedElastic(), upstream)
|
||||||
|
|
||||||
when:
|
when:
|
||||||
def act = head.getFlux()
|
def act = head.getFlux()
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
package io.emeraldpay.dshackle.upstream.ethereum
|
package io.emeraldpay.dshackle.upstream.ethereum
|
||||||
|
|
||||||
import io.emeraldpay.dshackle.Chain
|
import io.emeraldpay.dshackle.Chain
|
||||||
|
import io.emeraldpay.dshackle.test.EthereumPosRpcUpstreamMock
|
||||||
import io.emeraldpay.dshackle.test.MockWSServer
|
import io.emeraldpay.dshackle.test.MockWSServer
|
||||||
|
import io.emeraldpay.dshackle.test.TestingCommons
|
||||||
import io.emeraldpay.dshackle.upstream.DefaultUpstream
|
import io.emeraldpay.dshackle.upstream.DefaultUpstream
|
||||||
import io.emeraldpay.dshackle.upstream.UpstreamAvailability
|
import io.emeraldpay.dshackle.upstream.UpstreamAvailability
|
||||||
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcRequest
|
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcRequest
|
||||||
@@ -13,6 +15,7 @@ import spock.lang.Specification
|
|||||||
import java.time.Duration
|
import java.time.Duration
|
||||||
|
|
||||||
class WsConnectionImplRealSpec extends Specification {
|
class WsConnectionImplRealSpec extends Specification {
|
||||||
|
DefaultUpstream upstream = new EthereumPosRpcUpstreamMock(Chain.ETHEREUM__MAINNET, TestingCommons.api())
|
||||||
|
|
||||||
static SLEEP = 500
|
static SLEEP = 500
|
||||||
|
|
||||||
@@ -42,7 +45,7 @@ class WsConnectionImplRealSpec extends Specification {
|
|||||||
"http://localhost:${port}".toURI(),
|
"http://localhost:${port}".toURI(),
|
||||||
Schedulers.boundedElastic()
|
Schedulers.boundedElastic()
|
||||||
)
|
)
|
||||||
).create(null).getConnection()
|
).create(upstream).getConnection()
|
||||||
}
|
}
|
||||||
|
|
||||||
def cleanup() {
|
def cleanup() {
|
||||||
|
|||||||
@@ -17,7 +17,9 @@ package io.emeraldpay.dshackle.upstream.ethereum
|
|||||||
|
|
||||||
import io.emeraldpay.dshackle.Chain
|
import io.emeraldpay.dshackle.Chain
|
||||||
import io.emeraldpay.dshackle.Global
|
import io.emeraldpay.dshackle.Global
|
||||||
|
import io.emeraldpay.dshackle.test.EthereumPosRpcUpstreamMock
|
||||||
import io.emeraldpay.dshackle.test.TestingCommons
|
import io.emeraldpay.dshackle.test.TestingCommons
|
||||||
|
import io.emeraldpay.dshackle.upstream.DefaultUpstream
|
||||||
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcRequest
|
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcRequest
|
||||||
import io.emeraldpay.etherjar.domain.TransactionId
|
import io.emeraldpay.etherjar.domain.TransactionId
|
||||||
import io.emeraldpay.etherjar.rpc.RpcResponseError
|
import io.emeraldpay.etherjar.rpc.RpcResponseError
|
||||||
@@ -30,6 +32,7 @@ import spock.lang.Specification
|
|||||||
import java.time.Duration
|
import java.time.Duration
|
||||||
|
|
||||||
class WsConnectionImplSpec extends Specification {
|
class WsConnectionImplSpec extends Specification {
|
||||||
|
DefaultUpstream upstream = new EthereumPosRpcUpstreamMock(Chain.ETHEREUM__MAINNET, TestingCommons.api())
|
||||||
|
|
||||||
def "Makes a RPC call"() {
|
def "Makes a RPC call"() {
|
||||||
setup:
|
setup:
|
||||||
@@ -46,7 +49,7 @@ class WsConnectionImplSpec extends Specification {
|
|||||||
)
|
)
|
||||||
def apiMock = TestingCommons.api()
|
def apiMock = TestingCommons.api()
|
||||||
def wsApiMock = apiMock.asWebsocket()
|
def wsApiMock = apiMock.asWebsocket()
|
||||||
def ws = wsf.create(null).getConnection() as WsConnectionImpl
|
def ws = wsf.create(upstream).getConnection() as WsConnectionImpl
|
||||||
|
|
||||||
def tx = new TransactionJson().tap {
|
def tx = new TransactionJson().tap {
|
||||||
hash = TransactionId.from("0x3ec2ebf5d0ec474d0ac6bc50d2770d8409ad76e119968e7919f85d5ec8915200")
|
hash = TransactionId.from("0x3ec2ebf5d0ec474d0ac6bc50d2770d8409ad76e119968e7919f85d5ec8915200")
|
||||||
@@ -81,7 +84,7 @@ class WsConnectionImplSpec extends Specification {
|
|||||||
)
|
)
|
||||||
def apiMock = TestingCommons.api()
|
def apiMock = TestingCommons.api()
|
||||||
def wsApiMock = apiMock.asWebsocket()
|
def wsApiMock = apiMock.asWebsocket()
|
||||||
def ws = wsf.create(null).getConnection()
|
def ws = wsf.create(upstream).getConnection()
|
||||||
|
|
||||||
apiMock.answerOnce("eth_getTransactionByHash", ["0x3ec2ebf5d0ec474d0ac6bc50d2770d8409ad76e119968e7919f85d5ec8915200"], null)
|
apiMock.answerOnce("eth_getTransactionByHash", ["0x3ec2ebf5d0ec474d0ac6bc50d2770d8409ad76e119968e7919f85d5ec8915200"], null)
|
||||||
|
|
||||||
@@ -114,7 +117,7 @@ class WsConnectionImplSpec extends Specification {
|
|||||||
)
|
)
|
||||||
def apiMock = TestingCommons.api()
|
def apiMock = TestingCommons.api()
|
||||||
def wsApiMock = apiMock.asWebsocket()
|
def wsApiMock = apiMock.asWebsocket()
|
||||||
def ws = wsf.create(null).getConnection()
|
def ws = wsf.create(upstream).getConnection()
|
||||||
|
|
||||||
apiMock.answerOnce("eth_getTransactionByHash", ["0x3ec2ebf5d0ec474d0ac6bc50d2770d8409ad76e119968e7919f85d5ec8915200"],
|
apiMock.answerOnce("eth_getTransactionByHash", ["0x3ec2ebf5d0ec474d0ac6bc50d2770d8409ad76e119968e7919f85d5ec8915200"],
|
||||||
new RpcResponseError(RpcResponseError.CODE_METHOD_NOT_EXIST, "test"))
|
new RpcResponseError(RpcResponseError.CODE_METHOD_NOT_EXIST, "test"))
|
||||||
|
|||||||
Reference in New Issue
Block a user