RFC-0020:介面序數雜湊

RFC-0020:介面序數雜湊
狀態已接受
領域
  • FIDL
說明

我們建議移除程式設計師對介面方法手動指定序數的功能。相反地,編譯器會根據完整方法名稱的雜湊 (即程式庫名稱、介面名稱和方法名稱) 產生序數。

作者
提交日期 (年-月-日)2018-10-26
審查日期 (年-月-日)2018-11-29

「60% 的時間,也是面試問題的答案」

摘要

我們建議移除程式設計師手動 指定介面方法 1 的序數。 相反地,編譯器會根據 完整方法名稱,即程式庫名稱、介面名稱與種方式 名稱。方法重新命名會透過新的 Selector 屬性與 ABI 相容 (請參閱下文)。

我們特別限制此 FTP 對介面提出序式雜湊 ;不包含列舉、資料表或可延伸聯集。 我們認為這些結構的用途差異在於 需要進一步調查並取得其他 FTP

範例

目前,FIDL 作者會寫入以下內容:

library foo;

interface Science {
    1: Hypothesize();
    2: Investigate();
    3: Explode();
    4: Reproduce();
};

這個 FTP 可捨棄序數索引:

interface Science {
    Hypothesize();  // look, no ordinals!
    Investigate();
    Explode();
    Reproduce();
};

理論上,編譯器會有效產生像 :

interface Science {
    // ordinal = SHA-256 of the fully-qualified method name,
    // i.e. "foo.Science/MethodName", truncated to 32 bits
    0xf0b6ede8: Hypothesize();
    0x1c50e6df: Investigate();
    0xff408f25: Explode();
    0x0c2a400e: Reproduce();
};

提振精神

  • 手動指定序數在很大程度上是機械的。 您不必費心編寫介面 具體做法是指示 Kubernetes 建立並維護 一或多個代表這些 Pod 的物件
  • 如果使用良好的雜湊,雜湊值將不太可能發生 因而改良了人類手動寫字的能力 一般 (使用介面繼承時更是如此)。詳情請參閱 「序樣」一節 瞭解詳情
  • 程式設計師必須目前必須確保不同方法的標準 而且不會衝突這個方法適合採用幾種方法的介面, 介面有許多方法,這可能變得相當複雜。 有不同的程式設計風格和學區思維 編號,因此編碼樣式不一致。
    • 大部分的介面是從 1 開始到向上的。
    • 然而,有些作者偏好將不同的介面方法分組 範圍內 (例如1-10、100-110 等)。
    • 移除手動加上編號之序時,也會移除不一致的現象 ,不必讓作者做出決定 要採用哪種樣式
  • 介面繼承可能導致異常衝突。 至今已多次嘗試解決問題:
    • FTP-010 (已拒絕) 提出了 OrdinalRange 屬性,以便讓 介面 繼承較容易預測因此遭到拒絕
    • FragileBase 2 是目前的停靠站解決方案, 卻無法解決根本問題,確保負擔並不起 衝突。
    • 如果序數雜湊,且使用介面和程式庫名稱 計算雜湊值,雜湊序數不會導致 可以解決介面繼承問題 極少數的雜湊衝突)。

設計

雜湊

雜湊序數衍生自 SHA-256 雜湊:

library name (encoded as UTF-8; no trailing \0)
".", ASCII 0x2e
interface name (encoded as UTF-8; no trailing \0)
"/", ASCII 0x2f
method name (encoded as UTF-8; no trailing \0)

舉例來說,下列 FIDL 宣告:

library foo;

interface Science {
    Hypothesize();
    Investigate();
    Explode();
    Reproduce();
};

會使用下列位元組模式來計算序數 雜湊:

foo.Science/Hypothesize
foo.Science/Investigate
foo.Science/Explode
foo.Science/Reproduce

由於 fidlc 已經輸出,因此會使用 ./ 分隔符 格式如下的完整方法名稱 (c.f. fidlcNameName() 方法)。

計算 SHA-256 雜湊後:

  1. 系統會擷取 SHA-256 雜湊中前 32 位元的內容 (例如: echo -n foo.Science.Hypothesize | shasum -a 256 | head -c8)
  2. 上方位元會設為 0,因此可產生有效的 31 位元雜湊 處理 32 位元的零時差值( FIDL 線格式會在 32 位元中保留最重要的位元 ordinal.)

在虛擬程式碼中:

full_hash = sha256(library_name + "." + interface_name + "/" + method_name)
ordinal = full_hash[0] |
        full_hash[1] << 8 |
        full_hash[2] << 16 |
        full_hash[3] << 24;
ordinal &= 0x7fffffff;

選取器屬性重新命名方法

我們定義了供編譯器使用的 Selector 屬性 計算雜湊序數,而非使用方法名稱。 如果方法名稱沒有 Selector 屬性,則該方法 名稱將做為 Selector。(介面和程式庫) 名稱仍會用於雜湊計算)。

