Skip to main content
鏈提交的是區塊。而應用問的是這個帳戶上週成交了什麼、訂單簿現在長什麼樣——這類問題,以區塊為形態的紀錄很難回答。索引器就是把前者轉換成後者的那一層。 在大多數鏈上,索引器是基礎設施中的關鍵一環:鏈發出的是不透明的事件,由第三方從中重建含義,於是你的應用相信什麼,就看它信任哪個索引器。在這裡,重建這一步並不存在。核心發出的是帶類型、帶歸屬的輸出——每一次狀態變更都已綁定到引起它的那筆交易——因此索引器做的是重塑資料,而不是推斷資料。 這改變了索引器的定位:它是查詢服務層,不是事實來源。索引器報出的任何東西都可以對著鏈核驗,一旦分歧,那就是索引器的缺陷,不是懸而未決的問題。

路徑

按資料新舊分開
全節點已提交區塊,以帶類型記錄串流輸出
快取近期 — 從記憶體提供
檔案儲存歷史 — 持久化
資料服務把兩者呈現為一條流
閘道 → REST · WebSocket存取控制、配額、路由
為什麼要拆開跟隨鏈頭對延遲敏感、資料量小;歷史查詢對吞吐量敏感、資料量大。共用一條路徑,一次回填就會把即時路徑拖住。
查詢服務層,不是事實來源內核發出的是帶類型、帶歸屬的輸出,所以索引器做的是重塑,不是推斷。與鏈分歧,就是索引器的缺陷。
全節點是起點。交易紀錄從全節點流出時就是帶類型的資料,不是還要再作解釋的原始交易。 快取與檔案儲存按資料新舊把這條流分開。近期資料從記憶體提供,因為多數消費者要的就是這些,而且延遲很重要。歷史資料寫入持久化的檔案儲存,因為把一切都留在記憶體裡不是一種策略。有人來取舊資料,有人跟著鏈頭走,兩邊由不同的地方服務,而兩邊都感覺不到。 資料服務把兩者呈現為一條流。用戶端可以請求從任意位置開始的區間;這個區間由快取提供、由檔案提供,還是兩者共同提供,不是用戶端要操心的事。 閘道處理介於服務與公網之間的那些事:存取控制、配額和路由。 REST 與 WebSocket 介面才是應用實際使用的東西——行情資料、訂單與成交歷史、部位、帳戶狀態、資金費支付,以及即時訂閱。端點層級的細節參見 API 參考。

為什麼要拆開

同一個服務既要跟隨鏈頭、又要回答歷史查詢,兩件事都做不好。跟隨鏈頭對延遲敏感、資料量小;歷史查詢對吞吐量敏感、資料量大,一次大規模回填就會把即時路徑拖住。 把兩者分開,替新來的消費者回填幾個月前的資料,就不會拖慢正在跟隨鏈頭的造市商;兩者也可以獨立擴充——而且確實需要,因為兩邊的負載特徵毫無共同之處。

什麼可以放心依賴

可以依賴。 索引器提供的、由已提交區塊派生出來的一切:成交、訂單、部位、資金費支付、轉帳、行情資料。這些都是鏈上輸出的重塑。 不是一回事。 任何尚未提交的東西。訂單進了記憶池(mempool),也還沒有排序,索引器對它無話可說。在索引器裡查不到,意思是「還沒有提交」,不是「被拒絕了」。 可核驗。 某個答案若夠重要——一次結算爭議、一次稽核、一次帳務對帳——可以直接對著鏈核驗,不必從索引器裡取。自己跑一個全節點是最徹底的做法;參與者若承擔不起出錯的代價,就該這麼做。參見運行節點。
兩個消費者讀取同一段已提交區間,應該得到同樣的答案。若不一樣,差異出在服務鏈路上,是應當上報的缺陷,不是「透過索引器讀鏈」這件事的固有屬性。

後續閱讀

狀態模型

索引器讀的是什麼,以及哪一種表示是權威的。

開發者

REST 與 WebSocket 介面、SDK 與工具。

運行節點

自己對著鏈核驗,以及這個集合為什麼是封閉的。

程式服務

誰在消費這條流來計算派生的帳戶狀態。