Skip to content

Commit

Permalink
onchaind: cap max_possible_feerate using commitment transaction.
Browse files Browse the repository at this point in the history
The commitment tx uses the same feerate as the HTLC txs (which we have
to grind to find), but we can't use it directly since the fee could be
increased by the presence of dust HTLCs.  We can still use it to cap
the maximum though.

Time before: 1m6.984s
Time after:  0m15.794s

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Changelog-Fixed: onchaind is much faster when unilaterally closing old channels.
  • Loading branch information
rustyrussell authored and cdecker committed Dec 7, 2020
1 parent 5bc61e7 commit e13e3e9
Showing 1 changed file with 51 additions and 0 deletions.
51 changes: 51 additions & 0 deletions onchaind/onchaind.c
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,55 @@ static bool wally_tx_output_scripteq(const struct wally_tx_output *out,
return memeq(out->script, out->script_len, script, tal_bytelen(script));
}

/* The feerate for the HTLC txs (which we grind) are the same as the
* feerate for the main tx. However, there may be dust HTLCs which
* were added to the fee, so we can only estimate a maximum feerate */
static void trim_maximum_feerate(struct amount_sat funding,
const struct tx_parts *commitment)
{
size_t weight;
struct amount_sat fee = funding;

/* FIXME: This doesn't work for elements? */
if (chainparams->is_elements)
return;

weight = bitcoin_tx_core_weight(tal_count(commitment->inputs),
tal_count(commitment->outputs));

/* BOLT #3:
* ## Commitment Transaction
*...
* * `txin[0]` script bytes: 0
* * `txin[0]` witness: `0 <signature_for_pubkey1> <signature_for_pubkey2>`
*/
/* Account for witness (1 byte count + 1 empty + sig + sig) */
assert(tal_count(commitment->inputs) == 1);
weight += bitcoin_tx_input_weight(false, 1 + 1 + 2 * bitcoin_tx_input_sig_weight());

for (size_t i = 0; i < tal_count(commitment->outputs); i++) {
struct amount_asset amt;
weight += bitcoin_tx_output_weight(commitment->outputs[i]
->script_len);

amt = wally_tx_output_get_amount(commitment->outputs[i]);
if (!amount_asset_is_main(&amt))
continue;
if (!amount_sat_sub(&fee, fee, amount_asset_to_sat(&amt))) {
status_failed(STATUS_FAIL_INTERNAL_ERROR,
"Unable to subtract fee");
}
}

status_debug("reducing max_possible_feerate from %u...",
max_possible_feerate);
/* This is naive, but simple. */
while (amount_sat_greater(amount_tx_fee(max_possible_feerate, weight),
fee))
max_possible_feerate--;
status_debug("... to %u", max_possible_feerate);
}

static void send_coin_mvt(struct chain_coin_mvt *mvt TAKES)
{
wire_sync_write(REQ_FD,
Expand Down Expand Up @@ -3767,6 +3816,8 @@ int main(int argc, char *argv[])
type_to_string(tmpctx, struct pubkey,
&old_remote_per_commit_point));

trim_maximum_feerate(funding, tx);

/* BOLT #5:
*
* There are three ways a channel can end:
Expand Down

0 comments on commit e13e3e9

Please sign in to comment.