Selector 可用於重新命名方法,而不會破壞 ABI 相容性是手動指定的優點之一 有些奇蹟舉例來說,如要重新命名 Investigate 方法至 Science 介面中的 Experiment 方法,就可以寫入:

interface Science {
    [Selector="Investigate"] Experiment();
};

我們僅允許在方法上使用 Selector 屬性。正在重新命名 將程式庫視為罕見,並且維持 ABI 相容性 在此情況下,這不是高優先順序的情況同樣地, 重新命名介面。此外, 含有 Discoverable 屬性的重新命名介面 難懂的是哪個名稱?

序章解決衝突

如果經過雜湊處理的序數導致與其他動物產生衝突或衝突 同一個介面的雜湊序數,編譯器就會發出 因此需要真人為您指定 Selector 屬性 以解決衝突 3

例如,如果方法名稱 Hypothesize 與 方法名稱 Investigate,我們可以將 Selector 加入 Hypothesize,以避免衝突:

interface Science {
    [Selector="Hypothesize_"] Hypothesize();
    Investigate();  // should no longer conflict with Hypothesize_
};

我們將更新 FIDL API 評分量表 建議附加「_」設為 Selector 的方法名稱 解決衝突。「fidlc」也會提供這項修正建議。

請注意,每個介面只需要有序數, 與手動指定一般關鍵字類似如果希望普通 各介面的名稱不得重複,且應該在其他介面中提出 FTP。

研究顯示,只要使用 31 位元 介面上有 100 種方法,衝突的機率為 0 .0003% 因此雜湊衝突非常少見

選取器有腳踏車

還有 Selector 的其他建議:

  • WireName (abarth)
  • OriginalName (ctiller)
  • Salt (abarth;建議新增指定編譯器,因此略有不同) Salt 而不是替代名稱)
  • OrdinalName

我們選擇了 Selector,因為我們認為這個數字更能反映 屬性的意圖,而不是 WireName 或 OriginalName。

我們選擇讓程式設計師指定序數名稱 有幾個原因:

  • 要求索引更為繁瑣,例如複製貼上 原始 SHA-256 雜湊值 (如果發生衝突),
  • 指定序數名稱就能啟用與 ABI 相容的方法重新命名, 和
  • 指定名稱而非索引 和程式設計師的抽象層級相同 而不會降低一層抽象層 要求學生思考普通

零星體

0 是無效序數,如果 名稱雜湊設為零,編譯器會將其視為雜湊衝突 並要求使用者指定不會經過雜湊處理的 Selector 零時差弱點

我們考慮讓 fidlc 自動重新雜湊名稱,方法是: 但認為:

  • 任何這類演算法都是不明顯的
  • 零時差情況極為罕見

因此,這種方法並不保證 人體工學和編譯器實作

活動

這個 FTP 也有涵蓋事件,這些事件屬於 方法文件 4

編譯器與繫結變更

我們認為只須修改 fidlc 就能提供支援 序式雜湊;產生程式碼的後端 已修改。這是因為 fidlc 會計算序數 才會在 JSON IR 中對後端發出。

不需要變更繫結。

執行策略

我們預計在各個階段導入此做法:

  1. 將程式碼新增至 fidlc 來計算雜湊。
  2. 為程式庫新增屬性支援。
  3. 廣播「血糖改變」的意圖,幫助他們瞭解生意 以負載平衡機制分配流量 即可降低應用程式發生效能問題的風險 a.建議手動序數會在特定日期淘汰 就能完成下一步
  4. 在同一個 CL 中: a.修改 FIDL 文法的介面方法規則,將序數設為選用; 請參閱下文瞭解詳細資訊。 b.忽略手動指定的序數,並使用雜湊序數做為 傳遞至程式碼產生後端的序數名稱。 c.新增 Selector,手動修正現有的雜湊衝突 屬性。
  5. 並在兩週內測試變更,確保沒有正式環境的問題。 a.目前編寫的新 FIDL 介面不應使用一般。 b.手動序數被視為已淘汰,但 fidlc 不會發出 相關警告 c.與團隊合作,確保沒有手動指定的常態作業 存取 API d.請在兩週內更新 FIDL 格式設定工具,以移除 然後大量套用於整個福西亞樹
  6. 停止支援手動指定物件。

上述是 柔性轉換 變更 fidlc 以使用雜湊序 (步驟 4b) 不應破壞 擲骰子,因為滾動式是以整個樹狀結構的單一版本為基礎。

jeremymanson@google.com 實作這個 FTP 中, 他選擇以手動指定的序數,而非雜湊序數 這與上述步驟 4b 不同。這樣就能保留所有現有介面 採用手動指定的標準與 ABI 相容,且僅使用 不指定序數時,就會產生雜湊序數。

