Bitcoin-Core

可重現的 Gitian 建構 .. 但與 bitcoincore.org 的雜湊值不同

  • November 15, 2020

Bitcoincore.org 和 Bitcoin.org 將讓你下載比特幣 v0.20.1 的 tarball

當他們這樣做時

比特幣: 4ec74161b2a90293926ae8e20a2efbe952bd23b53aeebf051e6a6285ace18271

比特幣-0.20.1-x86_64-linux-gnu.tar.gz: 376194f06596ecfa40331167c39bc70c355f960280bd2a645fdbf18f66527397

他們還說:

為自己複製二進製文件將為您提供目前可用的最高級別的保證

因此,目前執行此操作的方法似乎是“gitian build”操作。

當我這樣做時

比特幣: c5fb850ed9e6afa0af5653e743084912c9bd71fb233acfe2d72738fc319f2181

比特幣-0.20.1-x86_64-linux-gnu.tar.gz: 277599356bd2df760832c6636797fe5ea5a5c28d929d53635b685f5ac1e4689b

使用Ubuntu 20.04Debian 10完成了 gitian 程序。兩者產生的一樣嘛?tarball,2 個不同的設置/ 2 個作業系統,相同的 tarball。

我的兩個斷言文件都是為 Debian 和 Ubuntu 上傳的。 <https://github.com/miketwenty1/images/tree/master/bad_asserts>


作為一個普通人,我可以想到兩件事中的一件事..

我的一些包/版本/環境/作業系統/設置有問題/關閉,或者,所有驗證者都在撒謊,比特幣已被盜用。幫助我縮小可能性。

我想正確地完成這個練習並重現相同的二進製文件..但不確定最好的前進方式..驗證 v0.20.1 建構的下一步是什麼?我似乎無法複製在 bitcoincore 上宣傳的 tarball。組織和比特幣。組織。然而,我可以製作一個可重複的建構,這讓我質疑很多事情。

如果有人能從頭開始完成他們的過程,看看他們是否能產生這些人在這個 repo 中看到的相同的 tarball,我會很高興。<https://github.com/bitcoin-core/gitian.sigs/blob/master/0.20.1-linux> /*/bitcoin-core-linux-0.20-build.assert的。並與我分享他們的完整過程。在複製自己之後,我很樂意對該方法進行目前的演練並更新文件,其中(下面的連結)幾乎所有方法都已過時和損壞。

注意:如果這確實是目前進行可重複建構的事實上的方式.. 擁有精確和最新的文件會很好。我知道 Ginx 正在開發中.. 但是對於想要驗證建構的人來說,在此期間有一個目前的文件會很好。如果有人指出我遺漏的東西,我也會非常滿意。

參考連結:

https ://gitian.org/

<https://github.com/bitcoin-core/docs/blob/master/gitian-building.md>

https://github.com/bitcoin-core/docs/tree/ master/gitian-building

<https://github.com/devrandom/gitian-builder/blob/master/README.md>

<https://github.com/bitcoin/bitcoin/blob/master/contrib/gitian-build.py>

參考 github 問題

<https://github.com/devrandom/gitian-builder/issues/235>

我已經完成了 0.20.1 的重建,並且得到了與您相同的結果。這表明建構依賴項已更新,產生的結果與發佈時使用的版本略有不同。與實際的軟體依賴項不同,建構依賴項版本是固定的。IIRC 這對於 gitian 建構很常見,嘗試重建更舊的版本會導致類似的不匹配。

正在進行的工作是轉移到稱為 guix 的不同的可重現建構系統。這個建構系統將固定確切的依賴版本,以及從頭開始建構整個工具鏈的選項。這應該啟用可以在任何時間點複製的完全可複制的建構。


這是對這種特殊不匹配的更深入解釋,複製自我在此 GitHub 問題中的回复。

如果您查看 gitian 建構結果,您將看到一個名為bitcoin-0.20.1-x86_64-linux-gnu-debug.tar.gz. 如果你解壓這個文件,就會有*.dbg文件,例如bitcoind.dbgbitcoin-qt.dbg. 這些*.dbg文件包含各自二進製文件的調試數據,即bitcoind.dbg包含bitcoind.

為了確保您使用正確的dbg文件和正確的二進製文件,gcc 將文件的校驗和嵌入dbg到二進製文件本身中。這意味著bitcoind包含 的校驗和bitcoind.dbg。這是為了防止嘗試bitcoind使用另一個dbg文件進行調試。例如,如果您試圖告訴 gdb 該bitcoin-qt.dbg文件包含 的調試符號bitcoind,它會檢測到它沒有並且不會嘗試從bitcoin-qt.dbg.

