Bitcoin-платежи: восстановление платёжного сервиса
Счёт, журнал и outbox уже существуют как отдельные модели. Теперь рассмотрим восстановление после сбоя сервиса. Цель — вернуть согласованное наблюдение и доставку, не создавая новые кошельки, новые счета или повторные денежные действия вместо прежних. Быстрый старт процесса ещё не означает восстановление правильного состояния.
В этой главе опишем последовательность для собственной лаборатории regtest. Не останавливаем узел, не копируем действительные кошельки и не выполняем восстановление. Примеры являются паспортом будущей процедуры, в котором явно отмечены исходные данные и пределы знания.
Что требуется сохранить
Для восстановления нужны не только файлы Bitcoin Core. Серверное назначение адресов находится в базе приложения; без него кошелёк может знать деньги, но не знать, какому заказу они относятся. Поэтому сохраняются счета, запросы создания, журнал наблюдений, контрольные точки, решения и задачи outbox.
Отдельно сохраняются профиль сети и версии схемы. Нельзя открыть базу regtest и подключить к ней произвольный mainnet-источник только потому, что интерфейс RPC отвечает. В начале восстановления сравниваем сеть, имя кошелька, выбранный datadir и закреплённые условия лаборатории.
Ключи и кошельковые данные требуют своей процедуры резервирования. Простое копирование живых файлов без документированных гарантий согласованности не является универсальным backup. В справочнике Core описан специальный метод резервирования кошелька; его применение тоже должно быть частью будущего самостоятельного профиля.
Останавливаем новые решения
Пока источник и база не согласованы, публичная карточка показывает режим восстановления и последнее известное состояние. Новая квалификация и автоматическая доставка приостанавливаются. Исторические сведения не стираются, чтобы создать иллюзию пустого чистого старта.
Это не обязательно означает полную недоступность сайта. Каталог и уже разрешённые материалы могут обслуживаться согласно отдельной политике. Главное — не принимать новые денежные решения на основе ещё не проверенного контекста. Режим обслуживания платёжного компонента отделён от статического содержимого библиотеки.
recovery mode
→ verify environment identity
→ restore application data and wallet procedure
→ establish source checkpoint
→ replay observations
→ reconcile outputs and deliveries
→ resume new decisions
Последовательность показывает порядок обязанностей. На каждом этапе сохраняется служебный результат и причина остановки. Если данных недостаточно, процедура не перескакивает сразу к последнему шагу только потому, что посетители ждут.
Восстанавливаем контрольную точку
Берём последний сохранённый checkpoint приложения и сравниваем его с основной веткой источника. Если он сохранился, можно продолжить историю от него. Если он оказался вне текущей цепочки, используется восстановление от общего предка и пересчёт, описанные в четырнадцатом уроке.
При отсутствии необходимых исторических данных выбирается более широкий rescan или другой документированный маршрут. Время такого восстановления зависит от реального окружения; здесь не обещаем количество минут и не подставляем случайный быстрый результат. Предел доступной истории входит в паспорт восстановления.
Повторно полученные выходы применяются по устойчивым ключам. Именно поэтому журнал был идемпотентным. Возврат к старому checkpoint может дать уже известные сведения, но не должен увеличить суммы или создать вторую выдачу курса.
Не восстанавливаем из одной памяти процесса
Программа могла держать последнюю вершину в оперативной памяти и успеть обработать несколько выходов. После падения доверяем только согласованной сохранённой транзакции базы. Если курсор был записан раньше соответствующих данных, этот дефект нужно выявить сверкой и исправить процедуру хранения.
Если часть outbox доставлена внешнему сервису, но ответ не сохранён, задача остаётся с неизвестным результатом. При восстановлении она сверяется по прежнему операционному ключу. Создание нового ключа превратило бы потерянный ответ в вторую выдачу.
Для возврата неизвестное отправление обрабатывается ещё осторожнее. Сначала устанавливается судьба прежнего подписанного результата. Пустая строка результата в базе не даёт разрешения снова отправлять ту же сумму с другой транзакцией.
Разбираем конкретный сбой
Условный выход 30 000 сатоши достиг двух подтверждений. Приложение сохранило квалификацию и outbox, но упало до HTTP-доставки. После восстановления задача остаётся в базе, а журнал подтверждает её происхождение. Обработчик отправляет прежнюю операцию выдачи и фиксирует результат.
В другом варианте HTTP-доставка успела создать доступ, а ответ потерялся. Сверка обнаружит существующее право по тому же ключу и завершит задачу без дублирования. Оба случая восстанавливаются одинаковым намерением, хотя техническая история попыток различается.
Третий вариант сложнее: за время простоя произошла реорганизация. Тогда сначала обновляем денежную проекцию, а уже затем решаем судьбу сохранённой задачи. Приоритет восстановления источника предотвращает выдачу на основании старой ветки, которую сервис ещё не перечитал.
Меняем условие: база старее кошелька
Предположим, резервная копия приложения сделана раньше последних назначений адресов. Кошелёк знает поступления, но восстановленная база не знает часть счетов. Не создаём фиктивные заказы по совпадающей цене. Сверка выделяет неназначенные поступления и ищет достоверные сведения в сохранённых запросах и операционных журналах.
Если часть назначения невозможно восстановить, это отдельный инцидент с ограничением результата. Нужно сохранить свидетельства и направить случай в разбор. Уверенное «Всё восстановлено» было бы неверным, пока существует денежный выход без объяснимой связи.
Этот пример показывает, почему согласованность резервирования важнее простого наличия архива. Кошельковые данные и коммерческие назначения относятся к разным системам. Их точки сохранения должны быть описаны так, чтобы после возврата к копии было понятно, какую область требуется пересмотреть.
Возобновление по этапам
Даже после согласования источника задачи доставки можно включать постепенно, наблюдая очередь и сохранённые причины отказов. Массовый одновременный повтор не является обязательным условием восстановления.
Паспорт завершения
В отчёте фиксируем сеть, контрольную точку, версии схемы, диапазон повторного чтения, число нерешённых расхождений и состояние доставки. Новые решения возобновляются только после установления согласованной области. Неразобранные случаи остаются отдельными записями, а не исчезают из общего счётчика.
Мы получили маршрут восстановления on-chain ветки без слепого повторения денежных действий. В следующем уроке перейдём к Lightning, сохраняя ту же коммерческую модель счёта и отдельный источник settlement. Оглавление курса связывает обе платёжные ветки.