From 65c383ac697522778bbb74ad7dcbaca157f6efe3 Mon Sep 17 00:00:00 2001 From: Anton Date: Tue, 7 May 2024 14:38:04 +0300 Subject: [PATCH] Node client_type & client_version not parsed for non-eth chains (#467) * Fix labels fill * return null in case of unknown client type --- .gitignore | 1 + emerald-grpc | 2 +- .../upstream/UpstreamSettingsDetector.kt | 42 +++++++++++-------- .../BeaconChainUpstreamSettingsDetector.kt | 10 +++-- .../EthereumUpstreamSettingsDetector.kt | 12 +++--- .../near/NearUpstreamSettingsDetector.kt | 18 ++++++-- .../solana/SolanaUpstreamSettingsDetector.kt | 18 ++++++-- 7 files changed, 70 insertions(+), 33 deletions(-) diff --git a/.gitignore b/.gitignore index 565a9829..d99af13f 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ build/ out/ ./dshackle.yaml +dshackle.yaml ./upstream.yaml testsetup/ .idea/ diff --git a/emerald-grpc b/emerald-grpc index 74434097..aec49041 160000 --- a/emerald-grpc +++ b/emerald-grpc @@ -1 +1 @@ -Subproject commit 744340971e13d081548788cf5e2e42ff291b1908 +Subproject commit aec49041db851005af1ac331865c25d8221812b5 diff --git a/src/main/kotlin/io/emeraldpay/dshackle/upstream/UpstreamSettingsDetector.kt b/src/main/kotlin/io/emeraldpay/dshackle/upstream/UpstreamSettingsDetector.kt index 688517db..a634c864 100644 --- a/src/main/kotlin/io/emeraldpay/dshackle/upstream/UpstreamSettingsDetector.kt +++ b/src/main/kotlin/io/emeraldpay/dshackle/upstream/UpstreamSettingsDetector.kt @@ -11,6 +11,7 @@ import reactor.core.publisher.Mono const val UNKNOWN_CLIENT_VERSION = "unknown" typealias UpstreamSettingsDetectorBuilder = (Chain, Upstream) -> UpstreamSettingsDetector? + abstract class UpstreamSettingsDetector( private val upstream: Upstream, ) { @@ -34,10 +35,12 @@ abstract class UpstreamSettingsDetector( protected abstract fun parseClientVersion(data: ByteArray): String } -abstract class BasicEthUpstreamSettingsDetector( +abstract class BasicUpstreamSettingsDetector( private val upstream: Upstream, ) : UpstreamSettingsDetector(upstream) { protected abstract fun nodeTypeRequest(): NodeTypeRequest + protected abstract fun clientVersion(node: JsonNode): String? + protected abstract fun clientType(node: JsonNode): String? protected fun detectNodeType(): Flux?> { val nodeTypeRequest = nodeTypeRequest() @@ -47,25 +50,30 @@ abstract class BasicEthUpstreamSettingsDetector( .flatMap(ChainResponse::requireResult) .map { Global.objectMapper.readValue(it) } .flatMapMany { node -> - val mappedNode = nodeTypeRequest.mapper(node) val labels = mutableListOf>() - if (mappedNode.isTextual) { - clientType(mappedNode.textValue())?.let { - labels.add("client_type" to it) - } - clientVersion(mappedNode.textValue())?.let { - labels.add("client_version" to it) - } + clientType(node)?.let { + labels.add("client_type" to it) + } + clientVersion(node)?.let { + labels.add("client_version" to it) } Flux.fromIterable(labels) } - .onErrorResume { + .onErrorResume { error -> + log.warn("Can't detect the node type of upstream ${upstream.getId()}, reason - {}", error.message) Flux.empty() } } +} - private fun clientVersion(client: String): String? { +abstract class BasicEthUpstreamSettingsDetector( + upstream: Upstream, +) : BasicUpstreamSettingsDetector(upstream) { + abstract fun mapping(node: JsonNode): String + + override fun clientVersion(node: JsonNode): String? { + val client = mapping(node) val firstSlash = client.indexOf("/") val secondSlash = client.indexOf("/", firstSlash + 1) if (firstSlash == -1 || secondSlash == -1 || secondSlash < firstSlash) { @@ -74,7 +82,8 @@ abstract class BasicEthUpstreamSettingsDetector( return client.substring(firstSlash + 1, secondSlash) } - private fun clientType(client: String): String? { + override fun clientType(node: JsonNode): String? { + val client = mapping(node) val firstSlash = client.indexOf("/") if (firstSlash == -1) { log.debug("Unknown client type: {}", client) @@ -82,9 +91,8 @@ abstract class BasicEthUpstreamSettingsDetector( } return client.substring(0, firstSlash).lowercase() } - - data class NodeTypeRequest( - val request: ChainRequest, - val mapper: (JsonNode) -> JsonNode, - ) } + +data class NodeTypeRequest( + val request: ChainRequest, +) diff --git a/src/main/kotlin/io/emeraldpay/dshackle/upstream/beaconchain/BeaconChainUpstreamSettingsDetector.kt b/src/main/kotlin/io/emeraldpay/dshackle/upstream/beaconchain/BeaconChainUpstreamSettingsDetector.kt index 6da9287b..8d8af4ef 100644 --- a/src/main/kotlin/io/emeraldpay/dshackle/upstream/beaconchain/BeaconChainUpstreamSettingsDetector.kt +++ b/src/main/kotlin/io/emeraldpay/dshackle/upstream/beaconchain/BeaconChainUpstreamSettingsDetector.kt @@ -1,11 +1,11 @@ package io.emeraldpay.dshackle.upstream.beaconchain import com.fasterxml.jackson.databind.JsonNode -import com.fasterxml.jackson.databind.node.NullNode import com.fasterxml.jackson.module.kotlin.readValue import io.emeraldpay.dshackle.Global import io.emeraldpay.dshackle.upstream.BasicEthUpstreamSettingsDetector import io.emeraldpay.dshackle.upstream.ChainRequest +import io.emeraldpay.dshackle.upstream.NodeTypeRequest import io.emeraldpay.dshackle.upstream.UNKNOWN_CLIENT_VERSION import io.emeraldpay.dshackle.upstream.Upstream import io.emeraldpay.dshackle.upstream.rpcclient.RestParams @@ -18,9 +18,7 @@ class BeaconChainUpstreamSettingsDetector( override fun nodeTypeRequest(): NodeTypeRequest { return NodeTypeRequest( clientVersionRequest(), - ) { node -> - node.get("data")?.get("version") ?: NullNode.instance - } + ) } override fun detectLabels(): Flux> { @@ -29,6 +27,10 @@ class BeaconChainUpstreamSettingsDetector( ) } + override fun mapping(node: JsonNode): String { + return node.get("data")?.get("version")?.asText() ?: "" + } + override fun clientVersionRequest(): ChainRequest { return ChainRequest("GET#/eth/v1/node/version", RestParams.emptyParams()) } diff --git a/src/main/kotlin/io/emeraldpay/dshackle/upstream/ethereum/EthereumUpstreamSettingsDetector.kt b/src/main/kotlin/io/emeraldpay/dshackle/upstream/ethereum/EthereumUpstreamSettingsDetector.kt index d2f8bacf..e99a22f5 100644 --- a/src/main/kotlin/io/emeraldpay/dshackle/upstream/ethereum/EthereumUpstreamSettingsDetector.kt +++ b/src/main/kotlin/io/emeraldpay/dshackle/upstream/ethereum/EthereumUpstreamSettingsDetector.kt @@ -1,9 +1,11 @@ package io.emeraldpay.dshackle.upstream.ethereum +import com.fasterxml.jackson.databind.JsonNode import io.emeraldpay.dshackle.Chain import io.emeraldpay.dshackle.upstream.BasicEthUpstreamSettingsDetector import io.emeraldpay.dshackle.upstream.ChainRequest import io.emeraldpay.dshackle.upstream.ChainResponse +import io.emeraldpay.dshackle.upstream.NodeTypeRequest import io.emeraldpay.dshackle.upstream.Upstream import io.emeraldpay.dshackle.upstream.rpcclient.ListParams import reactor.core.publisher.Flux @@ -24,6 +26,10 @@ class EthereumUpstreamSettingsDetector( ) } + override fun mapping(node: JsonNode): String { + return node.asText() + } + override fun clientVersionRequest(): ChainRequest { return ChainRequest("web3_clientVersion", ListParams()) } @@ -54,9 +60,5 @@ class EthereumUpstreamSettingsDetector( ).flatMap(ChainResponse::requireResult) } - override fun nodeTypeRequest(): NodeTypeRequest { - return NodeTypeRequest( - clientVersionRequest(), - ) { node -> node } - } + override fun nodeTypeRequest(): NodeTypeRequest = NodeTypeRequest(clientVersionRequest()) } diff --git a/src/main/kotlin/io/emeraldpay/dshackle/upstream/near/NearUpstreamSettingsDetector.kt b/src/main/kotlin/io/emeraldpay/dshackle/upstream/near/NearUpstreamSettingsDetector.kt index 685e26d0..85edb941 100644 --- a/src/main/kotlin/io/emeraldpay/dshackle/upstream/near/NearUpstreamSettingsDetector.kt +++ b/src/main/kotlin/io/emeraldpay/dshackle/upstream/near/NearUpstreamSettingsDetector.kt @@ -2,19 +2,24 @@ package io.emeraldpay.dshackle.upstream.near import com.fasterxml.jackson.annotation.JsonIgnoreProperties import com.fasterxml.jackson.annotation.JsonProperty +import com.fasterxml.jackson.databind.JsonNode import com.fasterxml.jackson.module.kotlin.readValue import io.emeraldpay.dshackle.Global +import io.emeraldpay.dshackle.upstream.BasicUpstreamSettingsDetector import io.emeraldpay.dshackle.upstream.ChainRequest +import io.emeraldpay.dshackle.upstream.NodeTypeRequest +import io.emeraldpay.dshackle.upstream.UNKNOWN_CLIENT_VERSION import io.emeraldpay.dshackle.upstream.Upstream -import io.emeraldpay.dshackle.upstream.UpstreamSettingsDetector import io.emeraldpay.dshackle.upstream.rpcclient.ListParams import reactor.core.publisher.Flux class NearUpstreamSettingsDetector( upstream: Upstream, -) : UpstreamSettingsDetector(upstream) { +) : BasicUpstreamSettingsDetector(upstream) { override fun detectLabels(): Flux> { - return Flux.empty() + return Flux.merge( + detectNodeType(), + ) } override fun clientVersionRequest(): ChainRequest { @@ -36,4 +41,11 @@ class NearUpstreamSettingsDetector( @JsonProperty("version") val version: String, ) + + override fun nodeTypeRequest(): NodeTypeRequest = NodeTypeRequest(clientVersionRequest()) + + override fun clientType(node: JsonNode): String? = null + + override fun clientVersion(node: JsonNode): String? = + node.get("version")?.get("version")?.asText() ?: UNKNOWN_CLIENT_VERSION } diff --git a/src/main/kotlin/io/emeraldpay/dshackle/upstream/solana/SolanaUpstreamSettingsDetector.kt b/src/main/kotlin/io/emeraldpay/dshackle/upstream/solana/SolanaUpstreamSettingsDetector.kt index 92c23e6c..da4386e0 100644 --- a/src/main/kotlin/io/emeraldpay/dshackle/upstream/solana/SolanaUpstreamSettingsDetector.kt +++ b/src/main/kotlin/io/emeraldpay/dshackle/upstream/solana/SolanaUpstreamSettingsDetector.kt @@ -2,19 +2,24 @@ package io.emeraldpay.dshackle.upstream.solana import com.fasterxml.jackson.annotation.JsonIgnoreProperties import com.fasterxml.jackson.annotation.JsonProperty +import com.fasterxml.jackson.databind.JsonNode import com.fasterxml.jackson.module.kotlin.readValue import io.emeraldpay.dshackle.Global +import io.emeraldpay.dshackle.upstream.BasicUpstreamSettingsDetector import io.emeraldpay.dshackle.upstream.ChainRequest +import io.emeraldpay.dshackle.upstream.NodeTypeRequest +import io.emeraldpay.dshackle.upstream.UNKNOWN_CLIENT_VERSION import io.emeraldpay.dshackle.upstream.Upstream -import io.emeraldpay.dshackle.upstream.UpstreamSettingsDetector import io.emeraldpay.dshackle.upstream.rpcclient.ListParams import reactor.core.publisher.Flux class SolanaUpstreamSettingsDetector( upstream: Upstream, -) : UpstreamSettingsDetector(upstream) { +) : BasicUpstreamSettingsDetector(upstream) { override fun detectLabels(): Flux> { - return Flux.empty() + return Flux.merge( + detectNodeType(), + ) } override fun clientVersionRequest(): ChainRequest { @@ -30,4 +35,11 @@ class SolanaUpstreamSettingsDetector( @JsonProperty("solana-core") val version: String, ) + + override fun nodeTypeRequest(): NodeTypeRequest = NodeTypeRequest(clientVersionRequest()) + + override fun clientVersion(node: JsonNode): String? = + node.get("solana-core")?.textValue() ?: UNKNOWN_CLIENT_VERSION + + override fun clientType(node: JsonNode): String? = null }