Validate old blocks (#268)

This commit is contained in:
KirillPamPam
2023-08-04 15:21:04 +04:00
committed by GitHub
parent 1d8445b3c3
commit 363af28bfc
24 changed files with 166 additions and 91 deletions

View File

@@ -0,0 +1,22 @@
package io.emeraldpay.dshackle.upstream.ethereum
import io.emeraldpay.dshackle.reader.JsonRpcReader
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcRequest
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcResponse
import io.emeraldpay.etherjar.hex.HexQuantity
import reactor.core.publisher.Mono
class EthereumArchiveBlockNumberReader(
private val reader: JsonRpcReader
) {
fun readArchiveBlock(): Mono<String> =
reader.read(JsonRpcRequest("eth_blockNumber", listOf()))
.flatMap(JsonRpcResponse::requireResult)
.map {
HexQuantity
.from(
String(it).substring(3, it.size - 1).toLong(radix = 16) - 10_000 // this is definitely archive
).toHex()
}
}

View File

@@ -113,7 +113,7 @@ open class EthereumUpstreamValidator @JvmOverloads constructor(
.then(Mono.error(TimeoutException("Validation timeout for Peers")))
)
.map { count ->
val minPeers = options.minPeers ?: 1
val minPeers = options.minPeers
if (count < minPeers) {
UpstreamAvailability.IMMATURE
} else {
@@ -137,9 +137,10 @@ open class EthereumUpstreamValidator @JvmOverloads constructor(
fun validateUpstreamSettings(): Boolean {
return Mono.zip(
validateChain(),
validateCallLimit()
validateCallLimit(),
validateOldBlocks()
).map {
it.t1 && it.t2
it.t1 && it.t2 && it.t3
}.block() ?: false
}
@@ -215,6 +216,35 @@ open class EthereumUpstreamValidator @JvmOverloads constructor(
.onErrorReturn(false)
}
private fun validateOldBlocks(): Mono<Boolean> {
return EthereumArchiveBlockNumberReader(upstream.getIngressReader())
.readArchiveBlock()
.flatMap {
upstream.getIngressReader()
.read(JsonRpcRequest("eth_getBlockByNumber", listOf(it, false)))
.flatMap(JsonRpcResponse::requireResult)
}
.retryRandomBackoff(3, Duration.ofMillis(100), Duration.ofMillis(500)) { ctx ->
log.warn(
"error during old block retrieving for ${upstream.getId()}, iteration ${ctx.iteration()}",
ctx.exception()
)
}
.map { result ->
val receivedResult = result.isNotEmpty() && !Global.nullValue.contentEquals(result)
if (!receivedResult) {
log.warn(
"Node ${upstream.getId()} probably is synced incorrectly, it is not possible to get old blocks"
)
}
true
}
.onErrorResume {
log.warn("Error during old blocks validation", it)
Mono.just(true)
}
}
private fun chainId(): Mono<String> {
return upstream.getIngressReader()
.read(JsonRpcRequest("eth_chainId", emptyList()))

View File

@@ -4,9 +4,9 @@ import com.fasterxml.jackson.databind.JsonNode
import com.fasterxml.jackson.module.kotlin.readValue
import io.emeraldpay.dshackle.Global.Companion.objectMapper
import io.emeraldpay.dshackle.reader.JsonRpcReader
import io.emeraldpay.dshackle.upstream.ethereum.EthereumArchiveBlockNumberReader
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcRequest
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcResponse
import io.emeraldpay.etherjar.hex.HexQuantity
import reactor.core.publisher.Flux
import reactor.core.publisher.Mono
@@ -39,15 +39,13 @@ class EthereumLabelsDetector(
}
private fun detectArchiveNode(): Mono<Pair<String, String>> {
return reader
.read(JsonRpcRequest("eth_blockNumber", listOf()))
.flatMap(JsonRpcResponse::requireResult)
return EthereumArchiveBlockNumberReader(reader)
.readArchiveBlock()
.flatMap {
val blockNum = HexQuantity.from(String(it).substring(3, it.size - 1).toLong(radix = 16) - 10_000) // this is definitely archive
reader.read(
JsonRpcRequest(
"eth_getBalance",
listOf("0x756F45E3FA69347A9A973A725E3C98bC4db0b5a0", blockNum.toHex())
listOf("0x756F45E3FA69347A9A973A725E3C98bC4db0b5a0", it)
)
)
}