Воспроизводимые сборки Gitian... но не тот хеш, что у bitcoincore.org

Bitcoincore.org и Bitcoin.org позволят вам загрузить tar-архив для биткойнов версии 0.20.1.

Когда они это делают

биткойнд: 4ec74161b2a90293926ae8e20a2efbe952bd23b53aeebf051e6a6285ace18271
биткойн-0.20.1-x86_64-linux-gnu.tar.gz: 376194f06596ecfa40331167c39bc70c355f960280bd2a645fdbf18f66527397

Они также говорят:

Воспроизведение двоичного файла для себя предоставит вам самый высокий уровень гарантии, доступный в настоящее время.

Итак, похоже, что текущий метод сделать это - это маневр «гигантской сборки».

когда я это делаю

биткойнд: c5fb850ed9e6afa0af5653e743084912c9bd71fb233acfe2d72738fc319f2181
биткойн-0.20.1-x86_64-linux-gnu.tar.gz: 277599356bd2df760832c6636797fe5ea5a5c28d929d53635b685f5ac1e4689b

Прошел процесс gitian с Ubuntu 20.04 и Debian 10 . Оба выдали одно и то же неверно? tarball, 2 разные настройки/ 2 операционные системы, один и тот же tarball.

Оба моих файла утверждений загружены здесь для Debian и Ubuntu. https://github.com/miketwenty1/images/tree/master/bad_asserts


Как плебс я могу думать 1 из 2 вещей..

Что-то не так с некоторыми моими пакетами/версиями/env/OS/setup ИЛИ Все верификаторы лгут, а биткойн скомпрометирован. Помогите мне сузить возможности.

Я хотел бы правильно выполнить это упражнение и воспроизвести те же двоичные файлы... но не знаю, как лучше двигаться вперед... каковы следующие шаги для проверки сборки для версии 0.20.1? Я не могу воспроизвести архив, рекламируемый на bitcoincore. орг и биткойн. орг. Однако я могу сделать воспроизводимую сборку, что заставляет меня сомневаться во многих вещах.

Было бы здорово, если бы кто-нибудь мог пройти этот процесс с нуля и посмотреть, смогут ли они создать те же архивы, которые эти люди видели в этом репо. 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

К вашему сведению, сообщил о проблеме на github.com/bitcoin/bitcoin/issues/20389 .

Ответы (2)

Я сделал перестройку 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 встраивает в двоичный файл. Идентификатор сборки — это хэш скомпилированного двоичного файла, включая данные отладки.

Таким образом, конечным результатом является то, что опубликованный двоичный файл содержит два обязательства по символам отладки, но на самом деле не содержит их сам.

Подробнее об этих отдельных файлах отладки можно прочитать здесь: https://sourceware.org/gdb/onlinedocs/gdb/Separate-Debug-Files.html.

Суть этой проблемы в том, что символы отладки из последних сборок gitian отличаются от символов отладки, созданных для исходного выпуска. Это означает, что идентификатор сборки и контрольная сумма символа отладки, которые мы находим внутри, 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.

Так почему же символы отладки здесь отличаются? Опять же, диффоскоп может нам немного помочь.

--- 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 библиотеки С++ stdlib.


Итак, произошло обновление libstdc++ в Ubuntu. Какие бы обновления ни произошли, часть кода была перемещена в некоторые заголовочные файлы, которые Bitcoin Core включает в использование C++ stdlib. В свою очередь, компиляция с этими обновленными заголовками приводит к другим символам отладки, поскольку объявления функций были перемещены в эти файлы заголовков. Это приводит к тому, что gcc вычисляет другой идентификатор сборки и другую контрольную сумму CRC для символов отладки. Это, наконец, приводит к тому, что окончательные двоичные файлы немного отличаются, что приводит к несоответствию хэшей.

Меня интересует выбор guix вместо Nix — есть ли у вас ссылка на какое-либо обсуждение на irc, github и т. д. о том, почему был выбран guix?
@RaghavSood Из github.com/bitcoin/bitcoin/pull/15277 : «Guix — это менеджер транзакционных пакетов, очень похожий на Nix, но в отличие от Nix, он больше ориентирован на загрузку и воспроизводимость, которые привлекательны для чувствительных к безопасности проектов, таких как биткойн. ." Я не думаю, что было много дискуссий о guix против nix, просто guix — это то, во что кто-то приложил усилия, так что это то, что мы получаем.
Спасибо за подробную информацию. Если это интересно, у меня есть вывод cmp, сравнивающий оба файла bitcoind. github.com/devrandom/gitian-builder/issues/235 Luke-jr дайте мне знать, что файлы, которые, как он выглядел, были под вопросом: как предполагалось?
Это конструктивный недостаток системы gitian, но система gitian также работает, как задумано.

Пока базовый образ ОС восприимчив к изменениям, вы не получите воспроизводимую систему сборки, гарантирующую воспроизводимость в течение длительного периода времени. Если ОС может обновлять цепочки инструментов компилятора, версии libc и любые инструменты, используемые во время сборки gitian, в будущем ожидаются изменения в выводе. Поскольку это так, поскольку gitian основан на Ubuntu, а исправления все еще поставляются для более старых версий Ubuntu, этого следует ожидать через некоторое время.