Validate old blocks (#268)
This commit is contained in:
@@ -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()
|
||||
}
|
||||
}
|
||||
@@ -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()))
|
||||
|
||||
@@ -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)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user