可重現的 Gitian 建構 .. 但與 bitcoincore.org 的雜湊值不同
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.04和Debian 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://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.dbg
和bitcoin-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 @@ │ <29607> DW_AT_decl_line : 124 │ <29608> DW_AT_decl_column : 16 │ <29609> DW_AT_type : <0x28761> │ <2960d> DW_AT_data_member_location: 12 │ <2><2960e>: Abbrev Number: 30 (DW_TAG_member) │ <2960f> DW_AT_name : (indirect string, offset: 0x13aaf): __kind │ <29613> DW_AT_decl_file : 108 │ - <29614> DW_AT_decl_line : 148 │ + <29614> DW_AT_decl_line : 128 │ <29615> DW_AT_decl_column : 7 │ <29616> DW_AT_type : <0x287a6> │ <2961a> DW_AT_data_member_location: 16 │ <2><2961b>: Abbrev Number: 30 (DW_TAG_member) │ <2961c> DW_AT_name : (indirect string, offset: 0x7a535): __spins │ <29620> DW_AT_decl_file : 108 │ - <29621> DW_AT_decl_line : 154 │ + <29621> DW_AT_decl_line : 134 │ <29622> DW_AT_decl_column : 3 │ <29623> DW_AT_type : <0x2879a> │ <29627> 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 校驗和。這最終導致最終的二進製文件略有不同,從而導致雜湊不匹配。