Закрытие канала Lightning и расчёт on-chain
Оглавление курса «Bitcoin и Lightning: платежи на сайте» · Урок 26 из 30.
Платёжный сайт может продолжать хранить оплаченные заказы, пока оператор Lightning-узла закрывает канал. Эти процессы связаны инфраструктурой, но не являются одним состоянием. В уроке разберём различие согласованного и принудительного закрытия, построим безопасную модель эксплуатационного решения и объясним, почему закрытие не превращает каждый завершённый invoice в новую on-chain оплату читателя.
Ни один канал здесь не открывается и не закрывается. Листинги не содержат команд управления средствами. Мы описываем договор оператора и отображение доступности услуги. Конкретные сроки, комиссии, условия выхода и ограничения принадлежат выбранному профилю канала и узла, поэтому универсальное число блоков в инструкцию не подставляем.
Два пути завершения
При cooperative close участники согласуют закрытие. При force close используется односторонний путь с дополнительными условиями и ожиданием доступности выходов. Детали соответствующих транзакций и сроков описаны в BOLT 3. Это не означает, что оператор может мгновенно получить весь отображаемый баланс любой кнопкой.
Вместимость, текущие обязательства и готовность средств к расходованию остаются разными понятиями. Некоторые части могут быть связаны с незавершёнными условиями. Комиссии и ветви разрешения также влияют на окончательные выходы. Наша упрощённая таблица балансов из урока 19 не предназначена для расчёта действительного закрытия.
Для сайта важны две вещи: можно ли создавать новые счета на выбранном источнике и как наблюдать судьбу уже созданных инструментов. Даже если прекращаем предлагать Lightning новым заказам, старые invoice и подтверждённые поступления не удаляем. История курса 17 продолжает объясняться сохранёнными платежными свидетельствами.
Закрытие и расчёт заказа
Предположим, заказ уже получил SETTLED и право на курс. Позднее канал узла закрывается. Это не делает прежний расчёт неоплаченным автоматически и не переводит его в политику onchain-v1 с двумя подтверждениями. Мы не ждём новую транзакцию от читателя только потому, что инфраструктура получателя меняет форму хранения средств.
Если invoice ещё pending, оператор обязан сохранить возможность выяснить его судьбу. Закрытие отдельного канала не является универсальным доказательством, что все счета узла отменены. У узла могут быть другие маршруты, а незавершённые условия требуют собственной обработки. Приложение читает конкретные источники, не угадывает результат по общей новости «канал закрывается».
Также платежный возврат — отдельная операция. Закрытие канала не отправляет покупателю возврат за курс автоматически. В системе возвратов существуют свои реквизиты, полномочия, сумма, состояние и журнал. Их нельзя заменить административным статусом канала.
Модель разрешённого действия оператора
Создадим функцию планирования. Она не вызывает RPC и не утверждает, что выбранный режим обязательно успешен. Её результат сообщает, какие проверки необходимы до реального действия в отдельной эксплуатационной процедуре.
from dataclasses import dataclass
@dataclass(frozen=True)
class ChannelOperationsContext:
operator_authorized: bool
backup_current: bool
peer_available: bool
unresolved_instruments: int
node_profile_verified: bool
def closure_plan(context, requested_mode):
if not context.operator_authorized:
return {'action': 'deny', 'reason': 'operator-role'}
if not context.node_profile_verified or not context.backup_current:
return {'action': 'stop', 'reason': 'preconditions'}
if requested_mode not in {'cooperative', 'force'}:
return {'action': 'deny', 'reason': 'mode'}
if requested_mode == 'cooperative' and not context.peer_available:
return {'action': 'review', 'reason': 'peer-unavailable'}
return {
'action': 'prepare-runbook',
'mode': requested_mode,
'reconcile_instruments': context.unresolved_instruments,
'requires_funds_observation': True,
}
backup_current здесь означает результат собственного операционного контроля, а не гарантированный способ возобновить канал. В следующем уроке разберём ограничения резервирования. Сам объект не доказывает состояние узла: все входы получает доверенный операторский слой и подтверждает выбранным источником.
Не делаем автоматический force close по истечению таймера сайта. Пользовательское ожидание оплаты не управляет каналом оператора. Решение имеет последствия для средств и доступности; оно требует отдельной процедуры и соответствующего полномочия. Даже в лаборатории такая команда не должна скрываться в обработчике обычного HTTP-статуса.
Доступность метода для новых заказов
Пока инфраструктура требует обслуживания, сайт может временно не выдавать новые Lightning invoice. Такое решение обозначается как состояние услуги. Оно не переписывает существующие заказы в failed. Для альтернативного on-chain пути создаётся явный инструмент и сохраняется риск двойного поступления по старому счёту.
Если у получателя несколько каналов, закрытие одного может вообще не остановить все поступления. Не выводим общий флаг unavailable только из одного уведомления без собственной политики. Сервис доступности агрегирует определённые факты, а окончательное состояние каждого invoice продолжает вычисляться по его источнику.
Публичное сообщение не раскрывает funding outpoint и подробную структуру каналов, если посетителю это не нужно. Достаточно объяснить, что метод временно недоступен для новых заказов и что ранее отправленные платежи продолжают сверяться. Операторская панель содержит более подробные идентификаторы под отдельным контролем доступа.
Наблюдение выхода в цепочку
После инициирования закрытия наблюдаем его отдельный жизненный цикл: подготовка, появление транзакции, подтверждение, возможная задержка определённых выходов и возможность расходования согласно профилю. Состояние «транзакция обнаружена» не всегда равно «все средства доступны».
Для собственных метрик полезно отдельно считать полученные платежи, доступный on-chain остаток и средства в незавершённых выходах. Сумма всех paid заказов — журнал выручки приложения, а не точный доступный баланс узла. Расходы инфраструктуры, переводы, комиссии и другие операции могут изменить остаток без изменения прав читателей.
Ожидаемые ситуации
Оператор без разрешения получает deny до любой подготовки. Недоступный peer при запросе cooperative close приводит к review, а не тайному выбору force. Непроверенный профиль останавливает процедуру. Успешный план ещё требует действительных наблюдений в отдельном внедрении и не выполняет действие сам.
Для читателя оплаченный заказ сохраняет свою связь и право. Ожидающий заказ продолжает сверку независимо от временного режима новых счетов. Для оператора закрытие имеет собственный журнал и собственную карту восстановления. Такое разделение предотвращает ошибку, когда управление каналом случайно превращается в управление доступом ко всем материалам сайта.
Закрытие одного канала в журнале
Административная запись содержит идентификатор задачи, выбранный режим и фактические наблюдения. Она не меняет payment hash старых счетов и не присваивает всем заказам один closing transaction id. Иначе журнал потеряет связь отдельных поступлений с назначениями.
Сайт может продолжать показывать сохранённые статусы, пока оператор ждёт доступности определённых выходов. Если новое поступление всё же завершено другим маршрутом, обработчик применяет обычную политику invoice. Канальная процедура и предметный settlement остаются независимыми, хотя используют один инфраструктурный контур.