鏈的可用資源是有限的。資源包括內存使用、存儲 I/O、計算、交易/塊大小和狀態資料庫大小。有幾種機制可以管理對資源的訪問,並防止鏈中的各個組件消耗過多的資源。重量(Weights)是用於管理驗證區塊所需時間的機制。一般來說,這來自於限制存儲 I/O 和計算。
注意:重量不是用於限制對其他資源的訪問,例如存儲本身或內存佔用。有其他機制用於這個。
塊可以包含的重量是有限的,可選的重量消耗(即不需要作為塊的初始化或終結階段的一部分部署的重量,也不需要用於強制的固有外部重量)通常通過經濟措施來限制,或者簡單地說,通過交易費用來限制。重量系統的費用含義包含在交易費用文檔中(https://substrate.dev/docs/en/knowledgebase/runtime/fees)。
Substrate 將一個重量單位定義為在固定參考硬體(Intel Core i7-7700K CPU,64GB RAM 和 NVMe 固態硬碟)上執行時間的皮秒(微微秒)。參考硬體上的基準測試使重量在 runtime 之間具有可比性,從而允許來自不同來源的軟體組件的可組合性。為了針對不同的驗證人硬體假設去調節 runtime,可以設置不同的最大塊重量。例如,為了允許驗證人參與,速度只有參考機器的一半,最大塊重量應該是默認值的一半,保持默認的塊時間。
最大塊重量應等於目標塊時間的三分之一,分配三分之一用於塊構造,三分之一用於網路傳播,三分之一用於導入和驗證。雙倍塊時間會雙倍最大塊重量。這些優化選項為 runtime 開發人員提供了一種方法,使其能夠在每秒交易數與硬體需求之間為其場景進行最佳權衡。這些權衡可以通過 runtime 更新進行調整,以跟上硬體和軟體的改進。
重量的功能
重量表示區塊鏈必須驗證區塊的有限時間。這包括計算周期和存儲 I/O。自定義實現可以使用複雜結構來表示這一點。Substrate 重量只是一個數值(https://crates.parity.io/frame_support/weights/type.Weight.html)。
重量的計算應始終:
在調度前可計算。塊生成器應該能夠在實際決定是否接受它之前檢查可調度的重量。
本身消耗的資源很少。消耗同樣的資源去計算交易重量是沒有意義的,當它會在執行中花費掉。因此,重量計算應該比調度輕得多。
能夠在不諮詢鏈狀態的情況下確定所使用的資源。在不需要昂貴的 I/O 的情況下,重量能夠很好地表示固定的測量值或僅基於可調度函數的參數的測量值。當成本取決於鏈的狀態時,重量就不那麼有用了。
在可調度的重量嚴重依賴於鏈狀態的情況下,有兩個選項可用:
確定或引入一個強制上限,以確定可調度的可能承受的重量。如果強制上限和可調度的最小可能重量之間的差異很小,則可以假定它始終處於重量上限,而無需諮詢狀態。然而,如果差異太大,那麼進行較少交易的經濟成本可能太大,這將扭曲激勵機制,造成吞吐量的低效率。
要求將有效重量(或可用於有效計算的前體)作為參數傳遞給調度。收取的重量應以這些參數為基礎,但也包括在調度期間驗證這些參數所需的時間。必須進行驗證,以確保重量參數與鏈上狀態準確對應,如果不符合,則操作可能出錯。
重量因素
有幾個因素會影響執行時間,從而影響重量計算。一個很大的貢獻者是一個可調度執行的資料庫訪問數。由於資料庫訪問的成本在很大程度上取決於資料庫後端和存儲硬體,因此重量計算是參數化的,而不是資料庫讀寫的重量成本。這些成本是通過在一些參考硬體上對每個可用的資料庫後端進行基準測試來確定的。這允許在不更改所有重量計算的情況下切換資料庫後端。
除了只使用常量進行預調度重量計算外,開發人員還可以將給定可調度對象的輸入參數考慮在內。當執行時間取決於例如一個參數的長度時,這非常有用。重要的是,這些計算本身不需要任何有意義的工作。使用一些基本演算法,可以從輸入參數中輕鬆計算預調度的最大重量。
系統模塊(System pallet )負責在執行時累積每個塊的重量,並確保其不超過限制。交易支付模塊(Transaction Payment pallet)負責解釋這些重量並根據這些重量扣除費用。重量功能是 runtime 的一部分,因此可以根據需要進行升級。
發布調度後的重量修正
在某些情況下,可調度的實際重量不能從其輸入中簡單地計算出來。例如,重量可能取決於可調度的邏輯路徑。如果在調度後沒有任何方法來校正重量,我們會不斷高估這些可調度的價格,然後再多收費,因為我們必須在調度前假設最壞的情況,以確保鏈條的安全。
發布調度後的重量修正允許任何可調度的在執行後返回其實際重量。此重量必須小於或等於調度前最壞情況的重量。要允許用戶包含外部用戶,他們仍然必須能夠支付最大重量,即使最終付款將基於實際重量。
區塊重量和長度限制
除了影響費用之外,重量系統的主要目的是防止一個區塊被執行時間過長的交易填滿。在塊內處理交易時,系統模塊將塊的總長度(以位元組為單位的編碼交易的總和)和塊的總重量相加。如果這兩個數字中的任何一個超過了限制,則該區塊不接受進一步的交易。這些限制在 MaximumBlockLength 和 MaximumBlockWeight是有定義的。
關於這些限制的一個重要注意事項是,其中一部分是為 Operational 調度類保留的。此規則適用於這兩個限制,比率可以在 AvailableBlockRatio中找到。
例如,如果塊長度限制為 1 兆位元組,並且比率設置為 80%,則所有交易都可以填充塊的前 800 千位元組,而最後 200 千位元組只能由操作類填充。
還有一個 Mandatory 調度類,可以用來確保外部始終包含在塊中,而不管它對塊重量的影響如何。請參閱交易費用文檔(https://substrate.dev/docs/en/knowledgebase/runtime/fees)以了解有關不同調度類以及何時使用它們的更多信息。
下一步
了解更多
Substrate 菜譜中有包含自定義重量(https://github.com/substrate-developer-hub/recipes/tree/master/pallets/weights)和重量費用(https://github.com/substrate-developer-hub/recipes/tree/master/runtimes/weight-fee-runtime)的案例。
案例模塊:https://github.com/paritytech/substrate/blob/master/frame/example/src/lib.rs
案例
查看給自定義 runtime 函數添加一個交易重量的例子。https://substrate.dev/recipes/3-entrees/weights.html
參考
交易支付模塊:https://github.com/paritytech/substrate/blob/master/frame/transaction-payment/src/lib.rs
重量:https://github.com/paritytech/substrate/blob/master/frame/support/src/weights.rs
原文:https://substrate.dev/docs/en/knowledgebase/learn-substrate/weight
翻譯:PolkaWorld 社區
歡迎學習 Substrate:
https://substrate.dev/
關注 Substrate 進展:
https://github.com/paritytech/substrate
關注 Polkadot 進展:
https://github.com/paritytech/polkadot
冷萃財經原創,作者:Awing,轉載請註明出處:https://www.lccjd.top/2020/06/27/substrate-%e4%b8%ad%e7%9a%84%e4%ba%a4%e6%98%93%e9%87%8d%e9%87%8f%e6%98%af%e4%bb%80%e4%b9%88%ef%bc%9f/?variant=zh-tw
文章評論