人體工學

優點:

  • 編寫介面應會較為簡單。

缺點:

  • 程式設計師必須瞭解一項新屬性 Selector, 有兩個用途:重新命名和衝突解決。
  • 變更方法名稱未必會破壞 ABI ,不符合程式設計師指定的常態。 使用者教育 (例如更好的說明文件) 可以不容易理解。
    • 請注意,其他元件系統,例如 COM 和 Objective-C 通常也會在介面方法執行時中斷 ABI 相容性 已重新命名因此,如果開發人員 也很類似
  • 若失去手動控制序數, 在特殊情況下 (例如:會有多個 FIDL 介面 同一個 Zircon 管道上的節目

請注意,本 FTP 作者多半是出於人體工學。

說明文件和範例

我們預計將調整 FIDL 屬性、文法、語言和 線段文件此外,也應更新 API 可讀性評分量表文件 (如 Selector 部分所述)。

回溯相容性

  • 雜湊序與手動指定的序數不相容,與 ABI 不相容。 。這應該不是問題
    • fidlc 變更為二進位 (雜湊的 xor 手動序數都會 值) 和
    • fidlc 是用來建構整個樹狀結構,因此
    • 樹狀圖的所有部分都會一致採用選定的序數配置。
  • 雜湊序與 API (來源) 相容。 現有來源檔案將維持相容。手動基數 已淘汰 (請參閱「導入策略」)。
  • 如果兩個不同的 fidlc (即兩個不同的 fidlc) 會發生錯誤 平台來源樹狀結構),以及 FIDL 介面 一種是跨機器通訊的機制作者知道目前未使用 所以這應該不是問題

成效

預計將拖慢至 fidlc,因為現在必須對所有方法進行雜湊處理 才能計算這些名稱

我們預計對執行階段效能產生輕微的影響。 編譯器可能會針對手動指定的序數產生跳轉表格 這些原本屬於小型的連續範圍,因此將成為二元搜尋 經由稀疏式空間來傳遞雜湊。 相同的機制也可能以不明顯的方式影響二進位檔大小。 (表格導向的調度作業,可能會同時降低其大小和速度方面的疑慮)。

安全性

序式雜湊沒有執行階段,因此不會預期執行階段安全性問題 透過 Wi-Fi 傳送 (例如變更序數值) 變更。

使用加密編譯雜湊 (SHA-256) 可能會導致某些人認為雜湊需求 具備高強度加密功能我們並未認為存在安全性問題,原因是:

  • FIDL 編譯器會在編譯時檢查雜湊衝突, 手動解決
  • 我們不會使用 SHA-256 進行加密編譯,但我們需要雜湊資料 不太可能引發衝突。 CRC-32 (甚至是 strlen()) 也能運作,但可能會產生更多 但這樣就可能會造成不便。

截斷 SHA-256 雜湊可能也會有疑慮,但再次提醒 認為存在安全性問題,因為 FIDL 編譯器會以靜態方式檢查 雜湊衝突 5

測試

ianloic@google.com 分析了現有的 FIDL 介面,並判定 表示雜湊衝突沒有錯誤

我們會審慎考量如何測試雜湊衝突的實際情況 在設計上,以人為方式產生雜湊衝突並不容易 (在設計上)。

否則,就電池單元測試 CQ 測試 相容性測試 手動測試應已足夠,確保序數雜湊是穩健的

缺點、替代方案和未知

這個 FTP 只會為介面處理序數雜湊。 它不會提議變更列舉的手動列舉序數 或可延伸聯集

jeffbrown@google.com 建議進行完美雜湊,當時我們考慮這麼做。 FTP 作者不熟悉完美的雜湊處理方式,不過相信 日後如果增加額外方法,現有 YAML 檔案 方法,因而破壞 ABI 的相容性,使得完美的雜湊值不適合我們。 動態完美雜湊或許可行,但同樣與 搜尋度也較不常見,也比標準格式更複雜 而不需要進一步調查。

另一種移除手動序數的方法,是傳送完整的方法名稱。 大多數 (大部分?) 其他遠端程序呼叫 (RPC) 系統都支援連線,請參閱 參考資料)。這會對執行階段效能造成影響 可能會與 FIDL 的預定用途發生衝突。

我們考慮指定使用的雜湊值,方便日後變更 萬一 SHA-256 最後發生其他雜湊能夠解決的問題, 這項設計很常見於安全性應用,在其廣泛使用的加密編譯中 雜湊值之後會發現安全漏洞。 不過,指定雜湊碼可能需要變更傳輸格式 且需要所有語言繫結都導入程式碼來選取雜湊演算法。 這會大幅簡化編譯器和繫結程式碼。 我們認為,不必在那之前做出取捨。 我們瞭解 git 也採用 SHA-1 態度, 現在還可用來追蹤決策進度,但我們認為 幾度差異,到適合以硬式編碼方式寫入雜湊演算法。

