Как я восстановил wallet.dat который выдавал ошибку чтения

Предисловие. Я не программист, не системный администратор, мои познания о базах данных минимальны, но я смог восстановить свой поломанный wallet.dat. И поэтому опишу здесь порядок действий простыми словами, которые сможет понять рядовой пользователь.

Я искал решение около 3-х дней, перечитал множество статей на форумах, многочисленные ветки на github о работе zcashd. Узнал, что такое база данных Berkeley DB и многое другое. Но тем не менее, я не нашёл ни одной инструкции по восстановлению кошелька, а переписки на форумах в поисках решений, которые я встретил, заканчивались ничем.

Разработчик ZecWallet в переписке сообщил мне, что при тех ошибках, которые я получал, это сделать в принципе невозможно. Но логика подталкивала искать.

Я очень мало спал, но очень рад что у меня всё получилось. Надеюсь, мой опыт поможет кому-то в подобной неприятной ситуации.

:warning:Внимание! В первую очередь сделайте несколько резервных копий вашего wallet.dat (или переименованного wallet.000000.bak) – как его найти, написал ниже. Скопируйте его в резервные каталоги или на флэшку. Без этого файла ничего не получится. Прочитайте весь текст до конца и уже потом производите любые манипуляции с кошельком. :warning:

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. :fearful:

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://docs.zecwallet.co/troubleshooting/
https://zcash.readthedocs.io/en/latest/rtd_pages/wallet_backup.html

Почему «условно актуально»? Потому что некоторые из текущих версий ZecWallet FullNode могут не содержать отдельных исполнительных файлов:
Zcashd.exe
zcash-cli.exe

Кроме того, не всегда вы сможете найти документацию для вашей операционной системы, поскольку она написана в первую очередь для людей понимающих архитектуру взаимодействия. И как правило средой разработки является Linux – не самая популярная операционная система среди рядовых юзеров, согласитесь. Также это связано с тем, что официальный кошелёк долгое время существовал только под линукс.

Я не буду дублировать документацию. Напишу лишь, что попытки восстановления должны начинаться с простых команд в командной строке с исполняющим клиентом zcashd, документация здесь - https://docs.zecwallet.co/troubleshooting/#via-an-external-zcashd

Команды:

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 - https://github.com/ZcashFoundation/zecwallet/releases/tag/v0.8.3

Также рекомендуется удалить папку с параметрами, для того чтобы в случае выхода этих баз данных из строя, кошелёк смог установить заново:
• 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. Нестандартный метод восстановления

Я добрался до самого интересного места, ради которого и написал этот длинный пост.
Даже прочитав безнадёжные прогнозы, моя логика говорила мне: Ок, даже если мой текущий файл был нарушен, то бэкап? Почему не подгружается бэкап? :thinking:

  • я создавал бэкап в здравом рассудке и трезвой памяти;
  • я отчётливо помню, как я это делал;
  • я делал его стандартным функционалом 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).
И это была зацепка. :smirk:

Итак, первое что нужно сделать это скачать исходники для работы в среде для баз данных Berkeley, они лежат тут - https://www.oracle.com/database/technologies/related/berkeleydb-release-history.html

Я выбрал ближайший релиз к версии 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.

Не буду утомлять рассказом обо всех безуспешных попытках, напишу конкретно команды, которые помогли мне, и я надеюсь помогут и вам.

Их всего три:

После установки пакета 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» - уже можете посылать кого-нибудь за вином :champagne:

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

После реиндексации вы увидите свои балансы :wink:

Вот такая, действительно не хитрая операция каким то образом поправляет структуру wallet.dat, который в результате замечательно читается zcashd и даже немного теряет в весе.

:no_entry: Если db_verify не выдаст успешный результат, это значит что ваш кошелёк действительно серьёзно повреждён. В таком случае попробуйте команду https://www.mankier.com/1/db_recover
На форумах программистов 1С (1С, Карл - я даже там был) я прочитал, что эта команда помогает поправить таблицы.

6. Заключение.

После длительных мытарств и восстановления своего кошелька я смог испытать очень приятные чувства облегчения и радости.

И если вы тоже их почувствуете, можете дать мне знать об этом:

zs1f2hlu6vzl65256mr0k2nh3n49wtrtj2vvalathwvzxt9asn6v0xtda2nfwgukvaaeuvcq3gpzqv
Спасибо!

PS чтобы не сталкиваться со всем этим головняком,

  1. Рекомендую для транзакций использовать ZecWallet Lite - https://www.zecwallet.co/#download
    потому что в отличие от FullNode:
    • Он имеет seed-фразу восстановления, по которой вы восстановите все свои созданные адреса, а не только те, которые у вас были на момент бэкапа кошелька;
    • не заставит вас проводить многочасовую переиндексацию в случае неправильного завершения работы;
    • позволяет зашифровать ваш wallet.dat

  2. Всегда вытягивайте приватные ключи из FullNode, если всё-таки хотите иметь его.

2 Likes