feat(snapshot): plausibilitaets-checks (relay-quorum, drop, min-events)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
ccd7daf14d
commit
7e38b73785
|
|
@ -0,0 +1,36 @@
|
|||
export interface CheckInput {
|
||||
relaysQueried: number
|
||||
relaysResponded: number
|
||||
eventCount: number
|
||||
minEvents: number
|
||||
lastKnownGoodCount: number | undefined
|
||||
newDeletionsCount: number
|
||||
allowShrink: boolean
|
||||
}
|
||||
|
||||
export function runChecks(input: CheckInput): void {
|
||||
const quorum = Math.ceil(input.relaysQueried * 0.6)
|
||||
if (input.relaysResponded < quorum) {
|
||||
throw new Error(
|
||||
`Relay-Quorum nicht erreicht: ${input.relaysResponded}/${input.relaysQueried} ` +
|
||||
`(brauche mindestens ${quorum})`,
|
||||
)
|
||||
}
|
||||
if (input.eventCount < input.minEvents) {
|
||||
throw new Error(
|
||||
`Event-Count ${input.eventCount} unter min-events ${input.minEvents}`,
|
||||
)
|
||||
}
|
||||
if (input.lastKnownGoodCount !== undefined && !input.allowShrink) {
|
||||
const drop = input.lastKnownGoodCount - input.eventCount
|
||||
const dropPct = drop / input.lastKnownGoodCount
|
||||
if (dropPct > 0.2 && drop > input.newDeletionsCount) {
|
||||
throw new Error(
|
||||
`Event-Count-Drop ${drop} (${(dropPct * 100).toFixed(0)}%) gegenueber ` +
|
||||
`last-known-good ${input.lastKnownGoodCount}, ` +
|
||||
`nur ${input.newDeletionsCount} korrespondierende kind:5. ` +
|
||||
`Override mit --allow-shrink falls bewusst.`,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
import { assertEquals, assertThrows } from '@std/assert'
|
||||
import { runChecks } from '../src/core/checks.ts'
|
||||
|
||||
Deno.test('runChecks: weniger als 60% relays geantwortet -> hard-fail', () => {
|
||||
assertThrows(
|
||||
() => runChecks({
|
||||
relaysQueried: 5, relaysResponded: 2,
|
||||
eventCount: 27, minEvents: 1, lastKnownGoodCount: undefined,
|
||||
newDeletionsCount: 0, allowShrink: false,
|
||||
}),
|
||||
Error, 'Relay-Quorum',
|
||||
)
|
||||
})
|
||||
|
||||
Deno.test('runChecks: event-count unter min-events -> hard-fail', () => {
|
||||
assertThrows(
|
||||
() => runChecks({
|
||||
relaysQueried: 5, relaysResponded: 5,
|
||||
eventCount: 0, minEvents: 1, lastKnownGoodCount: undefined,
|
||||
newDeletionsCount: 0, allowShrink: false,
|
||||
}),
|
||||
Error, 'min-events',
|
||||
)
|
||||
})
|
||||
|
||||
Deno.test('runChecks: drop > 20% ohne kind:5 -> hard-fail', () => {
|
||||
assertThrows(
|
||||
() => runChecks({
|
||||
relaysQueried: 5, relaysResponded: 5,
|
||||
eventCount: 20, minEvents: 1, lastKnownGoodCount: 27,
|
||||
newDeletionsCount: 0, allowShrink: false,
|
||||
}),
|
||||
Error, 'Event-Count-Drop',
|
||||
)
|
||||
})
|
||||
|
||||
Deno.test('runChecks: drop > 20% mit korrespondierenden kind:5 -> ok', () => {
|
||||
runChecks({
|
||||
relaysQueried: 5, relaysResponded: 5,
|
||||
eventCount: 20, minEvents: 1, lastKnownGoodCount: 27,
|
||||
newDeletionsCount: 7, allowShrink: false,
|
||||
})
|
||||
})
|
||||
|
||||
Deno.test('runChecks: --allow-shrink umgeht drop-check', () => {
|
||||
runChecks({
|
||||
relaysQueried: 5, relaysResponded: 5,
|
||||
eventCount: 1, minEvents: 1, lastKnownGoodCount: 27,
|
||||
newDeletionsCount: 0, allowShrink: true,
|
||||
})
|
||||
})
|
||||
|
||||
Deno.test('runChecks: erstlauf ohne cache + min-events=1 -> ok', () => {
|
||||
runChecks({
|
||||
relaysQueried: 5, relaysResponded: 5,
|
||||
eventCount: 1, minEvents: 1, lastKnownGoodCount: undefined,
|
||||
newDeletionsCount: 0, allowShrink: false,
|
||||
})
|
||||
})
|
||||
Loading…
Reference in New Issue