diff --git a/foundation/src/main/resources/chains.yaml b/foundation/src/main/resources/chains.yaml index e27581e84..3005d15da 100644 --- a/foundation/src/main/resources/chains.yaml +++ b/foundation/src/main/resources/chains.yaml @@ -244,7 +244,7 @@ chain-settings: label: Arbitrum Nova type: eth settings: - expected-block-time: 1s + expected-block-time: 260ms options: disable-validation: true lags: @@ -737,7 +737,7 @@ chain-settings: type: solana settings: currency: SOL - expected-block-time: 1s + expected-block-time: 400ms options: validate-peers: false lags: diff --git a/src/main/kotlin/io/emeraldpay/dshackle/upstream/LowerBoundBlockDetector.kt b/src/main/kotlin/io/emeraldpay/dshackle/upstream/LowerBoundBlockDetector.kt index 2a3ea89a0..8b12b68c2 100644 --- a/src/main/kotlin/io/emeraldpay/dshackle/upstream/LowerBoundBlockDetector.kt +++ b/src/main/kotlin/io/emeraldpay/dshackle/upstream/LowerBoundBlockDetector.kt @@ -6,6 +6,7 @@ import reactor.core.publisher.Flux import reactor.core.publisher.Mono import java.time.Duration import java.time.Instant +import java.util.concurrent.atomic.AtomicBoolean import java.util.concurrent.atomic.AtomicReference typealias LowerBoundBlockDetectorBuilder = (Chain, Upstream) -> LowerBoundBlockDetector @@ -21,11 +22,20 @@ abstract class LowerBoundBlockDetector( protected val log = LoggerFactory.getLogger(this::class.java) fun lowerBlock(): Flux { + val notProcessing = AtomicBoolean(true) + return Flux.interval( Duration.ofSeconds(15), - Duration.ofSeconds(60), + Duration.ofMinutes(periodRequest()), ) - .flatMap { lowerBlockDetect() } + .filter { notProcessing.get() } + .flatMap { + notProcessing.set(false) + lowerBlockDetect() + } + .doOnNext { + notProcessing.set(true) + } .filter { it.blockNumber > currentLowerBlock.get().blockNumber } .map { log.info("Lower block of ${upstream.getId()} $chain: block height - {}, slot - {}", it.blockNumber, it.slot ?: "NA") @@ -39,6 +49,8 @@ abstract class LowerBoundBlockDetector( protected abstract fun lowerBlockDetect(): Mono + protected abstract fun periodRequest(): Long + data class LowerBlockData( val blockNumber: Long, val slot: Long?, diff --git a/src/main/kotlin/io/emeraldpay/dshackle/upstream/RecursiveLowerBoundBlockDetector.kt b/src/main/kotlin/io/emeraldpay/dshackle/upstream/RecursiveLowerBoundBlockDetector.kt index 98f87d40e..e17fb00d8 100644 --- a/src/main/kotlin/io/emeraldpay/dshackle/upstream/RecursiveLowerBoundBlockDetector.kt +++ b/src/main/kotlin/io/emeraldpay/dshackle/upstream/RecursiveLowerBoundBlockDetector.kt @@ -27,7 +27,7 @@ abstract class RecursiveLowerBoundBlockDetector( } else { val middle = middleBlock(data) - if (data.left > data.right) { + if (data.left > data.right || middle == 0L) { val current = if (data.current == 0L) 1 else data.current Mono.just(LowerBoundData(current, true)) } else { @@ -57,7 +57,7 @@ abstract class RecursiveLowerBoundBlockDetector( Long.MAX_VALUE, Duration.ofSeconds(1), ) - .maxBackoff(Duration.ofSeconds(3)) + .maxBackoff(Duration.ofMinutes(3)) .filter { !nonRetryableErrors.any { err -> it.message?.contains(err, true) ?: false } } @@ -71,5 +71,9 @@ abstract class RecursiveLowerBoundBlockDetector( } } + override fun periodRequest(): Long { + return 10 + } + protected abstract fun hasState(blockNumber: Long): Mono } diff --git a/src/main/kotlin/io/emeraldpay/dshackle/upstream/ethereum/EthereumLowerBoundBlockDetector.kt b/src/main/kotlin/io/emeraldpay/dshackle/upstream/ethereum/EthereumLowerBoundBlockDetector.kt index da8ab10f2..53f8c7498 100644 --- a/src/main/kotlin/io/emeraldpay/dshackle/upstream/ethereum/EthereumLowerBoundBlockDetector.kt +++ b/src/main/kotlin/io/emeraldpay/dshackle/upstream/ethereum/EthereumLowerBoundBlockDetector.kt @@ -34,6 +34,8 @@ class EthereumLowerBoundBlockDetector( "after last accepted block", "Version has either been pruned, or is for a future block", // cronos "no historical RPC is available for this historical", // optimism + "historical backend error", // optimism + "load state tree: failed to load state tree", // filecoin ) } diff --git a/src/main/kotlin/io/emeraldpay/dshackle/upstream/solana/SolanaLowerBoundBlockDetector.kt b/src/main/kotlin/io/emeraldpay/dshackle/upstream/solana/SolanaLowerBoundBlockDetector.kt index 96505113d..bfa5f7427 100644 --- a/src/main/kotlin/io/emeraldpay/dshackle/upstream/solana/SolanaLowerBoundBlockDetector.kt +++ b/src/main/kotlin/io/emeraldpay/dshackle/upstream/solana/SolanaLowerBoundBlockDetector.kt @@ -79,7 +79,7 @@ class SolanaLowerBoundBlockDetector( .retryWhen( Retry .backoff(Long.MAX_VALUE, Duration.ofSeconds(1)) - .maxBackoff(Duration.ofSeconds(3)) + .maxBackoff(Duration.ofMinutes(3)) .doAfterRetry { log.debug( "Error in calculation of lower block of upstream {}, retry attempt - {}, message - {}", @@ -90,4 +90,8 @@ class SolanaLowerBoundBlockDetector( }, ) } + + override fun periodRequest(): Long { + return 3 + } } diff --git a/src/main/kotlin/io/emeraldpay/dshackle/upstream/starknet/StarknetLowerBoundBlockDetector.kt b/src/main/kotlin/io/emeraldpay/dshackle/upstream/starknet/StarknetLowerBoundBlockDetector.kt index 4f3d19412..a86fab28c 100644 --- a/src/main/kotlin/io/emeraldpay/dshackle/upstream/starknet/StarknetLowerBoundBlockDetector.kt +++ b/src/main/kotlin/io/emeraldpay/dshackle/upstream/starknet/StarknetLowerBoundBlockDetector.kt @@ -14,4 +14,8 @@ class StarknetLowerBoundBlockDetector( override fun lowerBlockDetect(): Mono { return Mono.just(LowerBlockData(1)) } + + override fun periodRequest(): Long { + return 120 + } } diff --git a/src/test/kotlin/io/emeraldpay/dshackle/upstream/RecursiveLowerBoundBlockDetectorTest.kt b/src/test/kotlin/io/emeraldpay/dshackle/upstream/RecursiveLowerBoundBlockDetectorTest.kt index 486f3c771..64a60b91b 100644 --- a/src/test/kotlin/io/emeraldpay/dshackle/upstream/RecursiveLowerBoundBlockDetectorTest.kt +++ b/src/test/kotlin/io/emeraldpay/dshackle/upstream/RecursiveLowerBoundBlockDetectorTest.kt @@ -38,7 +38,7 @@ class RecursiveLowerBoundBlockDetectorTest { StepVerifier.withVirtualTime { detector.lowerBlock() } .expectSubscription() .expectNoEvent(Duration.ofSeconds(15)) - .expectNext(LowerBoundBlockDetector.LowerBlockData(17964844L)) + .expectNextMatches { it.blockNumber == 17964844L } .thenCancel() .verify(Duration.ofSeconds(3)) @@ -64,7 +64,7 @@ class RecursiveLowerBoundBlockDetectorTest { StepVerifier.withVirtualTime { detector.lowerBlock() } .expectSubscription() .expectNoEvent(Duration.ofSeconds(15)) - .expectNext(LowerBoundBlockDetector.LowerBlockData(1)) + .expectNextMatches { it.blockNumber == 1L } .thenCancel() .verify(Duration.ofSeconds(3)) diff --git a/src/test/kotlin/io/emeraldpay/dshackle/upstream/solana/SolanaLowerBoundBlockDetectorTest.kt b/src/test/kotlin/io/emeraldpay/dshackle/upstream/solana/SolanaLowerBoundBlockDetectorTest.kt index b6646a58c..c4c4969df 100644 --- a/src/test/kotlin/io/emeraldpay/dshackle/upstream/solana/SolanaLowerBoundBlockDetectorTest.kt +++ b/src/test/kotlin/io/emeraldpay/dshackle/upstream/solana/SolanaLowerBoundBlockDetectorTest.kt @@ -61,7 +61,7 @@ class SolanaLowerBoundBlockDetectorTest { StepVerifier.withVirtualTime { detector.lowerBlock() } .expectSubscription() .expectNoEvent(Duration.ofSeconds(15)) - .expectNext(LowerBoundBlockDetector.LowerBlockData(21000000, 23000010)) + .expectNextMatches { it.blockNumber == 21000000L && it.slot == 23000010L } .thenCancel() .verify(Duration.ofSeconds(3))