調試符號最初被編譯到bitcoind二進製文件中,但後來在 gitian 建構期間,這些符號被刪除並放入bitcoind.dbg文件中。但是,因為它們bitcoind最初是編譯成的,所以調試符號會影響 gcc 嵌入到二進製文件中的建構 ID。建構 ID 是已編譯二進製文件的雜湊,包括調試數據。

所以最終結果是發布的二進製文件包含兩個對調試符號的承諾,但實際上並不包含它們本身。

您可以在此處閱讀有關這些單獨調試文件的更多資訊:https ://sourceware.org/gdb/onlinedocs/gdb/Separate-Debug-Files.html

這個問題的癥結在於,最近 gitian 建構的調試符號與為原始版本生成的調試符號不同。這意味著我們在其中找到的建構 ID 和調試符號校驗和bitcoind都是不同的。這會導致bitcoind雜湊值不同(以及所有其他二進製文件)。當然,這會導致 tarfile 雜湊值不同。


這是 diffoscope 生成的二進製文件的差異:

--- bitcoind
+++ /mnt/archive/bitcoin/bitcoin-binaries/0.20.1/bitcoin-0.20.1/bin/bitcoind
├── readelf --wide --notes {}
│ @@ -1,15 +1,15 @@
│  
│  Displaying notes found in: .note.ABI-tag
│    Owner                Data size     Description
│    GNU                  0x00000010    NT_GNU_ABI_TAG (ABI version tag)        OS: Linux, ABI: 3.2.0
│  
│  Displaying notes found in: .note.gnu.build-id
│    Owner                Data size     Description
│ -  GNU                  0x00000014    NT_GNU_BUILD_ID (unique build ID bitstring)     Build ID: 6b464617f7f91fd270ac86f43ef4a58eeeedff19
│ +  GNU                  0x00000014    NT_GNU_BUILD_ID (unique build ID bitstring)     Build ID: 3a439a31a5157ff7052ed310050df5643a02ea3f
│  
│  Displaying notes found in: .note.stapsdt
│    Owner                Data size     Description
│    stapsdt              0x00000036    NT_STAPSDT (SystemTap probe descriptors)        Provider: libstdcxx
│      Name: throw
│      Location: 0x00000000006e550d, Base: 0x000000000086d140, Semaphore: 0x0000000000000000
│      Arguments: 8@%rdi 8@%rsi
├── readelf --wide --decompress --hex-dump=.gnu_debuglink {}
│ @@ -1,5 +1,5 @@
│  
│  Hex dump of section '.gnu_debuglink':
│    0x00000000 62697463 6f696e64 2e646267 00000000 bitcoind.dbg....
│ -  0x00000010 b25ceebb                            .\..
│ +  0x00000010 114d519d                            .MQ.

如您所見,這裡只有兩個不同之處,一個在建構 ID 中,一個在.gnu_debuglink節中。從我之前連結的文件中,我們可以看到該.gnu_debuglink部分的第一行是調試文件名,後跟足夠的 0 字節以填充到 4 字節邊界。第二行是 4 字節 CRC 校驗和。正是這個 CRC 校驗和不同。

那麼為什麼這裡的調試符號不同呢?同樣,diffoscope 可以幫助我們一點。

