Skip to content

「在 0G Storage 上查看」修掉 404:改指 submission 頁並等查到序號才解鎖 - #13

Merged
k66inthesky merged 2 commits into
mainfrom
claude/0g-tech-competition-deploy-lv08or
Sep 10, 2026
Merged

k66inthesky merged 2 commits into
mainfrom
claude/0g-tech-competition-deploy-lv08or

Conversation

@k66inthesky

Copy link
Copy Markdown
Contributor

問題

按「在 0G Storage 上查看」跳到這個網址,404:

https://storagescan-galileo.0g.ai/file/0x2aba519d5e95ec4ee85fc6d549e29e4e5f7367fe6abf70b67432e81b9718da4b

storagescan 沒有 /file/<root> 這條路徑,那是我當初憑印象組的。它的檔案頁是用提交序號定位的 —— /submission/<txSeq>(例如 /submission/2492640)。

改法

  • 序號跟 indexer 查:/file/info/<root> 的回應裡有 tx.seq。不同版本也出現過 txSeq / seq,所以 seqOf() 都認一下,一個都拿不到就回 null。
  • 前端不再上傳完就把連結點亮。segment 傳完不等於索引好 —— 節點要先把 log entry 同步進來 indexer 才答得出序號,實測中間有幾秒到十幾秒。改成輪詢(最多 6 次、每次隔 3 秒),查到序號才解鎖按鈕。
  • 輪完仍然沒有就維持不可按,並說明檔案已上傳、只是還沒被索引到 —— 不要給玩家一個會 404 的連結。
  • 伺服器端 gateway 那條路徑(shard.js)同樣改掉,沒有序號就回 scanUrl: null。

測試

seqOf() 的 12 個邊界案例全過:

✅ 0g-storage-node 實際形狀  → 2492640      ✅ null 進來      → null
✅ 駝峰寫法 / 平放頂層 / 只有 seq             ✅ tx 是 null     → null
✅ 字串數字 '42'            → 42            ✅ seq 是 null    → null
✅ 負數 / 小數要拒絕         → null          ✅ 空字串         → null

Number(null) 是 0,不擋的話「查不到」會變成一個看起來合法的 /submission/0。

未驗證的部分

這個容器的 egress 擋掉 *.0g.ai:/submission/<txSeq> 的格式來自搜尋到的真實網址,indexer 回應裡 tx.seq 的欄位名我沒有實際打過。拿不到序號時按鈕會留成不可按,所以最壞情況是連結不出現,不會再 404。

要當場確認欄位名,可以打:

curl -s "https://indexer-storage-testnet-turbo.0g.ai/file/info/0x2aba519d5e95ec4ee85fc6d549e29e4e5f7367fe6abf70b67432e81b9718da4b" | head -c 400

🤖 Generated with Claude Code

https://claude.ai/code/session_015NBxaWtzqEX3i8NvoZEeq3


Generated by Claude Code

按下去 404:

  https://storagescan-galileo.0g.ai/file/0x2aba519d5e95ec4ee85fc6d549e29e4e5f7367fe6abf70b67432e81b9718da4b

storagescan 沒有 /file/<root> 這條路徑,那是我當初憑印象組的。它的檔案頁是用
提交序號定位的 —— /submission/<txSeq>(例如 /submission/2492640)。

序號要跟 indexer 查:/file/info/<root> 的回應裡有 tx.seq。不同版本也出現過
txSeq / seq 這幾種寫法,所以 seqOf() 都認一下,一個都拿不到就回 null。

前端不再上傳完就把連結點亮。segment 傳完不等於索引好,節點要先把 log entry
同步進來 indexer 才答得出序號,實測中間有幾秒到十幾秒。所以改成輪詢(最多 6 次、
每次隔 3 秒),查到序號才解鎖按鈕;輪完還是沒有就維持不可按,並說明檔案已經上傳、
只是還沒被索引到 —— 不要給玩家一個會 404 的連結。

seqOf 的邊界(12 個案例全過):Number(null) 是 0,不擋的話「查不到」會變成看起來
合法的 /submission/0。所以先擋掉 null / undefined / 空字串,再拒絕負數與小數。

