bug(native): delayed sync-complete can contaminate a re-added named root's lineage
メンテナーはふだん 1 日以内に返信
評価
- 難易度
- 4/5
- 見積もり時間
- 3〜5日
- 初心者へのやさしさ
- 48/100
- issue の種類
- バグ
- 明瞭さ
- 明確に書かれている
- 活発さ
- 活発
- 技術スタック
- go, sqlite
調査の方向性
Start with internal/p2p/routes.go, internal/p2p/syncengine/engine.go, and internal/store/game_roots.go to trace how a named-root report reaches the final SQLite write. Review the linked regression test and reproduction guide, then run the Go race regression suites. Done means stale reports cannot alter a replacement root’s lineage, valid reports still work, and the stated compatibility and build checks pass.
索引モデルが issue の本文から書いたものです。
説明
Summary
A delayed sync-complete event from an authenticated peer can refer to an old mapping of a named root, arrive after that root is removed and re-added under the same name, and populate the replacement mapping's game_root_sync_state with old pulledFiles. Signing/attributing a report to a peer does not prove it refers to the current root incarnation.
Observed defect: persisted stale lineage metadata. This reproduction does not establish a destructive file write or deletion.
Affected source: Liquid-co/OpenSave:dev-public@a0f6032b8ba36da25e3e0e5e90c5ace9ba0c1fc7, with disposable native handler and SQLite fixtures on Linux amd64.
Independent reproduction
Public Go regression · Reproduction guide
git checkout repro/native-root-lineage-import-20261030
go test -count=1 -race -v ./internal/p2p -run '^TestRegressionDelayedReportCannotAttachToReaddedRoot$'
- Create a disposable native P2P fixture with an additional mapped
configroot. - Remove
config, then re-addconfigat a different temporary path. The replacement root's lineage should be empty. - Deliver a
sync-completeevent attributed to the fixture peer, namingroot: configandpulledFiles: ["old-save.bin"]from the old incarnation. - Read
game_root_sync_statefor the newconfig.
Stock result: old-save.bin is incorrectly recorded in the new root's lineage. Required result: the report does not mutate the replacement mapping's lineage.
The test uses the native P2P test handler; it is not a test of a complete deployed LAN/relay connection.
Source-level cause
internal/p2p/routes.go accepts a sync-complete event and forwards its root name and file list. internal/p2p/syncengine/engine.go can merge these paths against the current named root based on name alone. internal/store/game_roots.go stores mapping timestamps, but the incoming old event is not bound to the incarnation that produced it.
This is distinct from active-writer-versus-removal: a lock around the removal cannot identify a stale message arriving later.
Bounded suggested fix
Bind a named-root state-bearing report to a receiver-issued mapping generation (for example the receiver's mapped timestamp echoed by the pulling peer) and check that generation in the final authoritative SQLite write. On a missing/old token, do not accept the report as confirmed lineage; fall back to safe fresh manifest reconciliation where appropriate. Preserve current primary-root behaviour and protocol compatibility.
Avoid a global version-vector protocol, new distributed coordinator or general maintenance state.
Acceptance criteria
- Stock test fails for stale
old-save.bincontamination and patched test passes. - Old same-name reports cannot affect a replacement root after remove/re-add, including rapid re-add and remap.
- Valid new-root reports are recorded; LAN/relay callbacks and deletion lineage still behave correctly.
- Older peers lacking a generation token fail safely or reconcile with documented compatibility limits.
- Go/race regression suites and supported builds pass.
Evidence limit: No claim of user-save loss or that a full two-daemon delayed delivery has been executed by this public test.
Independent public reproducer and original report: https://github.com/Seagulls/OpenSave/issues/14.
- 主要言語
- Go
- スター
- 225
- フォーク
- 9
- 平均マージ
- 1日 22時間
- マージ済み PR(30日)
- 75
環境構築
- Dockerfile または Docker Compose ファイルあり
- プルリクエストのテンプレートなし
- コントリビューションガイドなし
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
Liquid-co/OpenSave のほかの issue
-
難易度 2/5 1〜3時間 初心者へのやさしさ 78/100
Liquid-co/OpenSave#149 · コメント 1 件 ·
メンテナーはふだん 1 日以内に返信
-
難易度 5/5 1週間以上 初心者へのやさしさ 20/100
メンテナーはふだん 1 日以内に返信
-
難易度 4/5 3〜5日 初心者へのやさしさ 48/100
メンテナーはふだん 1 日以内に返信
-
難易度 4/5 3〜5日 初心者へのやさしさ 48/100
メンテナーはふだん 1 日以内に返信
-
Feature request: Allow atomic placement of offered games with AutoSync disabled対応中かも このイシューにリンクされたプルリクエストがオープン中、またはマージ済みです。 オープン
難易度 4/5 3〜5日 初心者へのやさしさ 22/100
Liquid-co/OpenSave#40 · コメント 1 件 ·
メンテナーはふだん 1 日以内に返信
Liquid-co/OpenSave の issue をすべて見る
似ている issue
-
Case detail: main-column section headers are hard to distinguish from body text対応中かも @yubessy が今日担当しました。 オープン
難易度 2/5 1〜3時間 初心者へのやさしさ 68/100
ubie-oss/hecatoncheires#347 ·
メンテナーはふだん 1 日以内に返信
-
[OperatorHub] Add OLM installation method to the documentation #1193対応中かも @NiccoloFei が今日担当しました。 オープン
難易度 2/5 1〜3時間 初心者へのやさしさ 70/100
cloudnative-pg/plugin-barman-cloud#1233 ·
メンテナーはふだん 1 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 68/100
メンテナーはふだん 1 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 67/100
メンテナーはふだん 2 日以内に返信
-
build: make check-linter version tests deterministic対応中かも このイシューにリンクされたプルリクエストがオープン中、またはマージ済みです。 オープン
難易度 2/5 1〜3時間 初心者へのやさしさ 75/100
メンテナーはふだん 1 日以内に返信