--- bitcoind.dbg
+++ /mnt/archive/bitcoin/bitcoin-binaries/0.20.1/bitcoin-0.20.1/bin/bitcoind.dbg
├── readelf --wide --notes {}
│ @@ -1,15 +1,15 @@
│  
│  Displaying notes found in: .note.ABI-tag
│    Owner                Data size     Description
│    GNU                  0x00000010    NT_GNU_ABI_TAG (ABI version tag)        OS: Linux, ABI: 3.2.0
│  
│  Displaying notes found in: .note.gnu.build-id
│    Owner                Data size     Description
│ -  GNU                  0x00000014    NT_GNU_BUILD_ID (unique build ID bitstring)     Build ID: 6b464617f7f91fd270ac86f43ef4a58eeeedff19
│ +  GNU                  0x00000014    NT_GNU_BUILD_ID (unique build ID bitstring)     Build ID: 3a439a31a5157ff7052ed310050df5643a02ea3f
│  
│  Displaying notes found in: .note.stapsdt
│    Owner                Data size     Description
│    stapsdt              0x00000036    NT_STAPSDT (SystemTap probe descriptors)        Provider: libstdcxx
│      Name: throw
│      Location: 0x00000000006e550d, Base: 0x000000000086d140, Semaphore: 0x0000000000000000
│      Arguments: 8@%rdi 8@%rsi
├── readelf --wide --debug-dump=info {}
│┄ error from `readelf --wide --debug-dump=info {}`:
│┄ readelf: Error: /build/binutils/src/binutils-gdb/binutils/dwarf.c:1989: read LEB value is too large to store in destination variable
│┄ readelf: Error: /build/binutils/src/binutils-gdb/binutils/dwarf.c:1989: read LEB value is too large to store in destination variable
│┄ readelf: Error: /build/binutils/src/binutils-gdb/binutils/dwarf.c:1989: read LEB value is too large to store in destination variable
│┄ readelf: Error: /build/binutils/src/binutils-gdb/binutils/dwarf.c:1989: read LEB value is too large to store in destination variable
│┄ readelf: Error: /build/binutils/src/binutils-gdb/binutils/dwarf.c:1989: read LEB value is too large to store in destination variable
│ @@ -85052,36 +85052,36 @@
│      &lt;29607&gt;   DW_AT_decl_line   : 124
│      &lt;29608&gt;   DW_AT_decl_column : 16
│      &lt;29609&gt;   DW_AT_type        : &lt;0x28761&gt;
│      &lt;2960d&gt;   DW_AT_data_member_location: 12
│   &lt;2&gt;&lt;2960e&gt;: Abbrev Number: 30 (DW_TAG_member)
│      &lt;2960f&gt;   DW_AT_name        : (indirect string, offset: 0x13aaf): __kind
│      &lt;29613&gt;   DW_AT_decl_file   : 108
│ -    &lt;29614&gt;   DW_AT_decl_line   : 148
│ +    &lt;29614&gt;   DW_AT_decl_line   : 128
│      &lt;29615&gt;   DW_AT_decl_column : 7
│      &lt;29616&gt;   DW_AT_type        : &lt;0x287a6&gt;
│      &lt;2961a&gt;   DW_AT_data_member_location: 16
│   &lt;2&gt;&lt;2961b&gt;: Abbrev Number: 30 (DW_TAG_member)
│      &lt;2961c&gt;   DW_AT_name        : (indirect string, offset: 0x7a535): __spins
│      &lt;29620&gt;   DW_AT_decl_file   : 108
│ -    &lt;29621&gt;   DW_AT_decl_line   : 154
│ +    &lt;29621&gt;   DW_AT_decl_line   : 134
│      &lt;29622&gt;   DW_AT_decl_column : 3
│      &lt;29623&gt;   DW_AT_type        : &lt;0x2879a&gt;
│      &lt;29627&gt;   DW_AT_data_member_location: 20
...

還有很多我沒有包括在內的輸出,因為它們幾乎都是一樣的。

現在這不是很有幫助,但我們可以看到,對於一堆函式,該函式的行號相差 20 行。

為了獲得更多資訊,我使用了 dwarfdump。這就是我在 diffoscope 中展示的兩個函式的新版本(函式是 __kind 和 __spins)。

0x0002960e:     DW_TAG_member
                 DW_AT_name    ("__kind")
                 DW_AT_decl_file       ("/usr/include/x86_64-linux-gnu/bits/thread-shared-types.h")
                 DW_AT_decl_line       (148)
                 DW_AT_decl_column     (0x07)
                 DW_AT_type    (0x000287a6 "int")
                 DW_AT_data_member_location    (0x10)

0x0002961b:     DW_TAG_member
                 DW_AT_name    ("__spins")
                 DW_AT_decl_file       ("/usr/include/x86_64-linux-gnu/bits/thread-shared-types.h")
                 DW_AT_decl_line       (154)
                 DW_AT_decl_column     (0x03)
                 DW_AT_type    (0x0002879a "short int")
                 DW_AT_data_member_location    (0x14)

從給定的文件名可以看出,這些函式來自安裝到系統的庫。這些似乎是 gcc 實現 c++ stdlib 的標頭。


所以發生的事情是 libstdc++ 已經在 Ubuntu 中更新了。無論發生什麼更新,Bitcoin Core 在使用 c++ stdlib 時都包含了一些標頭檔中的一些程式碼。反過來,使用這些更新的標頭檔進行編譯會產生不同的調試符號,因為函式聲明已移至這些標頭檔中。這會導致 gcc 為調試符號計算不同的建構 ID 和不同的 CRC 校驗和。這最終導致最終的二進製文件略有不同,從而導致雜湊不匹配。

引用自:https://bitcoin.stackexchange.com/questions/99967