伺服器端 gateway 那條路徑(shard.js)同樣改掉,沒有序號就回 scanUrl: null。

未驗證的部分:這個容器的 egress 擋掉 *.0g.ai,/submission/<txSeq> 的格式來自
搜尋到的真實網址,indexer 回應裡 tx.seq 的欄位名沒有實際打過。拿不到序號時
按鈕會留成不可按,所以最壞情況是連結沒出現,不會再出現 404。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015NBxaWtzqEX3i8NvoZEeq3
實際打了一次才發現答案包在一層 data 裡:

  {"code":0,"message":"Success","data":{"tx":{…,"seq":150104},"finalized":true,…}}

原本這支直接讀 body.finalized,那永遠是 undefined,所以 found 一直是 false。
「上傳完再跟 indexer 對一次,確認節點真的收下」這個確認靜靜地失敗了很久,
只是被上傳成功的畫面蓋過去,沒有人發現。

unwrap() 有 data 就剝掉、沒有就當作已經是內容本身(不同版本回過沒包信封的
形狀);code 不是 0 表示 indexer 自己說失敗,這時不把 data 當有效答案。
順便把檔案大小也一起回報。

用使用者實際打回來的那份 JSON 一個字不改地測:
  剝殼後 finalized : true
  提交序號 txSeq   : 150104
  檔案大小         : 745 bytes
  產生的連結       : https://storagescan-galileo.0g.ai/submission/150104
另外四個形狀(舊版無信封、code 非 0、data 缺 tx、整包 null)也都符合預期。

這也確認了上一個 commit 的推測是對的:欄位就是 tx.seq。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015NBxaWtzqEX3i8NvoZEeq3
@k66inthesky
k66inthesky marked this pull request as ready for review September 10, 2026 06:59
Copilot AI lite review requested due to automatic review settings September 10, 2026 06:59
@k66inthesky
k66inthesky merged commit c1750f6 into main Sep 10, 2026
1 check passed

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

已確認有一處可能造成 runtime 例外(file.tx === null 時取 .size)與一處對外部回應的 txSeq 清洗不一致/可能產生 /submission/0 的問題需先修正。

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

此 PR 修正「在 0G Storage 上查看」連結會導向 storagescan 不存在的 /file/<root> 而 404 的問題,改為透過 indexer 取得提交序號後,才解鎖並導向正確的 /submission/<txSeq> 檔案頁,避免玩家點到必然失敗的連結。

Changes:

  • 前端:上傳後改以輪詢 indexer,取得 txSeq(scanUrl)才啟用「在 0G Storage 上查看」按鈕。
  • 後端(/api/og/storage):支援 indexer 回應的 envelope({code,message,data})解包,並從多種欄位形狀推導 txSeq 生成 submission URL。
  • 後端(gateway shard):scanUrl 改用 /submission/<txSeq>,沒有序號就回 null。
File summaries
File Description
public/js/main.js 上傳後輪詢 storage info,查到 scanUrl 才解鎖 storagescan 連結,避免 404。
functions/api/og/storage.js 解包 indexer 回應並推導 txSeq,改回傳 storagescan submission URL 或 null。
functions/api/og/shard.js gateway 回傳的 storagescan 連結改為 submission URL,並在無序號時回 null。
Review details
  • Files reviewed: 3/3 changed files
  • Comments generated: 2
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +146 to +149
finalized: found ? Boolean(file.finalized) : null,
pruned: found ? Boolean(file.pruned) : null,
size: found && Number.isFinite(Number(file.tx && file.tx.size)) ? Number(file.tx.size) : null,
txSeq,
Comment thread functions/api/og/shard.js
Comment on lines 153 to +156
txSeq: txSeq === null ? null : clampInt(txSeq, 0, Number.MAX_SAFE_INTEGER),
scanUrl: root ? `${GALILEO.storageScan}/file/${root}` : null,
// storagescan 是用提交序號定位的(/submission/<txSeq>),沒有 /file/<root>。
// gateway 有回序號才給得出連結,否則留 null,不要給一個 404 的網址。
scanUrl: txSeq === null ? null : `${GALILEO.storageScan}/submission/${txSeq}`,
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants