Pass delta; fix coeffs calculation (#716)

This commit is contained in:
KirillPamPam
2025-08-28 18:02:58 +04:00
committed by GitHub
parent b3d8d39552
commit 0ec7e4fd70
4 changed files with 53 additions and 5 deletions

View File

@@ -109,6 +109,7 @@ class Selector {
it.lowerHeightSelector.height,
it.lowerHeightSelector.lowerBoundType.fromProtoType(),
it.lowerHeightSelector.timeOffset,
it.lowerHeightSelector.heightDelta,
)
} else {
empty
@@ -571,10 +572,11 @@ class Selector {
private val lowerHeight: Long,
private val boundType: LowerBoundType,
private val timeOffsetSeconds: Long = 0,
private val delta: Long = 0,
) : Matcher() {
override fun matchesWithCause(up: Upstream): MatchesResponse {
val predictedLowerBound = up.predictLowerBound(boundType, timeOffsetSeconds)
return if (lowerHeight >= predictedLowerBound && predictedLowerBound != 0L) {
return if (lowerHeight >= (predictedLowerBound - delta) && predictedLowerBound != 0L) {
Success
} else {
LowerHeightResponse(lowerHeight, predictedLowerBound, boundType)

View File

@@ -75,6 +75,12 @@ class LowerBounds(
return (lowerBoundCoeffs.k.get() * xTime + lowerBoundCoeffs.b.get()).roundToLong()
}
fun predictNextBoundAtSpecificTime(type: LowerBoundType, timestamp: Long): Long {
val lowerBoundCoeffs = lowerBounds[type] ?: return 0
return (lowerBoundCoeffs.k.get() * timestamp + lowerBoundCoeffs.b.get()).roundToLong()
}
fun getLastBound(type: LowerBoundType): LowerBoundData? {
return lowerBounds[type]?.getLastBound()
}
@@ -124,7 +130,8 @@ class LowerBounds(
regression.addObservation(doubleArrayOf(it.timestamp.toDouble()), it.lowerBound.toDouble())
}
updateCoeffs(regression.slope, regression.intercept)
// we want our line to go through the last point in terms of the function k(y-y(t))+b
updateCoeffs(regression.slope, lowerBounds.last.lowerBound.toDouble() - regression.slope * lowerBounds.last.timestamp)
}
}
}

View File

@@ -4,10 +4,49 @@ import io.emeraldpay.dshackle.Chain
import org.assertj.core.api.Assertions.assertThat
import org.junit.Test
import java.time.Instant
import java.time.LocalDateTime
import java.time.ZoneOffset
import java.time.format.DateTimeFormatter
import java.time.temporal.ChronoUnit
class LowerBoundsPredictionTest {
@Test
fun testPredictionAtSpecificTime() {
val lowerBounds = LowerBounds(Chain.`0G__GALILEO_TESTNET`)
val dateStr = "28.08.2025 11:00:57"
val reqStr = "28.08.2025 11:10:25"
val formatter = DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm:ss")
val localDateTime = LocalDateTime.parse(dateStr, formatter)
val reqDateTime = LocalDateTime.parse(reqStr, formatter)
lowerBounds.updateBound(
LowerBoundData(
3294252,
localDateTime.toEpochSecond(ZoneOffset.UTC),
LowerBoundType.RECEIPTS,
),
)
lowerBounds.updateBound(
LowerBoundData(
3294552,
localDateTime.plus(3, ChronoUnit.MINUTES).toEpochSecond(ZoneOffset.UTC),
LowerBoundType.RECEIPTS,
),
)
lowerBounds.updateBound(
LowerBoundData(
3294552,
localDateTime.plus(6, ChronoUnit.MINUTES).toEpochSecond(ZoneOffset.UTC),
LowerBoundType.RECEIPTS,
),
)
val predicted = lowerBounds.predictNextBoundAtSpecificTime(LowerBoundType.RECEIPTS, reqDateTime.toEpochSecond(ZoneOffset.UTC))
assertThat(predicted).isEqualTo(3294725)
}
@Test
fun `first archival lower bound data, get it and predict the next bound`() {
val lowerBounds = LowerBounds(Chain.ETHEREUM__MAINNET)
@@ -196,8 +235,8 @@ class LowerBoundsPredictionTest {
val predicted = lowerBounds.predictNextBound(LowerBoundType.STATE, 0)
assertThat(predicted)
.isLessThan(37996030)
.isGreaterThan(37996020)
.isLessThan(37996090)
.isGreaterThan(37996070)
}
@Test