darshankabariya 3accb291c9 feat: persist RLN proofs in the archive so synced history stays verifiable
Live messages carry an RLN proof, but archives dropped it at insert
time - so history handed over via store-sync transfer or store resume
arrived proofless and had to be accepted on faith, sidestepping the
spam limiter exactly where it should be load-bearing. A malicious peer
could invent 'history you missed' and a victim would swallow and
re-serve it.

- archive: proof column (sqlite schema v11, postgres v8; nullable, so
  existing rows migrate as a no-op and in-memory archives need no
  migration); insert/select thread message.proof through both drivers;
  the queue driver stores whole messages and needed no change
- transfer and store resume serve proof-bearing messages automatically
  (the wire codecs already carry the field) and both re-verify the
  original author's proof on arrival: the receiving node's FIRST
  verification of a message it missed on relay, not a repeat - same
  work the relay path would have done, deferred to catch-up
- store resume gains the same validator the sync transfer uses, since
  a store node could also serve invented history
- new --store-sync-require-proof flag (default off): the rollout lever;
  once the fleet persists and serves proofs, flipping it makes nodes
  reject proofless synced history when RLN is enabled
- reconciliation untouched: proofs are not part of the message hash,
  so identity, fingerprints and cursors are unchanged

Tested end-to-end: a proof survives full-node -> full-node sync
transfer and the store-query -> resume -> archive trip intact.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-24 01:42:26 +05:30

31 lines
1.3 KiB
Nim

import
content_script_version_1, content_script_version_2, content_script_version_3,
content_script_version_4, content_script_version_5, content_script_version_6,
content_script_version_7, content_script_version_8
type MigrationScript* = object
version*: int
scriptContent*: string
proc init*(T: type MigrationScript, targetVersion: int, scriptContent: string): T =
return MigrationScript(targetVersion: targetVersion, scriptContent: scriptContent)
const PgMigrationScripts* = @[
MigrationScript(version: 1, scriptContent: ContentScriptVersion_1),
MigrationScript(version: 2, scriptContent: ContentScriptVersion_2),
MigrationScript(version: 3, scriptContent: ContentScriptVersion_3),
MigrationScript(version: 4, scriptContent: ContentScriptVersion_4),
MigrationScript(version: 5, scriptContent: ContentScriptVersion_5),
MigrationScript(version: 6, scriptContent: ContentScriptVersion_6),
MigrationScript(version: 7, scriptContent: ContentScriptVersion_7),
MigrationScript(version: 8, scriptContent: ContentScriptVersion_8),
]
proc getMigrationScripts*(currentVersion: int64, targetVersion: int64): seq[string] =
var ret = newSeq[string]()
var v = currentVersion
while v < targetVersion:
ret.add(PgMigrationScripts[v].scriptContent)
v.inc()
return ret