Skip to content

Commit cbb7f95

Browse files
Add ChannelDataPersister trait.
The ChannelDataPersister is responsible for loading ChannelMonitors from disk on startup, and persisting new ChannelMonitors and ChannelMonitor updates.
1 parent 6b7a3d8 commit cbb7f95

File tree

2 files changed

+99
-0
lines changed

2 files changed

+99
-0
lines changed

lightning/src/ln/data_persister.rs

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
//! Logic for persisting data from ChannelMonitors on-disk. Per-platform data
2+
//! persisters are separated into the lightning-persist-data crate. These
3+
//! objects mainly interface with the ChainMonitor when a channel monitor is
4+
//! added or updated, and when they are all synced on startup.
5+
use chain::channelmonitor::{ChannelMonitor, ChannelMonitorUpdate, ChannelMonitorUpdateErr};
6+
use chain::keysinterface::ChannelKeys;
7+
use chain::transaction::OutPoint;
8+
use std::collections::HashMap;
9+
10+
/// ChannelDataPersister is responsible for persisting channel data: this could
11+
/// mean writing once to disk, and/or uploading to several backup services.
12+
///
13+
/// Note that for every new monitor, you **must** persist the new ChannelMonitor
14+
/// to disk/backups. And, on every update, you **must** persist either the
15+
/// ChannelMonitorUpdate or the updated monitor itself. Otherwise, there is risk
16+
/// of situations such as revoking a transaction, then crashing before this
17+
/// revocation can be persisted, then unintentionally broadcasting a revoked
18+
/// transaction and losing money. This is a risk because previous channel states
19+
/// are toxic, so it's important that whatever channel state is persisted is
20+
/// kept up-to-date.
21+
///
22+
/// Upon calls to update_channel_data, implementers of this trait should either
23+
/// persist the ChannelMonitorUpdate or the ChannelMonitor. If an implementer
24+
/// chooses to persist the updates only, they need to make sure that all the
25+
/// updates are applied to the ChannelMonitors *before* the set of channel
26+
/// monitors is given to the ChainMonitor at startup time (e.g., all monitors
27+
/// returned by `load_channel_data` must be up-to-date). If full ChannelMonitors
28+
/// are persisted, then there is no need to persist individual updates.
29+
///
30+
/// Note that there could be a performance tradeoff between persisting complete
31+
/// channel monitors on every update vs. persisting only updates and applying
32+
/// them in batches.
33+
///
34+
/// Given multiple backups, situations may arise where one or more backup sources
35+
/// have fallen behind or disagree on the current state. Because these backup
36+
/// sources don't have any transaction signing/broadcasting duties and are only
37+
/// supposed to be persisting bytes of data, backup sources may be considered
38+
/// "in consensus" if a majority of them agree on the current state and are on
39+
/// the highest known commitment number. See individual methods for more info.
40+
pub trait ChannelDataPersister: Send + Sync {
41+
/// The concrete type which signs for transactions and provides access to our channel public
42+
/// keys.
43+
type Keys: ChannelKeys;
44+
45+
/// Persist a new channel's data. The majority of backups should agree on a
46+
/// channel's state and be on the latest [`update_id`]. The data
47+
/// can be stored with any file name/path, but the identifier provided is the
48+
/// channel's outpoint.
49+
///
50+
/// See [`ChannelMonitor::write_for_disk`] for writing out a ChannelMonitor.
51+
///
52+
/// [`update_id`]: struct.ChannelMonitorUpdate.html#structfield.update_id
53+
/// [`ChannelMonitor::write_for_disk`]: ../../chain/channelmonitor/struct.ChannelMonitor.html#method.write_for_disk
54+
fn persist_channel_data(&self, id: OutPoint, data: &ChannelMonitor<Self::Keys>) -> Result<(), ChannelMonitorUpdateErr>;
55+
56+
/// Update one channel's data. The provided ChannelMonitor has already
57+
/// applied the given update.
58+
///
59+
/// Note that on every update, you **must** persist either the
60+
/// ChannelMonitorUpdate or the updated monitor itself to disk/backups.
61+
/// Otherwise, there is risk of situations such as revoking a transaction,
62+
/// then crashing before this revocation can be persisted, then
63+
/// unintentionally broadcasting a revoked transaction and losing money. This
64+
/// is a risk because previous channel states are toxic, so it's important
65+
/// that whatever channel state is persisted is kept up-to-date.
66+
///
67+
/// If an implementer chooses to persist the updates only, they need to make
68+
/// sure that all the updates are applied to the ChannelMonitors *before* the
69+
/// set of channel monitors is given to the ChainMonitor at startup time
70+
/// (e.g., all monitors returned by [`load_channel_data`] must be up-to-date).
71+
/// If full ChannelMonitors are persisted, then there is no need to persist
72+
/// individual updates.
73+
///
74+
/// In the case where one or more backups fail, it's likely safe to only
75+
/// require that the majority of backups succeed and agree on the latest
76+
/// [`update_id`] to succeed this method.
77+
///
78+
/// See [`ChannelMonitor::write_for_disk`] for writing out a ChannelMonitor
79+
/// and [`ChannelMonitorUpdate::write`] for writing out an update.
80+
///
81+
/// [`load_channel_data`]: trait.ChannelDataPersister.html#tymethod.load_channel_data
82+
/// [`update_id`]: struct.ChannelMonitorUpdate.html#structfield.update_id
83+
/// [`ChannelMonitor::write_for_disk`]: struct.ChannelMonitor.html#method.write_for_disk
84+
/// [`ChannelMonitorUpdate::write`]: struct.ChannelMonitorUpdate.html#method.write
85+
fn update_channel_data(&self, id: OutPoint, update: &ChannelMonitorUpdate, data: &ChannelMonitor<Self::Keys>) -> Result<(), ChannelMonitorUpdateErr>;
86+
87+
/// Load the data for all channels. Generally only called on startup. You must
88+
/// ensure that the ChannelMonitors returned are on the latest [`update_id`],
89+
/// with all of the updates given in [`update_channel_data`] applied. Otherwise,
90+
/// there is a risk of broadcasting a revoked transaction and losing money.
91+
///
92+
/// See [`ChannelMonitor::read`] for deserializing a ChannelMonitor.
93+
///
94+
/// [`update_id`]: struct.ChannelMonitorUpdate.html#structfield.update_id
95+
/// [`update_channel_data`]: trait.ChannelDataPersister.html#tymethod.update_channel_data
96+
/// [`ChannelMonitor::read`]: trait.Readable.html
97+
fn load_channel_data(&self) -> Result<HashMap<OutPoint, ChannelMonitor<Self::Keys>>, ChannelMonitorUpdateErr>;
98+
}

lightning/src/ln/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
//! call into your NetGraphMsgHandler.
2020
2121
pub mod channelmanager;
22+
pub mod data_persister;
2223
pub mod msgs;
2324
pub mod peer_handler;
2425
pub mod chan_utils;

0 commit comments

Comments
 (0)