Solana 聯創:Solana 狀態增長有何解決方案?

WEEX 唯客博客, 作者:toly,Solana 聯合創始人 編譯:Felix,PANews   每天大約有 100 萬個新賬戶被添加到 Solana 中,現在的總狀態已超 5 億,而快照大小約為 70GB。隨著硬體的改進,這些數字本身是完全可管理的,但是 SVM 運行時的目標是提供最便宜的硬體訪問方式,為了實現這一點,必須在當前硬體限制內管理狀態和內存。 PCI 帶寬 截至 2024 年,最新的 PCI 帶寬可以達到 0.5 Tbs 到 1 Tb 的吞吐量。或者每秒 64GB 到 128GB。雖然聽起來很大,但如果一個 tx 讀取 / 寫入為 128MB, 128GBps 的 PCI 帶寬會將鏈的 TPS 限制在 1000 左右。實際上,大多數 txs 訪問的是最近載入並緩存到 RAM 中的內存。理想的設計應該是允許載入 1000 個具有 128MB 新狀態的 txs,再加上 10k 或更多讀取和寫入現有緩存狀態的 txs。 帳戶索引 創建新帳戶需要證明該帳戶當前不存在。這通常是在每個驗證器上自動完成,因為每個驗證器都有當前所有有效帳戶的完整索引。即使帳戶數據不存儲在本地,只存儲數據的哈希,5 億個帳戶也將是 32 位元組的密鑰 + 32 位元組的數據哈希或者每項 64 位元組,即 32 GB。這已經足可以保證 RAM 和磁碟的分離。 快照大小 在某些快照大小(Snapshot Size)下,如果部分網路出現硬體故障,冷啟動新系統所需的時間足以延長最壞情況的重啟時間。隨著帶寬和硬體的改進,情況每天都在變化,而 Solana 並沒有接近這個限制,但該限制在任何時間點都存在。 概要 內存和磁碟具有不同的性能特徵和限制。如果 SVM 不區分,那麼交易和限制就必須針對最壞的情況進行定價,進而限制了性能。在交易執行期間,所有帳戶密鑰至少必須可用,並且總帳戶數量將影響 RAM 和磁碟 PCIi 帶寬利用率。快照不能任意增大。理想的解決方案是: 允許將更多不需要 PCI 資源的 txs 打包到區塊中 管理總索引大小和快照大小 Chilly、Avocado、LSR。糟糕的名字通常是優秀軟體設計的標誌。Anza 和 Firedancer 的工程師想出了以下方案。 Chilly 帳戶運行時的緩存由所有實例(instances)進行確定性管理。從更高層次看,這是訪問狀態的 LRU 緩存。在區塊構建和調度期間,該實現(implementation)可以很容易檢查帳戶,不需要鎖定或迭代 LRU 緩存。緩存是用一個非常簡單的計數器機制實現。 總載入位元組被跟蹤為 Bank::loaded_bytes:u64 每個帳戶在使用時都用當前運行總數 account::load_counter:u64 進行標記 載入帳戶時,如果 Bank::loaded_bytes – Account::load_counter > CACHE_SIZE,則帳戶被認為是冷帳戶,其大小是根據每個區塊的 LOAD_LIMIT 計算 新帳戶 load_counter 為 0,因此所有新帳戶都是冷帳戶 Leader 的調度程序將 LOAD_LIMIT 作為一個水印,類似於寫鎖 CU 限制。 這種設計的絕妙之處在於,它很自然地適合當前的調度程序。用戶只需要擔心他們的優先費。調度程序必須處理將所有低於 LOAD_LIMIT 和帳戶寫鎖限制的 tx 放入背包問題。最高優先順序的 tx 可以首先載入並使用 LOAD_LIMIT。一旦達到這個限制,所有其他 tx 仍然可以放入一個區塊中。因此,驗證器可以最大化緩解 txs 的緩存局部性。 Avocado Avacado 由兩部分組成,狀態壓縮和索引壓縮。首先用哈希替換帳戶數據,然後將帳戶索引遷移到 Binary Trie / patricia Trie。新帳戶必須提供證明,證明他們不在「trie」中。 狀態壓縮 大致設計如下: 在分配期間,每個帳戶每位元組綁定 X 個 lamports。 如果 X < 當前經濟底價,則將賬戶保留在內存中,該賬戶將被壓縮 壓縮是一個多步驟的過程,運行在一個 epoch 上 帳戶數據被替換為哈希值(data) 帳戶密鑰仍處於狀態之中 引用壓縮帳戶的交易失敗 解壓需要上傳類似於載入程序的數據 解壓的成本應該與分配一個新帳戶的成本相同 估計 75% 的賬戶在超過 6 個月的時間裡沒有被訪問,而且很可能永遠不會被訪問。壓縮它們可以節省 50% 的快照大小。 索引壓縮 這是一個更難解決的問題。僅通過狀態壓縮,驗證器仍然擁有系統中所有可能的有效帳戶。創建新帳戶需要檢查此資料庫。驗證器存儲此資料庫的成本很高,但用戶創建新帳戶的成本很低。要保證新私鑰不會與現有帳戶發生任何衝突。 Binary Trie mining Binary Trie 作為快照的一部分被跟蹤 想要獲得額外 sol 的驗證者可以創建一個交易,從狀態中刪除壓縮的帳戶 kv 對,並將它們添加到 Binary Trie 中 用戶可以在解壓過程中將 kv 從 Trie 中移除,從而在不被允許的情況下反向執行此操作(這可能需要在解壓時進行原子操作,以便在後台服務壓縮帳戶時更容易)。 對於驗證器,無論它包含多少 kv 對,Trie 根的大小都是恆定的 使用 zkp,每個 tx 可以壓縮約 30 個帳戶 假設每個區塊只有一個,那麼壓縮 5 億個賬戶需要大約 80 天的時間 這個過程的關鍵之處在於,執行此操作的驗證者將獲得獎勵,但並不是所有驗證者都必須執行此操作。如果所有驗證器都必須執行此操作,那麼所有驗證器都必須維護當前 Binary Trie 中的內容,這意味著整個狀態必須是快照的一部分。想要維護整個狀態的驗證器應該提交一個交易,將索引中的 N 個帳戶壓縮到 Trie 中。 新帳戶證明 要創建一個新帳戶,用戶必須證明該帳戶在 Trie 中不存在。維護整個狀態的驗證器可以生成帳戶不在 Trie 中的證明。這給用戶帶來了負擔,他們必須始終與大型狀態提供者連接以生成這些證明。 或者,用戶可以證明他們的帳戶是用最近的 PoH 哈希創建的。支持這一點的最簡單的方法是: 生成新的 PKI 帳戶地址是哈希(最近的 PoH 哈希,PKI::public_key) 鑒於 Trie 中的帳戶必須首先進行狀態壓縮,這需要一個完整的 epoch。Trie 中的任何帳戶都不可能使用最近的 PoH 哈希來生成地址。 其他可以支持的方法是 PKI 創建本身可以提供一個證明,證明私鑰是用哈希(用戶隱藏的秘密,最近的 PoH 哈希)創建的。 LSR Lightweight Simple Rent,又稱 Less Stupid Rent。如何為分配新帳戶的成本定價,以及如何確保舊的廢棄賬戶最終得到壓縮,並減少系統的整體負載和新用戶的價格? 需要恢復租金(Rent)制度。Rent 是指當前狀態下的賬戶應該支付 X 美元 / 位元組 / 天的費用,就像 AWS 上的賬戶支付存儲費用一樣。 Rent Rate bonding curve RentRate = K*(state_size)^N 無論當前狀態大小如何,如果很小,費率應該很低,如果接近快照限制,費率應該非常高。 Allocation Minimum Bonding Price 賬戶必須至少存在一個 epoch。分配需要將帳戶帶入 Hot 狀態。熱帳戶應該在緩存期間存在。 New Account bond = Epoch Slots * RentRate * Account::size 新賬戶的餘額中必須至少有這麼多的 lamports 才能創建。 Hot Account Burn lruturnverrate = 每個帳戶在 LRU 緩存中平均佔用的時間,最大值為 1 epoch。這個值可以是一個常數,也可以在鏈下計算,並作為中位數權益加權常數報告給 SVM。 壓縮 當(current slot – account::creation_slot) * RentRate * account::size > account::lamports 時,壓縮帳戶並燒毀所有 lamports。 上述解決方案,應該會讓 State 很便宜,因為隨著時間的推移,未使用的帳戶最終會達到 lamports 0,並將被壓縮。所以數據開銷會減少,甚至索引開銷也會減少,這將減少當前狀態的大小。減少狀態的大小將降低超二次分配的成本。 WEEX唯客交易所官網:weex.com

Previous:

Next: