eth_getProof lower bound detector (#651)

* getProof lowerbound

* update emerald-grps submodule

* add sepolia not retryable error to proof lower bound detector
This commit is contained in:
Andrey Bronin
2025-04-23 12:23:23 +03:00
committed by GitHub
parent d20f2d0c7f
commit bb6a0ea90b
6 changed files with 68 additions and 2 deletions

View File

@@ -147,6 +147,7 @@ class ChainEventMapper {
LowerBoundType.TX -> BlockchainOuterClass.LowerBoundType.LOWER_BOUND_TX LowerBoundType.TX -> BlockchainOuterClass.LowerBoundType.LOWER_BOUND_TX
LowerBoundType.LOGS -> BlockchainOuterClass.LowerBoundType.LOWER_BOUND_LOGS LowerBoundType.LOGS -> BlockchainOuterClass.LowerBoundType.LOWER_BOUND_LOGS
LowerBoundType.TRACE -> BlockchainOuterClass.LowerBoundType.LOWER_BOUND_TRACE LowerBoundType.TRACE -> BlockchainOuterClass.LowerBoundType.LOWER_BOUND_TRACE
LowerBoundType.PROOF -> BlockchainOuterClass.LowerBoundType.LOWER_BOUND_PROOF
} }
} }
} }

View File

@@ -107,6 +107,7 @@ class StreamHead(
LowerBoundType.TX -> BlockchainOuterClass.LowerBoundType.LOWER_BOUND_TX LowerBoundType.TX -> BlockchainOuterClass.LowerBoundType.LOWER_BOUND_TX
LowerBoundType.LOGS -> BlockchainOuterClass.LowerBoundType.LOWER_BOUND_LOGS LowerBoundType.LOGS -> BlockchainOuterClass.LowerBoundType.LOWER_BOUND_LOGS
LowerBoundType.TRACE -> BlockchainOuterClass.LowerBoundType.LOWER_BOUND_TRACE LowerBoundType.TRACE -> BlockchainOuterClass.LowerBoundType.LOWER_BOUND_TRACE
LowerBoundType.PROOF -> BlockchainOuterClass.LowerBoundType.LOWER_BOUND_PROOF
} }
} }

View File

@@ -0,0 +1,62 @@
package io.emeraldpay.dshackle.upstream.ethereum
import io.emeraldpay.dshackle.Defaults
import io.emeraldpay.dshackle.upstream.ChainRequest
import io.emeraldpay.dshackle.upstream.ChainResponse
import io.emeraldpay.dshackle.upstream.Upstream
import io.emeraldpay.dshackle.upstream.lowerbound.LowerBoundData
import io.emeraldpay.dshackle.upstream.lowerbound.LowerBoundDetector
import io.emeraldpay.dshackle.upstream.lowerbound.LowerBoundType
import io.emeraldpay.dshackle.upstream.lowerbound.detector.RecursiveLowerBound
import io.emeraldpay.dshackle.upstream.lowerbound.toHex
import io.emeraldpay.dshackle.upstream.rpcclient.ListParams
import reactor.core.publisher.Flux
import reactor.core.publisher.Mono
class EthereumLowerBoundProofDetector(
private val upstream: Upstream,
) : LowerBoundDetector(upstream.getChain()) {
companion object {
private const val NO_PROOF_DATA = "distance to target block exceeds maximum proof window"
val NO_PROOF_ERRORS = setOf(
NO_PROOF_DATA,
"requested block is too old",
"block not found",
"proofs are available only for the 'latest' block",
"missing trie node",
)
}
private val recursiveLowerBound = RecursiveLowerBound(upstream, LowerBoundType.PROOF, NO_PROOF_ERRORS, lowerBounds)
override fun period(): Long {
return 3
}
override fun internalDetectLowerBound(): Flux<LowerBoundData> {
return recursiveLowerBound.recursiveDetectLowerBound { block ->
if (block == 0L) {
Mono.just(ChainResponse(ByteArray(0), null))
} else {
val request = ChainRequest(
"eth_getProof",
ListParams("0x0000000000000000000000000000000000000000", listOf<Any>(), block.toHex()),
)
upstream.getIngressReader()
.read(request)
.timeout(Defaults.internalCallsTimeout)
.doOnNext {
if (it.hasResult() && it.getResult().contentEquals("null".toByteArray())) {
throw IllegalStateException(NO_PROOF_DATA)
}
}
}
}.flatMap {
Flux.just(it, lowerBoundFrom(it, LowerBoundType.PROOF))
}
}
override fun types(): Set<LowerBoundType> {
return setOf(LowerBoundType.PROOF)
}
}

View File

@@ -14,6 +14,7 @@ class EthereumLowerBoundService(
EthereumLowerBoundStateDetector(upstream), EthereumLowerBoundStateDetector(upstream),
EthereumLowerBoundBlockDetector(upstream), EthereumLowerBoundBlockDetector(upstream),
EthereumLowerBoundTxDetector(upstream), EthereumLowerBoundTxDetector(upstream),
EthereumLowerBoundProofDetector(upstream),
) )
} }
} }

View File

@@ -20,7 +20,7 @@ data class LowerBoundData(
} }
enum class LowerBoundType { enum class LowerBoundType {
UNKNOWN, STATE, SLOT, BLOCK, TX, LOGS, TRACE UNKNOWN, STATE, SLOT, BLOCK, TX, LOGS, TRACE, PROOF
} }
fun BlockchainOuterClass.LowerBoundType.fromProtoType(): LowerBoundType { fun BlockchainOuterClass.LowerBoundType.fromProtoType(): LowerBoundType {
@@ -33,5 +33,6 @@ fun BlockchainOuterClass.LowerBoundType.fromProtoType(): LowerBoundType {
BlockchainOuterClass.LowerBoundType.LOWER_BOUND_TX -> LowerBoundType.TX BlockchainOuterClass.LowerBoundType.LOWER_BOUND_TX -> LowerBoundType.TX
BlockchainOuterClass.LowerBoundType.LOWER_BOUND_LOGS -> LowerBoundType.LOGS BlockchainOuterClass.LowerBoundType.LOWER_BOUND_LOGS -> LowerBoundType.LOGS
BlockchainOuterClass.LowerBoundType.LOWER_BOUND_TRACE -> LowerBoundType.TRACE BlockchainOuterClass.LowerBoundType.LOWER_BOUND_TRACE -> LowerBoundType.TRACE
BlockchainOuterClass.LowerBoundType.LOWER_BOUND_PROOF -> LowerBoundType.PROOF
} }
} }