Trait Persist
pub trait Persist<ChannelSigner>where
ChannelSigner: WriteableEcdsaChannelSigner,{
// Required methods
fn persist_new_channel(
&self,
channel_id: OutPoint,
data: &ChannelMonitor<ChannelSigner>,
update_id: MonitorUpdateId,
) -> ChannelMonitorUpdateStatus;
fn update_persisted_channel(
&self,
channel_id: OutPoint,
update: Option<&ChannelMonitorUpdate>,
data: &ChannelMonitor<ChannelSigner>,
update_id: MonitorUpdateId,
) -> ChannelMonitorUpdateStatus;
}
Expand description
Persist
defines behavior for persisting channel monitors: this could mean
writing once to disk, and/or uploading to one or more backup services.
Persistence can happen in one of two ways - synchronously completing before the trait method calls return or asynchronously in the background.
§For those implementing synchronous persistence
-
If persistence completes fully (including any relevant
fsync()
calls), the implementation should returnChannelMonitorUpdateStatus::Completed
, indicating normal channel operation should continue. -
If persistence fails for some reason, implementations should consider returning
ChannelMonitorUpdateStatus::InProgress
and retry all pending persistence operations in the background withChainMonitor::list_pending_monitor_updates
andChainMonitor::get_monitor
.Once a full
ChannelMonitor
has been persisted, all pending updates for that channel can be marked as complete viaChainMonitor::channel_monitor_updated
.If at some point no further progress can be made towards persisting the pending updates, the node should simply shut down.
-
If the persistence has failed and cannot be retried further (e.g. because of an outage),
ChannelMonitorUpdateStatus::UnrecoverableError
can be used, though this will result in an immediate panic and future operations in LDK generally failing.
§For those implementing asynchronous persistence
All calls should generally spawn a background task and immediately return
ChannelMonitorUpdateStatus::InProgress
. Once the update completes,
ChainMonitor::channel_monitor_updated
should be called with the corresponding
MonitorUpdateId
.
Note that unlike the direct chain::Watch
interface,
ChainMonitor::channel_monitor_updated
must be called once for each update which occurs.
If at some point no further progress can be made towards persisting a pending update, the node
should simply shut down. Until then, the background task should either loop indefinitely, or
persistence should be regularly retried with ChainMonitor::list_pending_monitor_updates
and ChainMonitor::get_monitor
(note that if a full monitor is persisted all pending
monitor updates may be marked completed).
§Using remote watchtowers
Watchtowers may be updated as a part of an implementation of this trait, utilizing the async
update process described above while the watchtower is being updated. The following methods are
provided for bulding transactions for a watchtower:
ChannelMonitor::initial_counterparty_commitment_tx
,
ChannelMonitor::counterparty_commitment_txs_from_update
,
ChannelMonitor::sign_to_local_justice_tx
, TrustedCommitmentTransaction::revokeable_output_index
,
TrustedCommitmentTransaction::build_to_local_justice_tx
.
Required Methods§
fn persist_new_channel(
&self,
channel_id: OutPoint,
data: &ChannelMonitor<ChannelSigner>,
update_id: MonitorUpdateId,
) -> ChannelMonitorUpdateStatus
fn persist_new_channel( &self, channel_id: OutPoint, data: &ChannelMonitor<ChannelSigner>, update_id: MonitorUpdateId, ) -> ChannelMonitorUpdateStatus
Persist a new channel’s data in response to a chain::Watch::watch_channel
call. This is
called by ChannelManager
for new channels, or may be called directly, e.g. on startup.
The data can be stored any way you want, but the identifier provided by LDK is the channel’s outpoint (and it is up to you to maintain a correct mapping between the outpoint and the stored channel data). Note that you must persist every new monitor to disk.
The update_id
is used to identify this call to ChainMonitor::channel_monitor_updated
,
if you return ChannelMonitorUpdateStatus::InProgress
.
See Writeable::write
on ChannelMonitor
for writing out a ChannelMonitor
and ChannelMonitorUpdateStatus
for requirements when returning errors.
fn update_persisted_channel(
&self,
channel_id: OutPoint,
update: Option<&ChannelMonitorUpdate>,
data: &ChannelMonitor<ChannelSigner>,
update_id: MonitorUpdateId,
) -> ChannelMonitorUpdateStatus
fn update_persisted_channel( &self, channel_id: OutPoint, update: Option<&ChannelMonitorUpdate>, data: &ChannelMonitor<ChannelSigner>, update_id: MonitorUpdateId, ) -> ChannelMonitorUpdateStatus
Update one channel’s data. The provided ChannelMonitor
has already applied the given
update.
Note that on every update, you must persist either the ChannelMonitorUpdate
or the
updated monitor itself to disk/backups. See the Persist
trait documentation for more
details.
During blockchain synchronization operations, and in some rare cases, this may be called with
no ChannelMonitorUpdate
, in which case the full ChannelMonitor
needs to be persisted.
Note that after the full ChannelMonitor
is persisted any previous
ChannelMonitorUpdate
s which were persisted should be discarded - they can no longer be
applied to the persisted ChannelMonitor
as they were already applied.
If an implementer chooses to persist the updates only, they need to make
sure that all the updates are applied to the ChannelMonitors
before
the set of channel monitors is given to the ChannelManager
deserialization routine. See ChannelMonitor::update_monitor
for
applying a monitor update to a monitor. If full ChannelMonitors
are
persisted, then there is no need to persist individual updates.
Note that there could be a performance tradeoff between persisting complete
channel monitors on every update vs. persisting only updates and applying
them in batches. The size of each monitor grows O(number of state updates)
whereas updates are small and O(1)
.
The update_id
is used to identify this call to ChainMonitor::channel_monitor_updated
,
if you return ChannelMonitorUpdateStatus::InProgress
.
See Writeable::write
on ChannelMonitor
for writing out a ChannelMonitor
,
Writeable::write
on ChannelMonitorUpdate
for writing out an update, and
ChannelMonitorUpdateStatus
for requirements when returning errors.