mirror of
https://github.com/aljazceru/lightning.git
synced 2025-12-20 15:44:21 +01:00
mfc: rm declarations; invert call chain
Move only.
This commit is contained in:
@@ -621,11 +621,208 @@ This lets us initiate later with fundchannel_start with confidence that we
|
||||
can actually afford the channels we will create.
|
||||
*/
|
||||
|
||||
static struct command_result *
|
||||
perform_channel_start(struct multifundchannel_command *mfc);
|
||||
|
||||
static struct command_result *
|
||||
mfc_psbt_acquired(struct multifundchannel_command *mfc)
|
||||
{
|
||||
/* Add serials to all of our input/outputs, so they're stable
|
||||
* for the life of the tx */
|
||||
psbt_add_serials(mfc->psbt, TX_INITIATOR);
|
||||
|
||||
/* We also mark all of our inputs as *ours*, so we
|
||||
* can easily identify them for `signpsbt`, later */
|
||||
for (size_t i = 0; i < mfc->psbt->num_inputs; i++)
|
||||
psbt_input_mark_ours(mfc->psbt, &mfc->psbt->inputs[i]);
|
||||
|
||||
return perform_channel_start(mfc);
|
||||
}
|
||||
|
||||
static struct command_result *
|
||||
after_newaddr(struct command *cmd,
|
||||
const char *buf,
|
||||
const jsmntok_t *result,
|
||||
struct multifundchannel_command *mfc)
|
||||
{
|
||||
const jsmntok_t *field;
|
||||
|
||||
field = json_get_member(buf, result, "bech32");
|
||||
if (!field)
|
||||
plugin_err(cmd->plugin,
|
||||
"No bech32 field in newaddr result: %.*s",
|
||||
json_tok_full_len(result),
|
||||
json_tok_full(buf, result));
|
||||
if (json_to_address_scriptpubkey(mfc, chainparams, buf, field,
|
||||
&mfc->change_scriptpubkey)
|
||||
!= ADDRESS_PARSE_SUCCESS)
|
||||
plugin_err(cmd->plugin,
|
||||
"Unparseable bech32 field in newaddr result: %.*s",
|
||||
json_tok_full_len(result),
|
||||
json_tok_full(buf, result));
|
||||
|
||||
return mfc_psbt_acquired(mfc);
|
||||
}
|
||||
|
||||
static struct command_result *
|
||||
acquire_change_address(struct multifundchannel_command *mfc)
|
||||
{
|
||||
struct out_req *req;
|
||||
req = jsonrpc_request_start(mfc->cmd->plugin, mfc->cmd,
|
||||
"newaddr",
|
||||
&after_newaddr, &mfc_forward_error,
|
||||
mfc);
|
||||
json_add_string(req->js, "addresstype", "bech32");
|
||||
return send_outreq(mfc->cmd->plugin, req);
|
||||
}
|
||||
|
||||
static struct command_result *
|
||||
handle_mfc_change(struct multifundchannel_command *mfc)
|
||||
{
|
||||
size_t change_weight;
|
||||
struct amount_sat change_fee, fee_paid, total_fee;
|
||||
struct amount_sat change_min_limit;
|
||||
|
||||
/* Determine if adding a change output is worth it.
|
||||
* Get the weight of a change output and how much it
|
||||
* costs.
|
||||
*/
|
||||
change_weight = bitcoin_tx_output_weight(
|
||||
BITCOIN_SCRIPTPUBKEY_P2WPKH_LEN);
|
||||
|
||||
/* To avoid 'off-by-one' errors due to rounding down
|
||||
* (which we do in `amount_tx_fee`), we find the total calculated
|
||||
* fees (estimated_weight + change weight @ feerate) and subtract
|
||||
* the originally calculated fees (estimated_weight @ feerate) */
|
||||
fee_paid = amount_tx_fee(mfc->feerate_per_kw,
|
||||
mfc->estimated_final_weight);
|
||||
total_fee = amount_tx_fee(mfc->feerate_per_kw,
|
||||
mfc->estimated_final_weight + change_weight);
|
||||
if (!amount_sat_sub(&change_fee, total_fee, fee_paid))
|
||||
abort();
|
||||
|
||||
/* The limit is equal to the change_fee plus the dust limit. */
|
||||
if (!amount_sat_add(&change_min_limit,
|
||||
change_fee, chainparams->dust_limit))
|
||||
plugin_err(mfc->cmd->plugin,
|
||||
"Overflow dust limit and change fee.");
|
||||
|
||||
/* Is the excess over the limit? */
|
||||
if (amount_sat_greater(mfc->excess_sat, change_min_limit)) {
|
||||
bool ok = amount_sat_sub(&mfc->change_amount,
|
||||
mfc->excess_sat, change_fee);
|
||||
assert(ok);
|
||||
mfc->change_needed = true;
|
||||
if (!mfc->change_scriptpubkey)
|
||||
return acquire_change_address(mfc);
|
||||
} else
|
||||
mfc->change_needed = false;
|
||||
|
||||
return mfc_psbt_acquired(mfc);
|
||||
}
|
||||
|
||||
/* If one of the destinations specified "all", figure out how much that is. */
|
||||
static struct command_result *
|
||||
compute_mfc_all(struct multifundchannel_command *mfc)
|
||||
{
|
||||
size_t all_index = SIZE_MAX;
|
||||
struct multifundchannel_destination *all_dest;
|
||||
|
||||
assert(has_all(mfc));
|
||||
|
||||
for (size_t i = 0; i < tal_count(mfc->destinations); ++i) {
|
||||
struct multifundchannel_destination *dest;
|
||||
dest = &mfc->destinations[i];
|
||||
if (dest->all) {
|
||||
assert(all_index == SIZE_MAX);
|
||||
all_index = i;
|
||||
continue;
|
||||
}
|
||||
/* Subtract the amount from the excess. */
|
||||
if (!amount_sat_sub(&mfc->excess_sat,
|
||||
mfc->excess_sat, dest->amount))
|
||||
/* Not enough funds! */
|
||||
return mfc_fail(mfc, FUND_CANNOT_AFFORD,
|
||||
"Insufficient funds.");
|
||||
}
|
||||
assert(all_index != SIZE_MAX);
|
||||
all_dest = &mfc->destinations[all_index];
|
||||
|
||||
/* Is the excess above the dust amount? */
|
||||
if (amount_sat_less(mfc->excess_sat, chainparams->dust_limit))
|
||||
return mfc_fail(mfc, FUND_OUTPUT_IS_DUST,
|
||||
"Output 'all' %s would be dust",
|
||||
type_to_string(tmpctx, struct amount_sat,
|
||||
&mfc->excess_sat));
|
||||
|
||||
/* Assign the remainder to the 'all' output. */
|
||||
all_dest->amount = mfc->excess_sat;
|
||||
if (!feature_negotiated(plugin_feature_set(mfc->cmd->plugin),
|
||||
all_dest->their_features,
|
||||
OPT_LARGE_CHANNELS)
|
||||
&& amount_sat_greater(all_dest->amount,
|
||||
chainparams->max_funding))
|
||||
all_dest->amount = chainparams->max_funding;
|
||||
/* Remove it from the excess. */
|
||||
bool ok = amount_sat_sub(&mfc->excess_sat,
|
||||
mfc->excess_sat, all_dest->amount);
|
||||
assert(ok);
|
||||
/* Remove the 'all' flag. */
|
||||
all_dest->all = false;
|
||||
|
||||
/* Continue. */
|
||||
return handle_mfc_change(mfc);
|
||||
}
|
||||
|
||||
static struct command_result *
|
||||
after_fundpsbt(struct command *cmd,
|
||||
const char *buf,
|
||||
const jsmntok_t *result,
|
||||
struct multifundchannel_command *mfc);
|
||||
struct multifundchannel_command *mfc)
|
||||
{
|
||||
const jsmntok_t *field;
|
||||
|
||||
plugin_log(mfc->cmd->plugin, LOG_DBG,
|
||||
"mfc %"PRIu64": %s done.",
|
||||
mfc->id, mfc->utxos_str ? "utxopsbt" : "fundpsbt");
|
||||
|
||||
field = json_get_member(buf, result, "psbt");
|
||||
if (!field)
|
||||
goto fail;
|
||||
|
||||
mfc->psbt = psbt_from_b64(mfc,
|
||||
buf + field->start,
|
||||
field->end - field->start);
|
||||
if (!mfc->psbt)
|
||||
goto fail;
|
||||
|
||||
field = json_get_member(buf, result, "feerate_per_kw");
|
||||
if (!field || !json_to_u32(buf, field, &mfc->feerate_per_kw))
|
||||
goto fail;
|
||||
|
||||
field = json_get_member(buf, result, "estimated_final_weight");
|
||||
if (!field || !json_to_u32(buf, field, &mfc->estimated_final_weight))
|
||||
goto fail;
|
||||
|
||||
/* msat LOL. */
|
||||
field = json_get_member(buf, result, "excess_msat");
|
||||
if (!field || !parse_amount_sat(&mfc->excess_sat,
|
||||
buf + field->start,
|
||||
field->end - field->start))
|
||||
goto fail;
|
||||
|
||||
if (has_all(mfc))
|
||||
return compute_mfc_all(mfc);
|
||||
return handle_mfc_change(mfc);
|
||||
|
||||
fail:
|
||||
plugin_err(mfc->cmd->plugin,
|
||||
"Unexpected result from fundpsbt/utxopsbt: %.*s",
|
||||
json_tok_full_len(result),
|
||||
json_tok_full(buf, result));
|
||||
|
||||
}
|
||||
|
||||
|
||||
static struct command_result *
|
||||
perform_fundpsbt(struct multifundchannel_command *mfc)
|
||||
@@ -711,221 +908,6 @@ perform_fundpsbt(struct multifundchannel_command *mfc)
|
||||
return send_outreq(mfc->cmd->plugin, req);
|
||||
}
|
||||
|
||||
static struct command_result *
|
||||
compute_mfc_all(struct multifundchannel_command *mfc);
|
||||
static struct command_result *
|
||||
handle_mfc_change(struct multifundchannel_command *mfc);
|
||||
|
||||
static struct command_result *
|
||||
after_fundpsbt(struct command *cmd,
|
||||
const char *buf,
|
||||
const jsmntok_t *result,
|
||||
struct multifundchannel_command *mfc)
|
||||
{
|
||||
const jsmntok_t *field;
|
||||
|
||||
plugin_log(mfc->cmd->plugin, LOG_DBG,
|
||||
"mfc %"PRIu64": %s done.",
|
||||
mfc->id, mfc->utxos_str ? "utxopsbt" : "fundpsbt");
|
||||
|
||||
field = json_get_member(buf, result, "psbt");
|
||||
if (!field)
|
||||
goto fail;
|
||||
|
||||
mfc->psbt = psbt_from_b64(mfc,
|
||||
buf + field->start,
|
||||
field->end - field->start);
|
||||
if (!mfc->psbt)
|
||||
goto fail;
|
||||
|
||||
field = json_get_member(buf, result, "feerate_per_kw");
|
||||
if (!field || !json_to_u32(buf, field, &mfc->feerate_per_kw))
|
||||
goto fail;
|
||||
|
||||
field = json_get_member(buf, result, "estimated_final_weight");
|
||||
if (!field || !json_to_u32(buf, field, &mfc->estimated_final_weight))
|
||||
goto fail;
|
||||
|
||||
/* msat LOL. */
|
||||
field = json_get_member(buf, result, "excess_msat");
|
||||
if (!field || !parse_amount_sat(&mfc->excess_sat,
|
||||
buf + field->start,
|
||||
field->end - field->start))
|
||||
goto fail;
|
||||
|
||||
if (has_all(mfc))
|
||||
return compute_mfc_all(mfc);
|
||||
return handle_mfc_change(mfc);
|
||||
|
||||
fail:
|
||||
plugin_err(mfc->cmd->plugin,
|
||||
"Unexpected result from fundpsbt/utxopsbt: %.*s",
|
||||
json_tok_full_len(result),
|
||||
json_tok_full(buf, result));
|
||||
|
||||
}
|
||||
|
||||
/* If one of the destinations specified "all", figure out how much that is. */
|
||||
static struct command_result *
|
||||
compute_mfc_all(struct multifundchannel_command *mfc)
|
||||
{
|
||||
size_t all_index = SIZE_MAX;
|
||||
struct multifundchannel_destination *all_dest;
|
||||
|
||||
assert(has_all(mfc));
|
||||
|
||||
for (size_t i = 0; i < tal_count(mfc->destinations); ++i) {
|
||||
struct multifundchannel_destination *dest;
|
||||
dest = &mfc->destinations[i];
|
||||
if (dest->all) {
|
||||
assert(all_index == SIZE_MAX);
|
||||
all_index = i;
|
||||
continue;
|
||||
}
|
||||
/* Subtract the amount from the excess. */
|
||||
if (!amount_sat_sub(&mfc->excess_sat,
|
||||
mfc->excess_sat, dest->amount))
|
||||
/* Not enough funds! */
|
||||
return mfc_fail(mfc, FUND_CANNOT_AFFORD,
|
||||
"Insufficient funds.");
|
||||
}
|
||||
assert(all_index != SIZE_MAX);
|
||||
all_dest = &mfc->destinations[all_index];
|
||||
|
||||
/* Is the excess above the dust amount? */
|
||||
if (amount_sat_less(mfc->excess_sat, chainparams->dust_limit))
|
||||
return mfc_fail(mfc, FUND_OUTPUT_IS_DUST,
|
||||
"Output 'all' %s would be dust",
|
||||
type_to_string(tmpctx, struct amount_sat,
|
||||
&mfc->excess_sat));
|
||||
|
||||
/* Assign the remainder to the 'all' output. */
|
||||
all_dest->amount = mfc->excess_sat;
|
||||
if (!feature_negotiated(plugin_feature_set(mfc->cmd->plugin),
|
||||
all_dest->their_features,
|
||||
OPT_LARGE_CHANNELS)
|
||||
&& amount_sat_greater(all_dest->amount,
|
||||
chainparams->max_funding))
|
||||
all_dest->amount = chainparams->max_funding;
|
||||
/* Remove it from the excess. */
|
||||
bool ok = amount_sat_sub(&mfc->excess_sat,
|
||||
mfc->excess_sat, all_dest->amount);
|
||||
assert(ok);
|
||||
/* Remove the 'all' flag. */
|
||||
all_dest->all = false;
|
||||
|
||||
/* Continue. */
|
||||
return handle_mfc_change(mfc);
|
||||
}
|
||||
|
||||
static struct command_result *
|
||||
acquire_change_address(struct multifundchannel_command *mfc);
|
||||
static struct command_result *
|
||||
mfc_psbt_acquired(struct multifundchannel_command *mfc);
|
||||
|
||||
static struct command_result *
|
||||
handle_mfc_change(struct multifundchannel_command *mfc)
|
||||
{
|
||||
size_t change_weight;
|
||||
struct amount_sat change_fee, fee_paid, total_fee;
|
||||
struct amount_sat change_min_limit;
|
||||
|
||||
/* Determine if adding a change output is worth it.
|
||||
* Get the weight of a change output and how much it
|
||||
* costs.
|
||||
*/
|
||||
change_weight = bitcoin_tx_output_weight(
|
||||
BITCOIN_SCRIPTPUBKEY_P2WPKH_LEN);
|
||||
|
||||
/* To avoid 'off-by-one' errors due to rounding down
|
||||
* (which we do in `amount_tx_fee`), we find the total calculated
|
||||
* fees (estimated_weight + change weight @ feerate) and subtract
|
||||
* the originally calculated fees (estimated_weight @ feerate) */
|
||||
fee_paid = amount_tx_fee(mfc->feerate_per_kw,
|
||||
mfc->estimated_final_weight);
|
||||
total_fee = amount_tx_fee(mfc->feerate_per_kw,
|
||||
mfc->estimated_final_weight + change_weight);
|
||||
if (!amount_sat_sub(&change_fee, total_fee, fee_paid))
|
||||
abort();
|
||||
|
||||
/* The limit is equal to the change_fee plus the dust limit. */
|
||||
if (!amount_sat_add(&change_min_limit,
|
||||
change_fee, chainparams->dust_limit))
|
||||
plugin_err(mfc->cmd->plugin,
|
||||
"Overflow dust limit and change fee.");
|
||||
|
||||
/* Is the excess over the limit? */
|
||||
if (amount_sat_greater(mfc->excess_sat, change_min_limit)) {
|
||||
bool ok = amount_sat_sub(&mfc->change_amount,
|
||||
mfc->excess_sat, change_fee);
|
||||
assert(ok);
|
||||
mfc->change_needed = true;
|
||||
if (!mfc->change_scriptpubkey)
|
||||
return acquire_change_address(mfc);
|
||||
} else
|
||||
mfc->change_needed = false;
|
||||
|
||||
return mfc_psbt_acquired(mfc);
|
||||
}
|
||||
|
||||
static struct command_result *
|
||||
after_newaddr(struct command *cmd,
|
||||
const char *buf,
|
||||
const jsmntok_t *result,
|
||||
struct multifundchannel_command *mfc);
|
||||
|
||||
static struct command_result *
|
||||
acquire_change_address(struct multifundchannel_command *mfc)
|
||||
{
|
||||
struct out_req *req;
|
||||
req = jsonrpc_request_start(mfc->cmd->plugin, mfc->cmd,
|
||||
"newaddr",
|
||||
&after_newaddr, &mfc_forward_error,
|
||||
mfc);
|
||||
json_add_string(req->js, "addresstype", "bech32");
|
||||
return send_outreq(mfc->cmd->plugin, req);
|
||||
}
|
||||
static struct command_result *
|
||||
after_newaddr(struct command *cmd,
|
||||
const char *buf,
|
||||
const jsmntok_t *result,
|
||||
struct multifundchannel_command *mfc)
|
||||
{
|
||||
const jsmntok_t *field;
|
||||
|
||||
field = json_get_member(buf, result, "bech32");
|
||||
if (!field)
|
||||
plugin_err(cmd->plugin,
|
||||
"No bech32 field in newaddr result: %.*s",
|
||||
json_tok_full_len(result),
|
||||
json_tok_full(buf, result));
|
||||
if (json_to_address_scriptpubkey(mfc, chainparams, buf, field,
|
||||
&mfc->change_scriptpubkey)
|
||||
!= ADDRESS_PARSE_SUCCESS)
|
||||
plugin_err(cmd->plugin,
|
||||
"Unparseable bech32 field in newaddr result: %.*s",
|
||||
json_tok_full_len(result),
|
||||
json_tok_full(buf, result));
|
||||
|
||||
return mfc_psbt_acquired(mfc);
|
||||
}
|
||||
|
||||
static struct command_result *
|
||||
perform_channel_start(struct multifundchannel_command *mfc);
|
||||
static struct command_result *
|
||||
mfc_psbt_acquired(struct multifundchannel_command *mfc)
|
||||
{
|
||||
/* Add serials to all of our input/outputs, so they're stable
|
||||
* for the life of the tx */
|
||||
psbt_add_serials(mfc->psbt, TX_INITIATOR);
|
||||
|
||||
/* We also mark all of our inputs as *ours*, so we
|
||||
* can easily identify them for `signpsbt`, later */
|
||||
for (size_t i = 0; i < mfc->psbt->num_inputs; i++)
|
||||
psbt_input_mark_ours(mfc->psbt, &mfc->psbt->inputs[i]);
|
||||
|
||||
return perform_channel_start(mfc);
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
Reference in New Issue
Block a user