From 0e6115ee939b37685b8b61f75885eb7abfdc3906 Mon Sep 17 00:00:00 2001 From: Artem Rootman <4586640+artemrootman@users.noreply.github.com> Date: Mon, 22 Dec 2025 17:57:33 +0000 Subject: [PATCH] Use server_state.complete_ledgers for Ripple lower bound --- .../ripple/RippleLowerBoundStateDetector.kt | 37 ++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/src/main/kotlin/io/emeraldpay/dshackle/upstream/ripple/RippleLowerBoundStateDetector.kt b/src/main/kotlin/io/emeraldpay/dshackle/upstream/ripple/RippleLowerBoundStateDetector.kt index 5daebe30..9d9aac71 100644 --- a/src/main/kotlin/io/emeraldpay/dshackle/upstream/ripple/RippleLowerBoundStateDetector.kt +++ b/src/main/kotlin/io/emeraldpay/dshackle/upstream/ripple/RippleLowerBoundStateDetector.kt @@ -1,9 +1,13 @@ package io.emeraldpay.dshackle.upstream.ripple +import io.emeraldpay.dshackle.Defaults +import io.emeraldpay.dshackle.Global +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.rpcclient.ListParams import reactor.core.publisher.Flux class RippleLowerBoundStateDetector( @@ -15,10 +19,41 @@ class RippleLowerBoundStateDetector( } override fun internalDetectLowerBound(): Flux { - return Flux.just(LowerBoundData(1, LowerBoundType.STATE)) + return upstream.getIngressReader() + .read(ChainRequest("server_state", ListParams())) + .timeout(Defaults.internalCallsTimeout) + .map { + val resp = Global.objectMapper.readValue(it.getResult(), RippleState::class.java) + parseCompleteLedgersLowerBound(resp.state.completeLedgers) + } + .filter { it != null } + .map { it!! } + .flatMapMany { lowerBound -> + Flux.fromIterable(listOf(LowerBoundData(lowerBound, LowerBoundType.STATE))) + } } override fun types(): Set { return setOf(LowerBoundType.STATE) } + + private fun parseCompleteLedgersLowerBound(completeLedgers: String?): Long? { + if (completeLedgers.isNullOrBlank()) { + return null + } + if (completeLedgers == "empty") { + return null + } + + return completeLedgers.split(",") + .mapNotNull { part -> + val token = part.trim() + if (token.isEmpty()) { + null + } else { + token.substringBefore("-").toLongOrNull() + } + } + .minOrNull() + } }