Add SpanReader wrapper for creating additional spans (#155)
This commit is contained in:
20
src/main/kotlin/io/emeraldpay/dshackle/commons/constatnts.kt
Normal file
20
src/main/kotlin/io/emeraldpay/dshackle/commons/constatnts.kt
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
package io.emeraldpay.dshackle.commons
|
||||||
|
|
||||||
|
const val SPAN_READER_NAME = "reader.name"
|
||||||
|
const val SPAN_REQUEST_INFO = "request.info"
|
||||||
|
const val SPAN_ERROR = "error"
|
||||||
|
const val SPAN_STATUS_MESSAGE = "status.message"
|
||||||
|
const val SPAN_READER_RESULT = "reader.result"
|
||||||
|
const val SPAN_REQUEST_API_TYPE = "request.api.type"
|
||||||
|
const val SPAN_REQUEST_UPSTREAM_ID = "request.upstreamId"
|
||||||
|
const val SPAN_REQUEST_ID = "request.id"
|
||||||
|
|
||||||
|
const val LOCAL_READER = "localReader"
|
||||||
|
const val REMOTE_QUORUM_RPC_READER = "remoteQuorumRpcReader"
|
||||||
|
const val API_READER = "apiReader"
|
||||||
|
const val CACHE_BLOCK_BY_HASH_READER = "cacheBlockByHashReader"
|
||||||
|
const val DIRECT_QUORUM_RPC_READER = "directQuorumRpcReader"
|
||||||
|
const val CACHE_HEIGHT_BY_HASH_READER = "cacheHeightByHashReader"
|
||||||
|
const val CACHE_BLOCK_BY_HEIGHT_READER = "cacheBlockByHeightReader"
|
||||||
|
const val CACHE_TX_BY_HASH_READER = "cacheTxByHashReader"
|
||||||
|
const val CACHE_RECEIPTS_READER = "cacheReceiptsReader"
|
||||||
@@ -10,6 +10,7 @@ import io.emeraldpay.dshackle.upstream.ethereum.EthereumMultistream
|
|||||||
import io.emeraldpay.dshackle.upstream.ethereum.EthereumPosMultiStream
|
import io.emeraldpay.dshackle.upstream.ethereum.EthereumPosMultiStream
|
||||||
import org.springframework.beans.factory.annotation.Qualifier
|
import org.springframework.beans.factory.annotation.Qualifier
|
||||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory
|
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory
|
||||||
|
import org.springframework.cloud.sleuth.Tracer
|
||||||
import org.springframework.context.annotation.Bean
|
import org.springframework.context.annotation.Bean
|
||||||
import org.springframework.context.annotation.Configuration
|
import org.springframework.context.annotation.Configuration
|
||||||
import reactor.core.scheduler.Scheduler
|
import reactor.core.scheduler.Scheduler
|
||||||
@@ -21,14 +22,15 @@ open class MultistreamsConfig(val beanFactory: ConfigurableListableBeanFactory)
|
|||||||
cachesFactory: CachesFactory,
|
cachesFactory: CachesFactory,
|
||||||
callTargetsHolder: CallTargetsHolder,
|
callTargetsHolder: CallTargetsHolder,
|
||||||
@Qualifier("headMergedScheduler")
|
@Qualifier("headMergedScheduler")
|
||||||
headScheduler: Scheduler
|
headScheduler: Scheduler,
|
||||||
|
tracer: Tracer
|
||||||
): List<Multistream> {
|
): List<Multistream> {
|
||||||
return Chain.values()
|
return Chain.values()
|
||||||
.filterNot { it == Chain.UNSPECIFIED }
|
.filterNot { it == Chain.UNSPECIFIED }
|
||||||
.mapNotNull { chain ->
|
.mapNotNull { chain ->
|
||||||
when (BlockchainType.from(chain)) {
|
when (BlockchainType.from(chain)) {
|
||||||
BlockchainType.EVM_POS -> ethereumPosMultistream(chain, cachesFactory, headScheduler)
|
BlockchainType.EVM_POS -> ethereumPosMultistream(chain, cachesFactory, headScheduler, tracer)
|
||||||
BlockchainType.EVM_POW -> ethereumMultistream(chain, cachesFactory, headScheduler)
|
BlockchainType.EVM_POW -> ethereumMultistream(chain, cachesFactory, headScheduler, tracer)
|
||||||
BlockchainType.BITCOIN -> bitcoinMultistream(chain, cachesFactory)
|
BlockchainType.BITCOIN -> bitcoinMultistream(chain, cachesFactory)
|
||||||
else -> null
|
else -> null
|
||||||
}
|
}
|
||||||
@@ -38,7 +40,8 @@ open class MultistreamsConfig(val beanFactory: ConfigurableListableBeanFactory)
|
|||||||
private fun ethereumMultistream(
|
private fun ethereumMultistream(
|
||||||
chain: Chain,
|
chain: Chain,
|
||||||
cachesFactory: CachesFactory,
|
cachesFactory: CachesFactory,
|
||||||
headScheduler: Scheduler
|
headScheduler: Scheduler,
|
||||||
|
tracer: Tracer
|
||||||
): EthereumMultistream {
|
): EthereumMultistream {
|
||||||
val name = "multi-ethereum-$chain"
|
val name = "multi-ethereum-$chain"
|
||||||
|
|
||||||
@@ -46,14 +49,16 @@ open class MultistreamsConfig(val beanFactory: ConfigurableListableBeanFactory)
|
|||||||
chain,
|
chain,
|
||||||
ArrayList(),
|
ArrayList(),
|
||||||
cachesFactory.getCaches(chain),
|
cachesFactory.getCaches(chain),
|
||||||
headScheduler
|
headScheduler,
|
||||||
|
tracer
|
||||||
).also { register(it, name) }
|
).also { register(it, name) }
|
||||||
}
|
}
|
||||||
|
|
||||||
open fun ethereumPosMultistream(
|
open fun ethereumPosMultistream(
|
||||||
chain: Chain,
|
chain: Chain,
|
||||||
cachesFactory: CachesFactory,
|
cachesFactory: CachesFactory,
|
||||||
headScheduler: Scheduler
|
headScheduler: Scheduler,
|
||||||
|
tracer: Tracer
|
||||||
): EthereumPosMultiStream {
|
): EthereumPosMultiStream {
|
||||||
val name = "multi-ethereum-pos-$chain"
|
val name = "multi-ethereum-pos-$chain"
|
||||||
|
|
||||||
@@ -61,7 +66,8 @@ open class MultistreamsConfig(val beanFactory: ConfigurableListableBeanFactory)
|
|||||||
chain,
|
chain,
|
||||||
ArrayList(),
|
ArrayList(),
|
||||||
cachesFactory.getCaches(chain),
|
cachesFactory.getCaches(chain),
|
||||||
headScheduler
|
headScheduler,
|
||||||
|
tracer
|
||||||
).also { register(it, name) }
|
).also { register(it, name) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ import io.emeraldpay.dshackle.reader.Reader
|
|||||||
import io.emeraldpay.dshackle.upstream.ApiSource
|
import io.emeraldpay.dshackle.upstream.ApiSource
|
||||||
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcRequest
|
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcRequest
|
||||||
import io.emeraldpay.dshackle.upstream.signature.ResponseSigner
|
import io.emeraldpay.dshackle.upstream.signature.ResponseSigner
|
||||||
|
import org.springframework.cloud.sleuth.Tracer
|
||||||
|
|
||||||
// creates instance of a Quorum based reader
|
// creates instance of a Quorum based reader
|
||||||
interface QuorumReaderFactory {
|
interface QuorumReaderFactory {
|
||||||
@@ -29,11 +30,11 @@ interface QuorumReaderFactory {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun create(apis: ApiSource, quorum: CallQuorum, signer: ResponseSigner?): Reader<JsonRpcRequest, QuorumRpcReader.Result>
|
fun create(apis: ApiSource, quorum: CallQuorum, signer: ResponseSigner?, tracer: Tracer): Reader<JsonRpcRequest, QuorumRpcReader.Result>
|
||||||
|
|
||||||
class Default : QuorumReaderFactory {
|
class Default : QuorumReaderFactory {
|
||||||
override fun create(apis: ApiSource, quorum: CallQuorum, signer: ResponseSigner?): Reader<JsonRpcRequest, QuorumRpcReader.Result> {
|
override fun create(apis: ApiSource, quorum: CallQuorum, signer: ResponseSigner?, tracer: Tracer): Reader<JsonRpcRequest, QuorumRpcReader.Result> {
|
||||||
return QuorumRpcReader(apis, quorum, signer)
|
return QuorumRpcReader(apis, quorum, signer, tracer)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,7 +15,11 @@
|
|||||||
*/
|
*/
|
||||||
package io.emeraldpay.dshackle.quorum
|
package io.emeraldpay.dshackle.quorum
|
||||||
|
|
||||||
|
import io.emeraldpay.dshackle.commons.API_READER
|
||||||
|
import io.emeraldpay.dshackle.commons.SPAN_REQUEST_API_TYPE
|
||||||
|
import io.emeraldpay.dshackle.commons.SPAN_REQUEST_UPSTREAM_ID
|
||||||
import io.emeraldpay.dshackle.reader.Reader
|
import io.emeraldpay.dshackle.reader.Reader
|
||||||
|
import io.emeraldpay.dshackle.reader.SpannedReader
|
||||||
import io.emeraldpay.dshackle.upstream.ApiSource
|
import io.emeraldpay.dshackle.upstream.ApiSource
|
||||||
import io.emeraldpay.dshackle.upstream.Upstream
|
import io.emeraldpay.dshackle.upstream.Upstream
|
||||||
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcError
|
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcError
|
||||||
@@ -25,6 +29,7 @@ import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcResponse
|
|||||||
import io.emeraldpay.dshackle.upstream.signature.ResponseSigner
|
import io.emeraldpay.dshackle.upstream.signature.ResponseSigner
|
||||||
import io.emeraldpay.etherjar.rpc.RpcException
|
import io.emeraldpay.etherjar.rpc.RpcException
|
||||||
import org.slf4j.LoggerFactory
|
import org.slf4j.LoggerFactory
|
||||||
|
import org.springframework.cloud.sleuth.Tracer
|
||||||
import reactor.core.publisher.Flux
|
import reactor.core.publisher.Flux
|
||||||
import reactor.core.publisher.Mono
|
import reactor.core.publisher.Mono
|
||||||
import reactor.util.function.Tuple3
|
import reactor.util.function.Tuple3
|
||||||
@@ -42,13 +47,14 @@ class QuorumRpcReader(
|
|||||||
private val apiControl: ApiSource,
|
private val apiControl: ApiSource,
|
||||||
private val quorum: CallQuorum,
|
private val quorum: CallQuorum,
|
||||||
private val signer: ResponseSigner?,
|
private val signer: ResponseSigner?,
|
||||||
|
private val tracer: Tracer
|
||||||
) : Reader<JsonRpcRequest, QuorumRpcReader.Result> {
|
) : Reader<JsonRpcRequest, QuorumRpcReader.Result> {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private val log = LoggerFactory.getLogger(QuorumRpcReader::class.java)
|
private val log = LoggerFactory.getLogger(QuorumRpcReader::class.java)
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(apiControl: ApiSource, quorum: CallQuorum) : this(apiControl, quorum, null)
|
constructor(apiControl: ApiSource, quorum: CallQuorum, tracer: Tracer) : this(apiControl, quorum, null, tracer)
|
||||||
|
|
||||||
override fun read(key: JsonRpcRequest): Mono<Result> {
|
override fun read(key: JsonRpcRequest): Mono<Result> {
|
||||||
// needs at least one response, so start a request
|
// needs at least one response, so start a request
|
||||||
@@ -129,7 +135,12 @@ class QuorumRpcReader(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun callApi(api: Upstream, key: JsonRpcRequest): Mono<Tuple4<ByteArray, Optional<ResponseSigner.Signature>, Upstream, Optional<String>>> {
|
fun callApi(api: Upstream, key: JsonRpcRequest): Mono<Tuple4<ByteArray, Optional<ResponseSigner.Signature>, Upstream, Optional<String>>> {
|
||||||
return api.getIngressReader()
|
val apiReader = api.getIngressReader()
|
||||||
|
val spanParams = mapOf(
|
||||||
|
SPAN_REQUEST_API_TYPE to apiReader.javaClass.name,
|
||||||
|
SPAN_REQUEST_UPSTREAM_ID to api.getId()
|
||||||
|
)
|
||||||
|
return SpannedReader(apiReader, tracer, API_READER, spanParams)
|
||||||
.read(key)
|
.read(key)
|
||||||
.flatMap { response ->
|
.flatMap { response ->
|
||||||
log.debug("Received response from upstream ${api.getId()} for method ${key.method}")
|
log.debug("Received response from upstream ${api.getId()} for method ${key.method}")
|
||||||
|
|||||||
@@ -0,0 +1,57 @@
|
|||||||
|
package io.emeraldpay.dshackle.reader
|
||||||
|
|
||||||
|
import io.emeraldpay.dshackle.commons.SPAN_ERROR
|
||||||
|
import io.emeraldpay.dshackle.commons.SPAN_READER_NAME
|
||||||
|
import io.emeraldpay.dshackle.commons.SPAN_READER_RESULT
|
||||||
|
import io.emeraldpay.dshackle.commons.SPAN_REQUEST_INFO
|
||||||
|
import io.emeraldpay.dshackle.commons.SPAN_STATUS_MESSAGE
|
||||||
|
import io.emeraldpay.dshackle.data.HashId
|
||||||
|
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcRequest
|
||||||
|
import org.springframework.cloud.sleuth.Tracer
|
||||||
|
import org.springframework.cloud.sleuth.instrument.reactor.ReactorSleuth
|
||||||
|
import reactor.core.publisher.Mono
|
||||||
|
import reactor.kotlin.core.publisher.switchIfEmpty
|
||||||
|
|
||||||
|
class SpannedReader<K, D>(
|
||||||
|
private val reader: Reader<K, D>,
|
||||||
|
private val tracer: Tracer,
|
||||||
|
private val name: String,
|
||||||
|
private val additionalParams: Map<String, String> = emptyMap()
|
||||||
|
) : Reader<K, D> {
|
||||||
|
|
||||||
|
override fun read(key: K): Mono<D> {
|
||||||
|
val newSpan = tracer.nextSpan(tracer.currentSpan())
|
||||||
|
.name(reader.javaClass.name)
|
||||||
|
.tag(SPAN_READER_NAME, name)
|
||||||
|
.start()
|
||||||
|
|
||||||
|
extractInfoFromKey(key)?.let {
|
||||||
|
newSpan.tag(SPAN_REQUEST_INFO, it)
|
||||||
|
}
|
||||||
|
additionalParams.forEach { newSpan.tag(it.key, it.value) }
|
||||||
|
|
||||||
|
return reader.read(key)
|
||||||
|
.contextWrite { ReactorSleuth.putSpanInScope(tracer, it, newSpan) }
|
||||||
|
.doOnError {
|
||||||
|
newSpan.apply {
|
||||||
|
tag(SPAN_ERROR, "true")
|
||||||
|
tag(SPAN_STATUS_MESSAGE, it.message)
|
||||||
|
end()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.doOnNext { newSpan.end() }
|
||||||
|
.switchIfEmpty {
|
||||||
|
newSpan.tag(SPAN_READER_RESULT, "empty result")
|
||||||
|
newSpan.end()
|
||||||
|
Mono.empty()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun extractInfoFromKey(key: K): String? {
|
||||||
|
return when (key) {
|
||||||
|
is JsonRpcRequest -> "method: ${key.method}"
|
||||||
|
is HashId, Long -> "params: $key"
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -23,11 +23,17 @@ import io.emeraldpay.dshackle.BlockchainType
|
|||||||
import io.emeraldpay.dshackle.Chain
|
import io.emeraldpay.dshackle.Chain
|
||||||
import io.emeraldpay.dshackle.Global
|
import io.emeraldpay.dshackle.Global
|
||||||
import io.emeraldpay.dshackle.SilentException
|
import io.emeraldpay.dshackle.SilentException
|
||||||
|
import io.emeraldpay.dshackle.commons.LOCAL_READER
|
||||||
|
import io.emeraldpay.dshackle.commons.REMOTE_QUORUM_RPC_READER
|
||||||
|
import io.emeraldpay.dshackle.commons.SPAN_ERROR
|
||||||
|
import io.emeraldpay.dshackle.commons.SPAN_REQUEST_ID
|
||||||
|
import io.emeraldpay.dshackle.commons.SPAN_STATUS_MESSAGE
|
||||||
import io.emeraldpay.dshackle.config.MainConfig
|
import io.emeraldpay.dshackle.config.MainConfig
|
||||||
import io.emeraldpay.dshackle.quorum.CallQuorum
|
import io.emeraldpay.dshackle.quorum.CallQuorum
|
||||||
import io.emeraldpay.dshackle.quorum.NotLaggingQuorum
|
import io.emeraldpay.dshackle.quorum.NotLaggingQuorum
|
||||||
import io.emeraldpay.dshackle.quorum.QuorumReaderFactory
|
import io.emeraldpay.dshackle.quorum.QuorumReaderFactory
|
||||||
import io.emeraldpay.dshackle.quorum.QuorumRpcReader
|
import io.emeraldpay.dshackle.quorum.QuorumRpcReader
|
||||||
|
import io.emeraldpay.dshackle.reader.SpannedReader
|
||||||
import io.emeraldpay.dshackle.startup.UpstreamChangeEvent
|
import io.emeraldpay.dshackle.startup.UpstreamChangeEvent
|
||||||
import io.emeraldpay.dshackle.upstream.ApiSource
|
import io.emeraldpay.dshackle.upstream.ApiSource
|
||||||
import io.emeraldpay.dshackle.upstream.Multistream
|
import io.emeraldpay.dshackle.upstream.Multistream
|
||||||
@@ -137,8 +143,8 @@ open class NativeCall(
|
|||||||
|
|
||||||
private fun errorSpan(span: Span?, message: String) {
|
private fun errorSpan(span: Span?, message: String) {
|
||||||
span?.apply {
|
span?.apply {
|
||||||
tag("error", "true")
|
tag(SPAN_ERROR, "true")
|
||||||
tag("status.message", message)
|
tag(SPAN_STATUS_MESSAGE, message)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -151,7 +157,7 @@ open class NativeCall(
|
|||||||
if (requestCount > 1) {
|
if (requestCount > 1) {
|
||||||
val span = tracer.nextSpan(requestSpan)
|
val span = tracer.nextSpan(requestSpan)
|
||||||
.name(requestId)
|
.name(requestId)
|
||||||
.tag("request.id", requestId)
|
.tag(SPAN_REQUEST_ID, requestId)
|
||||||
.start()
|
.start()
|
||||||
return ReactorSleuth.putSpanInScope(tracer, ctx, span)
|
return ReactorSleuth.putSpanInScope(tracer, ctx, span)
|
||||||
}
|
}
|
||||||
@@ -170,7 +176,7 @@ open class NativeCall(
|
|||||||
return@run Mono.error(e)
|
return@run Mono.error(e)
|
||||||
}
|
}
|
||||||
if (callContext.requestCount == 1 && callContext.requestId.isNotBlank()) {
|
if (callContext.requestCount == 1 && callContext.requestId.isNotBlank()) {
|
||||||
requestSpan?.tag("request.id", callContext.requestId)
|
requestSpan?.tag(SPAN_REQUEST_ID, callContext.requestId)
|
||||||
}
|
}
|
||||||
this.fetch(parsed)
|
this.fetch(parsed)
|
||||||
.doOnError { e -> log.warn("Error during native call: ${e.message}") }
|
.doOnError { e -> log.warn("Error during native call: ${e.message}") }
|
||||||
@@ -358,7 +364,8 @@ open class NativeCall(
|
|||||||
fun fetch(ctx: ValidCallContext<ParsedCallDetails>): Mono<CallResult> {
|
fun fetch(ctx: ValidCallContext<ParsedCallDetails>): Mono<CallResult> {
|
||||||
return ctx.upstream.getLocalReader(localRouterEnabled)
|
return ctx.upstream.getLocalReader(localRouterEnabled)
|
||||||
.flatMap { api ->
|
.flatMap { api ->
|
||||||
api.read(JsonRpcRequest(ctx.payload.method, ctx.payload.params, ctx.nonce, ctx.forwardedSelector))
|
SpannedReader(api, tracer, LOCAL_READER)
|
||||||
|
.read(JsonRpcRequest(ctx.payload.method, ctx.payload.params, ctx.nonce, ctx.forwardedSelector))
|
||||||
.flatMap(JsonRpcResponse::requireResult)
|
.flatMap(JsonRpcResponse::requireResult)
|
||||||
.map {
|
.map {
|
||||||
validateResult(it, "local", ctx)
|
validateResult(it, "local", ctx)
|
||||||
@@ -381,14 +388,14 @@ open class NativeCall(
|
|||||||
if (!ctx.upstream.getMethods().isCallable(ctx.payload.method)) {
|
if (!ctx.upstream.getMethods().isCallable(ctx.payload.method)) {
|
||||||
return Mono.error(RpcException(RpcResponseError.CODE_METHOD_NOT_EXIST, "Unsupported method"))
|
return Mono.error(RpcException(RpcResponseError.CODE_METHOD_NOT_EXIST, "Unsupported method"))
|
||||||
}
|
}
|
||||||
val reader = quorumReaderFactory.create(ctx.getApis(), ctx.callQuorum, signer)
|
val reader = quorumReaderFactory.create(ctx.getApis(), ctx.callQuorum, signer, tracer)
|
||||||
val counter = if (reader is QuorumRpcReader) {
|
val counter = if (reader is QuorumRpcReader) {
|
||||||
reader.getValidAttemptsCount()
|
reader.getValidAttemptsCount()
|
||||||
} else {
|
} else {
|
||||||
AtomicInteger(-1)
|
AtomicInteger(-1)
|
||||||
}
|
}
|
||||||
|
|
||||||
return reader
|
return SpannedReader(reader, tracer, REMOTE_QUORUM_RPC_READER)
|
||||||
.read(JsonRpcRequest(ctx.payload.method, ctx.payload.params, ctx.nonce, ctx.forwardedSelector))
|
.read(JsonRpcRequest(ctx.payload.method, ctx.payload.params, ctx.nonce, ctx.forwardedSelector))
|
||||||
.map {
|
.map {
|
||||||
val bytes = ctx.resultDecorator.processResult(it)
|
val bytes = ctx.resultDecorator.processResult(it)
|
||||||
|
|||||||
@@ -20,6 +20,12 @@ import io.emeraldpay.dshackle.Global
|
|||||||
import io.emeraldpay.dshackle.cache.Caches
|
import io.emeraldpay.dshackle.cache.Caches
|
||||||
import io.emeraldpay.dshackle.cache.CurrentBlockCache
|
import io.emeraldpay.dshackle.cache.CurrentBlockCache
|
||||||
import io.emeraldpay.dshackle.cache.HeightByHashAdding
|
import io.emeraldpay.dshackle.cache.HeightByHashAdding
|
||||||
|
import io.emeraldpay.dshackle.commons.CACHE_BLOCK_BY_HASH_READER
|
||||||
|
import io.emeraldpay.dshackle.commons.CACHE_BLOCK_BY_HEIGHT_READER
|
||||||
|
import io.emeraldpay.dshackle.commons.CACHE_HEIGHT_BY_HASH_READER
|
||||||
|
import io.emeraldpay.dshackle.commons.CACHE_RECEIPTS_READER
|
||||||
|
import io.emeraldpay.dshackle.commons.CACHE_TX_BY_HASH_READER
|
||||||
|
import io.emeraldpay.dshackle.commons.DIRECT_QUORUM_RPC_READER
|
||||||
import io.emeraldpay.dshackle.data.BlockContainer
|
import io.emeraldpay.dshackle.data.BlockContainer
|
||||||
import io.emeraldpay.dshackle.data.BlockId
|
import io.emeraldpay.dshackle.data.BlockId
|
||||||
import io.emeraldpay.dshackle.data.SourceContainer
|
import io.emeraldpay.dshackle.data.SourceContainer
|
||||||
@@ -28,6 +34,7 @@ import io.emeraldpay.dshackle.data.TxId
|
|||||||
import io.emeraldpay.dshackle.reader.CompoundReader
|
import io.emeraldpay.dshackle.reader.CompoundReader
|
||||||
import io.emeraldpay.dshackle.reader.Reader
|
import io.emeraldpay.dshackle.reader.Reader
|
||||||
import io.emeraldpay.dshackle.reader.RekeyingReader
|
import io.emeraldpay.dshackle.reader.RekeyingReader
|
||||||
|
import io.emeraldpay.dshackle.reader.SpannedReader
|
||||||
import io.emeraldpay.dshackle.reader.TransformingReader
|
import io.emeraldpay.dshackle.reader.TransformingReader
|
||||||
import io.emeraldpay.dshackle.upstream.Lifecycle
|
import io.emeraldpay.dshackle.upstream.Lifecycle
|
||||||
import io.emeraldpay.dshackle.upstream.Multistream
|
import io.emeraldpay.dshackle.upstream.Multistream
|
||||||
@@ -41,6 +48,7 @@ import io.emeraldpay.etherjar.rpc.json.TransactionJson
|
|||||||
import io.emeraldpay.etherjar.rpc.json.TransactionRefJson
|
import io.emeraldpay.etherjar.rpc.json.TransactionRefJson
|
||||||
import org.apache.commons.collections4.Factory
|
import org.apache.commons.collections4.Factory
|
||||||
import org.slf4j.LoggerFactory
|
import org.slf4j.LoggerFactory
|
||||||
|
import org.springframework.cloud.sleuth.Tracer
|
||||||
import java.util.function.Function
|
import java.util.function.Function
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -49,7 +57,8 @@ import java.util.function.Function
|
|||||||
open class EthereumCachingReader(
|
open class EthereumCachingReader(
|
||||||
private val up: Multistream,
|
private val up: Multistream,
|
||||||
private val caches: Caches,
|
private val caches: Caches,
|
||||||
private val callMethodsFactory: Factory<CallMethods>
|
private val callMethodsFactory: Factory<CallMethods>,
|
||||||
|
private val tracer: Tracer
|
||||||
) : Lifecycle {
|
) : Lifecycle {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
@@ -58,7 +67,7 @@ open class EthereumCachingReader(
|
|||||||
|
|
||||||
private val objectMapper: ObjectMapper = Global.objectMapper
|
private val objectMapper: ObjectMapper = Global.objectMapper
|
||||||
private val balanceCache = CurrentBlockCache<Address, Wei>()
|
private val balanceCache = CurrentBlockCache<Address, Wei>()
|
||||||
private val directReader = EthereumDirectReader(up, caches, balanceCache, callMethodsFactory)
|
private val directReader = EthereumDirectReader(up, caches, balanceCache, callMethodsFactory, tracer)
|
||||||
|
|
||||||
val extractBlock = Function<BlockContainer, BlockJson<TransactionRefJson>> { block ->
|
val extractBlock = Function<BlockContainer, BlockJson<TransactionRefJson>> { block ->
|
||||||
val existing = block.getParsed(BlockJson::class.java)
|
val existing = block.getParsed(BlockJson::class.java)
|
||||||
@@ -86,16 +95,17 @@ open class EthereumCachingReader(
|
|||||||
private val idToTxHash = Function<TxId, TransactionId> { id -> TransactionId.from(id.value) }
|
private val idToTxHash = Function<TxId, TransactionId> { id -> TransactionId.from(id.value) }
|
||||||
|
|
||||||
private val blocksByIdAsCont = CompoundReader(
|
private val blocksByIdAsCont = CompoundReader(
|
||||||
caches.getBlocksByHash(),
|
SpannedReader(caches.getBlocksByHash(), tracer, CACHE_BLOCK_BY_HASH_READER),
|
||||||
RekeyingReader(idToBlockHash, directReader.blockReader)
|
SpannedReader(RekeyingReader(idToBlockHash, directReader.blockReader), tracer, DIRECT_QUORUM_RPC_READER)
|
||||||
)
|
)
|
||||||
|
|
||||||
private val heightByHash = HeightByHashAdding(caches, blocksByIdAsCont)
|
private val heightByHash =
|
||||||
|
SpannedReader(HeightByHashAdding(caches, blocksByIdAsCont), tracer, CACHE_HEIGHT_BY_HASH_READER)
|
||||||
|
|
||||||
fun blocksByHashAsCont(): Reader<BlockHash, BlockContainer> {
|
fun blocksByHashAsCont(): Reader<BlockHash, BlockContainer> {
|
||||||
return CompoundReader(
|
return CompoundReader(
|
||||||
RekeyingReader(blockHashToId, caches.getBlocksByHash()),
|
SpannedReader(RekeyingReader(blockHashToId, caches.getBlocksByHash()), tracer, CACHE_BLOCK_BY_HASH_READER),
|
||||||
directReader.blockReader
|
SpannedReader(directReader.blockReader, tracer, DIRECT_QUORUM_RPC_READER)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -119,8 +129,8 @@ open class EthereumCachingReader(
|
|||||||
|
|
||||||
open fun blocksByHeightAsCont(): Reader<Long, BlockContainer> {
|
open fun blocksByHeightAsCont(): Reader<Long, BlockContainer> {
|
||||||
return CompoundReader(
|
return CompoundReader(
|
||||||
caches.getBlocksByHeight(),
|
SpannedReader(caches.getBlocksByHeight(), tracer, CACHE_BLOCK_BY_HEIGHT_READER),
|
||||||
directReader.blockByHeightReader
|
SpannedReader(directReader.blockByHeightReader, tracer, DIRECT_QUORUM_RPC_READER)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -143,8 +153,8 @@ open class EthereumCachingReader(
|
|||||||
|
|
||||||
open fun txByHashAsCont(): Reader<TxId, TxContainer> {
|
open fun txByHashAsCont(): Reader<TxId, TxContainer> {
|
||||||
return CompoundReader(
|
return CompoundReader(
|
||||||
caches.getTxByHash(),
|
SpannedReader(caches.getTxByHash(), tracer, CACHE_TX_BY_HASH_READER),
|
||||||
RekeyingReader(idToTxHash, directReader.txReader)
|
SpannedReader(RekeyingReader(idToTxHash, directReader.txReader), tracer, DIRECT_QUORUM_RPC_READER)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -161,8 +171,8 @@ open class EthereumCachingReader(
|
|||||||
directReader.receiptReader
|
directReader.receiptReader
|
||||||
)
|
)
|
||||||
return CompoundReader(
|
return CompoundReader(
|
||||||
caches.getReceipts(),
|
SpannedReader(caches.getReceipts(), tracer, CACHE_RECEIPTS_READER),
|
||||||
requested
|
SpannedReader(requested, tracer, DIRECT_QUORUM_RPC_READER)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ import io.emeraldpay.etherjar.rpc.json.TransactionReceiptJson
|
|||||||
import io.emeraldpay.etherjar.rpc.json.TransactionRefJson
|
import io.emeraldpay.etherjar.rpc.json.TransactionRefJson
|
||||||
import org.apache.commons.collections4.Factory
|
import org.apache.commons.collections4.Factory
|
||||||
import org.slf4j.LoggerFactory
|
import org.slf4j.LoggerFactory
|
||||||
|
import org.springframework.cloud.sleuth.Tracer
|
||||||
import reactor.core.publisher.Mono
|
import reactor.core.publisher.Mono
|
||||||
import reactor.util.retry.Retry
|
import reactor.util.retry.Retry
|
||||||
import java.time.Duration
|
import java.time.Duration
|
||||||
@@ -41,7 +42,8 @@ class EthereumDirectReader(
|
|||||||
private val up: Multistream,
|
private val up: Multistream,
|
||||||
private val caches: Caches,
|
private val caches: Caches,
|
||||||
private val balanceCache: CurrentBlockCache<Address, Wei>,
|
private val balanceCache: CurrentBlockCache<Address, Wei>,
|
||||||
private val callMethodsFactory: Factory<CallMethods>
|
private val callMethodsFactory: Factory<CallMethods>,
|
||||||
|
private val tracer: Tracer
|
||||||
) {
|
) {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
@@ -175,7 +177,8 @@ class EthereumDirectReader(
|
|||||||
up.getApiSource(matcher),
|
up.getApiSource(matcher),
|
||||||
callMethodsFactory.create().createQuorumFor(request.method),
|
callMethodsFactory.create().createQuorumFor(request.method),
|
||||||
// we do not use Signer for internal requests because it doesn't make much sense
|
// we do not use Signer for internal requests because it doesn't make much sense
|
||||||
null
|
null,
|
||||||
|
tracer
|
||||||
)
|
)
|
||||||
}.flatMap {
|
}.flatMap {
|
||||||
it.read(request)
|
it.read(request)
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ import io.emeraldpay.dshackle.upstream.forkchoice.MostWorkForkChoice
|
|||||||
import io.emeraldpay.dshackle.upstream.forkchoice.PriorityForkChoice
|
import io.emeraldpay.dshackle.upstream.forkchoice.PriorityForkChoice
|
||||||
import io.emeraldpay.dshackle.upstream.grpc.GrpcUpstream
|
import io.emeraldpay.dshackle.upstream.grpc.GrpcUpstream
|
||||||
import org.slf4j.LoggerFactory
|
import org.slf4j.LoggerFactory
|
||||||
|
import org.springframework.cloud.sleuth.Tracer
|
||||||
import org.springframework.util.ConcurrentReferenceHashMap
|
import org.springframework.util.ConcurrentReferenceHashMap
|
||||||
import reactor.core.publisher.Flux
|
import reactor.core.publisher.Flux
|
||||||
import reactor.core.publisher.Mono
|
import reactor.core.publisher.Mono
|
||||||
@@ -49,7 +50,8 @@ open class EthereumMultistream(
|
|||||||
chain: Chain,
|
chain: Chain,
|
||||||
val upstreams: MutableList<EthereumUpstream>,
|
val upstreams: MutableList<EthereumUpstream>,
|
||||||
caches: Caches,
|
caches: Caches,
|
||||||
headScheduler: Scheduler
|
headScheduler: Scheduler,
|
||||||
|
tracer: Tracer
|
||||||
) : Multistream(chain, upstreams as MutableList<Upstream>, caches), EthereumLikeMultistream {
|
) : Multistream(chain, upstreams as MutableList<Upstream>, caches), EthereumLikeMultistream {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
@@ -65,7 +67,7 @@ open class EthereumMultistream(
|
|||||||
private val filteredHeads: MutableMap<String, Head> =
|
private val filteredHeads: MutableMap<String, Head> =
|
||||||
ConcurrentReferenceHashMap(16, ConcurrentReferenceHashMap.ReferenceType.WEAK)
|
ConcurrentReferenceHashMap(16, ConcurrentReferenceHashMap.ReferenceType.WEAK)
|
||||||
|
|
||||||
private val reader: EthereumCachingReader = EthereumCachingReader(this, this.caches, getMethodsFactory())
|
private val reader: EthereumCachingReader = EthereumCachingReader(this, this.caches, getMethodsFactory(), tracer)
|
||||||
private var subscribe = EthereumEgressSubscription(this, NoPendingTxes())
|
private var subscribe = EthereumEgressSubscription(this, NoPendingTxes())
|
||||||
|
|
||||||
private val supportsEIP1559 = when (chain) {
|
private val supportsEIP1559 = when (chain) {
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ import io.emeraldpay.dshackle.upstream.ethereum.subscribe.PendingTxesSource
|
|||||||
import io.emeraldpay.dshackle.upstream.forkchoice.PriorityForkChoice
|
import io.emeraldpay.dshackle.upstream.forkchoice.PriorityForkChoice
|
||||||
import io.emeraldpay.dshackle.upstream.grpc.GrpcUpstream
|
import io.emeraldpay.dshackle.upstream.grpc.GrpcUpstream
|
||||||
import org.slf4j.LoggerFactory
|
import org.slf4j.LoggerFactory
|
||||||
|
import org.springframework.cloud.sleuth.Tracer
|
||||||
import org.springframework.util.ConcurrentReferenceHashMap
|
import org.springframework.util.ConcurrentReferenceHashMap
|
||||||
import reactor.core.publisher.Flux
|
import reactor.core.publisher.Flux
|
||||||
import reactor.core.publisher.Mono
|
import reactor.core.publisher.Mono
|
||||||
@@ -47,7 +48,8 @@ open class EthereumPosMultiStream(
|
|||||||
chain: Chain,
|
chain: Chain,
|
||||||
val upstreams: MutableList<EthereumPosUpstream>,
|
val upstreams: MutableList<EthereumPosUpstream>,
|
||||||
caches: Caches,
|
caches: Caches,
|
||||||
headScheduler: Scheduler
|
headScheduler: Scheduler,
|
||||||
|
tracer: Tracer
|
||||||
) : Multistream(chain, upstreams as MutableList<Upstream>, caches), EthereumLikeMultistream {
|
) : Multistream(chain, upstreams as MutableList<Upstream>, caches), EthereumLikeMultistream {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
@@ -60,7 +62,7 @@ open class EthereumPosMultiStream(
|
|||||||
headScheduler
|
headScheduler
|
||||||
)
|
)
|
||||||
|
|
||||||
private val reader: EthereumCachingReader = EthereumCachingReader(this, this.caches, getMethodsFactory())
|
private val reader: EthereumCachingReader = EthereumCachingReader(this, this.caches, getMethodsFactory(), tracer)
|
||||||
private var subscribe = EthereumEgressSubscription(this, NoPendingTxes())
|
private var subscribe = EthereumEgressSubscription(this, NoPendingTxes())
|
||||||
private val feeEstimation = EthereumPriorityFees(this, reader, 256)
|
private val feeEstimation = EthereumPriorityFees(this, reader, 256)
|
||||||
private val filteredHeads: MutableMap<String, Head> =
|
private val filteredHeads: MutableMap<String, Head> =
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcRequest
|
|||||||
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcResponse
|
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcResponse
|
||||||
import io.emeraldpay.etherjar.rpc.RpcException
|
import io.emeraldpay.etherjar.rpc.RpcException
|
||||||
import io.emeraldpay.etherjar.rpc.RpcResponseError
|
import io.emeraldpay.etherjar.rpc.RpcResponseError
|
||||||
|
import org.springframework.cloud.sleuth.Tracer
|
||||||
import reactor.core.publisher.Mono
|
import reactor.core.publisher.Mono
|
||||||
import reactor.test.StepVerifier
|
import reactor.test.StepVerifier
|
||||||
import spock.lang.Specification
|
import spock.lang.Specification
|
||||||
@@ -47,7 +48,7 @@ class QuorumRpcReaderSpec extends Specification {
|
|||||||
Chain.ETHEREUM,
|
Chain.ETHEREUM,
|
||||||
[up], Selector.empty
|
[up], Selector.empty
|
||||||
)
|
)
|
||||||
def reader = new QuorumRpcReader(apis, new AlwaysQuorum())
|
def reader = new QuorumRpcReader(apis, new AlwaysQuorum(), Stub(Tracer))
|
||||||
|
|
||||||
when:
|
when:
|
||||||
def act = reader.read(new JsonRpcRequest("eth_test", []))
|
def act = reader.read(new JsonRpcRequest("eth_test", []))
|
||||||
@@ -78,7 +79,7 @@ class QuorumRpcReaderSpec extends Specification {
|
|||||||
Chain.ETHEREUM,
|
Chain.ETHEREUM,
|
||||||
[up], Selector.empty
|
[up], Selector.empty
|
||||||
)
|
)
|
||||||
def reader = new QuorumRpcReader(apis, new AlwaysQuorum())
|
def reader = new QuorumRpcReader(apis, new AlwaysQuorum(), Stub(Tracer))
|
||||||
|
|
||||||
when:
|
when:
|
||||||
def act = reader.read(new JsonRpcRequest("eth_test", []))
|
def act = reader.read(new JsonRpcRequest("eth_test", []))
|
||||||
@@ -115,7 +116,7 @@ class QuorumRpcReaderSpec extends Specification {
|
|||||||
Chain.ETHEREUM,
|
Chain.ETHEREUM,
|
||||||
[up], Selector.empty
|
[up], Selector.empty
|
||||||
)
|
)
|
||||||
def reader = new QuorumRpcReader(apis, new AlwaysQuorum())
|
def reader = new QuorumRpcReader(apis, new AlwaysQuorum(), Stub(Tracer))
|
||||||
|
|
||||||
when:
|
when:
|
||||||
def act = reader.read(new JsonRpcRequest("eth_test", []))
|
def act = reader.read(new JsonRpcRequest("eth_test", []))
|
||||||
@@ -147,7 +148,7 @@ class QuorumRpcReaderSpec extends Specification {
|
|||||||
Chain.ETHEREUM,
|
Chain.ETHEREUM,
|
||||||
[up], Selector.empty
|
[up], Selector.empty
|
||||||
)
|
)
|
||||||
def reader = new QuorumRpcReader(apis, new NonEmptyQuorum(3))
|
def reader = new QuorumRpcReader(apis, new NonEmptyQuorum(3), Stub(Tracer))
|
||||||
|
|
||||||
when:
|
when:
|
||||||
def act = reader.read(new JsonRpcRequest("eth_test", []))
|
def act = reader.read(new JsonRpcRequest("eth_test", []))
|
||||||
@@ -179,7 +180,7 @@ class QuorumRpcReaderSpec extends Specification {
|
|||||||
Chain.ETHEREUM,
|
Chain.ETHEREUM,
|
||||||
[up], Selector.empty
|
[up], Selector.empty
|
||||||
)
|
)
|
||||||
def reader = new QuorumRpcReader(apis, new NonEmptyQuorum(3))
|
def reader = new QuorumRpcReader(apis, new NonEmptyQuorum(3), Stub(Tracer))
|
||||||
|
|
||||||
when:
|
when:
|
||||||
def act = reader.read(new JsonRpcRequest("eth_test", []))
|
def act = reader.read(new JsonRpcRequest("eth_test", []))
|
||||||
@@ -211,7 +212,7 @@ class QuorumRpcReaderSpec extends Specification {
|
|||||||
Chain.ETHEREUM,
|
Chain.ETHEREUM,
|
||||||
[up], Selector.empty
|
[up], Selector.empty
|
||||||
)
|
)
|
||||||
def reader = new QuorumRpcReader(apis, new NonEmptyQuorum(3))
|
def reader = new QuorumRpcReader(apis, new NonEmptyQuorum(3), Stub(Tracer))
|
||||||
|
|
||||||
when:
|
when:
|
||||||
def act = reader.read(new JsonRpcRequest("eth_test", []))
|
def act = reader.read(new JsonRpcRequest("eth_test", []))
|
||||||
@@ -244,7 +245,7 @@ class QuorumRpcReaderSpec extends Specification {
|
|||||||
Chain.ETHEREUM,
|
Chain.ETHEREUM,
|
||||||
[up], Selector.empty
|
[up], Selector.empty
|
||||||
)
|
)
|
||||||
def reader = new QuorumRpcReader(apis, new NonEmptyQuorum(3))
|
def reader = new QuorumRpcReader(apis, new NonEmptyQuorum(3), Stub(Tracer))
|
||||||
|
|
||||||
when:
|
when:
|
||||||
def act = reader.read(new JsonRpcRequest("eth_test", []))
|
def act = reader.read(new JsonRpcRequest("eth_test", []))
|
||||||
@@ -274,7 +275,7 @@ class QuorumRpcReaderSpec extends Specification {
|
|||||||
Chain.ETHEREUM,
|
Chain.ETHEREUM,
|
||||||
[up], Selector.empty
|
[up], Selector.empty
|
||||||
)
|
)
|
||||||
def reader = new QuorumRpcReader(apis, new AlwaysQuorum())
|
def reader = new QuorumRpcReader(apis, new AlwaysQuorum(), Stub(Tracer))
|
||||||
|
|
||||||
when:
|
when:
|
||||||
def act = reader.read(new JsonRpcRequest("eth_test", []))
|
def act = reader.read(new JsonRpcRequest("eth_test", []))
|
||||||
@@ -307,7 +308,7 @@ class QuorumRpcReaderSpec extends Specification {
|
|||||||
Chain.ETHEREUM,
|
Chain.ETHEREUM,
|
||||||
[up], Selector.empty
|
[up], Selector.empty
|
||||||
)
|
)
|
||||||
def reader = new QuorumRpcReader(apis, new NotLaggingQuorum(1))
|
def reader = new QuorumRpcReader(apis, new NotLaggingQuorum(1), Stub(Tracer))
|
||||||
|
|
||||||
when:
|
when:
|
||||||
def act = reader.read(new JsonRpcRequest("eth_test", []))
|
def act = reader.read(new JsonRpcRequest("eth_test", []))
|
||||||
|
|||||||
@@ -131,7 +131,7 @@ class NativeCallSpec extends Specification {
|
|||||||
|
|
||||||
def nativeCall = nativeCall()
|
def nativeCall = nativeCall()
|
||||||
nativeCall.quorumReaderFactory = Mock(QuorumReaderFactory) {
|
nativeCall.quorumReaderFactory = Mock(QuorumReaderFactory) {
|
||||||
1 * create(_, _, _) >> Mock(Reader) {
|
1 * create(_, _, _, _) >> Mock(Reader) {
|
||||||
1 * read(_) >> Mono.just(new QuorumRpcReader.Result("\"foo\"".bytes, null, 1, Collections.singletonList(ups), null))
|
1 * read(_) >> Mono.just(new QuorumRpcReader.Result("\"foo\"".bytes, null, 1, Collections.singletonList(ups), null))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -152,7 +152,7 @@ class NativeCallSpec extends Specification {
|
|||||||
|
|
||||||
def nativeCall = nativeCall()
|
def nativeCall = nativeCall()
|
||||||
nativeCall.quorumReaderFactory = Mock(QuorumReaderFactory) {
|
nativeCall.quorumReaderFactory = Mock(QuorumReaderFactory) {
|
||||||
1 * create(_, _, _) >> Mock(Reader) {
|
1 * create(_, _, _, _) >> Mock(Reader) {
|
||||||
1 * read(new JsonRpcRequest("eth_test", [], 10)) >> Mono.empty()
|
1 * read(new JsonRpcRequest("eth_test", [], 10)) >> Mono.empty()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -176,7 +176,7 @@ class NativeCallSpec extends Specification {
|
|||||||
|
|
||||||
def nativeCall = nativeCall()
|
def nativeCall = nativeCall()
|
||||||
nativeCall.quorumReaderFactory = Mock(QuorumReaderFactory) {
|
nativeCall.quorumReaderFactory = Mock(QuorumReaderFactory) {
|
||||||
1 * create(_, _, _) >> Mock(Reader) {
|
1 * create(_, _, _, _) >> Mock(Reader) {
|
||||||
1 * read(new JsonRpcRequest("eth_test", [], 10)) >> Mono.error(
|
1 * read(new JsonRpcRequest("eth_test", [], 10)) >> Mono.error(
|
||||||
new JsonRpcException(JsonRpcResponse.Id.from(12), new JsonRpcError(-32123, "Foo Bar", "Foo Bar Baz"), true)
|
new JsonRpcException(JsonRpcResponse.Id.from(12), new JsonRpcError(-32123, "Foo Bar", "Foo Bar Baz"), true)
|
||||||
)
|
)
|
||||||
@@ -613,7 +613,7 @@ class NativeCallSpec extends Specification {
|
|||||||
}
|
}
|
||||||
def nativeCall = nativeCall(multistreamHolder)
|
def nativeCall = nativeCall(multistreamHolder)
|
||||||
nativeCall.quorumReaderFactory = Mock(QuorumReaderFactory) {
|
nativeCall.quorumReaderFactory = Mock(QuorumReaderFactory) {
|
||||||
1 * create(_, _, _) >> Mock(Reader) {
|
1 * create(_, _, _, _) >> Mock(Reader) {
|
||||||
1 * read(_) >> Mono.just(new QuorumRpcReader.Result("\"0xab\"".bytes, null, 1, Collections.singletonList(ups), null))
|
1 * read(_) >> Mono.just(new QuorumRpcReader.Result("\"0xab\"".bytes, null, 1, Collections.singletonList(ups), null))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -648,7 +648,7 @@ class NativeCallSpec extends Specification {
|
|||||||
}
|
}
|
||||||
def nativeCall = nativeCall(multistreamHolder)
|
def nativeCall = nativeCall(multistreamHolder)
|
||||||
nativeCall.quorumReaderFactory = Mock(QuorumReaderFactory) {
|
nativeCall.quorumReaderFactory = Mock(QuorumReaderFactory) {
|
||||||
1 * create(_, _, _) >> Mock(Reader) {
|
1 * create(_, _, _, _) >> Mock(Reader) {
|
||||||
1 * read(_) >> Mono.just(new QuorumRpcReader.Result("\"0xab\"".bytes, null, 1, Collections.singletonList(ups), null))
|
1 * read(_) >> Mono.just(new QuorumRpcReader.Result("\"0xab\"".bytes, null, 1, Collections.singletonList(ups), null))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,11 +19,7 @@ package io.emeraldpay.dshackle.test
|
|||||||
import io.emeraldpay.dshackle.BlockchainType
|
import io.emeraldpay.dshackle.BlockchainType
|
||||||
import io.emeraldpay.dshackle.Chain
|
import io.emeraldpay.dshackle.Chain
|
||||||
import io.emeraldpay.dshackle.cache.Caches
|
import io.emeraldpay.dshackle.cache.Caches
|
||||||
import io.emeraldpay.dshackle.upstream.Head
|
import io.emeraldpay.dshackle.upstream.*
|
||||||
import io.emeraldpay.dshackle.upstream.Multistream
|
|
||||||
import io.emeraldpay.dshackle.upstream.MultistreamHolder
|
|
||||||
import io.emeraldpay.dshackle.upstream.Selector
|
|
||||||
import io.emeraldpay.dshackle.upstream.Upstream
|
|
||||||
import io.emeraldpay.dshackle.upstream.bitcoin.BitcoinMultistream
|
import io.emeraldpay.dshackle.upstream.bitcoin.BitcoinMultistream
|
||||||
import io.emeraldpay.dshackle.upstream.bitcoin.BitcoinRpcUpstream
|
import io.emeraldpay.dshackle.upstream.bitcoin.BitcoinRpcUpstream
|
||||||
import io.emeraldpay.dshackle.upstream.calls.CallMethods
|
import io.emeraldpay.dshackle.upstream.calls.CallMethods
|
||||||
@@ -32,6 +28,8 @@ import io.emeraldpay.dshackle.upstream.ethereum.EthereumCachingReader
|
|||||||
import io.emeraldpay.dshackle.upstream.ethereum.EthereumPosMultiStream
|
import io.emeraldpay.dshackle.upstream.ethereum.EthereumPosMultiStream
|
||||||
import io.emeraldpay.dshackle.upstream.ethereum.EthereumPosRpcUpstream
|
import io.emeraldpay.dshackle.upstream.ethereum.EthereumPosRpcUpstream
|
||||||
import org.jetbrains.annotations.NotNull
|
import org.jetbrains.annotations.NotNull
|
||||||
|
import org.springframework.cloud.sleuth.Tracer
|
||||||
|
import org.springframework.cloud.sleuth.brave.bridge.BraveTracer
|
||||||
import reactor.core.scheduler.Schedulers
|
import reactor.core.scheduler.Schedulers
|
||||||
|
|
||||||
class MultistreamHolderMock implements MultistreamHolder {
|
class MultistreamHolderMock implements MultistreamHolder {
|
||||||
@@ -49,7 +47,10 @@ class MultistreamHolderMock implements MultistreamHolder {
|
|||||||
if (up instanceof EthereumPosMultiStream) {
|
if (up instanceof EthereumPosMultiStream) {
|
||||||
upstreams[chain] = up
|
upstreams[chain] = up
|
||||||
} else if (up instanceof EthereumPosRpcUpstream) {
|
} else if (up instanceof EthereumPosRpcUpstream) {
|
||||||
upstreams[chain] = new EthereumPosMultiStream(chain, [up as EthereumPosRpcUpstream], Caches.default(), Schedulers.boundedElastic())
|
upstreams[chain] = new EthereumPosMultiStream(
|
||||||
|
chain, [up as EthereumPosRpcUpstream], Caches.default(),
|
||||||
|
Schedulers.boundedElastic(), TestingCommons.tracerMock()
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
throw new IllegalArgumentException("Unsupported upstream type ${up.class}")
|
throw new IllegalArgumentException("Unsupported upstream type ${up.class}")
|
||||||
}
|
}
|
||||||
@@ -97,7 +98,7 @@ class MultistreamHolderMock implements MultistreamHolder {
|
|||||||
Head customHead = null
|
Head customHead = null
|
||||||
|
|
||||||
EthereumMultistreamMock(@NotNull Chain chain, @NotNull List<EthereumPosRpcUpstream> upstreams, @NotNull Caches caches) {
|
EthereumMultistreamMock(@NotNull Chain chain, @NotNull List<EthereumPosRpcUpstream> upstreams, @NotNull Caches caches) {
|
||||||
super(chain, upstreams, caches, Schedulers.boundedElastic())
|
super(chain, upstreams, caches, Schedulers.boundedElastic(), new BraveTracer(null, null, null))
|
||||||
}
|
}
|
||||||
|
|
||||||
EthereumMultistreamMock(@NotNull Chain chain, @NotNull List<EthereumPosRpcUpstream> upstreams) {
|
EthereumMultistreamMock(@NotNull Chain chain, @NotNull List<EthereumPosRpcUpstream> upstreams) {
|
||||||
|
|||||||
@@ -47,6 +47,10 @@ class TestingCommons {
|
|||||||
return new ApiReaderMock()
|
return new ApiReaderMock()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static TracerMock tracerMock() {
|
||||||
|
return new TracerMock(null, null, null)
|
||||||
|
}
|
||||||
|
|
||||||
static EthereumPosRpcUpstreamMock upstream() {
|
static EthereumPosRpcUpstreamMock upstream() {
|
||||||
return new EthereumPosRpcUpstreamMock(Chain.ETHEREUM, api())
|
return new EthereumPosRpcUpstreamMock(Chain.ETHEREUM, api())
|
||||||
}
|
}
|
||||||
@@ -84,7 +88,7 @@ class TestingCommons {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static Multistream multistream(EthereumPosRpcUpstreamMock up) {
|
static Multistream multistream(EthereumPosRpcUpstreamMock up) {
|
||||||
return new EthereumPosMultiStream(Chain.ETHEREUM, [up], Caches.default(), Schedulers.boundedElastic()).tap {
|
return new EthereumPosMultiStream(Chain.ETHEREUM, [up], Caches.default(), Schedulers.boundedElastic(), tracerMock()).tap {
|
||||||
start()
|
start()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -105,11 +109,11 @@ class TestingCommons {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static Multistream multistreamWithoutUpstreams(Chain chain) {
|
static Multistream multistreamWithoutUpstreams(Chain chain) {
|
||||||
return new EthereumPosMultiStream(chain, [], emptyCaches().getCaches(chain), Schedulers.boundedElastic())
|
return new EthereumPosMultiStream(chain, [], emptyCaches().getCaches(chain), Schedulers.boundedElastic(), tracerMock())
|
||||||
}
|
}
|
||||||
|
|
||||||
static Multistream multistreamClassicWithoutUpstreams(Chain chain) {
|
static Multistream multistreamClassicWithoutUpstreams(Chain chain) {
|
||||||
return new EthereumMultistream(chain, [], emptyCaches().getCaches(chain), Schedulers.boundedElastic())
|
return new EthereumMultistream(chain, [], emptyCaches().getCaches(chain), Schedulers.boundedElastic(), tracerMock())
|
||||||
}
|
}
|
||||||
|
|
||||||
static FileResolver fileResolver() {
|
static FileResolver fileResolver() {
|
||||||
|
|||||||
@@ -0,0 +1,64 @@
|
|||||||
|
package io.emeraldpay.dshackle.test
|
||||||
|
|
||||||
|
import brave.Tracer
|
||||||
|
import org.springframework.cloud.sleuth.CurrentTraceContext
|
||||||
|
import org.springframework.cloud.sleuth.Span
|
||||||
|
import org.springframework.cloud.sleuth.TraceContext
|
||||||
|
import org.springframework.cloud.sleuth.brave.bridge.BraveBaggageManager
|
||||||
|
import org.springframework.cloud.sleuth.brave.bridge.BraveSpan
|
||||||
|
import org.springframework.cloud.sleuth.brave.bridge.BraveTracer
|
||||||
|
import spock.mock.DetachedMockFactory
|
||||||
|
|
||||||
|
class TracerMock extends BraveTracer {
|
||||||
|
private final spanMock = new SpanMock(null)
|
||||||
|
private static final mockFactory = new DetachedMockFactory()
|
||||||
|
|
||||||
|
TracerMock(Tracer tracer, CurrentTraceContext context, BraveBaggageManager braveBaggageManager) {
|
||||||
|
super(tracer, context, braveBaggageManager)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
Span nextSpan(Span parent) {
|
||||||
|
return spanMock
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
Span currentSpan() {
|
||||||
|
return spanMock
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
SpanInScope withSpan(Span span) {
|
||||||
|
return mockFactory.Stub(SpanInScope)
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class SpanMock extends BraveSpan {
|
||||||
|
SpanMock(brave.Span delegate) {
|
||||||
|
super(delegate)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
Span start() {
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
Span name(String name) {
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
Span tag(String key, String value) {
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
void end() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
TraceContext context() {
|
||||||
|
return mockFactory.Stub(TraceContext)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -51,7 +51,7 @@ class MultistreamSpec extends Specification {
|
|||||||
setup:
|
setup:
|
||||||
def up1 = new EthereumPosRpcUpstreamMock("test1", Chain.ETHEREUM, TestingCommons.api(), new DirectCallMethods(["eth_test1", "eth_test2"]))
|
def up1 = new EthereumPosRpcUpstreamMock("test1", Chain.ETHEREUM, TestingCommons.api(), new DirectCallMethods(["eth_test1", "eth_test2"]))
|
||||||
def up2 = new EthereumPosRpcUpstreamMock("test1", Chain.ETHEREUM, TestingCommons.api(), new DirectCallMethods(["eth_test2", "eth_test3"]))
|
def up2 = new EthereumPosRpcUpstreamMock("test1", Chain.ETHEREUM, TestingCommons.api(), new DirectCallMethods(["eth_test2", "eth_test3"]))
|
||||||
def aggr = new EthereumPosMultiStream(Chain.ETHEREUM, [up1, up2], Caches.default(), Schedulers.boundedElastic())
|
def aggr = new EthereumPosMultiStream(Chain.ETHEREUM, [up1, up2], Caches.default(), Schedulers.boundedElastic(), TestingCommons.tracerMock())
|
||||||
when:
|
when:
|
||||||
aggr.onUpstreamsUpdated()
|
aggr.onUpstreamsUpdated()
|
||||||
def act = aggr.getMethods()
|
def act = aggr.getMethods()
|
||||||
@@ -187,7 +187,7 @@ class MultistreamSpec extends Specification {
|
|||||||
def up1 = TestingCommons.upstream("test-1", "internal")
|
def up1 = TestingCommons.upstream("test-1", "internal")
|
||||||
def up2 = TestingCommons.upstream("test-2", "external")
|
def up2 = TestingCommons.upstream("test-2", "external")
|
||||||
def up3 = TestingCommons.upstream("test-3", "external")
|
def up3 = TestingCommons.upstream("test-3", "external")
|
||||||
def multistream = new EthereumPosMultiStream(Chain.ETHEREUM, [up1, up2, up3], Caches.default(), Schedulers.boundedElastic())
|
def multistream = new EthereumPosMultiStream(Chain.ETHEREUM, [up1, up2, up3], Caches.default(), Schedulers.boundedElastic(), TestingCommons.tracerMock())
|
||||||
|
|
||||||
expect:
|
expect:
|
||||||
multistream.getHead(new Selector.LabelMatcher("provider", ["internal"])).is(up1.ethereumHeadMock)
|
multistream.getHead(new Selector.LabelMatcher("provider", ["internal"])).is(up1.ethereumHeadMock)
|
||||||
@@ -255,7 +255,7 @@ class MultistreamSpec extends Specification {
|
|||||||
class TestEthereumPosMultistream extends EthereumPosMultiStream {
|
class TestEthereumPosMultistream extends EthereumPosMultiStream {
|
||||||
|
|
||||||
TestEthereumPosMultistream(@NotNull Chain chain, @NotNull List<EthereumPosUpstream> upstreams, @NotNull Caches caches) {
|
TestEthereumPosMultistream(@NotNull Chain chain, @NotNull List<EthereumPosUpstream> upstreams, @NotNull Caches caches) {
|
||||||
super(chain, upstreams, caches, Schedulers.boundedElastic())
|
super(chain, upstreams, caches, Schedulers.boundedElastic(), TestingCommons.tracerMock())
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import io.emeraldpay.dshackle.data.DefaultContainer
|
|||||||
import io.emeraldpay.dshackle.quorum.QuorumReaderFactory
|
import io.emeraldpay.dshackle.quorum.QuorumReaderFactory
|
||||||
import io.emeraldpay.dshackle.quorum.QuorumRpcReader
|
import io.emeraldpay.dshackle.quorum.QuorumRpcReader
|
||||||
import io.emeraldpay.dshackle.reader.Reader
|
import io.emeraldpay.dshackle.reader.Reader
|
||||||
|
import io.emeraldpay.dshackle.test.TestingCommons
|
||||||
import io.emeraldpay.dshackle.upstream.ApiSource
|
import io.emeraldpay.dshackle.upstream.ApiSource
|
||||||
import io.emeraldpay.dshackle.upstream.Head
|
import io.emeraldpay.dshackle.upstream.Head
|
||||||
import io.emeraldpay.dshackle.upstream.Multistream
|
import io.emeraldpay.dshackle.upstream.Multistream
|
||||||
@@ -51,10 +52,10 @@ class EthereumDirectReaderSpec extends Specification {
|
|||||||
1 * create() >> new DefaultEthereumMethods(Chain.ETHEREUM)
|
1 * create() >> new DefaultEthereumMethods(Chain.ETHEREUM)
|
||||||
}
|
}
|
||||||
EthereumDirectReader reader = new EthereumDirectReader(
|
EthereumDirectReader reader = new EthereumDirectReader(
|
||||||
up, Caches.default(), new CurrentBlockCache(), calls
|
up, Caches.default(), new CurrentBlockCache(), calls, TestingCommons.tracerMock()
|
||||||
)
|
)
|
||||||
reader.quorumReaderFactory = Mock(QuorumReaderFactory) {
|
reader.quorumReaderFactory = Mock(QuorumReaderFactory) {
|
||||||
1 * create(_, _, _) >> Mock(Reader) {
|
1 * create(_, _, _, _) >> Mock(Reader) {
|
||||||
1 * read(new JsonRpcRequest("eth_getBlockByHash", [hash1, false])) >> Mono.just(
|
1 * read(new JsonRpcRequest("eth_getBlockByHash", [hash1, false])) >> Mono.just(
|
||||||
new QuorumRpcReader.Result(
|
new QuorumRpcReader.Result(
|
||||||
Global.objectMapper.writeValueAsBytes(json), null, 1, resolvers, null)
|
Global.objectMapper.writeValueAsBytes(json), null, 1, resolvers, null)
|
||||||
@@ -81,10 +82,10 @@ class EthereumDirectReaderSpec extends Specification {
|
|||||||
1 * create() >> new DefaultEthereumMethods(Chain.ETHEREUM)
|
1 * create() >> new DefaultEthereumMethods(Chain.ETHEREUM)
|
||||||
}
|
}
|
||||||
EthereumDirectReader reader = new EthereumDirectReader(
|
EthereumDirectReader reader = new EthereumDirectReader(
|
||||||
up, Caches.default(), new CurrentBlockCache(), calls
|
up, Caches.default(), new CurrentBlockCache(), calls, TestingCommons.tracerMock()
|
||||||
)
|
)
|
||||||
reader.quorumReaderFactory = Mock(QuorumReaderFactory) {
|
reader.quorumReaderFactory = Mock(QuorumReaderFactory) {
|
||||||
1 * create(_, _, _) >> Mock(Reader) {
|
1 * create(_, _, _, _) >> Mock(Reader) {
|
||||||
1 * read(new JsonRpcRequest("eth_getBlockByHash", [hash1, false])) >> Mono.just(
|
1 * read(new JsonRpcRequest("eth_getBlockByHash", [hash1, false])) >> Mono.just(
|
||||||
new QuorumRpcReader.Result(
|
new QuorumRpcReader.Result(
|
||||||
Global.objectMapper.writeValueAsBytes(null), null, 1, resolvers, null
|
Global.objectMapper.writeValueAsBytes(null), null, 1, resolvers, null
|
||||||
@@ -116,10 +117,10 @@ class EthereumDirectReaderSpec extends Specification {
|
|||||||
1 * create() >> new DefaultEthereumMethods(Chain.ETHEREUM)
|
1 * create() >> new DefaultEthereumMethods(Chain.ETHEREUM)
|
||||||
}
|
}
|
||||||
EthereumDirectReader reader = new EthereumDirectReader(
|
EthereumDirectReader reader = new EthereumDirectReader(
|
||||||
up, Caches.default(), new CurrentBlockCache(), calls
|
up, Caches.default(), new CurrentBlockCache(), calls, TestingCommons.tracerMock()
|
||||||
)
|
)
|
||||||
reader.quorumReaderFactory = Mock(QuorumReaderFactory) {
|
reader.quorumReaderFactory = Mock(QuorumReaderFactory) {
|
||||||
1 * create(_, _, _) >> Mock(Reader) {
|
1 * create(_, _, _, _) >> Mock(Reader) {
|
||||||
1 * read(new JsonRpcRequest("eth_getBlockByNumber", ["0x64", false])) >> Mono.just(
|
1 * read(new JsonRpcRequest("eth_getBlockByNumber", ["0x64", false])) >> Mono.just(
|
||||||
new QuorumRpcReader.Result(
|
new QuorumRpcReader.Result(
|
||||||
Global.objectMapper.writeValueAsBytes(json), null, 1, resolvers, null
|
Global.objectMapper.writeValueAsBytes(json), null, 1, resolvers, null
|
||||||
@@ -152,10 +153,10 @@ class EthereumDirectReaderSpec extends Specification {
|
|||||||
1 * create() >> new DefaultEthereumMethods(Chain.ETHEREUM)
|
1 * create() >> new DefaultEthereumMethods(Chain.ETHEREUM)
|
||||||
}
|
}
|
||||||
EthereumDirectReader reader = new EthereumDirectReader(
|
EthereumDirectReader reader = new EthereumDirectReader(
|
||||||
up, Caches.default(), new CurrentBlockCache(), calls
|
up, Caches.default(), new CurrentBlockCache(), calls, TestingCommons.tracerMock()
|
||||||
)
|
)
|
||||||
reader.quorumReaderFactory = Mock(QuorumReaderFactory) {
|
reader.quorumReaderFactory = Mock(QuorumReaderFactory) {
|
||||||
1 * create(_, _, _) >> Mock(Reader) {
|
1 * create(_, _, _, _) >> Mock(Reader) {
|
||||||
1 * read(new JsonRpcRequest("eth_getTransactionByHash", [hash1])) >> Mono.just(
|
1 * read(new JsonRpcRequest("eth_getTransactionByHash", [hash1])) >> Mono.just(
|
||||||
new QuorumRpcReader.Result(
|
new QuorumRpcReader.Result(
|
||||||
Global.objectMapper.writeValueAsBytes(json), null, 1, resolvers, null
|
Global.objectMapper.writeValueAsBytes(json), null, 1, resolvers, null
|
||||||
@@ -188,10 +189,10 @@ class EthereumDirectReaderSpec extends Specification {
|
|||||||
1 * create() >> new DefaultEthereumMethods(Chain.ETHEREUM)
|
1 * create() >> new DefaultEthereumMethods(Chain.ETHEREUM)
|
||||||
}
|
}
|
||||||
EthereumDirectReader reader = new EthereumDirectReader(
|
EthereumDirectReader reader = new EthereumDirectReader(
|
||||||
up, Caches.default(), new CurrentBlockCache(), calls
|
up, Caches.default(), new CurrentBlockCache(), calls, TestingCommons.tracerMock()
|
||||||
)
|
)
|
||||||
reader.quorumReaderFactory = Mock(QuorumReaderFactory) {
|
reader.quorumReaderFactory = Mock(QuorumReaderFactory) {
|
||||||
1 * create(_, _, _) >> Mock(Reader) {
|
1 * create(_, _, _, _) >> Mock(Reader) {
|
||||||
1 * read(new JsonRpcRequest("eth_getTransactionReceipt", [hash1])) >> Mono.just(
|
1 * read(new JsonRpcRequest("eth_getTransactionReceipt", [hash1])) >> Mono.just(
|
||||||
new QuorumRpcReader.Result(
|
new QuorumRpcReader.Result(
|
||||||
Global.objectMapper.writeValueAsBytes(json), null, 1, new ArrayList<Byte>(), null
|
Global.objectMapper.writeValueAsBytes(json), null, 1, new ArrayList<Byte>(), null
|
||||||
@@ -225,10 +226,10 @@ class EthereumDirectReaderSpec extends Specification {
|
|||||||
1 * cacheReceipt(Caches.Tag.REQUESTED, { DefaultContainer data -> data.txId.toHex() == hash1.substring(2) && data.height == 100 })
|
1 * cacheReceipt(Caches.Tag.REQUESTED, { DefaultContainer data -> data.txId.toHex() == hash1.substring(2) && data.height == 100 })
|
||||||
}
|
}
|
||||||
EthereumDirectReader reader = new EthereumDirectReader(
|
EthereumDirectReader reader = new EthereumDirectReader(
|
||||||
up, caches, new CurrentBlockCache(), calls
|
up, caches, new CurrentBlockCache(), calls, TestingCommons.tracerMock()
|
||||||
)
|
)
|
||||||
reader.quorumReaderFactory = Mock(QuorumReaderFactory) {
|
reader.quorumReaderFactory = Mock(QuorumReaderFactory) {
|
||||||
1 * create(_, _, _) >> Mock(Reader) {
|
1 * create(_, _, _, _) >> Mock(Reader) {
|
||||||
1 * read(new JsonRpcRequest("eth_getTransactionReceipt", [hash1])) >> Mono.just(
|
1 * read(new JsonRpcRequest("eth_getTransactionReceipt", [hash1])) >> Mono.just(
|
||||||
new QuorumRpcReader.Result(
|
new QuorumRpcReader.Result(
|
||||||
Global.objectMapper.writeValueAsBytes(json), null, 1, new ArrayList<Byte>(), null
|
Global.objectMapper.writeValueAsBytes(json), null, 1, new ArrayList<Byte>(), null
|
||||||
@@ -253,10 +254,10 @@ class EthereumDirectReaderSpec extends Specification {
|
|||||||
1 * create() >> new DefaultEthereumMethods(Chain.ETHEREUM)
|
1 * create() >> new DefaultEthereumMethods(Chain.ETHEREUM)
|
||||||
}
|
}
|
||||||
EthereumDirectReader reader = new EthereumDirectReader(
|
EthereumDirectReader reader = new EthereumDirectReader(
|
||||||
up, Caches.default(), new CurrentBlockCache(), calls
|
up, Caches.default(), new CurrentBlockCache(), calls, TestingCommons.tracerMock()
|
||||||
)
|
)
|
||||||
reader.quorumReaderFactory = Mock(QuorumReaderFactory) {
|
reader.quorumReaderFactory = Mock(QuorumReaderFactory) {
|
||||||
1 * create(_, _, _) >> Mock(Reader) {
|
1 * create(_, _, _, _) >> Mock(Reader) {
|
||||||
1 * read(new JsonRpcRequest("eth_getTransactionByHash", [hash1])) >> Mono.just(
|
1 * read(new JsonRpcRequest("eth_getTransactionByHash", [hash1])) >> Mono.just(
|
||||||
new QuorumRpcReader.Result(
|
new QuorumRpcReader.Result(
|
||||||
Global.objectMapper.writeValueAsBytes(null), null, 1, resolvers, null
|
Global.objectMapper.writeValueAsBytes(null), null, 1, resolvers, null
|
||||||
@@ -284,10 +285,10 @@ class EthereumDirectReaderSpec extends Specification {
|
|||||||
1 * create() >> new DefaultEthereumMethods(Chain.ETHEREUM)
|
1 * create() >> new DefaultEthereumMethods(Chain.ETHEREUM)
|
||||||
}
|
}
|
||||||
EthereumDirectReader reader = new EthereumDirectReader(
|
EthereumDirectReader reader = new EthereumDirectReader(
|
||||||
up, Caches.default(), new CurrentBlockCache(), calls
|
up, Caches.default(), new CurrentBlockCache(), calls, TestingCommons.tracerMock()
|
||||||
)
|
)
|
||||||
reader.quorumReaderFactory = Mock(QuorumReaderFactory) {
|
reader.quorumReaderFactory = Mock(QuorumReaderFactory) {
|
||||||
1 * create(_, _, _) >> Mock(Reader) {
|
1 * create(_, _, _, _) >> Mock(Reader) {
|
||||||
1 * read(new JsonRpcRequest("eth_getBalance", [address1, "latest"])) >> Mono.just(
|
1 * read(new JsonRpcRequest("eth_getBalance", [address1, "latest"])) >> Mono.just(
|
||||||
new QuorumRpcReader.Result(
|
new QuorumRpcReader.Result(
|
||||||
Global.objectMapper.writeValueAsBytes("0x100"), null, 1, resolvers, null
|
Global.objectMapper.writeValueAsBytes("0x100"), null, 1, resolvers, null
|
||||||
@@ -316,10 +317,10 @@ class EthereumDirectReaderSpec extends Specification {
|
|||||||
1 * create() >> new DefaultEthereumMethods(Chain.ETHEREUM)
|
1 * create() >> new DefaultEthereumMethods(Chain.ETHEREUM)
|
||||||
}
|
}
|
||||||
EthereumDirectReader reader = new EthereumDirectReader(
|
EthereumDirectReader reader = new EthereumDirectReader(
|
||||||
up, Caches.default(), new CurrentBlockCache(), calls
|
up, Caches.default(), new CurrentBlockCache(), calls, TestingCommons.tracerMock()
|
||||||
)
|
)
|
||||||
reader.quorumReaderFactory = Mock(QuorumReaderFactory) {
|
reader.quorumReaderFactory = Mock(QuorumReaderFactory) {
|
||||||
1 * create(_, _, _) >> Mock(Reader) {
|
1 * create(_, _, _, _) >> Mock(Reader) {
|
||||||
1 * read(new JsonRpcRequest("eth_getBalance", [address1, "0xa8c9bb"])) >> Mono.just(
|
1 * read(new JsonRpcRequest("eth_getBalance", [address1, "0xa8c9bb"])) >> Mono.just(
|
||||||
new QuorumRpcReader.Result(
|
new QuorumRpcReader.Result(
|
||||||
Global.objectMapper.writeValueAsBytes("0x100"), null, 1, resolvers, null
|
Global.objectMapper.writeValueAsBytes("0x100"), null, 1, resolvers, null
|
||||||
@@ -356,14 +357,14 @@ class EthereumDirectReaderSpec extends Specification {
|
|||||||
Global.objectMapper.writeValueAsBytes(json), null, 1, resolvers, null)
|
Global.objectMapper.writeValueAsBytes(json), null, 1, resolvers, null)
|
||||||
)
|
)
|
||||||
EthereumDirectReader ethereumDirectReader = new EthereumDirectReader(
|
EthereumDirectReader ethereumDirectReader = new EthereumDirectReader(
|
||||||
up, Caches.default(), new CurrentBlockCache(), calls
|
up, Caches.default(), new CurrentBlockCache(), calls, TestingCommons.tracerMock()
|
||||||
)
|
)
|
||||||
ethereumDirectReader.quorumReaderFactory = Mock(QuorumReaderFactory) {
|
ethereumDirectReader.quorumReaderFactory = Mock(QuorumReaderFactory) {
|
||||||
2 * create(_, _, _) >> Mock(Reader) {
|
2 * create(_, _, _, _) >> Mock(Reader) {
|
||||||
2 * read(new JsonRpcRequest("eth_getBlockByHash", [hash1, false])) >>>
|
2 * read(new JsonRpcRequest("eth_getBlockByHash", [hash1, false])) >>>
|
||||||
[Mono.error(new RuntimeException()), Mono.error(new RuntimeException())]
|
[Mono.error(new RuntimeException()), Mono.error(new RuntimeException())]
|
||||||
}
|
}
|
||||||
1 * create(_, _, _) >> Mock(Reader) {
|
1 * create(_, _, _, _) >> Mock(Reader) {
|
||||||
1 * read(new JsonRpcRequest("eth_getBlockByHash", [hash1, false])) >> result
|
1 * read(new JsonRpcRequest("eth_getBlockByHash", [hash1, false])) >> result
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -398,14 +399,14 @@ class EthereumDirectReaderSpec extends Specification {
|
|||||||
Global.objectMapper.writeValueAsBytes(json), null, 1, resolvers, null)
|
Global.objectMapper.writeValueAsBytes(json), null, 1, resolvers, null)
|
||||||
)
|
)
|
||||||
EthereumDirectReader ethereumDirectReader = new EthereumDirectReader(
|
EthereumDirectReader ethereumDirectReader = new EthereumDirectReader(
|
||||||
up, Caches.default(), new CurrentBlockCache(), calls
|
up, Caches.default(), new CurrentBlockCache(), calls, TestingCommons.tracerMock()
|
||||||
)
|
)
|
||||||
ethereumDirectReader.quorumReaderFactory = Mock(QuorumReaderFactory) {
|
ethereumDirectReader.quorumReaderFactory = Mock(QuorumReaderFactory) {
|
||||||
2 * create(_, _, _) >> Mock(Reader) {
|
2 * create(_, _, _, _) >> Mock(Reader) {
|
||||||
2 * read(new JsonRpcRequest("eth_getBlockByNumber", ["0x64", false])) >>>
|
2 * read(new JsonRpcRequest("eth_getBlockByNumber", ["0x64", false])) >>>
|
||||||
[Mono.error(new RuntimeException()), Mono.error(new RuntimeException())]
|
[Mono.error(new RuntimeException()), Mono.error(new RuntimeException())]
|
||||||
}
|
}
|
||||||
1 * create(_, _, _) >> Mock(Reader) {
|
1 * create(_, _, _, _) >> Mock(Reader) {
|
||||||
1 * read(new JsonRpcRequest("eth_getBlockByNumber", ["0x64", false])) >> result
|
1 * read(new JsonRpcRequest("eth_getBlockByNumber", ["0x64", false])) >> result
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,7 +26,8 @@ class EthereumLocalReaderSpec extends Specification {
|
|||||||
new EthereumCachingReader(
|
new EthereumCachingReader(
|
||||||
TestingCommons.multistream(TestingCommons.api()),
|
TestingCommons.multistream(TestingCommons.api()),
|
||||||
Caches.default(),
|
Caches.default(),
|
||||||
ConstantFactory.constantFactory(new DefaultEthereumMethods(Chain.ETHEREUM))
|
ConstantFactory.constantFactory(new DefaultEthereumMethods(Chain.ETHEREUM)),
|
||||||
|
TestingCommons.tracerMock()
|
||||||
),
|
),
|
||||||
methods,
|
methods,
|
||||||
new EmptyHead(),
|
new EmptyHead(),
|
||||||
@@ -45,7 +46,8 @@ class EthereumLocalReaderSpec extends Specification {
|
|||||||
new EthereumCachingReader(
|
new EthereumCachingReader(
|
||||||
TestingCommons.multistream(TestingCommons.api()),
|
TestingCommons.multistream(TestingCommons.api()),
|
||||||
Caches.default(),
|
Caches.default(),
|
||||||
ConstantFactory.constantFactory(new DefaultEthereumMethods(Chain.ETHEREUM))
|
ConstantFactory.constantFactory(new DefaultEthereumMethods(Chain.ETHEREUM)),
|
||||||
|
TestingCommons.tracerMock()
|
||||||
),
|
),
|
||||||
methods,
|
methods,
|
||||||
new EmptyHead(),
|
new EmptyHead(),
|
||||||
|
|||||||
Reference in New Issue
Block a user