Fix archive detection (#310)

This commit is contained in:
KirillPamPam
2023-10-02 15:34:48 +04:00
committed by GitHub
parent 3875ec2f3a
commit 208deb55a1
4 changed files with 36 additions and 14 deletions

View File

@@ -1,11 +1,16 @@
package io.emeraldpay.dshackle.upstream.ethereum
import io.emeraldpay.dshackle.Chain
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
private const val ARBITRUM_NITRO_BLOCK = "0x152DD47" // 22207815
private const val OPTIMISM_BEDROCK_BLOCK = "0x645C277" // 105235063
private const val EARLIEST_BLOCK = "0x2710" // 10000
class EthereumArchiveBlockNumberReader(
private val reader: JsonRpcReader,
) {
@@ -19,4 +24,12 @@ class EthereumArchiveBlockNumberReader(
String(it).substring(3, it.size - 1).toLong(radix = 16) - 10_000, // this is definitely archive
).toHex()
}
fun readEarliestBlock(chain: Chain): Mono<String> {
return when (chain) {
Chain.ARBITRUM__MAINNET -> ARBITRUM_NITRO_BLOCK
Chain.OPTIMISM__MAINNET -> OPTIMISM_BEDROCK_BLOCK
else -> EARLIEST_BLOCK
}.run { Mono.just(this) }
}
}

View File

@@ -53,7 +53,7 @@ open class EthereumLikeRpcUpstream(
) : EthereumLikeUpstream(id, hash, options, role, targets, node, chainConfig), Lifecycle, Upstream, CachesEnabled {
private val validator: EthereumUpstreamValidator = EthereumUpstreamValidator(chain, this, getOptions(), chainConfig.callLimitContract)
protected val connector: EthereumConnector = connectorFactory.create(this, validator, chain, skipEnhance)
private val labelsDetector = EthereumLabelsDetector(this.getIngressReader())
private val labelsDetector = EthereumLabelsDetector(this.getIngressReader(), chain)
private var hasLiveSubscriptionHead: AtomicBoolean = AtomicBoolean(false)
private var validatorSubscription: Disposable? = null

View File

@@ -2,6 +2,7 @@ package io.emeraldpay.dshackle.upstream.ethereum.subscribe
import com.fasterxml.jackson.databind.JsonNode
import com.fasterxml.jackson.module.kotlin.readValue
import io.emeraldpay.dshackle.Chain
import io.emeraldpay.dshackle.Global.Companion.objectMapper
import io.emeraldpay.dshackle.reader.JsonRpcReader
import io.emeraldpay.dshackle.upstream.ethereum.EthereumArchiveBlockNumberReader
@@ -12,7 +13,9 @@ import reactor.core.publisher.Mono
class EthereumLabelsDetector(
private val reader: JsonRpcReader,
private val chain: Chain,
) {
private val blockNumberReader = EthereumArchiveBlockNumberReader(reader)
fun detectLabels(): Flux<Pair<String, String>> {
return Flux.merge(
@@ -39,21 +42,23 @@ class EthereumLabelsDetector(
}
private fun detectArchiveNode(): Mono<Pair<String, String>> {
return EthereumArchiveBlockNumberReader(reader)
.readArchiveBlock()
.flatMap {
reader.read(
JsonRpcRequest(
"eth_getBalance",
listOf("0x756F45E3FA69347A9A973A725E3C98bC4db0b5a0", it),
),
)
}
.flatMap(JsonRpcResponse::requireResult)
return Mono.zip(
blockNumberReader.readEarliestBlock(chain).flatMap { haveBalance(it) },
blockNumberReader.readArchiveBlock().flatMap { haveBalance(it) },
)
.map { "archive" to "true" }
.onErrorResume { Mono.empty() }
}
private fun haveBalance(blockNumber: String): Mono<ByteArray> {
return reader.read(
JsonRpcRequest(
"eth_getBalance",
listOf("0x756F45E3FA69347A9A973A725E3C98bC4db0b5a0", blockNumber),
),
).flatMap(JsonRpcResponse::requireResult)
}
private fun nodeType(nodeType: String): String? {
return if (nodeType.contains("erigon", true)) {
"erigon"

View File

@@ -1,5 +1,6 @@
package io.emeraldpay.dshackle.upstream.ethereum
import io.emeraldpay.dshackle.Chain
import io.emeraldpay.dshackle.reader.Reader
import io.emeraldpay.dshackle.test.ApiReaderMock
import io.emeraldpay.dshackle.test.TestingCommons
@@ -23,9 +24,10 @@ class EthereumLabelsDetectorSpec extends Specification {
answer("web3_clientVersion", [], response)
answer("eth_blockNumber", [], "0x10df3e5")
answer("eth_getBalance", ["0x756F45E3FA69347A9A973A725E3C98bC4db0b5a0", "0x10dccd5"], "")
answer("eth_getBalance", ["0x756F45E3FA69347A9A973A725E3C98bC4db0b5a0", "0x2710"], "")
}
)
def detector = new EthereumLabelsDetector(up.getIngressReader())
def detector = new EthereumLabelsDetector(up.getIngressReader(), Chain.ETHEREUM__MAINNET)
when:
def act = detector.detectLabels()
@@ -55,9 +57,11 @@ class EthereumLabelsDetectorSpec extends Specification {
Mono.just(new JsonRpcResponse("\"0x10df3e5\"".getBytes(), null))
1 * read(new JsonRpcRequest("eth_getBalance", ["0x756F45E3FA69347A9A973A725E3C98bC4db0b5a0", "0x10dccd5"])) >>
Mono.error(new RuntimeException())
1 * read(new JsonRpcRequest("eth_getBalance", ["0x756F45E3FA69347A9A973A725E3C98bC4db0b5a0", "0x2710"])) >>
Mono.just(new JsonRpcResponse("".getBytes(), null))
}
}
def detector = new EthereumLabelsDetector(up.getIngressReader())
def detector = new EthereumLabelsDetector(up.getIngressReader(), Chain.ETHEREUM__MAINNET)
when:
def act = detector.detectLabels()
then: