Logs lower bound + fix state detection with null (#503)
This commit is contained in:
@@ -97,6 +97,7 @@ class StreamHead(
|
||||
LowerBoundType.STATE -> BlockchainOuterClass.LowerBoundType.LOWER_BOUND_STATE
|
||||
LowerBoundType.BLOCK -> BlockchainOuterClass.LowerBoundType.LOWER_BOUND_BLOCK
|
||||
LowerBoundType.TX -> BlockchainOuterClass.LowerBoundType.LOWER_BOUND_TX
|
||||
LowerBoundType.LOGS -> BlockchainOuterClass.LowerBoundType.LOWER_BOUND_LOGS
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -15,7 +15,12 @@ import reactor.core.publisher.Mono
|
||||
class EthereumLowerBoundBlockDetector(
|
||||
private val upstream: Upstream,
|
||||
) : LowerBoundDetector() {
|
||||
private val recursiveLowerBound = RecursiveLowerBound(upstream, LowerBoundType.BLOCK, setOf("No block data"), lowerBounds)
|
||||
|
||||
companion object {
|
||||
private const val NO_BLOCK_DATA = "No block data"
|
||||
}
|
||||
|
||||
private val recursiveLowerBound = RecursiveLowerBound(upstream, LowerBoundType.BLOCK, setOf(NO_BLOCK_DATA), lowerBounds)
|
||||
|
||||
override fun period(): Long {
|
||||
return 3
|
||||
@@ -35,7 +40,7 @@ class EthereumLowerBoundBlockDetector(
|
||||
)
|
||||
.doOnNext {
|
||||
if (it.hasResult() && it.getResult().contentEquals("null".toByteArray())) {
|
||||
throw IllegalStateException("No block data")
|
||||
throw IllegalStateException(NO_BLOCK_DATA)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
package io.emeraldpay.dshackle.upstream.ethereum
|
||||
|
||||
import io.emeraldpay.dshackle.upstream.ChainRequest
|
||||
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
|
||||
|
||||
class EthereumLowerBoundLogsDetector(
|
||||
private val upstream: Upstream,
|
||||
) : LowerBoundDetector() {
|
||||
|
||||
companion object {
|
||||
const val MAX_OFFSET = 20
|
||||
private const val NO_LOGS_DATA = "No logs data"
|
||||
}
|
||||
|
||||
private val recursiveLowerBound = RecursiveLowerBound(upstream, LowerBoundType.LOGS, setOf(NO_LOGS_DATA), lowerBounds)
|
||||
|
||||
override fun period(): Long {
|
||||
return 3
|
||||
}
|
||||
|
||||
override fun internalDetectLowerBound(): Flux<LowerBoundData> {
|
||||
return recursiveLowerBound.recursiveDetectLowerBoundWithOffset(MAX_OFFSET) { block ->
|
||||
upstream.getIngressReader()
|
||||
.read(
|
||||
ChainRequest(
|
||||
"eth_getLogs",
|
||||
ListParams(
|
||||
mapOf(
|
||||
"fromBlock" to block.toHex(),
|
||||
"toBlock" to block.toHex(),
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
.doOnNext {
|
||||
if (it.hasResult() && (it.getResult().contentEquals("null".toByteArray()) || it.getResult().contentEquals("[]".toByteArray()))) {
|
||||
throw IllegalStateException(NO_LOGS_DATA)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun types(): Set<LowerBoundType> {
|
||||
return setOf(LowerBoundType.LOGS)
|
||||
}
|
||||
}
|
||||
@@ -14,6 +14,7 @@ class EthereumLowerBoundService(
|
||||
EthereumLowerBoundStateDetector(upstream),
|
||||
EthereumLowerBoundBlockDetector(upstream),
|
||||
EthereumLowerBoundTxDetector(upstream),
|
||||
EthereumLowerBoundLogsDetector(upstream),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package io.emeraldpay.dshackle.upstream.ethereum
|
||||
|
||||
import io.emeraldpay.dshackle.Global
|
||||
import io.emeraldpay.dshackle.upstream.ChainRequest
|
||||
import io.emeraldpay.dshackle.upstream.ChainResponse
|
||||
import io.emeraldpay.dshackle.upstream.Upstream
|
||||
@@ -41,6 +42,7 @@ class EthereumLowerBoundStateDetector(
|
||||
"historical backend error", // optimism
|
||||
"load state tree: failed to load state tree", // filecoin
|
||||
"purged for block", // erigon
|
||||
"No state data", // our own error if there is "null" in response
|
||||
)
|
||||
}
|
||||
|
||||
@@ -59,6 +61,10 @@ class EthereumLowerBoundStateDetector(
|
||||
ListParams(ZERO_ADDRESS, block.toHex()),
|
||||
),
|
||||
)
|
||||
}.doOnNext {
|
||||
if (it.hasResult() && it.getResult().contentEquals(Global.nullValue)) {
|
||||
throw IllegalStateException("No state data")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,12 +10,16 @@ import io.emeraldpay.dshackle.upstream.lowerbound.toHex
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.ListParams
|
||||
import reactor.core.publisher.Flux
|
||||
|
||||
const val MAX_OFFSET = 20
|
||||
|
||||
class EthereumLowerBoundTxDetector(
|
||||
private val upstream: Upstream,
|
||||
) : LowerBoundDetector() {
|
||||
private val recursiveLowerBound = RecursiveLowerBound(upstream, LowerBoundType.TX, setOf("No tx data"), lowerBounds)
|
||||
|
||||
companion object {
|
||||
const val MAX_OFFSET = 20
|
||||
private const val NO_TX_DATA = "No tx data"
|
||||
}
|
||||
|
||||
private val recursiveLowerBound = RecursiveLowerBound(upstream, LowerBoundType.TX, setOf(NO_TX_DATA), lowerBounds)
|
||||
|
||||
override fun period(): Long {
|
||||
return 3
|
||||
@@ -32,7 +36,7 @@ class EthereumLowerBoundTxDetector(
|
||||
)
|
||||
.doOnNext {
|
||||
if (it.hasResult() && (it.getResult().contentEquals("null".toByteArray()) || it.getResultAsProcessedString().substring(2).toLong(16) == 0L)) {
|
||||
throw IllegalStateException("No tx data")
|
||||
throw IllegalStateException(NO_TX_DATA)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package io.emeraldpay.dshackle.upstream.ethereum
|
||||
|
||||
import com.fasterxml.jackson.databind.JsonNode
|
||||
import io.emeraldpay.dshackle.Chain
|
||||
import io.emeraldpay.dshackle.Global
|
||||
import io.emeraldpay.dshackle.upstream.BasicEthUpstreamSettingsDetector
|
||||
import io.emeraldpay.dshackle.upstream.ChainRequest
|
||||
import io.emeraldpay.dshackle.upstream.ChainResponse
|
||||
@@ -60,7 +61,13 @@ class EthereumUpstreamSettingsDetector(
|
||||
"eth_getBalance",
|
||||
ListParams(ZERO_ADDRESS, blockNumber),
|
||||
),
|
||||
).flatMap(ChainResponse::requireResult)
|
||||
)
|
||||
.flatMap(ChainResponse::requireResult)
|
||||
.doOnNext {
|
||||
if (it.contentEquals(Global.nullValue)) {
|
||||
throw IllegalStateException("Null data")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun nodeTypeRequest(): NodeTypeRequest = NodeTypeRequest(clientVersionRequest())
|
||||
|
||||
@@ -20,7 +20,7 @@ data class LowerBoundData(
|
||||
}
|
||||
|
||||
enum class LowerBoundType {
|
||||
UNKNOWN, STATE, SLOT, BLOCK, TX
|
||||
UNKNOWN, STATE, SLOT, BLOCK, TX, LOGS
|
||||
}
|
||||
|
||||
fun BlockchainOuterClass.LowerBoundType.fromProtoType(): LowerBoundType {
|
||||
@@ -31,5 +31,6 @@ fun BlockchainOuterClass.LowerBoundType.fromProtoType(): LowerBoundType {
|
||||
BlockchainOuterClass.LowerBoundType.LOWER_BOUND_BLOCK -> LowerBoundType.BLOCK
|
||||
BlockchainOuterClass.LowerBoundType.UNRECOGNIZED -> LowerBoundType.UNKNOWN
|
||||
BlockchainOuterClass.LowerBoundType.LOWER_BOUND_TX -> LowerBoundType.TX
|
||||
BlockchainOuterClass.LowerBoundType.LOWER_BOUND_LOGS -> LowerBoundType.LOGS
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user