diff --git a/emerald-grpc b/emerald-grpc index a85b55e5..947e7249 160000 --- a/emerald-grpc +++ b/emerald-grpc @@ -1 +1 @@ -Subproject commit a85b55e501f9465234d36aa9d37f9f6a4c1abb11 +Subproject commit 947e72497881707c1bfd430af10fe85ce6c62716 diff --git a/src/main/kotlin/io/emeraldpay/dshackle/upstream/DefaultUpstream.kt b/src/main/kotlin/io/emeraldpay/dshackle/upstream/DefaultUpstream.kt index eb350888..3ea8649b 100644 --- a/src/main/kotlin/io/emeraldpay/dshackle/upstream/DefaultUpstream.kt +++ b/src/main/kotlin/io/emeraldpay/dshackle/upstream/DefaultUpstream.kt @@ -168,7 +168,7 @@ abstract class DefaultUpstream( // NOOP } - override fun predictLowerBound(type: LowerBoundType): Long { + override fun predictLowerBound(type: LowerBoundType, timeOffsetSeconds: Long): Long { return 0 } diff --git a/src/main/kotlin/io/emeraldpay/dshackle/upstream/Multistream.kt b/src/main/kotlin/io/emeraldpay/dshackle/upstream/Multistream.kt index 27113e26..6f04efcc 100644 --- a/src/main/kotlin/io/emeraldpay/dshackle/upstream/Multistream.kt +++ b/src/main/kotlin/io/emeraldpay/dshackle/upstream/Multistream.kt @@ -257,7 +257,7 @@ abstract class Multistream( return getAll().any { it.isAvailable() } } - override fun predictLowerBound(type: LowerBoundType): Long { + override fun predictLowerBound(type: LowerBoundType, timeOffsetSeconds: Long): Long { return 0 } diff --git a/src/main/kotlin/io/emeraldpay/dshackle/upstream/Selector.kt b/src/main/kotlin/io/emeraldpay/dshackle/upstream/Selector.kt index 19e77d16..f901b9a6 100644 --- a/src/main/kotlin/io/emeraldpay/dshackle/upstream/Selector.kt +++ b/src/main/kotlin/io/emeraldpay/dshackle/upstream/Selector.kt @@ -108,6 +108,7 @@ class Selector { LowerHeightMatcher( it.lowerHeightSelector.height, it.lowerHeightSelector.lowerBoundType.fromProtoType(), + it.lowerHeightSelector.timeOffset, ) } else { empty @@ -569,9 +570,10 @@ class Selector { data class LowerHeightMatcher( private val lowerHeight: Long, private val boundType: LowerBoundType, + private val timeOffsetSeconds: Long = 0, ) : Matcher() { override fun matchesWithCause(up: Upstream): MatchesResponse { - val predictedLowerBound = up.predictLowerBound(boundType) + val predictedLowerBound = up.predictLowerBound(boundType, timeOffsetSeconds) return if (lowerHeight >= predictedLowerBound && predictedLowerBound != 0L) { Success } else { diff --git a/src/main/kotlin/io/emeraldpay/dshackle/upstream/Upstream.kt b/src/main/kotlin/io/emeraldpay/dshackle/upstream/Upstream.kt index 8457b60e..2a091cb6 100644 --- a/src/main/kotlin/io/emeraldpay/dshackle/upstream/Upstream.kt +++ b/src/main/kotlin/io/emeraldpay/dshackle/upstream/Upstream.kt @@ -55,7 +55,7 @@ interface Upstream : Lifecycle { fun addFinalization(finalization: FinalizationData, upstreamId: String) fun getUpstreamSettingsData(): UpstreamSettingsData? fun updateLowerBound(lowerBound: Long, type: LowerBoundType) - fun predictLowerBound(type: LowerBoundType): Long + fun predictLowerBound(type: LowerBoundType, timeOffsetSeconds: Long): Long fun getChain(): Chain diff --git a/src/main/kotlin/io/emeraldpay/dshackle/upstream/generic/GenericUpstream.kt b/src/main/kotlin/io/emeraldpay/dshackle/upstream/generic/GenericUpstream.kt index ea364ace..b5fa61df 100644 --- a/src/main/kotlin/io/emeraldpay/dshackle/upstream/generic/GenericUpstream.kt +++ b/src/main/kotlin/io/emeraldpay/dshackle/upstream/generic/GenericUpstream.kt @@ -437,8 +437,8 @@ open class GenericUpstream( lowerBoundService.updateLowerBound(lowerBound, type) } - override fun predictLowerBound(type: LowerBoundType): Long { - return lowerBoundService.predictLowerBound(type) + override fun predictLowerBound(type: LowerBoundType, timeOffsetSeconds: Long): Long { + return lowerBoundService.predictLowerBound(type, timeOffsetSeconds) } fun isValid(): Boolean = isUpstreamValid.get() diff --git a/src/main/kotlin/io/emeraldpay/dshackle/upstream/lowerbound/LowerBoundDetector.kt b/src/main/kotlin/io/emeraldpay/dshackle/upstream/lowerbound/LowerBoundDetector.kt index 72738e7d..857ee960 100644 --- a/src/main/kotlin/io/emeraldpay/dshackle/upstream/lowerbound/LowerBoundDetector.kt +++ b/src/main/kotlin/io/emeraldpay/dshackle/upstream/lowerbound/LowerBoundDetector.kt @@ -64,7 +64,7 @@ abstract class LowerBoundDetector( lowerBoundSink.emitNext(LowerBoundData(lowerBound, type)) { _, res -> res == Sinks.EmitResult.FAIL_NON_SERIALIZED } } - fun predictLowerBound(type: LowerBoundType): Long { - return lowerBounds.predictNextBound(type) + fun predictLowerBound(type: LowerBoundType, timeOffsetSeconds: Long): Long { + return lowerBounds.predictNextBound(type, timeOffsetSeconds) } } diff --git a/src/main/kotlin/io/emeraldpay/dshackle/upstream/lowerbound/LowerBoundService.kt b/src/main/kotlin/io/emeraldpay/dshackle/upstream/lowerbound/LowerBoundService.kt index 945d9918..c0693aa8 100644 --- a/src/main/kotlin/io/emeraldpay/dshackle/upstream/lowerbound/LowerBoundService.kt +++ b/src/main/kotlin/io/emeraldpay/dshackle/upstream/lowerbound/LowerBoundService.kt @@ -33,10 +33,10 @@ abstract class LowerBoundService( .forEach { it.updateLowerBound(lowerBound, type) } } - fun predictLowerBound(type: LowerBoundType): Long { + fun predictLowerBound(type: LowerBoundType, timeOffsetSeconds: Long): Long { return detectors .firstOrNull { it.types().contains(type) } - ?.predictLowerBound(type) + ?.predictLowerBound(type, timeOffsetSeconds) ?: 0 } diff --git a/src/main/kotlin/io/emeraldpay/dshackle/upstream/lowerbound/LowerBounds.kt b/src/main/kotlin/io/emeraldpay/dshackle/upstream/lowerbound/LowerBounds.kt index 839eff3f..723aa15c 100644 --- a/src/main/kotlin/io/emeraldpay/dshackle/upstream/lowerbound/LowerBounds.kt +++ b/src/main/kotlin/io/emeraldpay/dshackle/upstream/lowerbound/LowerBounds.kt @@ -67,16 +67,10 @@ class LowerBounds( } } - fun predictNextBound(type: LowerBoundType): Long { - val offset = if (chain == Chain.BSC__MAINNET && type == LowerBoundType.STATE) { - 30 - } else { - 0 - }.toLong() - + fun predictNextBound(type: LowerBoundType, timeOffsetSeconds: Long): Long { val lowerBoundCoeffs = lowerBounds[type] ?: return 0 - val xTime = Instant.now().plus(offset, ChronoUnit.SECONDS).epochSecond + val xTime = Instant.now().plus(timeOffsetSeconds, ChronoUnit.SECONDS).epochSecond return (lowerBoundCoeffs.k.get() * xTime + lowerBoundCoeffs.b.get()).roundToLong() } diff --git a/src/test/kotlin/io/emeraldpay/dshackle/upstream/SelectorTest.kt b/src/test/kotlin/io/emeraldpay/dshackle/upstream/SelectorTest.kt index f110cad9..fd01e4c5 100644 --- a/src/test/kotlin/io/emeraldpay/dshackle/upstream/SelectorTest.kt +++ b/src/test/kotlin/io/emeraldpay/dshackle/upstream/SelectorTest.kt @@ -225,7 +225,7 @@ class SelectorTest { expected: MatchesResponse, ) { val up = mock { - on { predictLowerBound(LowerBoundType.STATE) } doReturn predicted + on { predictLowerBound(LowerBoundType.STATE, 0) } doReturn predicted } val matcher = Selector.LowerHeightMatcher(lowerHeight, LowerBoundType.STATE) diff --git a/src/test/kotlin/io/emeraldpay/dshackle/upstream/lowerbound/LowerBoundServiceTest.kt b/src/test/kotlin/io/emeraldpay/dshackle/upstream/lowerbound/LowerBoundServiceTest.kt index f5d166bc..b834ee3a 100644 --- a/src/test/kotlin/io/emeraldpay/dshackle/upstream/lowerbound/LowerBoundServiceTest.kt +++ b/src/test/kotlin/io/emeraldpay/dshackle/upstream/lowerbound/LowerBoundServiceTest.kt @@ -15,15 +15,15 @@ class LowerBoundServiceTest { @Test fun `predict lower bound`() { val detector = mock { - on { predictLowerBound(LowerBoundType.STATE) } doReturn 4000 + on { predictLowerBound(LowerBoundType.STATE, 0) } doReturn 4000 on { types() } doReturn setOf(LowerBoundType.STATE) } val boundService = LowerBoundServiceMock(mock(), listOf(detector)) - val bound = boundService.predictLowerBound(LowerBoundType.STATE) + val bound = boundService.predictLowerBound(LowerBoundType.STATE, 0) verify(detector).types() - verify(detector).predictLowerBound(LowerBoundType.STATE) + verify(detector).predictLowerBound(LowerBoundType.STATE, 0) assertThat(bound).isEqualTo(4000) } @@ -35,10 +35,10 @@ class LowerBoundServiceTest { } val boundService = LowerBoundServiceMock(mock(), listOf(detector)) - val bound = boundService.predictLowerBound(LowerBoundType.BLOCK) + val bound = boundService.predictLowerBound(LowerBoundType.BLOCK, 0) verify(detector).types() - verify(detector, never()).predictLowerBound(any()) + verify(detector, never()).predictLowerBound(any(), any()) assertThat(bound).isEqualTo(0) } diff --git a/src/test/kotlin/io/emeraldpay/dshackle/upstream/lowerbound/LowerBoundsPredictionTest.kt b/src/test/kotlin/io/emeraldpay/dshackle/upstream/lowerbound/LowerBoundsPredictionTest.kt index 0aae8346..1bfeafb1 100644 --- a/src/test/kotlin/io/emeraldpay/dshackle/upstream/lowerbound/LowerBoundsPredictionTest.kt +++ b/src/test/kotlin/io/emeraldpay/dshackle/upstream/lowerbound/LowerBoundsPredictionTest.kt @@ -16,7 +16,7 @@ class LowerBoundsPredictionTest { lowerBounds.updateBound(newLowerBound) val lastBound = lowerBounds.getLastBound(LowerBoundType.STATE) - val predictedNextBound = lowerBounds.predictNextBound(LowerBoundType.STATE) + val predictedNextBound = lowerBounds.predictNextBound(LowerBoundType.STATE, 0) val allBounds = lowerBounds.getAllBounds(LowerBoundType.STATE) assertThat(lastBound).isEqualTo(newLowerBound) @@ -29,7 +29,7 @@ class LowerBoundsPredictionTest { val lowerBounds = LowerBounds(Chain.ETHEREUM__MAINNET) val lastBound = lowerBounds.getLastBound(LowerBoundType.STATE) - val predictedNextBound = lowerBounds.predictNextBound(LowerBoundType.STATE) + val predictedNextBound = lowerBounds.predictNextBound(LowerBoundType.STATE, 0) val allBounds = lowerBounds.getAllBounds(LowerBoundType.STATE) assertThat(lastBound).isNull() @@ -46,7 +46,7 @@ class LowerBoundsPredictionTest { lowerBounds.updateBound(newLowerBound) val lastBound = lowerBounds.getLastBound(LowerBoundType.STATE) - val predictedNextBound = lowerBounds.predictNextBound(LowerBoundType.STATE) + val predictedNextBound = lowerBounds.predictNextBound(LowerBoundType.STATE, 0) val allBounds = lowerBounds.getAllBounds(LowerBoundType.STATE) assertThat(lastBound).isEqualTo(newLowerBound) @@ -56,7 +56,7 @@ class LowerBoundsPredictionTest { lowerBounds.updateBound(nextNewLowerBound) val newLastBound = lowerBounds.getLastBound(LowerBoundType.STATE) - val newPredictedNextBound = lowerBounds.predictNextBound(LowerBoundType.STATE) + val newPredictedNextBound = lowerBounds.predictNextBound(LowerBoundType.STATE, 0) val newAllBounds = lowerBounds.getAllBounds(LowerBoundType.STATE) assertThat(newLastBound).isEqualTo(nextNewLowerBound) @@ -73,7 +73,7 @@ class LowerBoundsPredictionTest { lowerBounds.updateBound(LowerBoundData(100000L, 1000, LowerBoundType.STATE)) val lastBound = lowerBounds.getLastBound(LowerBoundType.STATE) - val predictedNextBound = lowerBounds.predictNextBound(LowerBoundType.STATE) + val predictedNextBound = lowerBounds.predictNextBound(LowerBoundType.STATE, 0) val allBounds = lowerBounds.getAllBounds(LowerBoundType.STATE) assertThat(lastBound).isEqualTo(newLowerBound) @@ -162,7 +162,7 @@ class LowerBoundsPredictionTest { lowerBounds.updateBound(lowerBound3) assertThat(lowerBounds.getLastBound(LowerBoundType.STATE)).isEqualTo(lowerBound3) - assertThat(lowerBounds.predictNextBound(LowerBoundType.STATE)).isEqualTo(15060L) + assertThat(lowerBounds.predictNextBound(LowerBoundType.STATE, 0)).isEqualTo(15060L) assertThat(lowerBounds.getAllBounds(LowerBoundType.STATE)).isEqualTo(listOf(lowerBound1, lowerBound2, lowerBound3)) } @@ -178,7 +178,7 @@ class LowerBoundsPredictionTest { lowerBounds.updateBound(lowerBound2) lowerBounds.updateBound(lowerBound3) - val predicted = lowerBounds.predictNextBound(LowerBoundType.STATE) + val predicted = lowerBounds.predictNextBound(LowerBoundType.STATE, 0) assertThat(predicted) .isLessThan(37996030) @@ -193,7 +193,7 @@ class LowerBoundsPredictionTest { lowerBounds.updateBound(lowerBound1) - val predicted = lowerBounds.predictNextBound(LowerBoundType.STATE) + val predicted = lowerBounds.predictNextBound(LowerBoundType.STATE, 0) assertThat(predicted) .isLessThan(37996030)