X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=src%2Fmain%2Fjava%2Forg%2Fldk%2Fstructs%2FPersist.java;h=57e740669264bc57958c727a220d93682eb3289c;hb=b9716bc7ee492882e4643c9365971fef3761989f;hp=d9f5690e70c25f01262741d329dd3b96448a0acc;hpb=a9b82019e7ffa7d32d44943133bb64e1197bd2f1;p=ldk-java diff --git a/src/main/java/org/ldk/structs/Persist.java b/src/main/java/org/ldk/structs/Persist.java index d9f5690e..57e74066 100644 --- a/src/main/java/org/ldk/structs/Persist.java +++ b/src/main/java/org/ldk/structs/Persist.java @@ -4,7 +4,21 @@ import org.ldk.impl.bindings; import org.ldk.enums.*; import org.ldk.util.*; import java.util.Arrays; +import javax.annotation.Nullable; +/** + * `Persist` defines behavior for persisting channel monitors: this could mean + * writing once to disk, and/or uploading to one or more backup services. + * + * Note that for every new monitor, you **must** persist the new `ChannelMonitor` + * to disk/backups. And, on every update, you **must** persist either the + * `ChannelMonitorUpdate` or the updated monitor itself. Otherwise, there is risk + * of situations such as revoking a transaction, then crashing before this + * revocation can be persisted, then unintentionally broadcasting a revoked + * transaction and losing money. This is a risk because previous channel states + * are toxic, so it's important that whatever channel state is persisted is + * kept up-to-date. + */ @SuppressWarnings("unchecked") // We correctly assign various generic arrays public class Persist extends CommonBase { final bindings.LDKPersist bindings_instance; @@ -20,7 +34,41 @@ public class Persist extends CommonBase { } public static interface PersistInterface { + /** + * Persist a new channel's data. The data can be stored any way you want, but + * the identifier provided by Rust-Lightning 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. See the `Persist` trait documentation for more details. + * + * See [`ChannelMonitor::write`] for writing out a `ChannelMonitor`, + * and [`ChannelMonitorUpdateErr`] for requirements when returning errors. + */ Result_NoneChannelMonitorUpdateErrZ persist_new_channel(OutPoint id, ChannelMonitor data); + /** + * 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. + * + * 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)`. + * + * See [`ChannelMonitor::write`] for writing out a `ChannelMonitor`, + * [`ChannelMonitorUpdate::write`] for writing out an update, and + * [`ChannelMonitorUpdateErr`] for requirements when returning errors. + */ Result_NoneChannelMonitorUpdateErrZ update_persisted_channel(OutPoint id, ChannelMonitorUpdate update, ChannelMonitor data); } private static class LDKPersistHolder { Persist held; } @@ -29,34 +77,70 @@ public class Persist extends CommonBase { impl_holder.held = new Persist(new bindings.LDKPersist() { @Override public long persist_new_channel(long id, long data) { OutPoint id_hu_conv = new OutPoint(null, id); + id_hu_conv.ptrs_to.add(this); ChannelMonitor data_hu_conv = new ChannelMonitor(null, data); Result_NoneChannelMonitorUpdateErrZ ret = arg.persist_new_channel(id_hu_conv, data_hu_conv); long result = ret != null ? ret.ptr : 0; - ret.ptr = 0; return result; } @Override public long update_persisted_channel(long id, long update, long data) { OutPoint id_hu_conv = new OutPoint(null, id); + id_hu_conv.ptrs_to.add(this); ChannelMonitorUpdate update_hu_conv = new ChannelMonitorUpdate(null, update); ChannelMonitor data_hu_conv = new ChannelMonitor(null, data); Result_NoneChannelMonitorUpdateErrZ ret = arg.update_persisted_channel(id_hu_conv, update_hu_conv, data_hu_conv); long result = ret != null ? ret.ptr : 0; - ret.ptr = 0; return result; } }); return impl_holder.held; } + /** + * Persist a new channel's data. The data can be stored any way you want, but + * the identifier provided by Rust-Lightning 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. See the `Persist` trait documentation for more details. + * + * See [`ChannelMonitor::write`] for writing out a `ChannelMonitor`, + * and [`ChannelMonitorUpdateErr`] for requirements when returning errors. + */ public Result_NoneChannelMonitorUpdateErrZ persist_new_channel(OutPoint id, ChannelMonitor data) { long ret = bindings.Persist_persist_new_channel(this.ptr, id == null ? 0 : id.ptr & ~1, data == null ? 0 : data.ptr & ~1); + if (ret < 1024) { return null; } Result_NoneChannelMonitorUpdateErrZ ret_hu_conv = Result_NoneChannelMonitorUpdateErrZ.constr_from_ptr(ret); this.ptrs_to.add(id); this.ptrs_to.add(data); return ret_hu_conv; } + /** + * 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. + * + * 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)`. + * + * See [`ChannelMonitor::write`] for writing out a `ChannelMonitor`, + * [`ChannelMonitorUpdate::write`] for writing out an update, and + * [`ChannelMonitorUpdateErr`] for requirements when returning errors. + */ public Result_NoneChannelMonitorUpdateErrZ update_persisted_channel(OutPoint id, ChannelMonitorUpdate update, ChannelMonitor data) { long ret = bindings.Persist_update_persisted_channel(this.ptr, id == null ? 0 : id.ptr & ~1, update == null ? 0 : update.ptr & ~1, data == null ? 0 : data.ptr & ~1); + if (ret < 1024) { return null; } Result_NoneChannelMonitorUpdateErrZ ret_hu_conv = Result_NoneChannelMonitorUpdateErrZ.constr_from_ptr(ret); this.ptrs_to.add(id); this.ptrs_to.add(update);