探索

  • 利用節省空間的方式找出方法, 方法的第一類別表示法,使方法成為第一類別
    • 例如啟用可在 FIDL 呼叫中用做引數的方法,或者 FIDL 方法則是傳回其他方法。 目前已有適用的用途,方法會傳回 具有單一方法的介面,做為傳回實際方法的 Proxy。
  • 建議的 31 位元雜湊值可擴展至64/128/53 位元; SHA-256 提供大量 Obit。
  • ordinal 重新命名為 selector,這是提供相同服務的現有概念 用於其他語言和元件系統
  • 建議您區分方法名稱和介面名稱,因此我們 包含兩項不同的資料 此 ID 可明確參照介面名稱,且可以明確參照方法名稱。 為此,我們可能需要超過 32 位元。
  • 如上所述,列舉、資料表和可延伸聯集不在範圍內。 即便如此,我們仍認為這種 FTP 可能適用於他們。 初步想法:
    • 我們無法確定列舉項目是否需要此功能。 更簡單且標準化的連續整數編號似乎已足夠。
    • 這可能直接套用至可延伸聯集。
    • 表格需要不同的線路格式才能採用序式雜湊,因為 普通
  • FIDL 目前會保留序數上限,並在文件中明確指出 部分上限位元適用於控制流程等。 作者認為其中一項原因也可能是牽涉到 與一般狀況產生衝突 要複習嗎?
    • 將序言展開至 64 位元 (如上文所述) 可大幅解決 而負責任的 AI 技術做法 有助於達成這項目標
    • abarth@google.com建議在 Fuchsia IPC 聊天室中預訂,以便僅預訂 0xFFFFxxxx
  • 我們可以將方法的引數類型加入計算後的雜湊值中 因為我們日後需要支援超載方法。
    • jeffbrown@google.com 提到,雜湊處理完整方法簽章可能會受到限制 介面擴充功能,導致地圖超載 預計投入大量的程式設計語言
  • 由於序數雜湊應會在介面繼承時解決一般衝突問題 FragileBase 屬性也可以移除。
    • 程式碼搜尋顯示約 9 次使用 FragileBase
  • 作者擔心介面有大幅進化的現象 如果許多方法都含有 Selector 屬性,這些方法會越來越難查看。
    • 解決這個問題的一種方法是採用類似於 Objective-C 類別C# 部分類別。 原已宣告的介面可以「擴充」具備屬性 新增至另一個宣告中。

既有藝術品和參考資料

有趣的是,我們並不知道 使用方法名稱的雜湊來識別要呼叫的方法。

大多數 RPC 系統會依名稱呼叫方法 (例如 gRPC/Protobuf 服務、Thrift、D-Bus)。 針對處理中的方法呼叫,Objective-C 會使用保證專屬字元* 指標 ,用來識別應在類別呼叫的方法。 Objective-C 執行階段可以將選取器對應至字串化方法名稱,反之亦然。 如果是獨立程序的方法呼叫,Objective-C 分散式物件會使用 方法 叫用名稱。 COM 會直接使用 C++ vtable 進行處理中的呼叫,因此取決於 ,以支援方法分派作業。 apang@google.com 建議 ctiller@google.com 中資料表的序數雜湊 提供提案。ianloic@google.com 和 apang@google.com 於 2018 年 10 月 18 日週四與 我在這裡


  1. Mojo/FIDL1 也並未要求程式設計師指定序數; 而是依序產生 (類似 FlatBuffers 的 資料表欄位的隱含標記編號)。 

  2. 您之前可以建立從 任何其他 FIDL 介面 不過,介面和超介面會使用相同的序數空間 因此如果您將方法新增至介面 子介面。 為瞭解決 繼承 / 序衝突問題,但直到我們找出 想要解決這個問題,我們已將介面的預設選項切換為 。 使用者仍然可以在介面上, [FragileBase] 屬性。 如果遇到這個問題,編譯器應顯示錯誤訊息 以簡要說明 我 (abarth@google.com) 新增了 [FragileBase] 屬性 「平台來源樹狀結構」中使用 FIDL 介面繼承的每個位置 (希望您!) 如有任何疑問或遇到任何問題,歡迎與我們聯絡。 --abarth@google.com 

  3. 我們不認為有充分的口頭衝突需要擔保 自動增加任何額外導入作業及認知到複雜程度 衝突解決我們可以回頭審視這項決策而不中斷 如果資料顯示序曲衝突 問題。 

  4. 如果只宣告結果,此方法會稱為事件。 然後再定義來自伺服器的垃圾郵件。 

  5. jln@google.com Write, "是可以截斷 SHA-2 而沒有, 所以你可以在不被截斷的地方使用