資料系統¶
本檔角色:ledger 事件結構、IPFS 內容尋址、canonical 序列化、治理事件、跨模組資料流。 對應模組
ledger/;實作細節(事件結構 / DerivedState 巢狀 / 帳本檢查點演算法 / partition / API)見 程式架構/ledger.md。
1. 三層資料儲存¶
| 層 | 用途 | 變動性 |
|---|---|---|
| IPFS(CID) | canonical UnixFS GLB DAG + GLB Root Extras(CIDv1 raw/dag-pb + SHA-256) | 不可改(root = 完整內容身分) |
| OrbitDB(CRDT log) | 事件鏈(UGC 上傳 / fork / match-result / 檢舉仲裁 / 治理——無獨立鑄幣 / 信譽事件,§3) | append-only,不可改寫 |
| 玩家本地(IndexedDB) | Loadout / 設定 / 快取 | 完全可改 |
1.1 鏈身分與信任根¶
「本專案的鏈」由 client build 內建錨定義,不依賴任何域名 / 端點:
- 〔LEDGER-R-001〕 位址錨:官方 ledger 的 OrbitDB 位址(
LEDGER_DB_ADDRESS,build 注入,protocol.md §5)= DB manifest 的 content-addressed CID——純內容派生、不含域名、不得從 origin 派生(部署資訊.md §8.3 CI 不變式)。位址不同即不同鏈:偽鏈無法佔用同一位址(需撞 SHA-256),client 也不會連上它。 - 〔LEDGER-R-091〕 單一 chain identity:
chainId固定等於 canonical/orbitdb/<CIDv1-base58btc>位址中的完整 CID segment,不截短、不再 hash,也不新增第二份 config。所有 ledger 事件與 checkpoint 簽章都使用ledgerSigningDigest(ledgerAddress, event),其 domain 為open4wd-ledger-signature-v1並涵蓋chainId;同一事件的簽章不得跨鏈重放。 - 〔LEDGER-R-092〕 本機 mutable state 分鏈:checkpoint IndexedDB 名稱與 control
key、Admission outbox record/key 都必須帶完整
chainId。動態 genesis 只能先以空暫存 open 取得 OrbitDB address,且須在第一筆 application write 前關閉暫存並以 chainId 重開。CID-keyed content blockstore 仍依內容尋址共用,不因鏈隔離複製;identity/profile store 屬使用者身分,也不按鏈複製。 - 治理錨:genesis config 內建初始
governanceSigners(流程/治理事件.md §4);signer set 演化須經前一代 quorum 簽核 → 從 genesis 可逐代驗證到最新帳本檢查點多簽(程式架構/ledger-checkpoint.md §3)。 - 驗證鏈:位址錨 → genesis signer set → 檢查點簽章鏈 → canonical log frontier (
log_head_cids) → 事件簽章 + 完整 DAG DerivedState 全網重算;網路層攻擊面(eclipse / 假分叉)與緩解見 資安規範.md §12.3。 - 信任根收斂於「你執行的官方 build」:開源 repo+PR/CI 閘(流程/升版.md §8.2)+SRI 防產物竄改(資安規範.md §5)。換 ledger 位址 = 換鏈,僅發生於鏈重生(§19)、隨 client major 出貨。
2. CID 命名空間¶
<cidv1> # GLB 內容(含 Root Extras)或其他 IPFS 內容
<ledger-event-cid> # canonical Ledger event 內容識別
config epoch = <uint> # ConfigUpdateEvent 內的治理版本欄位
〔LEDGER-R-002〕 資產引用另分三類前綴(builtin:<type>-<id> 公版 / local:<uuid> 本機測試資產(永不可用於上鏈賽)/ 一般 IPFS CID)。
〔LEDGER-R-094〕 內容 codec 必須與 bytes 語意一致:UGC GLB 依 canonical UnixFS profile
定址;≤ 1 MiB 可為 CIDv1(raw, sha2-256) root,較大檔案為 CIDv1(dag-pb, sha2-256) root,
其 raw leaves 固定 1 MiB chunk、balanced layout、無 name/mode/mtime,logical 上限 80 MiB、
完整 block 數上限 81。不得把 GLB 或 UnixFS node 宣告為 dag-cbor。
checkpoint、DerivedState、cold partition、signer set 等經 canonical DAG-CBOR 編碼的 Ledger
內容才使用 CIDv1(dag-cbor, sha2-256)。取塊完整性驗證保留請求 CID 自帶的 codec,對 bytes
重算 digest;不得把所有內容硬套單一 codec。專案尚未產生正式 UGC,不保留舊單-block profile
CID 的 alias、雙讀或 migration。
3. 事件清單(LedgerEvent union)¶
事件結構(BaseEvent 欄位 / 簽章 / union)見 程式架構/ledger-admission.md §1:
| 事件類別 | 範例 |
|---|---|
| UGC | UgcUploadEvent(immutable admission metadata+revision 0 presentation+similarityMatches)/ UgcMetadataUpdateEvent(exact CID 的 full replacement presentation)/ UgcForkEvent / UgcMaintenanceEvent(retire / renew / unretire)/ AssetVersionUpgradeEvent;上傳即接受 Fork,無逐作品開關 |
| 比賽 | MatchResultEvent(一場比賽一筆、內嵌 N 回合 rounds[]、總名次、grid/loadout proofs 與 roundAnchors[];經濟 / 信譽 / UGC 使用統計由 canonical fold derive、非事件自報)/RaceLeaveEvent(本人單簽離場成本)/RaceAbortEvidenceEvent(零處罰中止存證) |
| 經濟 | SlotPurchaseEvent / UgcSponsorBurnEvent(上鏈費只燒在 UgcUploadEvent;原創/fork 都寫 upload 並單次收費,UgcForkEvent 是免費血緣宣告;無獨立鑄幣事件——首次上鏈走負資產,見 經濟系統.md §10) |
| 信譽 | ReportEvent / ReportRevokeEvent / ArbitrationVoteEvent / ArbitrationResultEvent(檢舉走純仲裁,見 程式架構/moderation.md);信譽分數本身純 derive、無獨立事件(自 MatchResultEvent / 仲裁 / ugcUsageStats 推導,見 程式架構/reputation.md) |
| 評分 | UgcRateEvent / UgcRateRevokeEvent(整數量化,見 程式架構/ugc-rating.md) |
| 治理 | ConfigUpdateEvent(economy-config 多簽更新) |
| 黑名單 | BlacklistEvent(CID、仲裁通過);玩家全域黑名單=純 derive(同一責任人仲裁定罪 ≥ 3 三振、無獨立事件,見 程式架構/moderation.md §5.5);provider-scoped DMCA 下架不進帳本或全域 client state(見 程式架構/dmca.md) |
| 回合共識錨 | RaceConsensusAnchorEvent(每回合終局唯一嚴格多數證書,§6) |
| 賽內異常 | DesyncEvent(desync 中止記錄;被踢者自簽自報、不影響信譽、純供調查,程式架構/ledger.md §9) |
| 帳本檢查點 | LedgerCheckpointEvent(治理多簽、全網狀態整併) |
本表是 21 型別目錄;其中 AssetVersionUpgradeEvent 目前只是未啟用保留案。實際 persistence admission allowlist 為 20 型別准入,必須拒絕 asset-version-upgrade,直到 程式架構/ledger-admission.md §1〔LEDGER-R-032〕所列啟用條件完整落地。
所有事件帶:
type: EventTypepeerId: PeerId(簽署者)timestamp: numbersignature: Ed25519Signaturecause / payload(依事件類型)
〔LEDGER-R-003〕 多簽事件例外:
MatchResultEvent/RaceConsensusAnchorEvent/ConfigUpdateEvent/LedgerCheckpointEvent/DesyncEvent以signatures[]取代單一signature(match-result 與 anchor 的收件驗證規則見 程式架構/ledger-admission.md §1)。
4. DerivedState¶
純函數從事件鏈推導,可任何 peer 重算驗證:
| 子型別 | 來源 |
|---|---|
EconomyDerivedState |
鑄幣 / 燒幣 / 月軟曲線 / comboHash / recentPrizedMatches(per-player 有獎場數窗)/ firstUploadDebtUsed(首次上鏈負資產旗標)/ monthlyFlowsByMonth(rolling 12 UTC 月)/ lifetimeRoyaltyMintedByPeer(永久 royalty 累計)/ processedPaymentIntents(chain-bound UGC 付費意圖永久去重) |
ReputationDerivedState |
信譽 delta 累積(自來源事件 derive、無獨立信譽事件)+ clamp [0, 1000] |
ModerationDerivedState |
CID 黑名單(BlacklistEvent)/ 玩家全域黑名單(純 derive 三振)/ 檢舉狀態 / 檢舉準確率 |
RatingDerivedState |
UGC 評分累積(整數量化 Bayesian)/ creator 高評分里程碑(awardedCids) |
MatchDerivedState |
recentMatches(hot)/ TrueSkill μσ(X1000 整數定點,算式表.md §20)/ 車位數 |
UgcDerivedState |
ugcRecords(含 presentation/revision/updatedAt)/ 使用統計(ugcUsageStats)/ forkLineage / 退役狀態;版本後繼血緣節點層 aggregate(評分 / 使用次數跨 AssetVersionUpgradeEvent 串接的 CID 累積,見 版本規範.md §23) |
ForkTreeDerivedState |
概念視圖、非獨立頂層欄——impl 巢於 ugc.forkLineage + record ancestors(程式架構/ledger-checkpoint.md §2):由 parent 邊重建完整血緣(任意深度逐跳上溯);per-record ancestors 僅存 royalty 相關的 parent + grandparent |
AssetVersionDerivedState |
per-type 動態最低支援版、各 CID 的版本狀態、successorEdges 與 lineageNodeByCid(exact CID → 穩定血緣節點;presentation 更新不沿 successor 傳播);yanked = client 清單讀取層 overlay、不入 DerivedState——impl 頂層欄 assetVersion(程式架構/ledger-checkpoint.md §2) |
UgcDerivedState.presentationUpdatedAt 從 revision 0 起就是該 revision 套用時的 canonical
state.derivedAt,不是事件自報 timestamp。live 尚未 fold 時以
max(mirrorHead.derivedAt, event.timestamp) 投影同一 effective time;checkpoint 與 replay 皆以
此值執行一小時冷卻。
〔LEDGER-R-004〕 B 軸版本閘門使用房間 pin 的已驗
LedgerCheckpointEvent:host 開房時 pin 已同步的最新帳本檢查點 CID,所有 peer 驗證其 signer chain、derived_state_cid與完整 checkpoint state,並以其中AssetVersionDerivedState判定同一份版本快照。不得讓房間或事件自行指定任意 log frontier;freshness 與開賽前重驗見 版本規範.md §20。
4.1 血緣節點收斂(ForkTreeDerivedState × AssetVersionDerivedState)¶
UgcDerivedState(評分 / 使用次數)與 ForkTreeDerivedState(分潤 / fork 樹位置)的聚合單位是血緣節點,非單一 CID。推導規則:
- 血緣節點 = 由
AssetVersionUpgradeEvent後繼邊串起的一條版本鏈(同一創作者升級自己的 schema)收斂成一個節點;節點的創作者 = 鏈上原始創作者(後繼必為同人)。 - 〔LEDGER-R-005〕 fork record 的
parent/ancestors釘具體 CID;解析 royalty 收受者與 fork 樹位置時,先把該 CID 經AssetVersionDerivedState的後繼邊映射到所屬血緣節點,再取節點創作者。 - 版本後繼不改節點、不動 fork 樹拓樸:原 CID 與其升級後 CID 屬同一節點,故升版前產生的舊 fork(ancestors 仍指舊 CID)照樣解析到同一人、同一位置(版權.md §3.5、版本規範.md §23)。
- 舊 CID 即使轉 unusable / yanked 仍 immutable 留鏈 → 逐跳上溯(§4
ForkTreeDerivedState)與血緣映射永不踩死指標。
5. Canonical 序列化¶
〔LEDGER-R-006〕 跨 peer 共識必須完全一致:
- 格式:IPLD dag-cbor(原生支援 bigint)
- 欄位順序:dag-cbor canonical 排序(格式內建——map key 長度優先 +bytewise;非自訂順序、禁依語言 hashmap 插入序)
- 數字精度:bigint(金額)、整數 X100 / 查表(評分・信譽權重)、f32(物理)
- 簽章:
sign(privateKey, ledgerSigningDigest(ledgerAddress, event));digest 以 ledger-only domain、完整chainId與serializeForSigning(event)的 canonical bytes 組成
實作見 程式架構/ledger-admission.md §1(ledgerSigningDigest 與
serializeForSigning dag-cbor 的唯一權威)。
6. 回合共識錨(唯一多簽證書)¶
- 〔LEDGER-R-007〕 每 120 frame 的 ephemeral checksum 投票只做 desync 偵測,不寫 ledger。正式錨只在每回合終局建立一張
RaceConsensusAnchorEvent。 - proposer 依原始 roster 的 PeerId code-unit 穩定順序選出;逾時以同序 deterministic fallback。候選 frame 必為 120 的倍數,且落在
latestFinal = floor(max(0, terminalFrame - ROLLBACK_FRAME_BUFFER_DEFAULT) / 120) × 120或其前一個 120-frame 邊界;更舊候選一律拒簽。 - 〔LEDGER-R-008〕 每個 peer 對同一
(matchId, roundIndex)最多簽一份 anchor,不論 frame 或 checksum。signer 只在本機仍保留候選 frame、該幀已 final、checksum 相符且尚未簽過該回合時背書。 presentPeers是原始 roster 扣除 anchor timestamp 前已確認離場者,依 PeerId code-unit 嚴格排序去重;證書要求floor(presentPeers.length / 2) + 1個不同且 eligible 的有效簽章。未達門檻不得以 proposer 單簽 fallback 冒充共識。- 〔LEDGER-R-009〕
MatchResultEvent.rounds[].terminalFrame是 tail 驗證基準;roundAnchors長度必須等於回合數並逐回合 inline 唯一完整證書,缺證書填null。每張證書須通過 shape、match/round、grid binding、tail、roster/離場時序及 quorum 驗證;任一 null 時 canonical settlement 的mintEligible = false。
RaceConsensusAnchorEvent schema:matchId、gridContextDigest、gridSeed、roundIndex、frame、checksum、canonical presentPeers、timestamp、peerId、空 BaseEvent.signature 與嚴格多數 signatures[]。完整 grid proof 只在外層 MatchResult 保存一次,anchor 的 digest/seed 必須相符。首次廣播仍套 timestamp ±30 秒;timeless fold 另以自包含內容完整驗證。
回合共識錨 ≠ rollback snapshot ≠ 帳本檢查點:rollback snapshot 是記憶體內重播狀態;回合錨只證明終局尾窗 checksum,不含 state bytes、previous CID 或 branch ancestry,不能 restore/replay;帳本檢查點則是治理 signer set 對全網 derived state 的整併工件,見 程式架構/ledger-checkpoint.md §3。
7. 回合錨衝突(fail-closed;不選鏈)¶
〔LEDGER-R-010〕 同一回合若只出現一張達 quorum 的證書即採該證書;bounded 收集窗結束仍無證書則該回合錨缺失,允許非鑄幣 MatchResult,但不得鑄幣。
〔LEDGER-R-011〕 同一 (matchId, roundIndex) 出現兩張不同的完整有效證書時,保存兩張原始證書與重疊簽署者於 RaceAbortEvidenceEvent.anchorConflicts,整場標記 consensus-invalid,不得選最長鏈、first-seen 或 checksum 字典序,也不得把事件偽裝成個別玩家斷線/棄賽或直接套全域信譽處罰。OrbitDB event multi-head 與帳本 checkpoint equivocation 仍依各自規則處理(程式架構/ledger-checkpoint.md §3–§4)。
interface RaceAnchorConflictEvidence {
roundIndex: number;
first: RaceConsensusAnchorEvent;
second: RaceConsensusAnchorEvent;
equivocators: PeerId[];
}
first/second 都保存完整有效證書;equivocators 是兩張證書簽署者集合的交集。
8. 客戶端 Log 裁剪(OrbitDB 本機 event cache)¶
實作見 程式架構/ledger.md §10(@orbitdb/core 與有界本機 event cache):
- LRU size 限制本地保留事件數
- evict 後的行為:先向送出該 head 的 authenticated peer 走有界 entry-fetch;一般內容塊才可由 Bitswap/pinning provider 按 CID 補回
- Cold partition 不主動下載(依需求拉)
- 與帳本檢查點關係:帳本檢查點之前的事件可裁剪
9. Partition 切分(deterministic)¶
切分函式實作見 程式架構/ledger-checkpoint.md §2:
- 事件依
partitionKey分群 - 每群獨立 pinning / sync
- 跨 partition 引用走 CID(避免循環依賴)
9.1 Hot / Cold partition 切分時機¶
| 階段 | 職責 |
|---|---|
| 〔LEDGER-R-012〕 Apply 階段(套用 match-result 事件時) | 一律放進 hot.match.recentMatches,不在此階段判斷 hot/cold |
| 帳本檢查點 proposer 階段 | 決定哪些 hot match 該移到 cold(依時間 / 數量 / quarter 分桶) |
為什麼分階段:apply 階段必須是純函數可重算(不依賴「現在時刻」判斷),hot/cold 切分依賴時間視窗,放在帳本檢查點才不影響 DerivedState 純函數性質。
10. Cold Partition Pinning¶
歷史比賽記錄成為 cold partition:
- 由志願 pinning 節點 best-effort 保存;健康服務少於
LEDGER_PROVIDER_FAULT_DOMAINS_RECOMMENDED: 3個獨立 provider 故障域時只提示,不構成留存或恢復保證 - 普通 client 不主動下載 cold
- 需要查歷史時才從 pinning 拉
10.1 Cold partition lazy load 行為¶
| 場景 | 行為 |
|---|---|
| 新玩家初次載帳本檢查點 | 只下載 hot + coldMatchPartitions 的 CID map(很小),不預先下載任何 cold partition 內容 |
| 玩家查到 cold 內容(例:首頁續載較早比賽) | 自然觸發 lazy fetch(從 pinning 節點按 CID 拉) |
| UX 提示 | UI 顯示 loading 狀態;網路失敗時保留既有列與續載位置,提示稍後原位重試 |
getRecentMatchesForPlayer(peerId, { limit, cursor }) 回傳 { records, status,
nextCursor, failedPartitions }。查詢先讀 hot,再依 quarter 倒序 lazy fetch cold partitions;排序固定為
finishedAt DESC, matchId ASC 並以 matchId 去重。cursor 為綁定 PeerId 的不透明值,呼叫端只可保存並
原樣回傳。預設單頁 20、上限 50、單次最多掃描 4 個 cold partitions,三者皆由集中命名參數控制;
達頁面或掃描上限回 partial + nextCursor,不得靜默截斷。cold 區塊缺失時停在該 partition,已有資料
回 partial、完全無資料回 failure,並回報 failedPartitions;retry 必須從同一位置續讀而不重複列。
詳見 部署資訊.md §Pinning。
11. 簽章流程¶
簽章 / 序列化實作見 程式架構/ledger-admission.md §1:
1. event 物件構建(剔除 signature/signatures)
2. ledgerSigningDigest(ledgerAddress, event) → digest
3. sign(privateKey, digest) → signature
4. event.signature/event.signatures = signature
5. 廣播
6. 接收 peer 以 build 錨定的 ledgerAddress 重算同一 digest
7. verify(publicKey, digest, signature)
〔LEDGER-R-013〕 所有 P2P 訊息帶 timestamp + nonce:
P2P_MESSAGE_TIMESTAMP_TOLERANCE_SEC: 30(容差 30 秒)P2P_MESSAGE_NONCE_BYTES: 16(防 replay)
nonce屬 P2P 即時訊息層(SignedPayload);ledger 事件本身仍無nonce欄。永久事件由 Orbit entry 頂層admission: { version: 1, workNonce: Uint8Array(8) }提供 entry-bound PoW:proof 綁 canonical BaseEntry(含事件、parents、clock、identity、Orbit signature),完全相同 final entry 由 CID 去重,改任一欄都必須重新付出 18–22 bits 工作量。這仍不取代業務冪等:攻擊者可以把同一已簽 payload 包進不同 entry 並各自支付 PoW,所以累積型 reducer 仍須以matchId、內容 CID、事件 id 或 chain-scoped signed-intent digest 去重(見 程式架構/ledger-admission.md §1.1 與 程式架構/ledger.md §6.1);Set add/Map set 覆蓋才是天然冪等。
12. 治理事件(ConfigUpdateEvent)¶
economy-config 變更走 multisig(單一事件族:config 值變更 / governanceSigners signer set 變更 / 緊急回滾 = 設回舊值,皆同型別——無 SignerSetUpdateEvent / EmergencyRollbackEvent 獨立型別,流程/治理事件.md §4.2・§7):
interface ConfigUpdateEvent extends BaseEvent {
type: "config-update";
epoch: EconomyConfigEpoch;
prevEpoch: EconomyConfigEpoch;
newConfig: EconomyConfig; // 含 governanceSigners(signer set 本體,程式參數/economy-config.md §17.1)
rationale: string; // 公開說明(透明度要件;回滾時 = 事故說明 + 回滾自哪個 epoch)
signers: PeerId[]; // multisig 成員
signatures: Signature[]; // 每 signer 一筆;quorum 以 prevEpoch 的 signer set 計
}
詳見 economy-config.md §17;事件結構見 程式架構/ledger.md §8。
13. UGC 退役¶
退役狀態一律純 derive(可重算、跨 peer 一致),吃兩種輸入:
- 自動(資源管理):久未使用 / 低評分且久未用 / 創作者離開 任一達門檻 → 進退役候選;過續租窗未續租 → 自動退役。
- 〔LEDGER-R-014〕 手動(創作者意志 / 非違規下架):創作者本人付費寫一筆
UgcMaintenanceEvent(reason: 'retire')→ 立即退役(處理「想下架還有人在用的內容」,自動退役不會在全域仍被使用時觸發)。payer限血緣節點創作者、收件驗證不符無效(否則付一筆 burn 即可下架他人熱門 UGC;程式架構/ledger.md §7);renew/unretire任何人可付(利他續命)。
〔LEDGER-R-015〕 退役效果:既有 royalty 不回收(既得權益)、後續使用不算 royalty、仍可觀看但 loadout 阻擋、pinning 自動 unpin、保留歷史僅擋未來。續租 / 重啟也走 UgcMaintenanceEvent(renew 取消候選 / unretire 重啟)。仲裁「違規」走黑名單(BlacklistEvent),不佔退役。 deriveRetireStatus 與事件結構見 程式架構/ledger.md §7。
退役只擋直接使用,不碰 fork 分潤 —— 退役的祖先仍照血緣分潤(版權.md §3.4)。
14. 跨模組資料流¶
玩家上傳 GLB
↓
IPFS 寫入 → CID
↓
UgcUploadEvent 入 ledger
↓
Match(N 回合)→ MatchResultEvent(只含已多簽比賽事實;經濟與信譽由 canonical fold 推導)
↓
DerivedState 自動更新(EconomyDerivedState / ReputationDerivedState / UgcDerivedState)
↓
本地 client 即時反映
15. API(LedgerApi)¶
LedgerApi 介面(完整方法簽章)見 程式架構/ledger.md §11。
15.1 deriveStateAt 純函數保證¶
〔LEDGER-R-016〕 deriveStateAt 供 checkpoint review、復原稽核與診斷使用;B 軸房間閘直接讀已驗 pinned checkpoint,match settlement 也不讓事件或提案者指定 frontier。此 API 必須是純函數:
- 不修改本機 state cache(推導完即丟棄結果,不污染主流程)
- 同一 canonical
baseLogHeadCids集合多次呼叫結果一致;不得只取其中一個 head - 內部可走獨立的 derive worker,不影響主流程 sync
- 跨 peer 任何時刻呼叫結果應一致(共識安全)
16. Derive Utilities¶
跨子模組共用的純函數 derive 工具(consensusNow deterministic「現在」、lastEventTimestampOf 等)見 程式架構/ledger.md §6。
17. Determinism 保證¶
| 保證 | 機制 |
|---|---|
| 跨 peer canonical | IPLD dag-cbor + 固定欄位順序 |
| 跨 platform 浮點 | f32 全物理 + 整數量化(INTEGER_SCALE)+ wasm 統一 build |
| 跨 frontier 純函數 | deriveStateAt(logHeadCids) 純函數;輸入是已驗證的 log heads,不讀 wall-clock |
| 跨 peer「現在」 | derive 用 consensusNow(最大事件 timestamp),禁用 Date.now()(各 peer 時間不同 → 驗簽炸裂) |
| 〔LEDGER-R-017〕 超越函數禁入共識 | 浮點 log10 等跨硬體 libm 不一致——一律整數預算表(隱式評分查表 算式表.md §19、仲裁 weightX100 算式表.md §17) |
| 事件 timestamp 誠實性 | 首次廣播收件驗證 ±P2P_MESSAGE_TIMESTAMP_TOLERANCE_SEC(30s);registeredAt = 首筆事件套用時 consensusNow(倒填無效,程式架構/ledger-admission.md §1/程式架構/ledger.md §6) |
| 結算金額全網一致 | MatchResultEvent 無 payout/frontier;live 與 timeless fold 共用自包含 facts 驗證,fold 由事件位置前態執行唯一公式並套 incoming-inclusive hard cap(程式架構/ledger-admission.md §1、流程/比賽結算.md §8.6) |
| 跨語言 | bigint 全鑄幣公式 |
| 〔LEDGER-R-018〕 derive 規則變更 | 隨 derive_logic major 出貨(同 major 全網同規則,版本規範.md §5);生效切點=鏈上事件錨、規則 epoch 化(經濟系統.md §2.1)——禁 wall-clock 切換 |
deriveRuleEpoch 是 checkpoint v1 DerivedState 的必要欄位。每個新 era 以編譯進
client 的 afterEntryCid 啟用:錨點 entry 仍套舊 era,該筆 accepted fold 完成後才
切換,所以下一筆 accepted entry 才套新 era。live ingest、完整 refold、
deriveStateAt 與 checkpoint review 必須走同一 rulebook;post-anchor 卻仍宣稱舊
epoch 的 checkpoint 會因重算 state CID 不符而拒絕。
18. 不變式(CI 強制)¶
〔LEDGER-R-019〕 totalMinted 必須等於產出型與補助型鑄幣總和。
〔LEDGER-R-020〕 monthMinted 只累計當月產出型鑄幣,並依月份邊界重置。
〔LEDGER-R-021〕 每個 peer 的餘額不得低於零,唯一例外是首次上鏈負資產不得低於該次上鏈費。
〔ECON-R-021〕 〔MOD-R-001〕
totalMinted = Σ(產出型) + Σ(補助型)
monthMinted = 月內產出型總額
revShare.currentTierPct + parentTierPct + grandparentTierPct = 100
reputation = clamp(500 + Σ events, 0, 1000)
∀ peer: balance ≥ 0(唯一例外:首次上鏈負資產 ≥ −該次上鏈費,經濟系統 §10;燒幣 apply 守門見 程式架構/economy.md §2)
詳見 共通規則.md §19。
19. 鏈災難復原(鏈重生・最後手段)¶
適用於事件史本身壞損到無法以修法重算收拾的情境;先窮盡解讀層復原階梯——參數回滾 / 修法 + 全網重算(經濟系統.md §2.1)——本節是最後手段。
以最後一個良好的帳本檢查點為新鏈起點(檢查點 = content-addressed+ 治理 signer set floor(2N/3)+1 多簽背書 +pinning 長存,程式架構/ledger-checkpoint.md §3):
- 治理 signer quorum 議決切點檢查點、可接受的最小來源 timestamp 與新鏈治理 signer set,並對外公告(決策在治理層完成、不寫舊鏈事件——舊鏈已不可信)。
- 由 pinning ceremony 工具產生自包含
initialCheckpointProofbundle。Descriptor 是 closed version-1 shape:sourceLedgerAddress/其衍生sourceChainId、sourceGenesisSigners、targetGovernanceSigners、從來源首個 checkpoint 到切點的checkpointChainCids、checkpointCid、三方必須相等的initialStateCid/derivedStateCid/切點derived_state_cid、切點signerSetCid、sourceCheckpointTimestamp、sourceMinimumCheckpointTimestamp、sourceConfigEpoch,以及其餘欄位的 domain-separated canonical DAG-CBOR SHA-256commitment。Bundle 只可再帶完整驗證實際引用的 checkpoint/state/signer-set/log-head/cold-partition blocks,不得缺塊或夾帶未引用塊。 - 〔LEDGER-R-098〕 建新 OrbitDB log(新位址);ordinary genesis 與 rebirth genesis 互斥,rebirth 缺任一 proof 欄位或 block 即 fail closed,不得 fallback 到空 genesis。驗證由
sourceGenesisSigners起逐代檢查 checkpoint previous link、timestamp 單調、canonical signer set、來源 ledger domain 簽章與 quorum,再由前一代 state 的governanceSigners推進 authority;每代 derived state/cold partition 必須 CID 相符且 canonical,state lineage 必須接前一 checkpoint,切點不得早於 ceremony minimum,epoch/目標 signer/三方 state CID 必須精確相符。來源 ledger 必須不同於新位址;裸initialStateCid、新鏈自報 signer set、跨 ledger 重放與曾合法舊 checkpoint 回退全部拒絕。 - client major 升版同時出貨新
LEDGER_DB_ADDRESS、initialCheckpointProof與相同的targetGovernanceSigners(§1.1);整包先驗通過才以切點 canonical DerivedState 作新鏈 genesis,後續事件依syncFromCheckpoint同型流程推進。舊鏈由 pinning 封存供查證、不再收件。
| 內容 | |
|---|---|
| 保留 | 餘額 / 信譽 / UGC 註冊 / fork 血緣 / cold partition CID map——derived state 即全部帳目;IPFS 內容(GLB)content-addressed 不受影響 |
| 消失 | 切點之後的事件(含進行中仲裁案 / similarity-pending / 未入帳結算)——公告後重跑;此即「從未壞損點分支」的代價 |
20. 對應檔案 / 模組¶
| 對象 | 內容 |
|---|---|
| 程式架構/ledger.md | ledger 實作細節(本檔 資料系統.md 為設計權威) |
| 程式架構/economy.md | 經濟事件處理 / 結算實作 |
| 程式架構/ugc-rating.md | UGC 評分實作(整數量化 / Bayesian / 隱式 fallback / 里程碑) |
| 程式架構/reputation.md | 玩家信譽實作(事件 / 觸發 / 新手保護 / 連動權重) |
| 程式架構/moderation.md | 檢舉 / 純仲裁 / 黑名單實作 |
| 版本規範.md | derive_logic_version 升版時機(§2) |