|
| 1 | +package org.ldk.batteries; |
| 2 | + |
| 3 | +import org.ldk.enums.LDKNetwork; |
| 4 | +import org.ldk.structs.*; |
| 5 | +import org.ldk.util.TwoTuple; |
| 6 | + |
| 7 | + |
| 8 | +/** |
| 9 | + * A simple utility class which assists in constructing a fresh or deserializing from disk a ChannelManager and one or |
| 10 | + * more ChannelMonitors. |
| 11 | + */ |
| 12 | +public class ChannelManagerConstructor { |
| 13 | + /** |
| 14 | + * An Exception that indicates the serialized data is invalid and has been corrupted on disk. You should attempt to |
| 15 | + * restore from a backup if there is one which is known to be current. Otherwise, funds may have been lost. |
| 16 | + */ |
| 17 | + public static class InvalidSerializedDataException extends Exception {} |
| 18 | + |
| 19 | + /** |
| 20 | + * The ChannelManager either deserialized or newly-constructed. |
| 21 | + */ |
| 22 | + public final ChannelManager channel_manager; |
| 23 | + /** |
| 24 | + * The latest block has the channel manager saw. If this is non-null it is a 32-byte block hash. |
| 25 | + * You should sync the blockchain starting with the block that builds on this block. |
| 26 | + */ |
| 27 | + public final byte[] channel_manager_latest_block_hash; |
| 28 | + /** |
| 29 | + * A list of ChannelMonitors and the last block they each saw. You should sync the blockchain on each individually |
| 30 | + * starting with the block that builds on the hash given. |
| 31 | + * After doing so (and syncing the blockchain on the channel manager as well), you should call chain_sync_completed() |
| 32 | + * and then continue to normal application operation. |
| 33 | + */ |
| 34 | + public final TwoTuple<ChannelMonitor, byte[]>[] channel_monitors; |
| 35 | + |
| 36 | + private final Watch chain_watch; |
| 37 | + |
| 38 | + /** |
| 39 | + * Deserializes a channel manager and a set of channel monitors from the given serialized copies and interface implementations |
| 40 | + */ |
| 41 | + public ChannelManagerConstructor(byte[] channel_manager_serialized, byte[][] channel_monitors_serialized, |
| 42 | + KeysInterface keys_interface, FeeEstimator fee_estimator, Watch chain_watch, |
| 43 | + BroadcasterInterface tx_broadcaster, Logger logger) throws InvalidSerializedDataException { |
| 44 | + final ChannelMonitor[] monitors = new ChannelMonitor[channel_monitors_serialized.length]; |
| 45 | + this.channel_monitors = new TwoTuple[monitors.length]; |
| 46 | + for (int i = 0; i < monitors.length; i++) { |
| 47 | + Result_C2Tuple_BlockHashChannelMonitorZDecodeErrorZ res = UtilMethods.constructor_BlockHashChannelMonitorZ_read(channel_monitors_serialized[i], keys_interface); |
| 48 | + if (res instanceof Result_C2Tuple_BlockHashChannelMonitorZDecodeErrorZ.Result_C2Tuple_BlockHashChannelMonitorZDecodeErrorZ_Err) { |
| 49 | + throw new InvalidSerializedDataException(); |
| 50 | + } |
| 51 | + monitors[i] = ((Result_C2Tuple_BlockHashChannelMonitorZDecodeErrorZ.Result_C2Tuple_BlockHashChannelMonitorZDecodeErrorZ_OK) res).res.b; |
| 52 | + this.channel_monitors[i] = new TwoTuple<>(monitors[i], ((Result_C2Tuple_BlockHashChannelMonitorZDecodeErrorZ.Result_C2Tuple_BlockHashChannelMonitorZDecodeErrorZ_OK)res).res.a); |
| 53 | + } |
| 54 | + Result_C2Tuple_BlockHashChannelManagerZDecodeErrorZ res = |
| 55 | + UtilMethods.constructor_BlockHashChannelManagerZ_read(channel_manager_serialized, keys_interface, fee_estimator, chain_watch, tx_broadcaster, |
| 56 | + logger, UserConfig.constructor_default(), monitors); |
| 57 | + if (res instanceof Result_C2Tuple_BlockHashChannelManagerZDecodeErrorZ.Result_C2Tuple_BlockHashChannelManagerZDecodeErrorZ_Err) { |
| 58 | + throw new InvalidSerializedDataException(); |
| 59 | + } |
| 60 | + this.channel_manager = ((Result_C2Tuple_BlockHashChannelManagerZDecodeErrorZ.Result_C2Tuple_BlockHashChannelManagerZDecodeErrorZ_OK)res).res.b; |
| 61 | + this.channel_manager_latest_block_hash = ((Result_C2Tuple_BlockHashChannelManagerZDecodeErrorZ.Result_C2Tuple_BlockHashChannelManagerZDecodeErrorZ_OK)res).res.a; |
| 62 | + this.chain_watch = chain_watch; |
| 63 | + } |
| 64 | + |
| 65 | + /** |
| 66 | + * Constructs a channel manager from the given interface implementations |
| 67 | + */ |
| 68 | + public ChannelManagerConstructor(LDKNetwork network, UserConfig config, byte[] current_blockchain_tip_hash, int current_blockchain_tip_height, |
| 69 | + KeysInterface keys_interface, FeeEstimator fee_estimator, Watch chain_watch, |
| 70 | + BroadcasterInterface tx_broadcaster, Logger logger) throws InvalidSerializedDataException { |
| 71 | + channel_monitors = new TwoTuple[0]; |
| 72 | + channel_manager_latest_block_hash = null; |
| 73 | + this.chain_watch = chain_watch; |
| 74 | + // Note that current_blockchain_tip_hash will be required in a future version but is currently unused. |
| 75 | + channel_manager = ChannelManager.constructor_new(network, fee_estimator, chain_watch, tx_broadcaster, logger, keys_interface, config, current_blockchain_tip_height); |
| 76 | + } |
| 77 | + |
| 78 | + /** |
| 79 | + * Utility which adds all of the deserialized ChannelMonitors to the chain watch so that further updates from the |
| 80 | + * ChannelManager are processed as normal. |
| 81 | + */ |
| 82 | + public void chain_sync_completed() { |
| 83 | + for (TwoTuple<ChannelMonitor, byte[]> monitor: channel_monitors) { |
| 84 | + this.chain_watch.watch_channel(monitor.a.get_funding_txo().a, monitor.a); |
| 85 | + } |
| 86 | + } |
| 87 | +} |
0 commit comments