#ifndef LIGHTNING_PLUGINS_SPENDER_MULTIFUNDCHANNEL_H #define LIGHTNING_PLUGINS_SPENDER_MULTIFUNDCHANNEL_H #include "config.h" #include #include #include extern const struct plugin_command multifundchannel_commands[]; extern const size_t num_multifundchannel_commands; /* Which protocol this channel open is using. * OPEN_CHANNEL implies opt_dual_fund */ enum channel_protocol { FUND_CHANNEL, OPEN_CHANNEL, }; /* Current state of the funding process. */ enum multifundchannel_state { /* We have not yet performed `fundchannel_start`. */ MULTIFUNDCHANNEL_START_NOT_YET = 0, /* The `connect` command succeeded. `*/ MULTIFUNDCHANNEL_CONNECTED, /* The `fundchannel_start` or `openchannel_init` command * succeeded. */ MULTIFUNDCHANNEL_STARTED, /* V1 states */ /* The `fundchannel_complete` command succeeded. */ MULTIFUNDCHANNEL_COMPLETED, /* V2 states */ /* The `openchannel_update` command succeeded. */ MULTIFUNDCHANNEL_UPDATED, /* The commitments for this destinations have been secured */ MULTIFUNDCHANNEL_SECURED, /* We've recieved the peer sigs for this destination */ MULTIFUNDCHANNEL_SIGNED, /* We've gotten their sigs, but still waiting for their commit sigs */ MULTIFUNDCHANNEL_SIGNED_NOT_SECURED, /* The transaction might now be broadcasted. */ MULTIFUNDCHANNEL_DONE, /* Global fail state. Oops */ MULTIFUNDCHANNEL_FAILED, }; /* Stores a destination that was removed due to some failure. */ struct multifundchannel_removed { /* The destination we removed. */ struct node_id id; /* The method that failed: connect, fundchannel_start, fundchannel_complete. */ const char *method; const char *error_message; errcode_t error_code; /* Optional JSON object containing extra data */ const char *error_data; }; /* the object for a single destination. */ struct multifundchannel_destination { /* the overall multifundchannel command object. */ struct multifundchannel_command *mfc; /* the overall multifundchannel_command contains an array of multifundchannel_destinations. this provides the index within the array. this is used in debug printing. */ unsigned int index; /* id for this destination. */ struct node_id id; /* address hint for this destination, null if not specified. */ const char *addrhint; /* the features this destination has. */ const u8 *their_features; /* whether we have `fundchannel_start`, failed `connect` or `fundchannel_complete`, etc. */ enum multifundchannel_state state; /* Last known state before failure */ enum multifundchannel_state fail_state; /* the actual target script and address. */ const u8 *funding_script; const char *funding_addr; /* the upfront shutdown script for this channel */ const char *close_to_str; /* The scriptpubkey we will close to. Only set if * peer supports opt_upfront_shutdownscript and * we passsed in a valid close_to_str */ const u8 *close_to_script; /* the amount to be funded for this destination. if the specified amount is "all" then the `all` flag is set, and the amount is initially 0 until we have figured out how much exactly "all" is, after the dryrun stage. */ bool all; struct amount_sat amount; /* the output index for this destination. */ unsigned int outnum; /* whether the channel to this destination will be announced. */ bool announce; /* how much of the initial funding to push to the destination. */ struct amount_msat push_msat; /* the actual channel_id. */ struct channel_id channel_id; const char *error_message; errcode_t error_code; /* Optional JSON object containing extra data */ const char *error_data; /* what channel protocol this destination is using */ enum channel_protocol protocol; /* PSBT for the inflight channel open (OPEN_CHANNEL) */ struct wally_psbt *psbt; /* PSBT for the inflight channel open, updated (OPEN_CHANNEL) */ struct wally_psbt *updated_psbt; /* serial of the funding output for this channel (OPEN_CHANNEL) */ u64 funding_serial; /* amount to request peer to lease (OPEN_CHANNEL) */ struct amount_sat request_amt; /* Channel lease rates that we expect the peer to respond with */ struct lease_rates *rates; /* Number of blocks to wait before sending `channel_ready`. */ u32 *mindepth; }; /* The object for a single multifundchannel command. */ struct multifundchannel_command { /* A unique numeric identifier for this particular multifundchannel execution. This is used for debug logs; we want to be able to identify *which* multifundchannel is being described in the debug logs, especially if the user runs multiple `multifundchannel` commands in parallel, or in very close sequence, which might confuse us with *which* debug message belongs with *which* command. We actually just reuse the id from the cmd. Store it here for easier access. */ u64 id; /* The plugin-level command. */ struct command *cmd; /* An array of destinations. */ struct multifundchannel_destination *destinations; /* Number of pending parallel fundchannel_start or fundchannel_complete. */ size_t pending; /* The feerate desired by the user. */ const char *feerate_str; /* If specified, the feerate to be used for channel commitment * transactions. Defaults to the `feerate_str` if not provided. */ const char *cmtmt_feerate_str; /* The minimum number of confirmations for owned UTXOs to be selected. */ u32 minconf; /* The set of utxos to be used. */ const char *utxos_str; /* How long should we keep going if things fail. */ size_t minchannels; /* Array of destinations that were removed in a best-effort attempt to fund as many channels as possible. */ struct multifundchannel_removed *removeds; /* The PSBT of the funding transaction we are building. Prior to `fundchannel_start` completing for all destinations, this contains an unsigned incomplete transaction that is just a reservation of the inputs. After `fundchannel_start`, this contains an unsigned transaction with complete outputs. After `fundchannel_complete`, this contains a signed, finalized transaction. */ struct wally_psbt *psbt; /* The actual feerate of the PSBT. */ u32 feerate_per_kw; /* The expected weight of the PSBT after adding in all the outputs. * In weight units (sipa). */ u32 estimated_final_weight; /* Excess satoshi from the PSBT. * If "all" this is the entire amount; if not "all" this is the * proposed change amount, which if dusty should be donated to * the miners. */ struct amount_sat excess_sat; /* A convenient change address. NULL at the start, filled in * if we detect we need it. */ const u8 *change_scriptpubkey; /* Whether we need a change output. */ bool change_needed; /* The change amount. */ struct amount_sat change_amount; /* The txid of the final funding transaction. */ struct bitcoin_txid *txid; /* The actual tx of the actual final funding transaction that was broadcast. */ const char *final_tx; const char *final_txid; /* V2 things */ struct list_node list; /* V2 channel opens use this flag to gate PSBT signing */ bool sigs_collected; }; /* Use this instead of forward_error. */ struct command_result * mfc_forward_error(struct command *cmd, const char *buf, const jsmntok_t *error, struct multifundchannel_command *); /* When a destination fails, record the furthest state reached, and the * error message for the failure */ void fail_destination_tok(struct multifundchannel_destination *dest, const char *buf, const jsmntok_t *error); void fail_destination_msg(struct multifundchannel_destination *dest, int error_code, const char *err_str TAKES); /* dest_count - Returns count of destinations using given protocol version */ size_t dest_count(const struct multifundchannel_command *mfc, enum channel_protocol); /* Is this destination using the v2/OPEN_CHANNEL protocol? */ bool is_v2(const struct multifundchannel_destination *dest); /* Use this instead of command_finished. */ struct command_result * mfc_finished(struct multifundchannel_command *, struct json_stream *response); struct command_result * after_channel_start(struct multifundchannel_command *mfc); struct command_result * perform_fundchannel_complete(struct multifundchannel_command *mfc); struct command_result * perform_signpsbt(struct multifundchannel_command *mfc); struct command_result * multifundchannel_finished(struct multifundchannel_command *mfc); struct command_result * redo_multifundchannel(struct multifundchannel_command *mfc, const char *failing_method, const char *why); #endif /* LIGHTNING_PLUGINS_SPENDER_MULTIFUNDCHANNEL_H */