solution: refactoring, make ObjectMapper as a global object, not bean
This commit is contained in:
@@ -73,20 +73,6 @@ open class Config(
|
||||
return target
|
||||
}
|
||||
|
||||
@Bean
|
||||
open fun objectMapper(): ObjectMapper {
|
||||
val module = SimpleModule("EmeraldDshackle", Version(1, 0, 0, null, null, null))
|
||||
|
||||
val objectMapper = ObjectMapper()
|
||||
objectMapper.registerModule(module)
|
||||
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
|
||||
objectMapper
|
||||
.setDateFormat(SimpleDateFormat("yyyy-MM-dd\'T\'HH:mm:ss.SSS"))
|
||||
.setTimeZone(TimeZone.getTimeZone("UTC"))
|
||||
|
||||
return objectMapper
|
||||
}
|
||||
|
||||
@Bean @Qualifier("upstreamScheduler")
|
||||
open fun upstreamScheduler(): Scheduler {
|
||||
return Schedulers.fromExecutorService(Executors.newFixedThreadPool(16))
|
||||
|
||||
47
src/main/kotlin/io/emeraldpay/dshackle/Global.kt
Normal file
47
src/main/kotlin/io/emeraldpay/dshackle/Global.kt
Normal file
@@ -0,0 +1,47 @@
|
||||
/**
|
||||
* Copyright (c) 2020 EmeraldPay, Inc
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.emeraldpay.dshackle
|
||||
|
||||
import com.fasterxml.jackson.core.Version
|
||||
import com.fasterxml.jackson.databind.DeserializationFeature
|
||||
import com.fasterxml.jackson.databind.ObjectMapper
|
||||
import com.fasterxml.jackson.databind.module.SimpleModule
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.*
|
||||
|
||||
class Global {
|
||||
|
||||
companion object {
|
||||
|
||||
@JvmStatic
|
||||
val objectMapper: ObjectMapper = createObjectMapper()
|
||||
|
||||
private fun createObjectMapper(): ObjectMapper {
|
||||
val module = SimpleModule("EmeraldDshackle", Version(1, 0, 0, null, null, null))
|
||||
|
||||
val objectMapper = ObjectMapper()
|
||||
objectMapper.registerModule(module)
|
||||
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
|
||||
objectMapper
|
||||
.setDateFormat(SimpleDateFormat("yyyy-MM-dd\'T\'HH:mm:ss.SSS"))
|
||||
.setTimeZone(TimeZone.getTimeZone("UTC"))
|
||||
|
||||
return objectMapper
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -16,6 +16,7 @@
|
||||
package io.emeraldpay.dshackle.cache
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper
|
||||
import io.emeraldpay.dshackle.Global
|
||||
import io.emeraldpay.dshackle.data.BlockContainer
|
||||
import io.emeraldpay.dshackle.data.BlockId
|
||||
import io.emeraldpay.dshackle.data.TxContainer
|
||||
@@ -34,8 +35,7 @@ open class Caches(
|
||||
private val blocksByHeight: HeightCache,
|
||||
private val memTxsByHash: TxMemCache,
|
||||
private val redisBlocksByHash: BlocksRedisCache?,
|
||||
private val redisTxsByHash: TxRedisCache?,
|
||||
private val objectMapper: ObjectMapper
|
||||
private val redisTxsByHash: TxRedisCache?
|
||||
) {
|
||||
|
||||
companion object {
|
||||
@@ -47,8 +47,8 @@ open class Caches(
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun default(objectMapper: ObjectMapper): Caches {
|
||||
return newBuilder().setObjectMapper(objectMapper).build()
|
||||
fun default(): Caches {
|
||||
return newBuilder().build()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -113,10 +113,10 @@ open class Caches(
|
||||
var blockOnlyContainer: BlockContainer? = null
|
||||
var jsonValue: BlockJson<*>? = null
|
||||
if (block.full) {
|
||||
jsonValue = objectMapper.readValue<BlockJson<*>>(block.json, BlockJson::class.java)
|
||||
jsonValue = Global.objectMapper.readValue<BlockJson<*>>(block.json, BlockJson::class.java)
|
||||
//shouldn't cache block json with transactions, separate txes and blocks with refs
|
||||
val blockOnly = jsonValue.withoutTransactionDetails()
|
||||
blockOnlyContainer = BlockContainer.from(blockOnly, objectMapper)
|
||||
blockOnlyContainer = BlockContainer.from(blockOnly)
|
||||
} else {
|
||||
blockOnlyContainer = block
|
||||
}
|
||||
@@ -128,7 +128,7 @@ open class Caches(
|
||||
val plainTransactions = jsonValue.transactions.filterIsInstance<TransactionJson>()
|
||||
if (plainTransactions.isNotEmpty()) {
|
||||
val transactions = plainTransactions.map { tx ->
|
||||
TxContainer.from(tx, objectMapper)
|
||||
TxContainer.from(tx)
|
||||
}
|
||||
transactions.forEach {
|
||||
cache(Tag.REQUESTED, it)
|
||||
@@ -159,11 +159,11 @@ open class Caches(
|
||||
}
|
||||
|
||||
fun getFullBlocks(): Reader<BlockId, BlockContainer> {
|
||||
return EthereumFullBlocksReader(objectMapper, blocksByHash, txsByHash)
|
||||
return EthereumFullBlocksReader(blocksByHash, txsByHash)
|
||||
}
|
||||
|
||||
fun getFullBlocksByHeight(): Reader<Long, BlockContainer> {
|
||||
return BlockByHeight(blocksByHeight, EthereumFullBlocksReader(objectMapper, blocksByHash, txsByHash))
|
||||
return BlockByHeight(blocksByHeight, EthereumFullBlocksReader(blocksByHash, txsByHash))
|
||||
}
|
||||
|
||||
enum class Tag {
|
||||
@@ -184,7 +184,6 @@ open class Caches(
|
||||
private var txsByHash: TxMemCache? = null
|
||||
private var redisBlocksByHash: BlocksRedisCache? = null
|
||||
private var redisTxsByHash: TxRedisCache? = null
|
||||
private var objectMapper: ObjectMapper? = null
|
||||
|
||||
fun setBlockByHash(cache: BlocksMemCache): Builder {
|
||||
blocksByHash = cache
|
||||
@@ -211,11 +210,6 @@ open class Caches(
|
||||
return this
|
||||
}
|
||||
|
||||
fun setObjectMapper(value: ObjectMapper): Builder {
|
||||
objectMapper = value
|
||||
return this
|
||||
}
|
||||
|
||||
fun build(): Caches {
|
||||
if (blocksByHash == null) {
|
||||
blocksByHash = BlocksMemCache()
|
||||
@@ -226,10 +220,7 @@ open class Caches(
|
||||
if (txsByHash == null) {
|
||||
txsByHash = TxMemCache()
|
||||
}
|
||||
if (objectMapper == null) {
|
||||
throw IllegalStateException("ObjectMapper is not set")
|
||||
}
|
||||
return Caches(blocksByHash!!, blocksByHeight!!, txsByHash!!, redisBlocksByHash, redisTxsByHash, objectMapper!!)
|
||||
return Caches(blocksByHash!!, blocksByHeight!!, txsByHash!!, redisBlocksByHash, redisTxsByHash)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -33,7 +33,6 @@ import javax.annotation.PostConstruct
|
||||
|
||||
@Repository
|
||||
class CachesFactory(
|
||||
@Autowired private val objectMapper: ObjectMapper,
|
||||
@Autowired private val cacheConfig: CacheConfig
|
||||
) {
|
||||
|
||||
@@ -74,7 +73,6 @@ class CachesFactory(
|
||||
|
||||
private fun initCache(chain: Chain): Caches {
|
||||
val caches = Caches.newBuilder()
|
||||
.setObjectMapper(objectMapper)
|
||||
redis?.let { redis ->
|
||||
caches.setBlockByHash(BlocksRedisCache(redis.reactive(), chain))
|
||||
caches.setTxByHash(TxRedisCache(redis.reactive(), chain))
|
||||
|
||||
@@ -16,11 +16,9 @@
|
||||
*/
|
||||
package io.emeraldpay.dshackle.data
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper
|
||||
import io.emeraldpay.dshackle.Global
|
||||
import io.infinitape.etherjar.rpc.json.BlockJson
|
||||
import io.infinitape.etherjar.rpc.json.TransactionJson
|
||||
import io.infinitape.etherjar.rpc.json.TransactionRefJson
|
||||
import org.apache.commons.codec.binary.Hex
|
||||
import java.math.BigInteger
|
||||
import java.time.Instant
|
||||
|
||||
@@ -52,13 +50,13 @@ class BlockContainer(
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun from(block: BlockJson<*>, objectMapper: ObjectMapper): BlockContainer {
|
||||
return from(block, objectMapper.writeValueAsBytes(block))
|
||||
fun from(block: BlockJson<*>): BlockContainer {
|
||||
return from(block, Global.objectMapper.writeValueAsBytes(block))
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun from(raw: ByteArray, objectMapper: ObjectMapper): BlockContainer {
|
||||
val block = objectMapper.readValue(raw, BlockJson::class.java)
|
||||
fun from(raw: ByteArray): BlockContainer {
|
||||
val block = Global.objectMapper.readValue(raw, BlockJson::class.java)
|
||||
return from(block, raw)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package io.emeraldpay.dshackle.data
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper
|
||||
import io.emeraldpay.dshackle.Global
|
||||
import io.infinitape.etherjar.rpc.json.TransactionJson
|
||||
|
||||
class TxContainer(
|
||||
@@ -29,8 +30,8 @@ class TxContainer(
|
||||
|
||||
companion object {
|
||||
@JvmStatic
|
||||
fun from(tx: TransactionJson, objectMapper: ObjectMapper): TxContainer {
|
||||
return from(tx, objectMapper.writeValueAsBytes(tx))
|
||||
fun from(tx: TransactionJson): TxContainer {
|
||||
return from(tx, Global.objectMapper.writeValueAsBytes(tx))
|
||||
}
|
||||
|
||||
fun from(tx: TransactionJson, raw: ByteArray): TxContainer {
|
||||
|
||||
@@ -19,6 +19,7 @@ package io.emeraldpay.dshackle.proxy
|
||||
import com.fasterxml.jackson.databind.ObjectMapper
|
||||
import com.google.protobuf.ByteString
|
||||
import io.emeraldpay.api.proto.BlockchainOuterClass
|
||||
import io.emeraldpay.dshackle.Global
|
||||
import io.infinitape.etherjar.rpc.RpcException
|
||||
import io.infinitape.etherjar.rpc.RpcResponseError
|
||||
import io.infinitape.etherjar.rpc.json.RequestJson
|
||||
@@ -36,7 +37,6 @@ import java.util.stream.Collectors
|
||||
*/
|
||||
@Service
|
||||
open class ReadRpcJson(
|
||||
@Autowired private val objectMapper: ObjectMapper
|
||||
) : Function<ByteArray, ProxyCall> {
|
||||
|
||||
companion object {
|
||||
@@ -45,6 +45,7 @@ open class ReadRpcJson(
|
||||
}
|
||||
|
||||
private val jsonExtractor: Function<Map<*, *>, RequestJson<Any>>
|
||||
private val objectMapper: ObjectMapper = Global.objectMapper
|
||||
|
||||
init {
|
||||
jsonExtractor = Function { json ->
|
||||
|
||||
@@ -18,6 +18,7 @@ package io.emeraldpay.dshackle.proxy
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper
|
||||
import io.emeraldpay.api.proto.BlockchainOuterClass
|
||||
import io.emeraldpay.dshackle.Global
|
||||
import io.infinitape.etherjar.rpc.RpcResponseError
|
||||
import io.infinitape.etherjar.rpc.json.ResponseJson
|
||||
import org.slf4j.LoggerFactory
|
||||
@@ -33,14 +34,14 @@ import java.util.function.Function
|
||||
* Writer for JSON RPC requests
|
||||
*/
|
||||
@Service
|
||||
open class WriteRpcJson(
|
||||
@Autowired private val objectMapper: ObjectMapper
|
||||
) {
|
||||
open class WriteRpcJson() {
|
||||
|
||||
companion object {
|
||||
private val log = LoggerFactory.getLogger(WriteRpcJson::class.java)
|
||||
}
|
||||
|
||||
private val objectMapper: ObjectMapper = Global.objectMapper
|
||||
|
||||
/**
|
||||
* Convert Dshackle protobuf based responses to JSON RPC formatted as strings
|
||||
*/
|
||||
|
||||
@@ -22,9 +22,8 @@ import io.emeraldpay.dshackle.upstream.Upstream
|
||||
import io.infinitape.etherjar.rpc.JacksonRpcConverter
|
||||
|
||||
open class BroadcastQuorum(
|
||||
objectMapper: ObjectMapper,
|
||||
val quorum: Int = 3
|
||||
) : CallQuorum, ValueAwareQuorum<String>(objectMapper, String::class.java) {
|
||||
) : CallQuorum, ValueAwareQuorum<String>(String::class.java) {
|
||||
|
||||
private var result: ByteArray? = null
|
||||
private var txid: String? = null
|
||||
|
||||
@@ -23,9 +23,8 @@ import io.infinitape.etherjar.rpc.JacksonRpcConverter
|
||||
import io.infinitape.etherjar.rpc.RpcException
|
||||
|
||||
open class NonEmptyQuorum(
|
||||
objectMapper: ObjectMapper,
|
||||
val maxTries: Int = 3
|
||||
) : CallQuorum, ValueAwareQuorum<Any>(objectMapper, Any::class.java) {
|
||||
) : CallQuorum, ValueAwareQuorum<Any>(Any::class.java) {
|
||||
|
||||
private var result: ByteArray? = null
|
||||
private var tries: Int = 0
|
||||
|
||||
@@ -26,9 +26,8 @@ import java.util.concurrent.locks.ReentrantLock
|
||||
import kotlin.concurrent.withLock
|
||||
|
||||
open class NonceQuorum(
|
||||
objectMapper: ObjectMapper,
|
||||
val tries: Int = 3
|
||||
) : CallQuorum, ValueAwareQuorum<String>(objectMapper, String::class.java) {
|
||||
) : CallQuorum, ValueAwareQuorum<String>(String::class.java) {
|
||||
|
||||
private val lock = ReentrantLock()
|
||||
private var resultValue = 0L
|
||||
|
||||
@@ -17,20 +17,20 @@
|
||||
package io.emeraldpay.dshackle.quorum
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper
|
||||
import io.emeraldpay.dshackle.Global
|
||||
import io.emeraldpay.dshackle.upstream.Upstream
|
||||
import io.infinitape.etherjar.rpc.JacksonRpcConverter
|
||||
import io.infinitape.etherjar.rpc.RpcException
|
||||
import org.slf4j.LoggerFactory
|
||||
|
||||
abstract class ValueAwareQuorum<T>(
|
||||
val objectMapper: ObjectMapper,
|
||||
val clazz: Class<T>
|
||||
): CallQuorum {
|
||||
|
||||
private val log = LoggerFactory.getLogger(ValueAwareQuorum::class.java)
|
||||
|
||||
fun extractValue(response: ByteArray, clazz: Class<T>): T? {
|
||||
return objectMapper.readValue(response.inputStream(), clazz)
|
||||
return Global.objectMapper.readValue(response.inputStream(), clazz)
|
||||
}
|
||||
|
||||
override fun record(response: ByteArray, upstream: Upstream): Boolean {
|
||||
|
||||
@@ -20,6 +20,7 @@ import com.fasterxml.jackson.databind.ObjectMapper
|
||||
import com.google.protobuf.ByteString
|
||||
import io.emeraldpay.api.proto.BlockchainOuterClass
|
||||
import io.emeraldpay.dshackle.BlockchainType
|
||||
import io.emeraldpay.dshackle.Global
|
||||
import io.emeraldpay.dshackle.SilentException
|
||||
import io.emeraldpay.dshackle.upstream.*
|
||||
import io.emeraldpay.dshackle.quorum.AlwaysQuorum
|
||||
@@ -42,11 +43,11 @@ import java.lang.Exception
|
||||
|
||||
@Service
|
||||
open class NativeCall(
|
||||
@Autowired private val multistreamHolder: MultistreamHolder,
|
||||
@Autowired private val objectMapper: ObjectMapper
|
||||
@Autowired private val multistreamHolder: MultistreamHolder
|
||||
) {
|
||||
|
||||
private val log = LoggerFactory.getLogger(NativeCall::class.java)
|
||||
private val objectMapper: ObjectMapper = Global.objectMapper
|
||||
|
||||
var quorumReaderFactory: QuorumReaderFactory = QuorumReaderFactory.default()
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@ package io.emeraldpay.dshackle.startup
|
||||
import com.fasterxml.jackson.databind.ObjectMapper
|
||||
import io.emeraldpay.dshackle.BlockchainType
|
||||
import io.emeraldpay.dshackle.FileResolver
|
||||
import io.emeraldpay.dshackle.Global
|
||||
import io.emeraldpay.dshackle.cache.CachesFactory
|
||||
import io.emeraldpay.dshackle.config.UpstreamsConfig
|
||||
import io.emeraldpay.dshackle.reader.Reader
|
||||
@@ -44,7 +45,6 @@ import kotlin.collections.HashMap
|
||||
|
||||
@Repository
|
||||
open class ConfiguredUpstreams(
|
||||
@Autowired private val objectMapper: ObjectMapper,
|
||||
@Autowired private val currentUpstreams: CurrentMultistreamHolder,
|
||||
@Autowired private val fileResolver: FileResolver,
|
||||
@Autowired private val config: UpstreamsConfig,
|
||||
@@ -146,7 +146,7 @@ open class ConfiguredUpstreams(
|
||||
val upstream = BitcoinUpstream(config.id
|
||||
?: "bitcoin-${seq.getAndIncrement()}", chain, directApi,
|
||||
options, QuorumForLabels.QuorumItem(1, config.labels),
|
||||
objectMapper, methods)
|
||||
methods)
|
||||
|
||||
upstream.start()
|
||||
currentUpstreams.update(UpstreamChange(chain, upstream, UpstreamChange.ChangeType.ADDED))
|
||||
@@ -171,8 +171,7 @@ open class ConfiguredUpstreams(
|
||||
val wsFactoryApi: EthereumWsFactory? = conn.ws?.let { endpoint ->
|
||||
val wsApi = EthereumWsFactory(
|
||||
endpoint.url,
|
||||
endpoint.origin ?: URI("http://localhost"),
|
||||
objectMapper
|
||||
endpoint.origin ?: URI("http://localhost")
|
||||
)
|
||||
endpoint.basicAuth?.let { auth ->
|
||||
wsApi.basicAuth = auth
|
||||
@@ -186,8 +185,7 @@ open class ConfiguredUpstreams(
|
||||
config.id!!,
|
||||
chain, directApi, wsFactoryApi, options,
|
||||
QuorumForLabels.QuorumItem(1, config.labels),
|
||||
methods,
|
||||
objectMapper
|
||||
methods
|
||||
)
|
||||
ethereumUpstream.start()
|
||||
currentUpstreams.update(UpstreamChange(chain, ethereumUpstream, UpstreamChange.ChangeType.ADDED))
|
||||
@@ -199,7 +197,6 @@ open class ConfiguredUpstreams(
|
||||
config.id!!,
|
||||
endpoint.host!!,
|
||||
endpoint.port ?: 2449,
|
||||
objectMapper,
|
||||
endpoint.auth,
|
||||
fileResolver
|
||||
).apply {
|
||||
@@ -225,7 +222,6 @@ open class ConfiguredUpstreams(
|
||||
urls.add(endpoint.url)
|
||||
JsonRpcHttpClient(
|
||||
endpoint.url.toString(),
|
||||
objectMapper,
|
||||
conn.rpc?.basicAuth,
|
||||
tls
|
||||
)
|
||||
|
||||
@@ -18,6 +18,7 @@ package io.emeraldpay.dshackle.upstream
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper
|
||||
import io.emeraldpay.dshackle.BlockchainType
|
||||
import io.emeraldpay.dshackle.Global
|
||||
import io.emeraldpay.dshackle.cache.CachesEnabled
|
||||
import io.emeraldpay.dshackle.cache.CachesFactory
|
||||
import io.emeraldpay.dshackle.startup.UpstreamChange
|
||||
@@ -43,12 +44,13 @@ import kotlin.concurrent.withLock
|
||||
|
||||
@Repository
|
||||
class CurrentMultistreamHolder(
|
||||
@Autowired private val objectMapper: ObjectMapper,
|
||||
@Autowired private val cachesFactory: CachesFactory
|
||||
) : MultistreamHolder {
|
||||
|
||||
private val log = LoggerFactory.getLogger(CurrentMultistreamHolder::class.java)
|
||||
|
||||
private val objectMapper: ObjectMapper = Global.objectMapper
|
||||
|
||||
private val chainMapping = ConcurrentHashMap<Chain, Multistream>()
|
||||
private val chainsBus = TopicProcessor.create<Chain>()
|
||||
private val callTargets = HashMap<Chain, CallMethods>()
|
||||
@@ -62,7 +64,7 @@ class CurrentMultistreamHolder(
|
||||
val up = change.upstream.cast(EthereumUpstream::class.java)
|
||||
val current = chainMapping[chain] as Multistream?
|
||||
val factory = Callable {
|
||||
EthereumMultistream(chain, ArrayList(), cachesFactory.getCaches(chain), objectMapper) as Multistream
|
||||
EthereumMultistream(chain, ArrayList(), cachesFactory.getCaches(chain)) as Multistream
|
||||
}
|
||||
processUpdate(change, up, current, factory)
|
||||
}
|
||||
@@ -70,7 +72,7 @@ class CurrentMultistreamHolder(
|
||||
val up = change.upstream.cast(BitcoinUpstream::class.java)
|
||||
val current = chainMapping[chain] as Multistream?
|
||||
val factory = Callable {
|
||||
BitcoinMultistream(chain, ArrayList(), cachesFactory.getCaches(chain), objectMapper) as Multistream
|
||||
BitcoinMultistream(chain, ArrayList(), cachesFactory.getCaches(chain)) as Multistream
|
||||
}
|
||||
processUpdate(change, up, current, factory)
|
||||
}
|
||||
@@ -135,8 +137,8 @@ class CurrentMultistreamHolder(
|
||||
|
||||
fun setupDefaultMethods(chain: Chain): CallMethods {
|
||||
val created = when (BlockchainType.fromBlockchain(chain)) {
|
||||
BlockchainType.ETHEREUM -> DefaultEthereumMethods(objectMapper, chain)
|
||||
BlockchainType.BITCOIN -> DefaultBitcoinMethods(objectMapper)
|
||||
BlockchainType.ETHEREUM -> DefaultEthereumMethods(chain)
|
||||
BlockchainType.BITCOIN -> DefaultBitcoinMethods()
|
||||
else -> throw IllegalStateException("Unsupported chain: $chain")
|
||||
}
|
||||
callTargets[chain] = created
|
||||
|
||||
@@ -31,8 +31,7 @@ import reactor.core.publisher.Mono
|
||||
open class BitcoinMultistream(
|
||||
chain: Chain,
|
||||
val upstreams: MutableList<BitcoinUpstream>,
|
||||
caches: Caches,
|
||||
private val objectMapper: ObjectMapper
|
||||
caches: Caches
|
||||
) : Multistream(chain, upstreams as MutableList<Upstream>, caches), Lifecycle {
|
||||
|
||||
companion object {
|
||||
@@ -40,7 +39,7 @@ open class BitcoinMultistream(
|
||||
}
|
||||
|
||||
private var head: Head? = null
|
||||
private var reader = BitcoinReader(this, EmptyHead(), objectMapper)
|
||||
private var reader = BitcoinReader(this, EmptyHead())
|
||||
|
||||
override fun init() {
|
||||
if (upstreams.size > 0) {
|
||||
@@ -84,7 +83,7 @@ open class BitcoinMultistream(
|
||||
|
||||
override fun setHead(head: Head) {
|
||||
this.head = head
|
||||
reader = BitcoinReader(this, head, objectMapper)
|
||||
reader = BitcoinReader(this, head)
|
||||
}
|
||||
|
||||
override fun getHead(): Head {
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
package io.emeraldpay.dshackle.upstream.bitcoin
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper
|
||||
import io.emeraldpay.dshackle.Global
|
||||
import io.emeraldpay.dshackle.upstream.Head
|
||||
import io.emeraldpay.dshackle.upstream.Selector
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcRequest
|
||||
@@ -27,15 +28,15 @@ import reactor.kotlin.core.publisher.cast
|
||||
|
||||
open class BitcoinReader(
|
||||
private val upstreams: BitcoinMultistream,
|
||||
head: Head,
|
||||
private val objectMapper: ObjectMapper
|
||||
head: Head
|
||||
) : Lifecycle {
|
||||
|
||||
companion object {
|
||||
private val log = LoggerFactory.getLogger(BitcoinReader::class.java)
|
||||
}
|
||||
|
||||
private val mempool = CachingMempoolData(upstreams, head, objectMapper)
|
||||
private val objectMapper: ObjectMapper = Global.objectMapper
|
||||
private val mempool = CachingMempoolData(upstreams, head)
|
||||
|
||||
open fun getMempool(): CachingMempoolData {
|
||||
return mempool
|
||||
|
||||
@@ -35,7 +35,6 @@ open class BitcoinUpstream(
|
||||
private val directApi: Reader<JsonRpcRequest, JsonRpcResponse>,
|
||||
options: UpstreamsConfig.Options,
|
||||
val node: QuorumForLabels.QuorumItem,
|
||||
private val objectMapper: ObjectMapper,
|
||||
callMethods: CallMethods
|
||||
) : DefaultUpstream(id, options, callMethods), Lifecycle {
|
||||
|
||||
@@ -49,7 +48,7 @@ open class BitcoinUpstream(
|
||||
private fun createHead(): Head {
|
||||
return BitcoinRpcHead(
|
||||
directApi,
|
||||
ExtractBlock(objectMapper)
|
||||
ExtractBlock()
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
package io.emeraldpay.dshackle.upstream.bitcoin
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper
|
||||
import io.emeraldpay.dshackle.Global
|
||||
import io.emeraldpay.dshackle.upstream.Head
|
||||
import io.emeraldpay.dshackle.upstream.Selector
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcRequest
|
||||
@@ -31,8 +32,7 @@ import java.util.concurrent.locks.ReentrantLock
|
||||
|
||||
open class CachingMempoolData(
|
||||
private val upstreams: BitcoinMultistream,
|
||||
private val head: Head,
|
||||
private val objectMapper: ObjectMapper
|
||||
private val head: Head
|
||||
) : Lifecycle {
|
||||
|
||||
companion object {
|
||||
@@ -40,6 +40,8 @@ open class CachingMempoolData(
|
||||
private val TTL = Duration.ofSeconds(15)
|
||||
}
|
||||
|
||||
private val objectMapper: ObjectMapper = Global.objectMapper
|
||||
|
||||
private val current = AtomicReference<Container>(Container.empty())
|
||||
private val updateLock = ReentrantLock()
|
||||
private var headListener: Disposable? = null
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
package io.emeraldpay.dshackle.upstream.bitcoin
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper
|
||||
import io.emeraldpay.dshackle.Global
|
||||
import io.emeraldpay.dshackle.data.BlockContainer
|
||||
import io.emeraldpay.dshackle.data.BlockId
|
||||
import io.emeraldpay.dshackle.data.TxId
|
||||
@@ -24,9 +25,7 @@ import org.slf4j.LoggerFactory
|
||||
import java.math.BigInteger
|
||||
import java.time.Instant
|
||||
|
||||
class ExtractBlock(
|
||||
private val objectMapper: ObjectMapper
|
||||
) {
|
||||
class ExtractBlock() {
|
||||
|
||||
companion object {
|
||||
private val log = LoggerFactory.getLogger(ExtractBlock::class.java)
|
||||
@@ -50,6 +49,8 @@ class ExtractBlock(
|
||||
}
|
||||
}
|
||||
|
||||
private val objectMapper: ObjectMapper = Global.objectMapper
|
||||
|
||||
fun extract(json: ByteArray): BlockContainer {
|
||||
val data = objectMapper.readValue(json, Map::class.java) as Map<String, Any>
|
||||
|
||||
|
||||
@@ -20,9 +20,7 @@ import io.emeraldpay.dshackle.quorum.*
|
||||
import io.infinitape.etherjar.rpc.RpcException
|
||||
import java.util.*
|
||||
|
||||
class DefaultBitcoinMethods(
|
||||
private val objectMapper: ObjectMapper
|
||||
) : CallMethods {
|
||||
class DefaultBitcoinMethods() : CallMethods {
|
||||
|
||||
private val anyResponseMethods = listOf(
|
||||
"getblock",
|
||||
@@ -50,7 +48,7 @@ class DefaultBitcoinMethods(
|
||||
Collections.binarySearch(hardcodedMethods, method) >= 0 -> AlwaysQuorum()
|
||||
Collections.binarySearch(anyResponseMethods, method) >= 0 -> NotLaggingQuorum(2)
|
||||
Collections.binarySearch(headVerifiedMethods, method) >= 0 -> NotLaggingQuorum(0)
|
||||
Collections.binarySearch(broadcastMethods, method) >= 0 -> BroadcastQuorum(objectMapper)
|
||||
Collections.binarySearch(broadcastMethods, method) >= 0 -> BroadcastQuorum()
|
||||
else -> AlwaysQuorum()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,7 +28,6 @@ import java.util.*
|
||||
* hardcoded results for base methods, such as `net_version`, `web3_clientVersion` and similar
|
||||
*/
|
||||
class DefaultEthereumMethods(
|
||||
private val objectMapper: ObjectMapper,
|
||||
private val chain: Chain
|
||||
) : CallMethods {
|
||||
|
||||
@@ -88,9 +87,9 @@ class DefaultEthereumMethods(
|
||||
headVerifiedMethods.contains(method) -> NotLaggingQuorum(1)
|
||||
specialMethods.contains(method) -> {
|
||||
when (method) {
|
||||
"eth_getTransactionCount" -> NonceQuorum(objectMapper)
|
||||
"eth_getTransactionCount" -> NonceQuorum()
|
||||
"eth_getBalance" -> NotLaggingQuorum(1)
|
||||
"eth_sendRawTransaction" -> BroadcastQuorum(objectMapper)
|
||||
"eth_sendRawTransaction" -> BroadcastQuorum()
|
||||
else -> AlwaysQuorum()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
package io.emeraldpay.dshackle.upstream.ethereum
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper
|
||||
import io.emeraldpay.dshackle.Global
|
||||
import io.emeraldpay.dshackle.data.BlockContainer
|
||||
import io.emeraldpay.dshackle.data.BlockId
|
||||
import io.emeraldpay.dshackle.data.TxContainer
|
||||
@@ -37,7 +38,6 @@ import reactor.core.publisher.Mono
|
||||
* If any of the expected block transactions is not available it returns empty
|
||||
*/
|
||||
class EthereumFullBlocksReader(
|
||||
private val objectMapper: ObjectMapper,
|
||||
private val blocks: Reader<BlockId, BlockContainer>,
|
||||
private val txes: Reader<TxId, TxContainer>
|
||||
) : Reader<BlockId, BlockContainer> {
|
||||
@@ -48,7 +48,7 @@ class EthereumFullBlocksReader(
|
||||
|
||||
override fun read(key: BlockId): Mono<BlockContainer> {
|
||||
return blocks.read(key).flatMap { block ->
|
||||
val block = objectMapper.readValue(block.json, BlockJson::class.java) as BlockJson<TransactionRefJson>
|
||||
val block = Global.objectMapper.readValue(block.json, BlockJson::class.java) as BlockJson<TransactionRefJson>
|
||||
val fullBlock = if (block.transactions == null || block.transactions.isEmpty()) {
|
||||
// in fact it's not necessary to create a copy, made just for code clarity but it may be a performance loss
|
||||
val fullBlock = BlockJson<TransactionJson>()
|
||||
@@ -66,7 +66,7 @@ class EthereumFullBlocksReader(
|
||||
val fullBlock = BlockJson<TransactionJson>()
|
||||
BeanUtils.copyProperties(block, fullBlock)
|
||||
fullBlock.transactions = list.map {
|
||||
objectMapper.readValue(it.json, TransactionJson::class.java)
|
||||
Global.objectMapper.readValue(it.json, TransactionJson::class.java)
|
||||
}
|
||||
Mono.just(fullBlock)
|
||||
}
|
||||
@@ -75,7 +75,7 @@ class EthereumFullBlocksReader(
|
||||
fullBlock
|
||||
.map { block ->
|
||||
BlockContainer(block.number, BlockId.from(block.hash), block.totalDifficulty, block.timestamp, true,
|
||||
objectMapper.writeValueAsBytes(block),
|
||||
Global.objectMapper.writeValueAsBytes(block),
|
||||
block.transactions.map { tx -> TxId.from(tx) }
|
||||
)
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package io.emeraldpay.dshackle.upstream.ethereum
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper
|
||||
import io.emeraldpay.dshackle.Global
|
||||
import io.emeraldpay.dshackle.cache.Caches
|
||||
import io.emeraldpay.dshackle.config.UpstreamsConfig
|
||||
import io.emeraldpay.dshackle.reader.Reader
|
||||
@@ -31,17 +32,17 @@ import reactor.core.publisher.Mono
|
||||
open class EthereumMultistream(
|
||||
chain: Chain,
|
||||
val upstreams: MutableList<EthereumUpstream>,
|
||||
caches: Caches,
|
||||
private val objectMapper: ObjectMapper
|
||||
caches: Caches
|
||||
) : Multistream(chain, upstreams as MutableList<Upstream>, caches) {
|
||||
|
||||
companion object {
|
||||
private val log = LoggerFactory.getLogger(EthereumMultistream::class.java)
|
||||
}
|
||||
|
||||
private val objectMapper: ObjectMapper = Global.objectMapper
|
||||
private var head: Head? = null
|
||||
|
||||
private val reader: EthereumReader = EthereumReader(this, this.caches, objectMapper)
|
||||
private val reader: EthereumReader = EthereumReader(this, this.caches)
|
||||
|
||||
init {
|
||||
this.init()
|
||||
@@ -119,7 +120,7 @@ open class EthereumMultistream(
|
||||
}
|
||||
|
||||
override fun getRoutedApi(matcher: Selector.Matcher): Mono<Reader<JsonRpcRequest, JsonRpcResponse>> {
|
||||
return Mono.just(NativeCallRouter(objectMapper, reader, getMethods()))
|
||||
return Mono.just(NativeCallRouter(reader, getMethods()))
|
||||
}
|
||||
|
||||
}
|
||||
@@ -17,6 +17,7 @@ package io.emeraldpay.dshackle.upstream.ethereum
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper
|
||||
import io.emeraldpay.dshackle.Defaults
|
||||
import io.emeraldpay.dshackle.Global
|
||||
import io.emeraldpay.dshackle.cache.Caches
|
||||
import io.emeraldpay.dshackle.cache.CurrentBlockCache
|
||||
import io.emeraldpay.dshackle.data.*
|
||||
@@ -46,14 +47,14 @@ import java.util.function.Function
|
||||
|
||||
open class EthereumReader(
|
||||
private val up: Multistream,
|
||||
private val caches: Caches,
|
||||
private val objectMapper: ObjectMapper
|
||||
private val caches: Caches
|
||||
) : Lifecycle {
|
||||
|
||||
companion object {
|
||||
private val log = LoggerFactory.getLogger(EthereumReader::class.java)
|
||||
}
|
||||
|
||||
private val objectMapper: ObjectMapper = Global.objectMapper
|
||||
private val balanceCache = CurrentBlockCache<Address, Wei>()
|
||||
|
||||
val extractBlock = Function<BlockContainer, BlockJson<TransactionRefJson>> { block ->
|
||||
@@ -80,10 +81,10 @@ open class EthereumReader(
|
||||
}
|
||||
|
||||
val blockAsContainer = Function<BlockJson<*>, BlockContainer> { block ->
|
||||
BlockContainer.from(block.withoutTransactionDetails(), objectMapper)
|
||||
BlockContainer.from(block.withoutTransactionDetails())
|
||||
}
|
||||
val txAsContainer = Function<TransactionJson, TxContainer> { tx ->
|
||||
TxContainer.from(tx, objectMapper)
|
||||
TxContainer.from(tx)
|
||||
}
|
||||
|
||||
private val blocksDirect: Reader<BlockHash, BlockContainer>
|
||||
@@ -150,9 +151,13 @@ open class EthereumReader(
|
||||
.timeout(Defaults.timeoutInternal, Mono.error(TimeoutException("Tx not read $key")))
|
||||
.map(directResponseBytes)
|
||||
.retryWhen(Retry.backoff(3, Duration.ofSeconds(1)))
|
||||
.map { txbytes ->
|
||||
.flatMap { txbytes ->
|
||||
val tx = objectMapper.readValue(txbytes, TransactionJson::class.java)
|
||||
TxContainer.from(tx, txbytes)
|
||||
if (tx == null) {
|
||||
Mono.empty()
|
||||
} else {
|
||||
Mono.just(TxContainer.from(tx, txbytes))
|
||||
}
|
||||
}
|
||||
.doOnNext { tx ->
|
||||
if (tx.blockId != null) {
|
||||
|
||||
@@ -35,8 +35,7 @@ import java.time.Duration
|
||||
import java.util.concurrent.Executors
|
||||
|
||||
class EthereumRpcHead(
|
||||
private val api: Reader<in JsonRpcRequest, out JsonRpcResponse>,
|
||||
private val objectMapper: ObjectMapper,
|
||||
private val api: Reader<JsonRpcRequest, JsonRpcResponse>,
|
||||
private val interval: Duration = Duration.ofSeconds(10)
|
||||
): DefaultEthereumHead(), Lifecycle {
|
||||
|
||||
@@ -72,7 +71,7 @@ class EthereumRpcHead(
|
||||
.timeout(Defaults.timeout, Mono.error(Exception("Block data not received")))
|
||||
}
|
||||
.map {
|
||||
BlockContainer.from(it.getResult(), objectMapper)
|
||||
BlockContainer.from(it.getResult())
|
||||
}
|
||||
.onErrorContinue { err, _ ->
|
||||
log.debug("RPC error ${err.message}")
|
||||
|
||||
@@ -41,13 +41,12 @@ open class EthereumUpstream(
|
||||
private val ethereumWsFactory: EthereumWsFactory? = null,
|
||||
options: UpstreamsConfig.Options,
|
||||
val node: QuorumForLabels.QuorumItem,
|
||||
targets: CallMethods,
|
||||
private val objectMapper: ObjectMapper
|
||||
targets: CallMethods
|
||||
) : DefaultUpstream(id, options, targets), Upstream, CachesEnabled, Lifecycle {
|
||||
|
||||
constructor(id: String, chain: Chain, api: Reader<JsonRpcRequest, JsonRpcResponse>, objectMapper: ObjectMapper) : this(id, chain, api, null,
|
||||
constructor(id: String, chain: Chain, api: Reader<JsonRpcRequest, JsonRpcResponse>) : this(id, chain, api, null,
|
||||
UpstreamsConfig.Options.getDefaults(), QuorumForLabels.QuorumItem(1, UpstreamsConfig.Labels()),
|
||||
DirectCallMethods(), objectMapper)
|
||||
DirectCallMethods())
|
||||
|
||||
|
||||
private val log = LoggerFactory.getLogger(EthereumUpstream::class.java)
|
||||
@@ -68,7 +67,7 @@ open class EthereumUpstream(
|
||||
this.setLag(0)
|
||||
this.setStatus(UpstreamAvailability.OK)
|
||||
} else {
|
||||
val validator = EthereumUpstreamValidator(this, getOptions(), objectMapper)
|
||||
val validator = EthereumUpstreamValidator(this, getOptions())
|
||||
validatorSubscription = validator.start()
|
||||
.subscribe(this::setStatus)
|
||||
}
|
||||
@@ -95,7 +94,7 @@ open class EthereumUpstream(
|
||||
start()
|
||||
}
|
||||
// receive bew blocks through WebSockets, but also periodically verify with RPC in case if WS failed
|
||||
val rpcHead = EthereumRpcHead(getApi(), objectMapper, Duration.ofSeconds(60)).apply {
|
||||
val rpcHead = EthereumRpcHead(getApi(), Duration.ofSeconds(60)).apply {
|
||||
start()
|
||||
}
|
||||
MergedHead(listOf(rpcHead, wsHead)).apply {
|
||||
@@ -103,7 +102,7 @@ open class EthereumUpstream(
|
||||
}
|
||||
} else {
|
||||
log.warn("Setting up upstream ${this.getId()} with RPC-only access, less effective than WS+RPC")
|
||||
EthereumRpcHead(getApi(), objectMapper).apply {
|
||||
EthereumRpcHead(getApi()).apply {
|
||||
start()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ package io.emeraldpay.dshackle.upstream.ethereum
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper
|
||||
import io.emeraldpay.dshackle.Defaults
|
||||
import io.emeraldpay.dshackle.Global
|
||||
import io.emeraldpay.dshackle.config.UpstreamsConfig
|
||||
import io.emeraldpay.dshackle.upstream.UpstreamAvailability
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcRequest
|
||||
@@ -33,14 +34,15 @@ import java.util.concurrent.Executors
|
||||
|
||||
class EthereumUpstreamValidator(
|
||||
private val upstream: EthereumUpstream,
|
||||
private val options: UpstreamsConfig.Options,
|
||||
private val objectMapper: ObjectMapper
|
||||
private val options: UpstreamsConfig.Options
|
||||
) {
|
||||
companion object {
|
||||
private val log = LoggerFactory.getLogger(EthereumUpstreamValidator::class.java)
|
||||
val scheduler = Schedulers.fromExecutor(Executors.newCachedThreadPool(CustomizableThreadFactory("ethereum-validator")))
|
||||
}
|
||||
|
||||
private val objectMapper: ObjectMapper = Global.objectMapper
|
||||
|
||||
fun validate(): Mono<UpstreamAvailability> {
|
||||
return upstream
|
||||
.getApi()
|
||||
|
||||
@@ -18,6 +18,7 @@ package io.emeraldpay.dshackle.upstream.ethereum
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper
|
||||
import io.emeraldpay.dshackle.Defaults
|
||||
import io.emeraldpay.dshackle.Global
|
||||
import io.emeraldpay.dshackle.SilentException
|
||||
import io.emeraldpay.dshackle.config.AuthConfig
|
||||
import io.emeraldpay.dshackle.data.BlockContainer
|
||||
@@ -37,21 +38,19 @@ import java.time.Duration
|
||||
|
||||
class EthereumWsFactory(
|
||||
private val uri: URI,
|
||||
private val origin: URI,
|
||||
private val objectMapper: ObjectMapper
|
||||
private val origin: URI
|
||||
) {
|
||||
|
||||
var basicAuth: AuthConfig.ClientBasicAuth? = null
|
||||
|
||||
fun create(upstream: EthereumUpstream): EthereumWs {
|
||||
return EthereumWs(uri, origin, upstream, objectMapper, basicAuth)
|
||||
return EthereumWs(uri, origin, upstream, basicAuth)
|
||||
}
|
||||
|
||||
class EthereumWs(
|
||||
private val uri: URI,
|
||||
private val origin: URI,
|
||||
private val upstream: EthereumUpstream,
|
||||
private val objectMapper: ObjectMapper,
|
||||
private val basicAuth: AuthConfig.ClientBasicAuth?
|
||||
) {
|
||||
|
||||
@@ -96,7 +95,7 @@ class EthereumWsFactory(
|
||||
}
|
||||
}
|
||||
.flatMap(JsonRpcResponse::requireResult)
|
||||
.map { BlockContainer.from(it, objectMapper) }
|
||||
.map { BlockContainer.from(it) }
|
||||
}.repeatWhenEmpty { n ->
|
||||
Repeat.times<Any>(5)
|
||||
.exponentialBackoff(Duration.ofMillis(50), Duration.ofMillis(500))
|
||||
@@ -107,7 +106,7 @@ class EthereumWsFactory(
|
||||
.subscribe(topic::onNext)
|
||||
|
||||
} else {
|
||||
topic.onNext(BlockContainer.from(block, objectMapper))
|
||||
topic.onNext(BlockContainer.from(block))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
package io.emeraldpay.dshackle.upstream.ethereum
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper
|
||||
import io.emeraldpay.dshackle.Global
|
||||
import io.emeraldpay.dshackle.data.BlockId
|
||||
import io.emeraldpay.dshackle.data.TxId
|
||||
import io.emeraldpay.dshackle.reader.Reader
|
||||
@@ -30,7 +31,6 @@ import reactor.core.publisher.Mono
|
||||
import java.math.BigInteger
|
||||
|
||||
class NativeCallRouter(
|
||||
private val objectMapper: ObjectMapper,
|
||||
private val reader: EthereumReader,
|
||||
private val methods: CallMethods
|
||||
) : Reader<JsonRpcRequest, JsonRpcResponse> {
|
||||
@@ -40,7 +40,6 @@ class NativeCallRouter(
|
||||
}
|
||||
|
||||
private val fullBlocksReader = EthereumFullBlocksReader(
|
||||
objectMapper,
|
||||
reader.blocksByIdAsCont(),
|
||||
reader.txByHashAsCont()
|
||||
)
|
||||
|
||||
@@ -56,7 +56,6 @@ open class EthereumGrpcUpstream(
|
||||
private val parentId: String,
|
||||
private val chain: Chain,
|
||||
private val blockchainStub: ReactorBlockchainGrpc.ReactorBlockchainStub,
|
||||
private val objectMapper: ObjectMapper,
|
||||
private val client: JsonRpcGrpcClient
|
||||
) : DefaultUpstream(
|
||||
"$parentId/${chain.chainCode}",
|
||||
@@ -125,7 +124,7 @@ open class EthereumGrpcUpstream(
|
||||
defaultReader.read(JsonRpcRequest("eth_getBlockByHash", listOf(it.hash.toHexWithPrefix(), false)))
|
||||
.flatMap(JsonRpcResponse::requireResult)
|
||||
.map {
|
||||
BlockContainer.from(it, objectMapper)
|
||||
BlockContainer.from(it)
|
||||
}
|
||||
.timeout(timeout, Mono.error(TimeoutException("Timeout from upstream")))
|
||||
.doOnError { t ->
|
||||
|
||||
@@ -46,7 +46,6 @@ class GrpcUpstreams(
|
||||
private val id: String,
|
||||
private val host: String,
|
||||
private val port: Int,
|
||||
private val objectMapper: ObjectMapper,
|
||||
private val auth: AuthConfig.ClientTlsAuth? = null,
|
||||
private val fileResolver: FileResolver
|
||||
) {
|
||||
@@ -157,8 +156,8 @@ class GrpcUpstreams(
|
||||
lock.withLock {
|
||||
val current = known[chain]
|
||||
return if (current == null) {
|
||||
val rpcClient = JsonRpcGrpcClient(client!!, chain, objectMapper)
|
||||
val created = EthereumGrpcUpstream(id, chain, client!!, objectMapper, rpcClient)
|
||||
val rpcClient = JsonRpcGrpcClient(client!!, chain)
|
||||
val created = EthereumGrpcUpstream(id, chain, client!!, rpcClient)
|
||||
created.timeout = this.timeout
|
||||
known[chain] = created
|
||||
created.start()
|
||||
|
||||
@@ -19,6 +19,7 @@ import com.fasterxml.jackson.databind.ObjectMapper
|
||||
import com.google.protobuf.ByteString
|
||||
import io.emeraldpay.api.proto.BlockchainOuterClass
|
||||
import io.emeraldpay.api.proto.ReactorBlockchainGrpc
|
||||
import io.emeraldpay.dshackle.Global
|
||||
import io.emeraldpay.dshackle.reader.Reader
|
||||
import io.emeraldpay.dshackle.upstream.Selector
|
||||
import io.emeraldpay.grpc.Chain
|
||||
@@ -30,8 +31,7 @@ import reactor.core.publisher.Mono
|
||||
|
||||
class JsonRpcGrpcClient(
|
||||
private val stub: ReactorBlockchainGrpc.ReactorBlockchainStub,
|
||||
private val chain: Chain,
|
||||
private val objectMapper: ObjectMapper
|
||||
private val chain: Chain
|
||||
) {
|
||||
|
||||
companion object {
|
||||
@@ -39,14 +39,13 @@ class JsonRpcGrpcClient(
|
||||
}
|
||||
|
||||
fun forSelector(matcher: Selector.Matcher): Reader<JsonRpcRequest, JsonRpcResponse> {
|
||||
return Executor(stub, chain, matcher, objectMapper)
|
||||
return Executor(stub, chain, matcher)
|
||||
}
|
||||
|
||||
class Executor(
|
||||
private val stub: ReactorBlockchainGrpc.ReactorBlockchainStub,
|
||||
private val chain: Chain,
|
||||
private val matcher: Selector.Matcher,
|
||||
private val objectMapper: ObjectMapper
|
||||
private val matcher: Selector.Matcher
|
||||
) : Reader<JsonRpcRequest, JsonRpcResponse> {
|
||||
|
||||
private val parser = JsonRpcParser()
|
||||
@@ -64,7 +63,7 @@ class JsonRpcGrpcClient(
|
||||
BlockchainOuterClass.NativeCallItem.newBuilder()
|
||||
.setId(1)
|
||||
.setMethod(key.method)
|
||||
.setPayload(ByteString.copyFrom(objectMapper.writeValueAsBytes(key.params)))
|
||||
.setPayload(ByteString.copyFrom(Global.objectMapper.writeValueAsBytes(key.params)))
|
||||
.build().let {
|
||||
req.addItems(it)
|
||||
}
|
||||
|
||||
@@ -38,7 +38,6 @@ import java.util.function.Consumer
|
||||
*/
|
||||
class JsonRpcHttpClient(
|
||||
private val target: String,
|
||||
private val objectMapper: ObjectMapper,
|
||||
basicAuth: AuthConfig.ClientBasicAuth? = null,
|
||||
tlsCAAuth: ByteArray? = null
|
||||
) : Reader<JsonRpcRequest, JsonRpcResponse> {
|
||||
@@ -94,7 +93,7 @@ class JsonRpcHttpClient(
|
||||
|
||||
override fun read(key: JsonRpcRequest): Mono<JsonRpcResponse> {
|
||||
return Mono.just(key)
|
||||
.map { it.toJson(objectMapper) }
|
||||
.map(JsonRpcRequest::toJson)
|
||||
.flatMap(this@JsonRpcHttpClient::execute)
|
||||
.map(parser::parse)
|
||||
}
|
||||
|
||||
@@ -15,21 +15,21 @@
|
||||
*/
|
||||
package io.emeraldpay.dshackle.upstream.rpcclient
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper
|
||||
import io.emeraldpay.dshackle.Global
|
||||
|
||||
class JsonRpcRequest(
|
||||
val method: String,
|
||||
val params: List<Any>
|
||||
) {
|
||||
|
||||
fun toJson(objectMapper: ObjectMapper): ByteArray {
|
||||
fun toJson(): ByteArray {
|
||||
val json = mapOf(
|
||||
"jsonrpc" to "2.0",
|
||||
"id" to 1,
|
||||
"method" to method,
|
||||
"params" to params
|
||||
)
|
||||
return objectMapper.writeValueAsBytes(json)
|
||||
return Global.objectMapper.writeValueAsBytes(json)
|
||||
}
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
|
||||
Reference in New Issue
Block a user