Автор статьи — Джеймсон Лопп, технический директор биткоин-стартапа Casa и один из разработчиков Bitcoin Core.
Как я уже неоднократно отмечал в прошлом, использование полного узла (или ноды) биткоина обеспечивает самый высокий уровень безопасности и конфиденциальности пользователя. Год назад я провел всестороннее сравнение различных реализаций, чтобы узнать, насколько хорошо они выполняют свою работу. Теперь пришло время посмотреть, что изменилось за последний год!
Компьютер, который использовался в этом тестировании, я купил в начале 2018 года — в то время он стоил около $2000.
Обратите внимание, что ни одна реализация биткоина по умолчанию не проверяет всю историю блокчейна. Для лучшей производительности большинство из них не проверяют подписи дальше определенного момента времени (обычно проверяются подписи за год или два). Это делается исходя из предположения, что если на последних блоках был собран год или больше доказательств выполнения работы, то маловероятно, что вам выдадут подписи, которые еще никто не проверял, а если это так, то это глубокая ошибка и правила безопасности, лежащие в основе системы, могут быть скомпрометированы.
Для целей этих тестов мне нужно контролировать как можно больше переменных, и некоторые реализации могут пропустить проверку подписей в течение более длительного периода времени в блокчейне, чем другие. Поэтому тесты, которые я запускаю, не используют настройки по умолчанию — я изменяю один параметр, чтобы принудительно проверять все подписи транзакций, и часто настраиваю другие параметры, чтобы использовать большее количество ядер ЦП и объем ОЗУ на моем компьютере.
Bcoin master
Синхронизация полной ноды Bcoin master (коммит 77d8804) на блоке 601 300 выполнена за 18 часов 29 минут.
Если вы читали прошлогодний отчет, вы можете вспомнить, что мне пришлось повозиться с Bcoin — я пробовал синхронизироваться около десяти раз, прежде чем смог найти правильные параметры, которые не приводили бы к тому, что процесс NodeJS прерывался и зависал. С тех пор команда Bcoin внесла ряд улучшений по синхронизации.
Моя конфигурация:
- checkpoints:false
- cache-size:10000
- sigcache-size:1000000
- max-files:5000
Bitcoin Core 0.19
Синхронизация Bitcoin Core 0.19 от генезис-блока до блока 601 300 заняла 399 минут с assumevalid = 0 на моем компьютере. Узким местом продолжает оставаться процессор.
Как обычно, тестирование Bitcoin Core было простым. Я не думаю, что Core станет намного быстрее, потому что они выжали из ПО как можно большую производительность.
Моя конфигурация:
- assumevalid = 0
- DbCache = 24000
- maxmempool = 1000
BTCD v0.20.0 beta
Полная синхронизация btcd v0.20.0-beta с блоком 601,300 заняла 3 дня, 3 часа, 12 минут. Время зависит от скорости процессора.
BTCD считался мертвым проектом, который не обновлялся в течение 4 лет с тех пор, как разработчики оставили его для работы над Decred. Олаолува Осунтокун взял бразды правления в качестве основного мейнтейнера, вероятно потому, что он работал над ним много лет назад, а теперь использует BTCD в качестве библиотеки. Они добавили лучшее обнаружение задержки и более быстрый анализ pubkey после прошлогоднего теста.
Моя конфигурация:
- nocheckpoints = 1
- sigcachemaxsize = 1000000
Gocoin 1.9.7
Полная синхронизация Gocoin 1.9.7 до блока 601 300 с включенной библиотекой secp256k1 заняла 19 часов 56 минут. Нагрузка на ЦП оставалась стабильной (на уровне 50%) и никакие другие ресурсы не были максимально использованы.
Прочитав документацию, я внес следующие изменения, чтобы добиться максимальной производительности:
Установил библиотеку secp256k1 и собрал gocoin с помощью sipasec.go.
Отключен функционал кошелька через AllBalances.AutoLoad:false
Моя конфигурация:
- LastTrustedBlock: 00000000839a8e6886ab5951d76f411475428afc90947ee320161bbf18eb6048;
- AllBalances.AutoLoad:false;
- UTXOSave.SecondsToTake:0.
Gocoin все еще довольно быстр по сравнению с конкурентами, но я не думаю, что он синхронизировался так быстро, как мог бы. На ранних блоках загрузка моего процессора составляла около 20% и никогда не превышала 50%. Я подозреваю, что это может быть связано с тем, что я не использую гиперпоточность — на моей машине 6 физических, но 12 виртуальных процессоров. Я пытался увеличить количество пиров с 10 до 20 и улучшил переход с 1.11 до 1.13, но это не привело к существенному улучшению эффективности. С другой стороны, у Gocoin лучшая админ-панель их всех реализаций.
Libbitcoin Node 3.6.0
Полная синхронизация Libbitcoin Node 3.6.0 на блоке 601 300 заняла 27 часов 37 минут с 10 000 кешем UTXO.
Libbitcoin Node был не так уж и плох — самая сложная часть заключалась в удалении жестко запрограммированных контрольных точек блоков. Для этого мне пришлось клонировать репозиторий git, извлечь ветку «version3», удалить все контрольные точки (кроме genesis) из bn.cfg и запустить скрипт install.sh, чтобы скомпилировать узел и его зависимости.
Моя конфигурация:
- [database]
- cache_capacity = 100000
- [node]
- block_latency_seconds = 5
Я заметил, что в ходе синхронизации Libbitcoin записал 3 ТБ и прочитал более 30 ТБ на диск и с диска. Общее количество записи выглядит разумным, но общее количество операций чтения намного выше, чем в других реализациях. Можно улучшить кэширование; к концу синхронизации использовалось только 5 ГБ оперативной памяти. Был также ряд коротких пауз, когда казалось, что узел не работает; предположительно, очередь блоков для обработки время от времени простаивала.
Parity Bitcoin master
Полная проверка Parity Bitcoin (коммит 7fb158d) на блоке 601 300 на моем компьютере для тестирования заняла 2 дня, 2 часа, 10 минут.
Parity — интересная реализация, в которой хорошо проработано управление пропускной способностью. Загрузка ЦП остается ниже 50%, возможно, из-за отсутствия поддержки гиперпоточности, но она использовал большую часть кэша, который я сделал доступным — 21 ГБ из 24 ГБ, которые я выделил! Реальным узким местом является дисковый ввод-вывод — по какой-то причине он постоянно набирает 100 MB/s при чтении и записи на диск, хотя добавляет только около 2 MB/s данных блокчейна. Странно, что такая большая активность на диске выполняется несмотря на 21 ГБ кеша.
Вероятно, во внутренней базе данных Parity (RocksDB) есть некоторые недостатки, которые создают эту проблему. В прошлом у меня были проблемы с RocksDB при работе с узлом эфириума в Parity и при работе с узлами Ripple. RocksDB был настолько плох, что Ripple фактически написала свою собственную базу данных под названием NuDB.
Моя конфигурация:
- btc
- db-cache 24000
- verification-edge 00000000839a8e6886ab5951d76f411475428afc90947ee320161bbf18eb6048
Stratis 3.0.5
Синхронизация узла Stratis вызывает разочарование. Через 4 дня и 3 часа был достигнут только блок 428 002, а затем процесс завис из-за нехватки памяти на диске. Оказывается, что узел не удаляет UTXO с диска, когда они потрачены. 77 ГБ блоков и 632 ГБ UTXO!
Stratis — это альткоин, который имеет многие атрибуты биткоина, хотя работает на Proof-of-Stake и призван стать платформой для других блокчейнов через сайдсейны. Разработчики Stratis создали свою собственную реализацию нолной ноды, написанную на C# (поддерживает Stratis и биткоин).
Моя конфигурация:
- assumevalid = 0
- контрольные точки = 0
- maxblkmem = 1000
Я также заметил одну вещь: похоже, что кэш UTXO жестко запрограммирован на 100 000 UTXO — если бы был способ увеличить это, вы могли бы получить чуть лучшую производительность. Я спросил об этой функции и разработчики Stratis добавили ее через час! Тем не менее, процессор остается узким местом на сегодняшний день — как только он смог достичь 300 000 блока, обработка замедлилась до пары блоков в секунду, хотя очередь обрабатываемых блоков была заполнена и работа диска была незначительной. Часто использовалось только 1 из моих 12 ядер, поэтому похоже, что есть много возможностей для улучшения распараллеливания.
К сожалению, критической нерешенной проблемой является то, что их база данных UTXO, по-видимому, фактически не удаляет UTXO, и вам потребуется несколько терабайт дискового пространства по сравнению с большинством современных реализаций биткоина, которые используют менее 300 ГБ. Таким образом, я не смог завершить синхронизацию, потому что на моем компьютере всего 1 ТБ.
Результаты
- Bitcoin Core 0.19: 6 часов, 39 минут;
- Bcoin: 18 часов, 29 минут;
- Gocoin 1.9.7: 19 часов, 56 минут;
- Libbitcoin Node 3.2.0: 1 день, 3 часа, 37 минут;
- Parity Bitcoin: 2 дня, 2 часа, 10 минут;
- BTCD v0.20.0-beta: 3 дня, 3 часа, 12 минут;
- Stratis 3.0.5.0: Синхнонизация не была завершена; определенно больше недели.
Разница с прошлогодними тестами
Мы видим, что для большинства реализаций требуется больше времени для синхронизации, что вполне ожидаемо, учитывая саму природу блокчейна. Обратите внимание, что общий размер блокчейна вырос на 30% со времени моего последнего тестирования, поэтому ожидается, что реализация без существенных улучшений производительности должна занять на 30% больше времени для синхронизации.
- Bcoin: -9 часов, 2 минуты (на 44% короче);
- BTCD: -20 часов (на 27% короче);
- Bitcoin Core 0.19: +1 час, 28 минут (на 28% дольше);
- Parity: +11 часов, 53 минуты (на 31% больше);
- Libbitcoin Node 3.2.0: +7 часов, 13 минут (на 35% больше);
- Gocoin 1.9.7: +7 часов, 24 минуты (на 59% больше).
Как мы видим, Bcoin и BTCD улучшили производительность, в то время как у Gocoin есть существенная проблема, которая ухудшает производительность по мере роста блокчейна.
Хотя я запускал каждую реализацию на одном и том же оборудовании, чтобы создать равные условия для тестирования, существуют и другие факторы.
Так, нет никаких гарантий, что мой провайдер работал одинаково на протяжении всех синхронизаций. Также некоторые реализации могут подключаться к узлам с большей пропускной способностью — это может произойти случайно или из-за лучшей логики управления сетью в некоторых реализациях. Не все реализации имеют кэширование; даже если доступны настраиваемые параметры кэширования, это не всегда тот же тип кэширования.
Не все узлы выполняют одинаковые функции индексации. Например, Libbitcoin Node всегда индексирует все транзакции по хешу — это присуще структуре базы данных. Таким образом, эта синхронизация узлов более сопоставима с Bitcoin Core с включенной опцией индексации транзакций.
Синхронизация также может варьироваться в зависимости от количества других переменных, таких как операционная система и производительность файловой системы.
Заключение
Учитывая, что самая надежная модель безопасности, которую пользователь может получить в публичном блокчейне, — это полная проверка всей его истории, я думаю, что важно отслеживать ресурсы, которые необходимы для выполнения этой задачи.
Мы знаем, что из-за природы блокчейна объем данных, который должен быть проверен новым узлом, будет неуклонно расти со временем. Пока что тесты, которые я запускаю, проводятся на одном и том же оборудовании каждый год, но, с другой стороны, мы знаем, что производительность оборудования также будет увеличиваться с каждым годом.