X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=c_sharp%2Fsrc%2Forg%2Fldk%2Fstructs%2FWatch.cs;fp=c_sharp%2Fsrc%2Forg%2Fldk%2Fstructs%2FWatch.cs;h=95bf7129538f884abeb5f45e05d2f277bb6bfbf3;hb=8de7213fbf663ff60322896282dad51e8ab2f001;hp=4fc936e0cc517fc7b7b6ca148ab3943d95523e17;hpb=afc50e5d491a11364849383b75a8f939df703bac;p=ldk-java diff --git a/c_sharp/src/org/ldk/structs/Watch.cs b/c_sharp/src/org/ldk/structs/Watch.cs index 4fc936e0..95bf7129 100644 --- a/c_sharp/src/org/ldk/structs/Watch.cs +++ b/c_sharp/src/org/ldk/structs/Watch.cs @@ -1,3 +1,4 @@ + using org.ldk.impl; using org.ldk.enums; using org.ldk.util; @@ -5,89 +6,92 @@ using System; namespace org { namespace ldk { namespace structs { + + +/** An implementation of Watch */ +public interface WatchInterface { + /**Watches a channel identified by `funding_txo` using `monitor`. + * + * Implementations are responsible for watching the chain for the funding transaction along + * with any spends of outputs returned by [`get_outputs_to_watch`]. In practice, this means + * calling [`block_connected`] and [`block_disconnected`] on the monitor. + * + * A return of `Err(())` indicates that the channel should immediately be force-closed without + * broadcasting the funding transaction. + * + * If the given `funding_txo` has previously been registered via `watch_channel`, `Err(())` + * must be returned. + * + * [`get_outputs_to_watch`]: channelmonitor::ChannelMonitor::get_outputs_to_watch + * [`block_connected`]: channelmonitor::ChannelMonitor::block_connected + * [`block_disconnected`]: channelmonitor::ChannelMonitor::block_disconnected + */ + Result_ChannelMonitorUpdateStatusNoneZ watch_channel(OutPoint funding_txo, ChannelMonitor monitor); + /**Updates a channel identified by `funding_txo` by applying `update` to its monitor. + * + * Implementations must call [`ChannelMonitor::update_monitor`] with the given update. This + * may fail (returning an `Err(())`), in which case this should return + * [`ChannelMonitorUpdateStatus::InProgress`] (and the update should never complete). This + * generally implies the channel has been closed (either by the funding outpoint being spent + * on-chain or the [`ChannelMonitor`] having decided to do so and broadcasted a transaction), + * and the [`ChannelManager`] state will be updated once it sees the funding spend on-chain. + * + * In general, persistence failures should be retried after returning + * [`ChannelMonitorUpdateStatus::InProgress`] and eventually complete. If a failure truly + * cannot be retried, the node should shut down immediately after returning + * [`ChannelMonitorUpdateStatus::UnrecoverableError`], see its documentation for more info. + * + * [`ChannelManager`]: crate::ln::channelmanager::ChannelManager + */ + ChannelMonitorUpdateStatus update_channel(OutPoint funding_txo, ChannelMonitorUpdate update); + /**Returns any monitor events since the last call. Subsequent calls must only return new + * events. + * + * Note that after any block- or transaction-connection calls to a [`ChannelMonitor`], no + * further events may be returned here until the [`ChannelMonitor`] has been fully persisted + * to disk. + * + * For details on asynchronous [`ChannelMonitor`] updating and returning + * [`MonitorEvent::Completed`] here, see [`ChannelMonitorUpdateStatus::InProgress`]. + */ + ThreeTuple_OutPointCVec_MonitorEventZPublicKeyZ[] release_pending_monitor_events(); +} + /** * The `Watch` trait defines behavior for watching on-chain activity pertaining to channels as * blocks are connected and disconnected. * * Each channel is associated with a [`ChannelMonitor`]. Implementations of this trait are - * responsible for maintaining a set of monitors such that they can be updated accordingly as - * channel state changes and HTLCs are resolved. See method documentation for specific - * requirements. - * - * Implementations **must** ensure that updates are successfully applied and persisted upon method - * completion. If an update fails with a [`PermanentFailure`], then it must immediately shut down - * without taking any further action such as persisting the current state. + * responsible for maintaining a set of monitors such that they can be updated as channel state + * changes. On each update, *all copies* of a [`ChannelMonitor`] must be updated and the update + * persisted to disk to ensure that the latest [`ChannelMonitor`] state can be reloaded if the + * application crashes. * - * If an implementation maintains multiple instances of a channel's monitor (e.g., by storing - * backup copies), then it must ensure that updates are applied across all instances. Otherwise, it - * could result in a revoked transaction being broadcast, allowing the counterparty to claim all - * funds in the channel. See [`ChannelMonitorUpdateStatus`] for more details about how to handle - * multiple instances. - * - * [`PermanentFailure`]: ChannelMonitorUpdateStatus::PermanentFailure + * See method documentation and [`ChannelMonitorUpdateStatus`] for specific requirements. */ public class Watch : CommonBase { - internal readonly bindings.LDKWatch bindings_instance; + internal bindings.LDKWatch bindings_instance; + internal long instance_idx; + internal Watch(object _dummy, long ptr) : base(ptr) { bindings_instance = null; } - private Watch(bindings.LDKWatch arg) : base(bindings.LDKWatch_new(arg)) { - this.ptrs_to.AddLast(arg); - this.bindings_instance = arg; - } ~Watch() { if (ptr != 0) { bindings.Watch_free(ptr); } } - public interface WatchInterface { - /** - * Watches a channel identified by `funding_txo` using `monitor`. - * - * Implementations are responsible for watching the chain for the funding transaction along - * with any spends of outputs returned by [`get_outputs_to_watch`]. In practice, this means - * calling [`block_connected`] and [`block_disconnected`] on the monitor. - * - * Note: this interface MUST error with [`ChannelMonitorUpdateStatus::PermanentFailure`] if - * the given `funding_txo` has previously been registered via `watch_channel`. - * - * [`get_outputs_to_watch`]: channelmonitor::ChannelMonitor::get_outputs_to_watch - * [`block_connected`]: channelmonitor::ChannelMonitor::block_connected - * [`block_disconnected`]: channelmonitor::ChannelMonitor::block_disconnected - */ - ChannelMonitorUpdateStatus watch_channel(OutPoint _funding_txo, ChannelMonitor _monitor); - /** - * Updates a channel identified by `funding_txo` by applying `update` to its monitor. - * - * Implementations must call [`update_monitor`] with the given update. See - * [`ChannelMonitorUpdateStatus`] for invariants around returning an error. - * - * [`update_monitor`]: channelmonitor::ChannelMonitor::update_monitor - */ - ChannelMonitorUpdateStatus update_channel(OutPoint _funding_txo, ChannelMonitorUpdate _update); - /** - * Returns any monitor events since the last call. Subsequent calls must only return new - * events. - * - * Note that after any block- or transaction-connection calls to a [`ChannelMonitor`], no - * further events may be returned here until the [`ChannelMonitor`] has been fully persisted - * to disk. - * - * For details on asynchronous [`ChannelMonitor`] updating and returning - * [`MonitorEvent::Completed`] here, see [`ChannelMonitorUpdateStatus::InProgress`]. - */ - ThreeTuple_OutPointCVec_MonitorEventZPublicKeyZ[] release_pending_monitor_events(); - } private class LDKWatchHolder { internal Watch held; } private class LDKWatchImpl : bindings.LDKWatch { internal LDKWatchImpl(WatchInterface arg, LDKWatchHolder impl_holder) { this.arg = arg; this.impl_holder = impl_holder; } private WatchInterface arg; private LDKWatchHolder impl_holder; - public ChannelMonitorUpdateStatus watch_channel(long _funding_txo, long _monitor) { + public long watch_channel(long _funding_txo, long _monitor) { org.ldk.structs.OutPoint _funding_txo_hu_conv = null; if (_funding_txo < 0 || _funding_txo > 4096) { _funding_txo_hu_conv = new org.ldk.structs.OutPoint(null, _funding_txo); } if (_funding_txo_hu_conv != null) { _funding_txo_hu_conv.ptrs_to.AddLast(this); }; org.ldk.structs.ChannelMonitor _monitor_hu_conv = null; if (_monitor < 0 || _monitor > 4096) { _monitor_hu_conv = new org.ldk.structs.ChannelMonitor(null, _monitor); } if (_monitor_hu_conv != null) { _monitor_hu_conv.ptrs_to.AddLast(this); }; - ChannelMonitorUpdateStatus ret = arg.watch_channel(_funding_txo_hu_conv, _monitor_hu_conv); + Result_ChannelMonitorUpdateStatusNoneZ ret = arg.watch_channel(_funding_txo_hu_conv, _monitor_hu_conv); GC.KeepAlive(arg); - return ret; + long result = ret == null ? 0 : ret.clone_ptr(); + return result; } public ChannelMonitorUpdateStatus update_channel(long _funding_txo, long _update) { org.ldk.structs.OutPoint _funding_txo_hu_conv = null; if (_funding_txo < 0 || _funding_txo > 4096) { _funding_txo_hu_conv = new org.ldk.structs.OutPoint(null, _funding_txo); } @@ -97,18 +101,26 @@ public class Watch : CommonBase { GC.KeepAlive(arg); return ret; } - public long[] release_pending_monitor_events() { + public long release_pending_monitor_events() { ThreeTuple_OutPointCVec_MonitorEventZPublicKeyZ[] ret = arg.release_pending_monitor_events(); GC.KeepAlive(arg); - long[] result = ret != null ? InternalUtils.mapArray(ret, ret_conv_49 => ret_conv_49 == null ? 0 : ret_conv_49.clone_ptr()) : null; + long result = InternalUtils.encodeUint64Array(InternalUtils.mapArray(ret, ret_conv_49 => ret_conv_49 == null ? 0 : ret_conv_49.clone_ptr())); return result; } } + + /** Creates a new instance of Watch from a given implementation */ public static Watch new_impl(WatchInterface arg) { LDKWatchHolder impl_holder = new LDKWatchHolder(); - impl_holder.held = new Watch(new LDKWatchImpl(arg, impl_holder)); + LDKWatchImpl impl = new LDKWatchImpl(arg, impl_holder); + long[] ptr_idx = bindings.LDKWatch_new(impl); + + impl_holder.held = new Watch(null, ptr_idx[0]); + impl_holder.held.instance_idx = ptr_idx[1]; + impl_holder.held.bindings_instance = impl; return impl_holder.held; } + /** * Watches a channel identified by `funding_txo` using `monitor`. * @@ -116,30 +128,44 @@ public class Watch : CommonBase { * with any spends of outputs returned by [`get_outputs_to_watch`]. In practice, this means * calling [`block_connected`] and [`block_disconnected`] on the monitor. * - * Note: this interface MUST error with [`ChannelMonitorUpdateStatus::PermanentFailure`] if - * the given `funding_txo` has previously been registered via `watch_channel`. + * A return of `Err(())` indicates that the channel should immediately be force-closed without + * broadcasting the funding transaction. + * + * If the given `funding_txo` has previously been registered via `watch_channel`, `Err(())` + * must be returned. * * [`get_outputs_to_watch`]: channelmonitor::ChannelMonitor::get_outputs_to_watch * [`block_connected`]: channelmonitor::ChannelMonitor::block_connected * [`block_disconnected`]: channelmonitor::ChannelMonitor::block_disconnected */ - public ChannelMonitorUpdateStatus watch_channel(org.ldk.structs.OutPoint funding_txo, org.ldk.structs.ChannelMonitor monitor) { - ChannelMonitorUpdateStatus ret = bindings.Watch_watch_channel(this.ptr, funding_txo == null ? 0 : funding_txo.ptr, monitor == null ? 0 : monitor.ptr); + public Result_ChannelMonitorUpdateStatusNoneZ watch_channel(org.ldk.structs.OutPoint funding_txo, org.ldk.structs.ChannelMonitor monitor) { + long ret = bindings.Watch_watch_channel(this.ptr, funding_txo == null ? 0 : funding_txo.ptr, monitor == null ? 0 : monitor.ptr); GC.KeepAlive(this); GC.KeepAlive(funding_txo); GC.KeepAlive(monitor); + if (ret >= 0 && ret <= 4096) { return null; } + Result_ChannelMonitorUpdateStatusNoneZ ret_hu_conv = Result_ChannelMonitorUpdateStatusNoneZ.constr_from_ptr(ret); if (this != null) { this.ptrs_to.AddLast(funding_txo); }; if (this != null) { this.ptrs_to.AddLast(monitor); }; - return ret; + return ret_hu_conv; } /** * Updates a channel identified by `funding_txo` by applying `update` to its monitor. * - * Implementations must call [`update_monitor`] with the given update. See - * [`ChannelMonitorUpdateStatus`] for invariants around returning an error. + * Implementations must call [`ChannelMonitor::update_monitor`] with the given update. This + * may fail (returning an `Err(())`), in which case this should return + * [`ChannelMonitorUpdateStatus::InProgress`] (and the update should never complete). This + * generally implies the channel has been closed (either by the funding outpoint being spent + * on-chain or the [`ChannelMonitor`] having decided to do so and broadcasted a transaction), + * and the [`ChannelManager`] state will be updated once it sees the funding spend on-chain. + * + * In general, persistence failures should be retried after returning + * [`ChannelMonitorUpdateStatus::InProgress`] and eventually complete. If a failure truly + * cannot be retried, the node should shut down immediately after returning + * [`ChannelMonitorUpdateStatus::UnrecoverableError`], see its documentation for more info. * - * [`update_monitor`]: channelmonitor::ChannelMonitor::update_monitor + * [`ChannelManager`]: crate::ln::channelmanager::ChannelManager */ public ChannelMonitorUpdateStatus update_channel(org.ldk.structs.OutPoint funding_txo, org.ldk.structs.ChannelMonitorUpdate update) { ChannelMonitorUpdateStatus ret = bindings.Watch_update_channel(this.ptr, funding_txo == null ? 0 : funding_txo.ptr, update == null ? 0 : update.ptr); @@ -163,16 +189,18 @@ public class Watch : CommonBase { * [`MonitorEvent::Completed`] here, see [`ChannelMonitorUpdateStatus::InProgress`]. */ public ThreeTuple_OutPointCVec_MonitorEventZPublicKeyZ[] release_pending_monitor_events() { - long[] ret = bindings.Watch_release_pending_monitor_events(this.ptr); + long ret = bindings.Watch_release_pending_monitor_events(this.ptr); GC.KeepAlive(this); - int ret_conv_49_len = ret.Length; + if (ret >= 0 && ret <= 4096) { return null; } + int ret_conv_49_len = InternalUtils.getArrayLength(ret); ThreeTuple_OutPointCVec_MonitorEventZPublicKeyZ[] ret_conv_49_arr = new ThreeTuple_OutPointCVec_MonitorEventZPublicKeyZ[ret_conv_49_len]; for (int x = 0; x < ret_conv_49_len; x++) { - long ret_conv_49 = ret[x]; + long ret_conv_49 = InternalUtils.getU64ArrayElem(ret, x); ThreeTuple_OutPointCVec_MonitorEventZPublicKeyZ ret_conv_49_hu_conv = new ThreeTuple_OutPointCVec_MonitorEventZPublicKeyZ(null, ret_conv_49); if (ret_conv_49_hu_conv != null) { ret_conv_49_hu_conv.ptrs_to.AddLast(this); }; ret_conv_49_arr[x] = ret_conv_49_hu_conv; } + bindings.free_buffer(ret); return ret_conv_49_arr; }