Предисловие. Я не программист, не системный администратор, мои познания о базах данных минимальны, но я смог восстановить свой поломанный wallet.dat. И поэтому опишу здесь порядок действий простыми словами, которые сможет понять рядовой пользователь.
Я искал решение около 3-х дней, перечитал множество статей на форумах, многочисленные ветки на github о работе zcashd. Узнал, что такое база данных Berkeley DB и многое другое. Но тем не менее, я не нашёл ни одной инструкции по восстановлению кошелька, а переписки на форумах в поисках решений, которые я встретил, заканчивались ничем.
Разработчик ZecWallet в переписке сообщил мне, что при тех ошибках, которые я получал, это сделать в принципе невозможно. Но логика подталкивала искать.
Я очень мало спал, но очень рад что у меня всё получилось. Надеюсь, мой опыт поможет кому-то в подобной неприятной ситуации.
Внимание! В первую очередь сделайте несколько резервных копий вашего wallet.dat (или переименованного wallet.000000.bak) – как его найти, написал ниже. Скопируйте его в резервные каталоги или на флэшку. Без этого файла ничего не получится. Прочитайте весь текст до конца и уже потом производите любые манипуляции с кошельком.
1. В начале определимся о какой ошибке идёт речь, как я её получил и как понять, что у вас именно она.
Как я её получил. Те, кто использует кошелёк ZecWallet FullNode возможно сталкивались с ситуацией, когда обновление блоков по каким-то причинам останавливается и что бы вы не делали кошелёк будет выдавать ошибку соединения до тех пор, пока вы не сделаете переиндексацию.
Я использую ZecWallet FullNode на MAC OS и после версии 9.1 обратил внимание, что из самой программы сделать реиндекс стало невозможно, поскольку соответствующую вкладку с данной функцией убрали после версии 8.3.
Я держал версию 8.3 чтобы при необходимости сделать переиндексацию из неё, в понятном графическом интерфейсе (ещё неделю назад я даже не знал как запустить zcashd вручную с атрибутами из терминала MAC OS).
После очередной проблемной ситуации (возможно мой macbook разрядился и погас с включённым кошельком), мне следовало вновь провести реиндексацию, но этот процесс настолько длителен (у меня он занимает точно более 14 часов), что я решил просто заменить папки blocks и chainstate в директории: ~/Library/Application Support/Zcash/
У меня всегда открыта полная нода на ПК под управлением Windows и я ранее делал такой финт, который решал проблему соединения – но в этот раз что то пошло не так…
Версия FullNode 8.3 (старый графический интерфейс) – выдавала ошибку:
«zcashd said: Error: wallet.dat corrupt, salvage failed»
Версия FullNode 9.1 и выше (новый графический интерфейс) – выдавала ошибку:
«Failed to start zcashd. Giving up! Please file an issue with Zecwallet»
Перезапуск кошелька происходил как ни в чём небывало, но совершенно с новыми пустыми адресами.
Я описал первичную визуальную симптоматику, теперь о том что при этом происходит внутри папки /Zcash/ которая находится в:
• Windows: %HOMEPATH%\AppData\Roaming\Zcash\debug.log
• macOS: ~/Library/Application Support/Zcash/debug.log
• Linux: ~/.zcash/debug.log
В ней будет находиться ваш повреждённый файл wallet.0000000.bak (цифры любые), который сохраняется с расширением .bak и создаётся новый wallet.dat
Файлы с логами (находятся здесь же) будут содержать следующие записи:
debug.log
020-04-26 05:25:14 Renamed wallet.dat to wallet.1587878714.bak
2020-04-26 05:25:14 CDBEnv::Salvage: Database salvage found errors, all data may not be recoverable.
2020-04-26 05:25:14 Salvage(aggressive) found no records in wallet.1587878714.bak.
db.log
BDB2506 file unknown has LSN 448/450072, past end of log at 1/204362
BDB2507 Commonly caused by moving a database from one database environment
BDB2508 to another without clearing the database LSNs, or by removing all of
BDB2509 the log files from a database environment
BDB0522 Page 0: metadata page corrupted
BDB0523 Page 0: could not check metadata page
wallet.dat: BDB0090 DB_VERIFY_BAD: Database verification failed
BDB2506 file unknown has LSN 448/450072, past end of log at 1/205410
BDB2507 Commonly caused by moving a database from one database environment
BDB2508 to another without clearing the database LSNs, or by removing all of
BDB2509 the log files from a database environment
wallet.1587877729.bak: BDB0090 DB_VERIFY_BAD: Database verification failed
2. Осознание проблемы
Вообще до этого момента ситуация меня не тревожила. Я предполагал, что walled.dat мог подвергнутся какой-то неудачной операции, которая его повредила, но у меня на этот случай был бэкап wallet.dat давностью 1 месяц, который содержал все мои активные адреса. Я создал его через стандартную функцию в графическом интерфейсе FullNode 8.3 и записал на диск.
Я скопировал свой бэкап в папку \Zcash простой заменой, заранее сохранив поломанную версию. Забегая вперёд, я напишу, что смог восстановить и поломанную версию тоже - его сохраняем обязательно, ведь бэкапа у вас может и не быть.
После перезапуска ZecWallet ошибка никуда не ушла. Мой бэкап точно также не принимался кошельком и внутренний обработчик zcashd записывал в логи все те же ошибки.
Логичным действием было переименовать папку Zcash во временную, деинсталлировать все кошельки, стереть все папки с внутренними данными кошелька, переустановить всё заново, загрузить бэкап по новой и переиндексировать всю базу.
Я так и поступил – никакого результата, оба мои wallet.dat и «повреждённый» и бэкап не принимались zcashd и вновь и вновь выдавали ошибку: Salvage: Database salvage found errors, all data may not be recoverable.
3. Возможные причины
Я обратил внимание, что оба мои файла wallet.dat имели необычно большой вес для подобных файлов, не то чтобы у меня было много транзакций на моих адресах, но мой Z-адрес был указан в списках на сервисе zecpages.com и поэтому я регулярно получал рассылку с большим объёмом зашифрованной информации в memo-полях.
Поскольку wallet.dat содержит в себе всю информацию о всех произведённых транзакциях на адресах, а также информацию, полученную в memo-полях, то его объём значительно прирастал с каждым днём. Сервис zecpages.com был запущен в феврале. Так вот, мой бэкап на 22 марта wallet.dat весил 15,6 Мб, а повреждённая версия от 23 апреля составляла уже 36 Мб. И это, как мне кажется, повод задуматься. Справедливости ради отмечу, что поток инфы в рассылках был большим: 5-8 нагруженных информацией сообщений ежедневно в виде z2z-транзакций.
Я не могу назвать это в качестве причины, по крайней мере мой текущий восстановленный wallet.dat также имеет вес более 36 Мб и это не мешает ему подгружаться на вновь установленный кошелёк. Тем не менее это подтолкнуло меня на мысль, что резервные копии wallet.dat не являются надёжным способом резервирования. Об этом я напишу в PS.
4. Стандартные методы восстановления.
Итак, с симптоматикой разобрались, теперь опишу стандартные рекомендуемые методы восстановления, которые мне никак не помогли.
Существует документация, которая описывает различные атрибуты и команды для исполнительных файлов – клиентов, позволяющих ноде взаимодействовать с сетью (блокчейном), получать и отправлять команды и производить операции с базами данных.
Информация с условно актуальной документацией находится здесь –
https://zcash.readthedocs.io/en/latest/rtd_pages/wallet_backup.html
Почему «условно актуально»? Потому что некоторые из текущих версий ZecWallet FullNode могут не содержать отдельных исполнительных файлов:
Zcashd.exe
zcash-cli.exe
Кроме того, не всегда вы сможете найти документацию для вашей операционной системы, поскольку она написана в первую очередь для людей понимающих архитектуру взаимодействия. И как правило средой разработки является Linux – не самая популярная операционная система среди рядовых юзеров, согласитесь. Также это связано с тем, что официальный кошелёк долгое время существовал только под линукс.
Я не буду дублировать документацию. Напишу лишь, что попытки восстановления должны начинаться с простых команд в командной строке с исполняющим клиентом zcashd, документация здесь - Troubleshooting Issues - ZecWallet Docs
Команды:
zcashd -rescan
zcashd -reindex
zcashd -salvage
Как запускаются:
Windows
cmd /C ““C:\Program Files (x86)\zecwallet\zcashd.exe” -rescan”
MacOS
В Finder открываете программы, находите ZecWallet FullNode, правой кнопкой вызываете контекстное меню, «Показать содержимое пакета», внутри заходите в “Contnets”, и там в “Mac OS”. Открываете окно терминала, перетаскиваете туда zcashd, добавляете атрибут команды, например, -reindex
Кстати, если вы его не найдёте в текущей версии ZecWallet FullNode, то качайте специальные версии, в котором он точно есть, два варианта:
Zecwallet Special Build (master branch zcashd) - https://www.zecwallet.co/masterzcashd.html
ZecWallet FullNode v.0.8.3 - Release zcashd update · ZcashFoundation/zecwallet · GitHub
Также рекомендуется удалить папку с параметрами, для того чтобы в случае выхода этих баз данных из строя, кошелёк смог установить заново:
• Windows: %HOMEPATH%\AppData\Roaming\ZcashParams
• macOS: ~/Library/Application Support/ZcashParams/
• Linux: ~/.zcash-params/
Удаляйте целиком папку, не стесняйтесь, её вам восстановит кошелёк автоматически при следующем запуске ZecWallet.
Собственно, на этом весь стандартизированный арсенал средств заканчивается.
Но будьте уверены, в случае если ваш wallet.dat повреждён, то в логах будет одна и та же формулировка «CDBEnv::Salvage: Database salvage found errors, all data may not be recoverable.» и все манипуляции будут производится с вновь созданным wallet.dat, а ваш wallet.dat будет переименован с расширением *.bak (а в некоторых случаях он попросту удаляется в случае неудачного бэкапа поэтому всегда делайте резервную копию).
5. Нестандартный метод восстановления
Я добрался до самого интересного места, ради которого и написал этот длинный пост.
Даже прочитав безнадёжные прогнозы, моя логика говорила мне: Ок, даже если мой текущий файл был нарушен, то бэкап? Почему не подгружается бэкап?
- я создавал бэкап в здравом рассудке и трезвой памяти;
- я отчётливо помню, как я это делал;
- я делал его стандартным функционалом ZecWallet FullNode v.0.8.3;
- нода была полностью синхронизирована;
- бинарная копия этого файла успешно продолжала работать после бэкапа – просто потому, что операция бэкапа это банальный копи-паст wallet.dat с новым именем.
Почему же сейчас zcashd его выплёвывает?
Начал я с банального просмотра текстовым редактором своего резервного wallet.dat
Проматывая туда-сюда этот бессмысленный набор символов, я обнаружил что у файла присутствует чёткая структура. То есть скорее всего он является базой данных.
А поскольку FullNode не поддерживает функцию шифрования - это к тому же незашифрованная база данных.
Не имея понятия как там всё устроено, я предположил, что wallet.dat не всегда является самостоятельной базой данных, где хранятся ключи и транзакции, а взаимодействует именно с той структурой блоков, которая была в момент его актуальности (то есть по состоянию и на дату бэкапа) и в случае если какой-либо процесс незавершён, она сохраняется в некотором «открытом» положении, что в дальнейшем мешает ей выступать в качестве резервной копии.
Таким образом, я подумал, что мне нужно точно узнать момент бэкапа и увидеть в логах какой это был блок, чтобы каким-то образом отмотать на него – впрочем я быстро понял, что это анриал и оставил эту попытку, но благодаря этому я более внимательно изучил все имеющиеся логи.
Среди прочего в логах я увидел строчку
Using BerkeleyDB version Berkeley DB 6.2.23: (March 28, 2016).
И это была зацепка.
Итак, первое что нужно сделать это скачать исходники для работы в среде для баз данных Berkeley, они лежат тут - Oracle Berkeley DB Downloads
Я выбрал ближайший релиз к версии Berkeley DB 6.2.23, это 12cR1 Releases
Berkeley DB 12cR1 (12.1.6.2.38) - https://download.oracle.com/otn/berkeley-db/db-6.2.38_64.msi ссылка для версии Windows 64. Кстати, для скачивания придётся пройти регистрацию на сайте Oracle.
Не буду утомлять рассказом обо всех безуспешных попытках, напишу конкретно команды, которые помогли мне, и я надеюсь помогут и вам.
Их всего три:
-
db_verify (описание - db_verify man page - libdb-utils - General Commands) – позволяет проверить структуру wallet.bak на целостность
-
db_dump (описание - db_dump man page - libdb-utils - General Commands | ManKier) – позволяет декомпилировать wallet.bak
-
db_load (описание - db_load man page - libdb-utils - General Commands | ManKier) – позволяет скомпилировать wallet.dat обратно
После установки пакета Berkeley DB, находится эта радость в папке C:\Program Files\Oracle\Berkeley DB 12cR1 6.2.38\bin
Открываете в этой папке PowerShell (в окне папки Windows в контекстном меню правой кнопкой мыши с прижатым Shift).
Допустим ваш файл называется wallet.bak – переместите его в эту папку \bin где находятся все эти exe-шники, тогда команды с атрибутами будут такие (в терминале PowerShell, будьте внимательнее с расширениями):
db_verify wallet.bak
И если ответ звучит: «BDB5105 Verification of wallet.bak succeeded» - уже можете посылать кого-нибудь за вином
db_dump -f 1.txt wallet.bak
что означает декомпилировать ваш wallet.bak в файл 1.txt
Кстати, открыв его в просмотре вы можете насладится чёткой структурой записей.
db_load -f 1.txt wallet.dat
что означает обратная компиляция wallet.dat из 1.txt
Полученный файл копируйте обратно в папку Zcash (там где у нас хранится структура блоков и логи).
Стартуйте кошелёк, если увидите знакомые адреса, но естественно будет нулевой баланс (поскольку у вас сейчас новая структура файлов), то вы на финишной прямой - делайте реиндекс из командной строки (или терминала MAC OS):
zcashd -reindex
После реиндексации вы увидите свои балансы
Вот такая, действительно не хитрая операция каким то образом поправляет структуру wallet.dat, который в результате замечательно читается zcashd и даже немного теряет в весе.
Если db_verify не выдаст успешный результат, это значит что ваш кошелёк действительно серьёзно повреждён. В таком случае попробуйте команду db_recover man page - libdb-utils - General Commands
На форумах программистов 1С (1С, Карл - я даже там был) я прочитал, что эта команда помогает поправить таблицы.
6. Заключение.
После длительных мытарств и восстановления своего кошелька я смог испытать очень приятные чувства облегчения и радости.
И если вы тоже их почувствуете, можете дать мне знать об этом:
zs1f2hlu6vzl65256mr0k2nh3n49wtrtj2vvalathwvzxt9asn6v0xtda2nfwgukvaaeuvcq3gpzqv
Спасибо!
PS чтобы не сталкиваться со всем этим головняком,
-
Рекомендую для транзакций использовать ZecWallet Lite - Zecwallet Lite - Fully featured Zcash wallet
потому что в отличие от FullNode:
• Он имеет seed-фразу восстановления, по которой вы восстановите все свои созданные адреса, а не только те, которые у вас были на момент бэкапа кошелька;
• не заставит вас проводить многочасовую переиндексацию в случае неправильного завершения работы;
• позволяет зашифровать ваш wallet.dat -
Всегда вытягивайте приватные ключи из FullNode, если всё-таки хотите иметь его.