2017-07-04 02:49:43 +02:00
|
|
|
#include <bitcoin/script.h>
|
2019-05-04 07:53:13 +02:00
|
|
|
#include <ccan/fdpass/fdpass.h>
|
2020-08-25 04:15:48 +02:00
|
|
|
#include <closingd/closingd_wiregen.h>
|
2017-08-28 18:02:01 +02:00
|
|
|
#include <common/close_tx.h>
|
2020-01-03 14:08:29 +01:00
|
|
|
#include <common/closing_fee.h>
|
2017-08-28 18:05:01 +02:00
|
|
|
#include <common/crypto_sync.h>
|
2017-08-28 18:02:01 +02:00
|
|
|
#include <common/derive_basepoints.h>
|
2017-08-28 18:04:01 +02:00
|
|
|
#include <common/htlc.h>
|
2018-11-22 03:17:29 +01:00
|
|
|
#include <common/memleak.h>
|
2018-02-23 06:53:47 +01:00
|
|
|
#include <common/peer_billboard.h>
|
2017-09-12 06:55:52 +02:00
|
|
|
#include <common/peer_failed.h>
|
2019-06-03 20:11:25 +02:00
|
|
|
#include <common/per_peer_state.h>
|
2018-01-31 03:53:42 +01:00
|
|
|
#include <common/read_peer_msg.h>
|
2018-05-05 06:57:58 +02:00
|
|
|
#include <common/socket_close.h>
|
2017-08-28 18:05:01 +02:00
|
|
|
#include <common/status.h>
|
2018-01-08 11:01:09 +01:00
|
|
|
#include <common/subdaemon.h>
|
2017-08-28 18:02:01 +02:00
|
|
|
#include <common/type_to_string.h>
|
|
|
|
#include <common/utils.h>
|
|
|
|
#include <common/version.h>
|
2018-01-30 01:44:08 +01:00
|
|
|
#include <common/wire_error.h>
|
2017-07-04 02:49:43 +02:00
|
|
|
#include <errno.h>
|
2020-08-25 04:05:45 +02:00
|
|
|
#include <gossipd/gossipd_peerd_wiregen.h>
|
2020-08-25 03:55:38 +02:00
|
|
|
#include <hsmd/hsmd_wiregen.h>
|
2017-07-04 02:49:43 +02:00
|
|
|
#include <inttypes.h>
|
|
|
|
#include <stdio.h>
|
2017-08-28 18:05:01 +02:00
|
|
|
#include <unistd.h>
|
2021-04-01 20:22:44 +02:00
|
|
|
#include <wire/common_wiregen.h>
|
2017-07-04 02:49:43 +02:00
|
|
|
#include <wire/peer_wire.h>
|
|
|
|
#include <wire/wire_sync.h>
|
|
|
|
|
2019-05-04 07:53:13 +02:00
|
|
|
/* stdin == requests, 3 == peer, 4 = gossip, 5 = gossip_store, 6 = hsmd */
|
2017-07-04 02:49:43 +02:00
|
|
|
#define REQ_FD STDIN_FILENO
|
2019-05-04 07:53:13 +02:00
|
|
|
#define HSM_FD 6
|
2017-07-04 02:49:43 +02:00
|
|
|
|
|
|
|
static struct bitcoin_tx *close_tx(const tal_t *ctx,
|
2019-07-30 16:14:43 +02:00
|
|
|
const struct chainparams *chainparams,
|
2019-06-03 20:11:25 +02:00
|
|
|
struct per_peer_state *pps,
|
2017-09-12 06:55:52 +02:00
|
|
|
const struct channel_id *channel_id,
|
2017-07-04 02:49:43 +02:00
|
|
|
u8 *scriptpubkey[NUM_SIDES],
|
2017-12-18 07:41:52 +01:00
|
|
|
const struct bitcoin_txid *funding_txid,
|
2017-07-04 02:49:43 +02:00
|
|
|
unsigned int funding_txout,
|
2019-02-21 04:45:55 +01:00
|
|
|
struct amount_sat funding,
|
2020-05-21 21:46:19 +02:00
|
|
|
const u8 *funding_wscript,
|
2019-02-21 04:45:55 +01:00
|
|
|
const struct amount_sat out[NUM_SIDES],
|
2019-09-09 18:11:24 +02:00
|
|
|
enum side opener,
|
2019-02-21 04:45:55 +01:00
|
|
|
struct amount_sat fee,
|
2021-03-15 21:25:54 +01:00
|
|
|
struct amount_sat dust_limit,
|
|
|
|
const struct bitcoin_outpoint *wrong_funding)
|
2017-07-04 02:49:43 +02:00
|
|
|
{
|
|
|
|
struct bitcoin_tx *tx;
|
2019-02-21 04:45:55 +01:00
|
|
|
struct amount_sat out_minus_fee[NUM_SIDES];
|
2017-07-04 02:49:43 +02:00
|
|
|
|
2019-02-21 04:45:55 +01:00
|
|
|
out_minus_fee[LOCAL] = out[LOCAL];
|
|
|
|
out_minus_fee[REMOTE] = out[REMOTE];
|
2019-09-09 18:11:24 +02:00
|
|
|
if (!amount_sat_sub(&out_minus_fee[opener], out[opener], fee))
|
2021-02-02 13:49:01 +01:00
|
|
|
peer_failed_warn(pps, channel_id,
|
|
|
|
"Funder cannot afford fee %s (%s and %s)",
|
|
|
|
type_to_string(tmpctx, struct amount_sat, &fee),
|
|
|
|
type_to_string(tmpctx, struct amount_sat,
|
|
|
|
&out[LOCAL]),
|
|
|
|
type_to_string(tmpctx, struct amount_sat,
|
|
|
|
&out[REMOTE]));
|
2019-02-21 04:45:55 +01:00
|
|
|
|
2019-09-08 18:39:26 +02:00
|
|
|
status_debug("Making close tx at = %s/%s fee %s",
|
2019-02-21 04:45:55 +01:00
|
|
|
type_to_string(tmpctx, struct amount_sat, &out[LOCAL]),
|
|
|
|
type_to_string(tmpctx, struct amount_sat, &out[REMOTE]),
|
|
|
|
type_to_string(tmpctx, struct amount_sat, &fee));
|
2017-07-10 03:54:45 +02:00
|
|
|
|
2017-09-12 06:55:52 +02:00
|
|
|
/* FIXME: We need to allow this! */
|
|
|
|
tx = create_close_tx(ctx,
|
2019-07-30 16:14:43 +02:00
|
|
|
chainparams,
|
2017-09-12 06:55:52 +02:00
|
|
|
scriptpubkey[LOCAL], scriptpubkey[REMOTE],
|
2020-05-21 21:46:19 +02:00
|
|
|
funding_wscript,
|
2017-07-04 02:49:43 +02:00
|
|
|
funding_txid,
|
|
|
|
funding_txout,
|
2019-02-21 04:45:55 +01:00
|
|
|
funding,
|
|
|
|
out_minus_fee[LOCAL],
|
|
|
|
out_minus_fee[REMOTE],
|
2017-07-04 02:49:43 +02:00
|
|
|
dust_limit);
|
|
|
|
if (!tx)
|
2021-02-02 13:49:01 +01:00
|
|
|
peer_failed_err(pps, channel_id,
|
|
|
|
"Both outputs below dust limit:"
|
|
|
|
" funding = %s"
|
|
|
|
" fee = %s"
|
|
|
|
" dust_limit = %s"
|
|
|
|
" LOCAL = %s"
|
|
|
|
" REMOTE = %s",
|
|
|
|
type_to_string(tmpctx, struct amount_sat, &funding),
|
|
|
|
type_to_string(tmpctx, struct amount_sat, &fee),
|
|
|
|
type_to_string(tmpctx, struct amount_sat, &dust_limit),
|
|
|
|
type_to_string(tmpctx, struct amount_sat, &out[LOCAL]),
|
|
|
|
type_to_string(tmpctx, struct amount_sat, &out[REMOTE]));
|
2021-03-15 21:25:54 +01:00
|
|
|
|
|
|
|
if (wrong_funding)
|
|
|
|
bitcoin_tx_input_set_txid(tx, 0,
|
|
|
|
&wrong_funding->txid,
|
|
|
|
wrong_funding->n);
|
|
|
|
|
2017-07-04 02:49:43 +02:00
|
|
|
return tx;
|
|
|
|
}
|
|
|
|
|
2018-08-02 08:49:56 +02:00
|
|
|
/* Handle random messages we might get, returning the first non-handled one. */
|
|
|
|
static u8 *closing_read_peer_msg(const tal_t *ctx,
|
2019-06-03 20:11:25 +02:00
|
|
|
struct per_peer_state *pps,
|
2018-08-02 08:49:56 +02:00
|
|
|
const struct channel_id *channel_id)
|
|
|
|
{
|
|
|
|
for (;;) {
|
|
|
|
u8 *msg;
|
|
|
|
bool from_gossipd;
|
|
|
|
|
|
|
|
clean_tmpctx();
|
2019-06-03 20:11:25 +02:00
|
|
|
msg = peer_or_gossip_sync_read(ctx, pps, &from_gossipd);
|
2018-08-02 08:49:56 +02:00
|
|
|
if (from_gossipd) {
|
2019-06-03 20:11:25 +02:00
|
|
|
handle_gossip_msg(pps, take(msg));
|
2018-08-02 08:49:56 +02:00
|
|
|
continue;
|
|
|
|
}
|
2021-04-01 20:22:44 +02:00
|
|
|
/* Handle custommsgs */
|
|
|
|
enum peer_wire type = fromwire_peektype(msg);
|
|
|
|
if (type % 2 == 1 && !peer_wire_is_defined(type)) {
|
|
|
|
/* The message is not part of the messages we know
|
|
|
|
* how to handle. Assume is custommsg, forward it
|
|
|
|
* to master. */
|
|
|
|
wire_sync_write(REQ_FD, take(towire_custommsg_in(NULL, msg)));
|
|
|
|
continue;
|
|
|
|
}
|
2019-12-13 11:16:14 +01:00
|
|
|
if (!handle_peer_gossip_or_error(pps, channel_id, false, msg))
|
2018-08-02 08:49:56 +02:00
|
|
|
return msg;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-06-03 20:11:25 +02:00
|
|
|
static void send_offer(struct per_peer_state *pps,
|
2019-07-30 16:14:43 +02:00
|
|
|
const struct chainparams *chainparams,
|
2018-02-02 01:55:03 +01:00
|
|
|
const struct channel_id *channel_id,
|
|
|
|
const struct pubkey funding_pubkey[NUM_SIDES],
|
2020-05-21 21:46:19 +02:00
|
|
|
const u8 *funding_wscript,
|
2018-02-02 01:55:03 +01:00
|
|
|
u8 *scriptpubkey[NUM_SIDES],
|
|
|
|
const struct bitcoin_txid *funding_txid,
|
|
|
|
unsigned int funding_txout,
|
2019-02-21 04:45:55 +01:00
|
|
|
struct amount_sat funding,
|
|
|
|
const struct amount_sat out[NUM_SIDES],
|
2019-09-09 18:11:24 +02:00
|
|
|
enum side opener,
|
2019-02-21 04:45:55 +01:00
|
|
|
struct amount_sat our_dust_limit,
|
2021-03-15 21:25:54 +01:00
|
|
|
struct amount_sat fee_to_offer,
|
|
|
|
const struct bitcoin_outpoint *wrong_funding)
|
2018-02-02 01:55:03 +01:00
|
|
|
{
|
|
|
|
struct bitcoin_tx *tx;
|
2018-12-03 00:15:06 +01:00
|
|
|
struct bitcoin_signature our_sig;
|
2018-02-02 01:55:03 +01:00
|
|
|
u8 *msg;
|
|
|
|
|
|
|
|
/* BOLT #2:
|
|
|
|
*
|
2018-06-17 12:13:44 +02:00
|
|
|
* - MUST set `signature` to the Bitcoin signature of the close
|
|
|
|
* transaction, as specified in [BOLT
|
|
|
|
* #3](03-transactions.md#closing-transaction).
|
2018-02-02 01:55:03 +01:00
|
|
|
*/
|
2019-07-30 16:14:43 +02:00
|
|
|
tx = close_tx(tmpctx, chainparams, pps, channel_id,
|
2018-02-02 01:55:03 +01:00
|
|
|
scriptpubkey,
|
|
|
|
funding_txid,
|
|
|
|
funding_txout,
|
2019-02-21 04:45:55 +01:00
|
|
|
funding,
|
2020-05-21 21:46:19 +02:00
|
|
|
funding_wscript,
|
2019-02-21 04:45:55 +01:00
|
|
|
out,
|
2021-03-15 21:25:54 +01:00
|
|
|
opener, fee_to_offer, our_dust_limit,
|
|
|
|
wrong_funding);
|
2018-02-02 01:55:03 +01:00
|
|
|
|
|
|
|
/* BOLT #3:
|
|
|
|
*
|
|
|
|
* ## Closing Transaction
|
|
|
|
*...
|
2018-06-17 12:13:44 +02:00
|
|
|
* Each node offering a signature... MAY eliminate its
|
2018-02-02 01:55:03 +01:00
|
|
|
* own output.
|
|
|
|
*/
|
|
|
|
/* (We don't do this). */
|
2018-07-23 04:23:03 +02:00
|
|
|
wire_sync_write(HSM_FD,
|
2020-08-25 03:55:38 +02:00
|
|
|
take(towire_hsmd_sign_mutual_close_tx(NULL,
|
2018-07-23 04:23:03 +02:00
|
|
|
tx,
|
2020-05-27 03:37:44 +02:00
|
|
|
&funding_pubkey[REMOTE])));
|
2018-07-23 04:23:03 +02:00
|
|
|
msg = wire_sync_read(tmpctx, HSM_FD);
|
2020-08-25 03:55:38 +02:00
|
|
|
if (!fromwire_hsmd_sign_tx_reply(msg, &our_sig))
|
2018-07-23 04:23:03 +02:00
|
|
|
status_failed(STATUS_FAIL_HSM_IO,
|
|
|
|
"Bad hsm_sign_mutual_close_tx reply %s",
|
|
|
|
tal_hex(tmpctx, msg));
|
2018-02-02 01:55:03 +01:00
|
|
|
|
2019-09-08 18:39:26 +02:00
|
|
|
status_debug("sending fee offer %s",
|
2019-02-21 04:45:55 +01:00
|
|
|
type_to_string(tmpctx, struct amount_sat, &fee_to_offer));
|
2018-02-02 01:55:03 +01:00
|
|
|
|
2018-12-03 00:15:06 +01:00
|
|
|
assert(our_sig.sighash_type == SIGHASH_ALL);
|
2019-02-21 04:45:55 +01:00
|
|
|
msg = towire_closing_signed(NULL, channel_id, fee_to_offer, &our_sig.s);
|
2019-06-03 20:11:25 +02:00
|
|
|
sync_crypto_write(pps, take(msg));
|
2018-02-02 01:55:03 +01:00
|
|
|
}
|
|
|
|
|
2018-12-03 00:15:06 +01:00
|
|
|
static void tell_master_their_offer(const struct bitcoin_signature *their_sig,
|
2019-04-10 23:58:01 +02:00
|
|
|
const struct bitcoin_tx *tx,
|
|
|
|
struct bitcoin_txid *tx_id)
|
2018-02-02 01:55:03 +01:00
|
|
|
{
|
2020-08-25 04:15:48 +02:00
|
|
|
u8 *msg = towire_closingd_received_signature(NULL, their_sig, tx);
|
2018-02-02 01:55:03 +01:00
|
|
|
if (!wire_sync_write(REQ_FD, take(msg)))
|
|
|
|
status_failed(STATUS_FAIL_MASTER_IO,
|
|
|
|
"Writing received to master: %s",
|
|
|
|
strerror(errno));
|
|
|
|
|
|
|
|
/* Wait for master to ack, to make sure it's in db. */
|
|
|
|
msg = wire_sync_read(NULL, REQ_FD);
|
2020-08-25 04:15:48 +02:00
|
|
|
if (!fromwire_closingd_received_signature_reply(msg, tx_id))
|
|
|
|
master_badmsg(WIRE_CLOSINGD_RECEIVED_SIGNATURE_REPLY, msg);
|
2018-02-02 01:55:03 +01:00
|
|
|
tal_free(msg);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Returns fee they offered. */
|
2019-02-21 04:45:55 +01:00
|
|
|
static struct amount_sat
|
2019-06-03 20:11:25 +02:00
|
|
|
receive_offer(struct per_peer_state *pps,
|
2019-07-30 16:14:43 +02:00
|
|
|
const struct chainparams *chainparams,
|
2019-02-21 04:45:55 +01:00
|
|
|
const struct channel_id *channel_id,
|
|
|
|
const struct pubkey funding_pubkey[NUM_SIDES],
|
|
|
|
const u8 *funding_wscript,
|
|
|
|
u8 *scriptpubkey[NUM_SIDES],
|
|
|
|
const struct bitcoin_txid *funding_txid,
|
|
|
|
unsigned int funding_txout,
|
|
|
|
struct amount_sat funding,
|
|
|
|
const struct amount_sat out[NUM_SIDES],
|
2019-09-09 18:11:24 +02:00
|
|
|
enum side opener,
|
2019-02-21 04:45:55 +01:00
|
|
|
struct amount_sat our_dust_limit,
|
2019-04-10 23:58:01 +02:00
|
|
|
struct amount_sat min_fee_to_accept,
|
2021-03-15 21:25:54 +01:00
|
|
|
const struct bitcoin_outpoint *wrong_funding,
|
2019-04-10 23:58:01 +02:00
|
|
|
struct bitcoin_txid *closing_txid)
|
2018-02-02 01:55:03 +01:00
|
|
|
{
|
|
|
|
u8 *msg;
|
|
|
|
struct channel_id their_channel_id;
|
2019-02-21 04:45:55 +01:00
|
|
|
struct amount_sat received_fee;
|
2018-12-03 00:15:06 +01:00
|
|
|
struct bitcoin_signature their_sig;
|
2018-02-02 01:55:03 +01:00
|
|
|
struct bitcoin_tx *tx;
|
|
|
|
|
|
|
|
/* Wait for them to say something interesting */
|
|
|
|
do {
|
2019-06-03 20:11:25 +02:00
|
|
|
msg = closing_read_peer_msg(tmpctx, pps, channel_id);
|
2018-02-02 01:55:03 +01:00
|
|
|
|
|
|
|
/* BOLT #2:
|
|
|
|
*
|
2018-06-17 12:13:44 +02:00
|
|
|
* - upon reconnection:
|
|
|
|
* - MUST ignore any redundant `funding_locked` it receives.
|
2018-02-02 01:55:03 +01:00
|
|
|
*/
|
|
|
|
/* This should only happen if we've made no commitments, but
|
|
|
|
* we don't have to check that: it's their problem. */
|
2018-08-02 08:49:56 +02:00
|
|
|
if (fromwire_peektype(msg) == WIRE_FUNDING_LOCKED)
|
2018-02-02 01:55:03 +01:00
|
|
|
msg = tal_free(msg);
|
|
|
|
/* BOLT #2:
|
2018-06-17 12:13:44 +02:00
|
|
|
* - if it has sent a previous `shutdown`:
|
|
|
|
* - MUST retransmit `shutdown`.
|
2018-02-02 01:55:03 +01:00
|
|
|
*/
|
2018-08-02 08:49:56 +02:00
|
|
|
else if (fromwire_peektype(msg) == WIRE_SHUTDOWN)
|
2018-02-02 01:55:03 +01:00
|
|
|
msg = tal_free(msg);
|
|
|
|
} while (!msg);
|
|
|
|
|
2018-12-03 00:15:06 +01:00
|
|
|
their_sig.sighash_type = SIGHASH_ALL;
|
2018-02-20 21:59:09 +01:00
|
|
|
if (!fromwire_closing_signed(msg, &their_channel_id,
|
2019-02-21 04:45:55 +01:00
|
|
|
&received_fee, &their_sig.s))
|
2021-02-02 13:49:01 +01:00
|
|
|
peer_failed_warn(pps, channel_id,
|
|
|
|
"Expected closing_signed: %s",
|
|
|
|
tal_hex(tmpctx, msg));
|
2018-02-02 01:55:03 +01:00
|
|
|
|
|
|
|
/* BOLT #2:
|
|
|
|
*
|
2018-06-17 12:13:44 +02:00
|
|
|
* The receiving node:
|
2019-01-14 03:26:25 +01:00
|
|
|
* - if the `signature` is not valid for either variant of closing transaction
|
2021-02-22 02:57:57 +01:00
|
|
|
* specified in [BOLT #3](03-transactions.md#closing-transaction)
|
|
|
|
* OR non-compliant with LOW-S-standard rule...:
|
2018-06-17 12:13:44 +02:00
|
|
|
* - MUST fail the connection.
|
2018-02-02 01:55:03 +01:00
|
|
|
*/
|
2019-07-30 16:14:43 +02:00
|
|
|
tx = close_tx(tmpctx, chainparams, pps, channel_id,
|
2018-02-02 01:55:03 +01:00
|
|
|
scriptpubkey,
|
|
|
|
funding_txid,
|
|
|
|
funding_txout,
|
2019-02-21 04:45:55 +01:00
|
|
|
funding,
|
2020-05-21 21:46:19 +02:00
|
|
|
funding_wscript,
|
2021-03-15 21:25:54 +01:00
|
|
|
out, opener, received_fee, our_dust_limit,
|
|
|
|
wrong_funding);
|
2018-02-02 01:55:03 +01:00
|
|
|
|
|
|
|
if (!check_tx_sig(tx, 0, NULL, funding_wscript,
|
|
|
|
&funding_pubkey[REMOTE], &their_sig)) {
|
|
|
|
/* Trim it by reducing their output to minimum */
|
|
|
|
struct bitcoin_tx *trimmed;
|
2019-02-21 04:45:55 +01:00
|
|
|
struct amount_sat trimming_out[NUM_SIDES];
|
2018-02-02 01:55:03 +01:00
|
|
|
|
2019-09-09 18:11:24 +02:00
|
|
|
if (opener == REMOTE)
|
2019-02-21 04:45:55 +01:00
|
|
|
trimming_out[REMOTE] = received_fee;
|
2018-02-02 01:55:03 +01:00
|
|
|
else
|
2019-02-21 04:45:55 +01:00
|
|
|
trimming_out[REMOTE] = AMOUNT_SAT(0);
|
|
|
|
trimming_out[LOCAL] = out[LOCAL];
|
2018-02-02 01:55:03 +01:00
|
|
|
|
|
|
|
/* BOLT #3:
|
|
|
|
*
|
2018-06-17 12:13:44 +02:00
|
|
|
* Each node offering a signature:
|
|
|
|
* - MUST round each output down to whole satoshis.
|
|
|
|
* - MUST subtract the fee given by `fee_satoshis` from the
|
|
|
|
* output to the funder.
|
|
|
|
* - MUST remove any output below its own
|
|
|
|
* `dust_limit_satoshis`.
|
|
|
|
* - MAY eliminate its own output.
|
2018-02-02 01:55:03 +01:00
|
|
|
*/
|
2019-07-30 16:14:43 +02:00
|
|
|
trimmed = close_tx(tmpctx, chainparams, pps, channel_id,
|
2018-02-02 01:55:03 +01:00
|
|
|
scriptpubkey,
|
|
|
|
funding_txid,
|
|
|
|
funding_txout,
|
2019-02-21 04:45:55 +01:00
|
|
|
funding,
|
2020-05-21 21:46:19 +02:00
|
|
|
funding_wscript,
|
2019-02-21 04:45:55 +01:00
|
|
|
trimming_out,
|
2021-03-15 21:25:54 +01:00
|
|
|
opener, received_fee, our_dust_limit,
|
|
|
|
wrong_funding);
|
2018-02-02 01:55:03 +01:00
|
|
|
if (!trimmed
|
|
|
|
|| !check_tx_sig(trimmed, 0, NULL, funding_wscript,
|
|
|
|
&funding_pubkey[REMOTE], &their_sig)) {
|
2021-02-02 13:49:01 +01:00
|
|
|
peer_failed_warn(pps, channel_id,
|
|
|
|
"Bad closing_signed signature for"
|
|
|
|
" %s (and trimmed version %s)",
|
|
|
|
type_to_string(tmpctx,
|
|
|
|
struct bitcoin_tx,
|
|
|
|
tx),
|
|
|
|
trimmed ?
|
|
|
|
type_to_string(tmpctx,
|
|
|
|
struct bitcoin_tx,
|
|
|
|
trimmed)
|
|
|
|
: "NONE");
|
2018-02-02 01:55:03 +01:00
|
|
|
}
|
|
|
|
tx = trimmed;
|
|
|
|
}
|
|
|
|
|
2019-09-08 18:39:26 +02:00
|
|
|
status_debug("Received fee offer %s",
|
2019-02-21 04:45:55 +01:00
|
|
|
type_to_string(tmpctx, struct amount_sat, &received_fee));
|
2018-02-02 01:55:03 +01:00
|
|
|
|
|
|
|
/* Master sorts out what is best offer, we just tell it any above min */
|
2019-02-21 04:45:55 +01:00
|
|
|
if (amount_sat_greater_eq(received_fee, min_fee_to_accept)) {
|
2019-09-08 18:39:26 +02:00
|
|
|
status_debug("...offer is reasonable");
|
2019-04-10 23:58:01 +02:00
|
|
|
tell_master_their_offer(&their_sig, tx, closing_txid);
|
2018-02-02 01:55:03 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return received_fee;
|
|
|
|
}
|
|
|
|
|
|
|
|
struct feerange {
|
|
|
|
enum side higher_side;
|
2019-02-21 04:45:55 +01:00
|
|
|
struct amount_sat min, max;
|
2018-02-02 01:55:03 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
static void init_feerange(struct feerange *feerange,
|
2019-02-21 04:45:55 +01:00
|
|
|
struct amount_sat commitment_fee,
|
|
|
|
const struct amount_sat offer[NUM_SIDES])
|
2018-02-02 01:55:03 +01:00
|
|
|
{
|
2019-02-21 04:45:55 +01:00
|
|
|
feerange->min = AMOUNT_SAT(0);
|
2018-02-02 01:55:03 +01:00
|
|
|
|
|
|
|
/* BOLT #2:
|
|
|
|
*
|
|
|
|
* - MUST set `fee_satoshis` less than or equal to the base
|
|
|
|
* fee of the final commitment transaction, as calculated
|
|
|
|
* in [BOLT #3](03-transactions.md#fee-calculation).
|
|
|
|
*/
|
|
|
|
feerange->max = commitment_fee;
|
|
|
|
|
2019-02-21 04:45:55 +01:00
|
|
|
if (amount_sat_greater(offer[LOCAL], offer[REMOTE]))
|
2018-02-02 01:55:03 +01:00
|
|
|
feerange->higher_side = LOCAL;
|
|
|
|
else
|
|
|
|
feerange->higher_side = REMOTE;
|
|
|
|
|
2019-09-08 18:39:26 +02:00
|
|
|
status_debug("Feerange init %s-%s, %s higher",
|
2019-02-21 04:45:55 +01:00
|
|
|
type_to_string(tmpctx, struct amount_sat, &feerange->min),
|
|
|
|
type_to_string(tmpctx, struct amount_sat, &feerange->max),
|
2018-02-02 01:55:03 +01:00
|
|
|
feerange->higher_side == LOCAL ? "local" : "remote");
|
|
|
|
}
|
|
|
|
|
2018-07-31 11:47:54 +02:00
|
|
|
static void adjust_feerange(struct feerange *feerange,
|
2019-02-21 04:45:55 +01:00
|
|
|
struct amount_sat offer, enum side side)
|
2018-02-02 01:55:03 +01:00
|
|
|
{
|
2019-02-21 04:45:55 +01:00
|
|
|
bool ok;
|
|
|
|
|
2018-02-02 01:55:03 +01:00
|
|
|
/* BOLT #2:
|
|
|
|
*
|
2018-06-17 12:13:44 +02:00
|
|
|
* - MUST propose a value "strictly between" the received
|
|
|
|
* `fee_satoshis` and its previously-sent `fee_satoshis`.
|
2018-02-02 01:55:03 +01:00
|
|
|
*/
|
|
|
|
if (side == feerange->higher_side)
|
2019-02-21 04:45:55 +01:00
|
|
|
ok = amount_sat_sub(&feerange->max, offer, AMOUNT_SAT(1));
|
2018-02-02 01:55:03 +01:00
|
|
|
else
|
2019-02-21 04:45:55 +01:00
|
|
|
ok = amount_sat_add(&feerange->min, offer, AMOUNT_SAT(1));
|
2018-02-02 01:55:03 +01:00
|
|
|
|
2019-09-08 18:39:26 +02:00
|
|
|
status_debug("Feerange %s update %s: now %s-%s",
|
2018-02-02 01:55:03 +01:00
|
|
|
side == LOCAL ? "local" : "remote",
|
2019-02-21 04:45:55 +01:00
|
|
|
type_to_string(tmpctx, struct amount_sat, &offer),
|
|
|
|
type_to_string(tmpctx, struct amount_sat, &feerange->min),
|
|
|
|
type_to_string(tmpctx, struct amount_sat, &feerange->max));
|
|
|
|
|
|
|
|
if (!ok)
|
|
|
|
status_failed(STATUS_FAIL_INTERNAL_ERROR,
|
|
|
|
"Overflow in updating fee range");
|
2018-02-02 01:55:03 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Figure out what we should offer now. */
|
2020-01-03 14:08:29 +01:00
|
|
|
static struct amount_sat
|
|
|
|
adjust_offer(struct per_peer_state *pps, const struct channel_id *channel_id,
|
|
|
|
const struct feerange *feerange, struct amount_sat remote_offer,
|
|
|
|
struct amount_sat min_fee_to_accept, u64 fee_negotiation_step,
|
|
|
|
u8 fee_negotiation_step_unit)
|
2018-02-02 01:55:03 +01:00
|
|
|
{
|
2020-01-03 14:08:29 +01:00
|
|
|
struct amount_sat min_plus_one, range_len, step_sat, result;
|
|
|
|
struct amount_msat step_msat;
|
2019-02-21 04:45:55 +01:00
|
|
|
|
2018-02-02 01:55:03 +01:00
|
|
|
/* Within 1 satoshi? Agree. */
|
2019-02-21 04:45:55 +01:00
|
|
|
if (!amount_sat_add(&min_plus_one, feerange->min, AMOUNT_SAT(1)))
|
2021-02-02 13:49:01 +01:00
|
|
|
peer_failed_warn(pps, channel_id,
|
|
|
|
"Fee offer %s min too large",
|
|
|
|
type_to_string(tmpctx, struct amount_sat,
|
|
|
|
&feerange->min));
|
2019-02-21 04:45:55 +01:00
|
|
|
|
|
|
|
if (amount_sat_greater_eq(min_plus_one, feerange->max))
|
2018-02-02 01:55:03 +01:00
|
|
|
return remote_offer;
|
|
|
|
|
2020-01-03 14:08:29 +01:00
|
|
|
/* feerange has already been adjusted so that our new offer is ok to be
|
|
|
|
* any number in [feerange->min, feerange->max] and after the following
|
|
|
|
* min_fee_to_accept is in that range. Thus, pick a fee in
|
|
|
|
* [min_fee_to_accept, feerange->max]. */
|
|
|
|
if (amount_sat_greater(feerange->min, min_fee_to_accept))
|
|
|
|
min_fee_to_accept = feerange->min;
|
|
|
|
|
2018-02-02 01:55:03 +01:00
|
|
|
/* Max is below our minimum acceptable? */
|
2020-01-03 14:08:29 +01:00
|
|
|
if (!amount_sat_sub(&range_len, feerange->max, min_fee_to_accept))
|
2021-02-02 13:49:01 +01:00
|
|
|
peer_failed_warn(pps, channel_id,
|
|
|
|
"Feerange %s-%s"
|
|
|
|
" below minimum acceptable %s",
|
|
|
|
type_to_string(tmpctx, struct amount_sat,
|
|
|
|
&feerange->min),
|
|
|
|
type_to_string(tmpctx, struct amount_sat,
|
|
|
|
&feerange->max),
|
|
|
|
type_to_string(tmpctx, struct amount_sat,
|
|
|
|
&min_fee_to_accept));
|
2018-02-02 01:55:03 +01:00
|
|
|
|
2020-01-03 14:08:29 +01:00
|
|
|
if (fee_negotiation_step_unit ==
|
|
|
|
CLOSING_FEE_NEGOTIATION_STEP_UNIT_SATOSHI) {
|
|
|
|
/* -1 because the range boundary has already been adjusted with
|
|
|
|
* one from our previous proposal. So, if the user requested a
|
|
|
|
* step of 1 satoshi at a time we should just return our end of
|
|
|
|
* the range from this function. */
|
2020-08-05 05:55:15 +02:00
|
|
|
step_msat = amount_msat((fee_negotiation_step - 1)
|
|
|
|
* MSAT_PER_SAT);
|
2020-01-03 14:08:29 +01:00
|
|
|
} else {
|
|
|
|
/* fee_negotiation_step is e.g. 20 to designate 20% from
|
|
|
|
* range_len (which is in satoshi), so:
|
|
|
|
* range_len * fee_negotiation_step / 100 [sat]
|
|
|
|
* is equivalent to:
|
|
|
|
* range_len * fee_negotiation_step * 10 [msat] */
|
2020-08-05 05:55:15 +02:00
|
|
|
step_msat = amount_msat(range_len.satoshis /* Raw: % calc */ *
|
|
|
|
fee_negotiation_step * 10);
|
2020-01-03 14:08:29 +01:00
|
|
|
}
|
2018-02-02 01:55:03 +01:00
|
|
|
|
2020-01-03 14:08:29 +01:00
|
|
|
step_sat = amount_msat_to_sat_round_down(step_msat);
|
|
|
|
|
|
|
|
if (feerange->higher_side == LOCAL) {
|
|
|
|
if (!amount_sat_sub(&result, feerange->max, step_sat))
|
|
|
|
/* step_sat > feerange->max, unlikely */
|
|
|
|
return min_fee_to_accept;
|
|
|
|
|
|
|
|
if (amount_sat_less_eq(result, min_fee_to_accept))
|
|
|
|
return min_fee_to_accept;
|
|
|
|
} else {
|
|
|
|
if (!amount_sat_add(&result, min_fee_to_accept, step_sat))
|
|
|
|
/* overflow, unlikely */
|
|
|
|
return feerange->max;
|
2019-02-21 04:45:55 +01:00
|
|
|
|
2020-01-03 14:08:29 +01:00
|
|
|
if (amount_sat_greater_eq(result, feerange->max))
|
|
|
|
return feerange->max;
|
|
|
|
}
|
|
|
|
|
|
|
|
return result;
|
2018-02-02 01:55:03 +01:00
|
|
|
}
|
|
|
|
|
2018-11-22 03:17:29 +01:00
|
|
|
#if DEVELOPER
|
|
|
|
/* FIXME: We should talk to lightningd anyway, rather than doing this */
|
|
|
|
static void closing_dev_memleak(const tal_t *ctx,
|
|
|
|
u8 *scriptpubkey[NUM_SIDES],
|
|
|
|
const u8 *funding_wscript)
|
|
|
|
{
|
|
|
|
struct htable *memtable;
|
|
|
|
|
2020-09-23 03:37:04 +02:00
|
|
|
memtable = memleak_find_allocations(tmpctx, NULL, NULL);
|
2018-11-22 03:17:29 +01:00
|
|
|
|
2020-09-23 03:37:04 +02:00
|
|
|
memleak_remove_pointer(memtable, ctx);
|
|
|
|
memleak_remove_pointer(memtable, scriptpubkey[LOCAL]);
|
|
|
|
memleak_remove_pointer(memtable, scriptpubkey[REMOTE]);
|
|
|
|
memleak_remove_pointer(memtable, funding_wscript);
|
2018-11-22 03:17:29 +01:00
|
|
|
|
|
|
|
dump_memleak(memtable);
|
|
|
|
}
|
|
|
|
#endif /* DEVELOPER */
|
|
|
|
|
2021-06-28 07:08:10 +02:00
|
|
|
/* Figure out what weight we actually expect for this closing tx (using zero fees
|
|
|
|
* gives the largest possible tx: larger values might omit outputs). */
|
|
|
|
static size_t closing_tx_weight_estimate(u8 *scriptpubkey[NUM_SIDES],
|
|
|
|
const u8 *funding_wscript,
|
|
|
|
const struct amount_sat *out,
|
|
|
|
struct amount_sat funding,
|
|
|
|
struct amount_sat dust_limit)
|
|
|
|
{
|
|
|
|
/* We create a dummy close */
|
|
|
|
struct bitcoin_tx *tx;
|
|
|
|
struct bitcoin_txid dummy_txid;
|
|
|
|
struct bitcoin_signature dummy_sig;
|
|
|
|
struct privkey dummy_privkey;
|
|
|
|
struct pubkey dummy_pubkey;
|
|
|
|
u8 **witness;
|
|
|
|
|
|
|
|
memset(&dummy_txid, 0, sizeof(dummy_txid));
|
|
|
|
tx = create_close_tx(tmpctx, chainparams,
|
|
|
|
scriptpubkey[LOCAL], scriptpubkey[REMOTE],
|
|
|
|
funding_wscript,
|
|
|
|
&dummy_txid, 0,
|
|
|
|
funding,
|
|
|
|
out[LOCAL],
|
|
|
|
out[REMOTE],
|
|
|
|
dust_limit);
|
|
|
|
|
|
|
|
/* Create a signature, any signature, so we can weigh fully "signed"
|
|
|
|
* tx. */
|
|
|
|
dummy_sig.sighash_type = SIGHASH_ALL;
|
|
|
|
memset(&dummy_privkey, 1, sizeof(dummy_privkey));
|
|
|
|
sign_hash(&dummy_privkey, &dummy_txid.shad, &dummy_sig.s);
|
|
|
|
pubkey_from_privkey(&dummy_privkey, &dummy_pubkey);
|
|
|
|
witness = bitcoin_witness_2of2(NULL, &dummy_sig, &dummy_sig,
|
|
|
|
&dummy_pubkey, &dummy_pubkey);
|
|
|
|
bitcoin_tx_input_set_witness(tx, 0, take(witness));
|
|
|
|
|
|
|
|
return bitcoin_tx_weight(tx);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Get the minimum and desired fees */
|
|
|
|
static void calc_fee_bounds(size_t expected_weight,
|
|
|
|
u32 min_feerate,
|
|
|
|
u32 desired_feerate,
|
|
|
|
struct amount_sat maxfee,
|
|
|
|
struct amount_sat *minfee,
|
|
|
|
struct amount_sat *desiredfee)
|
|
|
|
{
|
|
|
|
*minfee = amount_tx_fee(min_feerate, expected_weight);
|
|
|
|
*desiredfee = amount_tx_fee(desired_feerate, expected_weight);
|
|
|
|
|
|
|
|
/* Can't exceed maxfee. */
|
|
|
|
if (amount_sat_greater(*minfee, maxfee))
|
|
|
|
*minfee = maxfee;
|
|
|
|
|
|
|
|
if (amount_sat_less(*desiredfee, *minfee)) {
|
|
|
|
status_unusual("Our ideal fee is %s (%u sats/perkw),"
|
|
|
|
" but our minimum is %s: using that",
|
|
|
|
type_to_string(tmpctx, struct amount_sat, desiredfee),
|
|
|
|
desired_feerate,
|
|
|
|
type_to_string(tmpctx, struct amount_sat, minfee));
|
|
|
|
*desiredfee = *minfee;
|
|
|
|
}
|
|
|
|
if (amount_sat_greater(*desiredfee, maxfee)) {
|
|
|
|
status_unusual("Our ideal fee is %s (%u sats/perkw),"
|
|
|
|
" but our maximum is %s: using that",
|
|
|
|
type_to_string(tmpctx, struct amount_sat, desiredfee),
|
|
|
|
desired_feerate,
|
|
|
|
type_to_string(tmpctx, struct amount_sat, &maxfee));
|
|
|
|
*desiredfee = maxfee;
|
|
|
|
}
|
|
|
|
|
|
|
|
status_debug("Expected closing weight = %zu, fee %s (min %s, max %s)",
|
|
|
|
expected_weight,
|
|
|
|
type_to_string(tmpctx, struct amount_sat, desiredfee),
|
|
|
|
type_to_string(tmpctx, struct amount_sat, minfee),
|
|
|
|
type_to_string(tmpctx, struct amount_sat, &maxfee));
|
|
|
|
}
|
|
|
|
|
2017-07-04 02:49:43 +02:00
|
|
|
int main(int argc, char *argv[])
|
|
|
|
{
|
2018-04-25 12:55:34 +02:00
|
|
|
setup_locale();
|
|
|
|
|
2018-03-15 05:30:41 +01:00
|
|
|
const tal_t *ctx = tal(NULL, char);
|
2019-06-03 20:11:25 +02:00
|
|
|
struct per_peer_state *pps;
|
2017-07-04 02:49:43 +02:00
|
|
|
u8 *msg;
|
|
|
|
struct pubkey funding_pubkey[NUM_SIDES];
|
2019-04-10 23:58:01 +02:00
|
|
|
struct bitcoin_txid funding_txid, closing_txid;
|
2017-07-04 02:49:43 +02:00
|
|
|
u16 funding_txout;
|
2019-02-21 04:45:55 +01:00
|
|
|
struct amount_sat funding, out[NUM_SIDES];
|
|
|
|
struct amount_sat our_dust_limit;
|
|
|
|
struct amount_sat min_fee_to_accept, commitment_fee, offer[NUM_SIDES];
|
2021-06-28 07:08:10 +02:00
|
|
|
u32 min_feerate, initial_feerate;
|
2018-02-02 01:55:03 +01:00
|
|
|
struct feerange feerange;
|
2019-09-09 18:11:24 +02:00
|
|
|
enum side opener;
|
2019-09-29 21:12:26 +02:00
|
|
|
u8 *scriptpubkey[NUM_SIDES], *funding_wscript;
|
2020-01-03 14:08:29 +01:00
|
|
|
u64 fee_negotiation_step;
|
|
|
|
u8 fee_negotiation_step_unit;
|
|
|
|
char fee_negotiation_step_str[32]; /* fee_negotiation_step + "sat" */
|
2017-07-04 02:49:43 +02:00
|
|
|
struct channel_id channel_id;
|
2018-02-02 01:55:03 +01:00
|
|
|
enum side whose_turn;
|
2021-03-15 21:25:54 +01:00
|
|
|
struct bitcoin_outpoint *wrong_funding;
|
2017-07-04 02:49:43 +02:00
|
|
|
|
2018-01-08 11:01:09 +01:00
|
|
|
subdaemon_setup(argc, argv);
|
2017-07-04 02:49:43 +02:00
|
|
|
|
|
|
|
status_setup_sync(REQ_FD);
|
|
|
|
|
2018-03-15 05:30:41 +01:00
|
|
|
msg = wire_sync_read(tmpctx, REQ_FD);
|
2020-08-25 04:15:48 +02:00
|
|
|
if (!fromwire_closingd_init(ctx, msg,
|
2021-03-15 21:25:54 +01:00
|
|
|
&chainparams,
|
|
|
|
&pps,
|
|
|
|
&channel_id,
|
|
|
|
&funding_txid, &funding_txout,
|
|
|
|
&funding,
|
|
|
|
&funding_pubkey[LOCAL],
|
|
|
|
&funding_pubkey[REMOTE],
|
|
|
|
&opener,
|
|
|
|
&out[LOCAL],
|
|
|
|
&out[REMOTE],
|
|
|
|
&our_dust_limit,
|
2021-06-28 07:08:10 +02:00
|
|
|
&min_feerate, &initial_feerate,
|
|
|
|
&commitment_fee,
|
2021-03-15 21:25:54 +01:00
|
|
|
&scriptpubkey[LOCAL],
|
|
|
|
&scriptpubkey[REMOTE],
|
|
|
|
&fee_negotiation_step,
|
|
|
|
&fee_negotiation_step_unit,
|
|
|
|
&dev_fast_gossip,
|
|
|
|
&wrong_funding))
|
2020-08-25 04:15:48 +02:00
|
|
|
master_badmsg(WIRE_CLOSINGD_INIT, msg);
|
2017-09-12 06:55:52 +02:00
|
|
|
|
2019-06-03 20:11:25 +02:00
|
|
|
/* stdin == requests, 3 == peer, 4 = gossip, 5 = gossip_store, 6 = hsmd */
|
2020-09-23 03:37:04 +02:00
|
|
|
per_peer_state_set_fds(notleak(pps), 3, 4, 5);
|
2019-06-03 20:11:25 +02:00
|
|
|
|
2021-06-28 07:08:10 +02:00
|
|
|
funding_wscript = bitcoin_redeem_2of2(ctx,
|
|
|
|
&funding_pubkey[LOCAL],
|
|
|
|
&funding_pubkey[REMOTE]);
|
|
|
|
|
|
|
|
/* Start at what we consider a reasonable feerate for this tx. */
|
|
|
|
calc_fee_bounds(closing_tx_weight_estimate(scriptpubkey,
|
|
|
|
funding_wscript,
|
|
|
|
out, funding, our_dust_limit),
|
|
|
|
min_feerate, initial_feerate, commitment_fee,
|
|
|
|
&min_fee_to_accept, &offer[LOCAL]);
|
|
|
|
|
2020-01-03 14:08:29 +01:00
|
|
|
snprintf(fee_negotiation_step_str, sizeof(fee_negotiation_step_str),
|
|
|
|
"%" PRIu64 "%s", fee_negotiation_step,
|
|
|
|
fee_negotiation_step_unit ==
|
|
|
|
CLOSING_FEE_NEGOTIATION_STEP_UNIT_PERCENTAGE
|
|
|
|
? "%"
|
|
|
|
: "sat");
|
|
|
|
|
2019-09-08 18:39:26 +02:00
|
|
|
status_debug("out = %s/%s",
|
2019-02-21 04:45:55 +01:00
|
|
|
type_to_string(tmpctx, struct amount_sat, &out[LOCAL]),
|
|
|
|
type_to_string(tmpctx, struct amount_sat, &out[REMOTE]));
|
2019-09-08 18:39:26 +02:00
|
|
|
status_debug("dustlimit = %s",
|
2019-02-21 04:45:55 +01:00
|
|
|
type_to_string(tmpctx, struct amount_sat, &our_dust_limit));
|
2019-09-08 18:39:26 +02:00
|
|
|
status_debug("fee = %s",
|
2019-02-21 04:45:55 +01:00
|
|
|
type_to_string(tmpctx, struct amount_sat, &offer[LOCAL]));
|
2020-01-03 14:08:29 +01:00
|
|
|
status_debug("fee negotiation step = %s", fee_negotiation_step_str);
|
2021-03-15 21:25:54 +01:00
|
|
|
if (wrong_funding)
|
|
|
|
status_unusual("Setting wrong_funding_txid to %s:%u",
|
|
|
|
type_to_string(tmpctx, struct bitcoin_txid,
|
|
|
|
&wrong_funding->txid),
|
|
|
|
wrong_funding->n);
|
2017-07-04 02:49:43 +02:00
|
|
|
|
2020-01-03 14:08:29 +01:00
|
|
|
peer_billboard(
|
|
|
|
true,
|
|
|
|
"Negotiating closing fee between %s and %s satoshi (ideal %s) "
|
|
|
|
"using step %s",
|
|
|
|
type_to_string(tmpctx, struct amount_sat, &min_fee_to_accept),
|
|
|
|
type_to_string(tmpctx, struct amount_sat, &commitment_fee),
|
|
|
|
type_to_string(tmpctx, struct amount_sat, &offer[LOCAL]),
|
|
|
|
fee_negotiation_step_str);
|
2018-02-23 06:53:47 +01:00
|
|
|
|
2017-07-04 02:49:43 +02:00
|
|
|
/* BOLT #2:
|
|
|
|
*
|
2018-02-02 01:55:03 +01:00
|
|
|
* The funding node:
|
|
|
|
* - after `shutdown` has been received, AND no HTLCs remain in either
|
|
|
|
* commitment transaction:
|
|
|
|
* - SHOULD send a `closing_signed` message.
|
2017-07-04 02:49:43 +02:00
|
|
|
*/
|
2019-09-09 18:11:24 +02:00
|
|
|
whose_turn = opener;
|
2018-02-02 01:55:03 +01:00
|
|
|
for (size_t i = 0; i < 2; i++, whose_turn = !whose_turn) {
|
|
|
|
if (whose_turn == LOCAL) {
|
2019-07-30 16:14:43 +02:00
|
|
|
send_offer(pps, chainparams,
|
2020-05-21 21:46:19 +02:00
|
|
|
&channel_id, funding_pubkey, funding_wscript,
|
2018-02-02 01:55:03 +01:00
|
|
|
scriptpubkey, &funding_txid, funding_txout,
|
2019-09-09 18:11:24 +02:00
|
|
|
funding, out, opener,
|
2018-07-23 04:23:03 +02:00
|
|
|
our_dust_limit,
|
2021-03-15 21:25:54 +01:00
|
|
|
offer[LOCAL],
|
|
|
|
wrong_funding);
|
2017-07-04 02:49:43 +02:00
|
|
|
} else {
|
2018-02-23 06:53:47 +01:00
|
|
|
if (i == 0)
|
|
|
|
peer_billboard(false, "Waiting for their initial"
|
|
|
|
" closing fee offer");
|
|
|
|
else
|
|
|
|
peer_billboard(false, "Waiting for their initial"
|
|
|
|
" closing fee offer:"
|
2019-02-21 04:45:55 +01:00
|
|
|
" ours was %s",
|
|
|
|
type_to_string(tmpctx,
|
|
|
|
struct amount_sat,
|
|
|
|
&offer[LOCAL]));
|
2018-02-02 01:55:03 +01:00
|
|
|
offer[REMOTE]
|
2019-07-30 16:14:43 +02:00
|
|
|
= receive_offer(pps, chainparams,
|
2018-02-19 02:06:14 +01:00
|
|
|
&channel_id, funding_pubkey,
|
2018-02-02 01:55:03 +01:00
|
|
|
funding_wscript,
|
|
|
|
scriptpubkey, &funding_txid,
|
2019-02-21 04:45:55 +01:00
|
|
|
funding_txout, funding,
|
2019-09-09 18:11:24 +02:00
|
|
|
out, opener,
|
2018-02-02 01:55:03 +01:00
|
|
|
our_dust_limit,
|
2019-04-10 23:58:01 +02:00
|
|
|
min_fee_to_accept,
|
2021-03-15 21:25:54 +01:00
|
|
|
wrong_funding,
|
2019-04-10 23:58:01 +02:00
|
|
|
&closing_txid);
|
2017-07-04 02:49:43 +02:00
|
|
|
}
|
2018-02-02 01:55:03 +01:00
|
|
|
}
|
2017-07-04 02:49:43 +02:00
|
|
|
|
2018-02-02 01:55:03 +01:00
|
|
|
/* Now we have first two points, we can init fee range. */
|
2018-04-13 03:03:03 +02:00
|
|
|
init_feerange(&feerange, commitment_fee, offer);
|
2018-02-02 01:55:03 +01:00
|
|
|
|
2019-09-09 18:11:24 +02:00
|
|
|
/* Apply (and check) opener offer now. */
|
|
|
|
adjust_feerange(&feerange, offer[opener], opener);
|
2018-04-13 02:58:38 +02:00
|
|
|
|
2018-02-02 01:55:03 +01:00
|
|
|
/* Now any extra rounds required. */
|
2019-02-21 04:45:55 +01:00
|
|
|
while (!amount_sat_eq(offer[LOCAL], offer[REMOTE])) {
|
2018-04-12 05:03:26 +02:00
|
|
|
/* Still don't agree: adjust feerange based on previous offer */
|
2018-07-31 11:47:54 +02:00
|
|
|
adjust_feerange(&feerange,
|
2018-04-12 05:03:26 +02:00
|
|
|
offer[!whose_turn], !whose_turn);
|
2018-02-02 01:55:03 +01:00
|
|
|
|
|
|
|
if (whose_turn == LOCAL) {
|
2019-06-03 20:11:25 +02:00
|
|
|
offer[LOCAL] = adjust_offer(pps,
|
2018-02-19 02:06:14 +01:00
|
|
|
&channel_id,
|
2018-02-02 01:55:03 +01:00
|
|
|
&feerange, offer[REMOTE],
|
2020-01-03 14:08:29 +01:00
|
|
|
min_fee_to_accept,
|
|
|
|
fee_negotiation_step,
|
|
|
|
fee_negotiation_step_unit);
|
2019-07-30 16:14:43 +02:00
|
|
|
send_offer(pps, chainparams, &channel_id,
|
2020-05-21 21:46:19 +02:00
|
|
|
funding_pubkey, funding_wscript,
|
2018-02-02 01:55:03 +01:00
|
|
|
scriptpubkey, &funding_txid, funding_txout,
|
2019-09-09 18:11:24 +02:00
|
|
|
funding, out, opener,
|
2018-07-23 04:23:03 +02:00
|
|
|
our_dust_limit,
|
2021-03-15 21:25:54 +01:00
|
|
|
offer[LOCAL],
|
|
|
|
wrong_funding);
|
2018-02-02 01:55:03 +01:00
|
|
|
} else {
|
2018-02-23 06:53:47 +01:00
|
|
|
peer_billboard(false, "Waiting for another"
|
|
|
|
" closing fee offer:"
|
|
|
|
" ours was %"PRIu64" satoshi,"
|
|
|
|
" theirs was %"PRIu64" satoshi,",
|
|
|
|
offer[LOCAL], offer[REMOTE]);
|
2018-02-02 01:55:03 +01:00
|
|
|
offer[REMOTE]
|
2019-07-30 16:14:43 +02:00
|
|
|
= receive_offer(pps, chainparams, &channel_id,
|
2018-02-19 02:06:14 +01:00
|
|
|
funding_pubkey,
|
2018-02-02 01:55:03 +01:00
|
|
|
funding_wscript,
|
|
|
|
scriptpubkey, &funding_txid,
|
2019-02-21 04:45:55 +01:00
|
|
|
funding_txout, funding,
|
2019-09-09 18:11:24 +02:00
|
|
|
out, opener,
|
2018-02-02 01:55:03 +01:00
|
|
|
our_dust_limit,
|
2019-04-10 23:58:01 +02:00
|
|
|
min_fee_to_accept,
|
2021-03-15 21:25:54 +01:00
|
|
|
wrong_funding,
|
2019-04-10 23:58:01 +02:00
|
|
|
&closing_txid);
|
2017-07-04 02:49:43 +02:00
|
|
|
}
|
2018-04-12 05:03:26 +02:00
|
|
|
|
|
|
|
whose_turn = !whose_turn;
|
2017-07-04 02:49:43 +02:00
|
|
|
}
|
|
|
|
|
2019-04-10 23:58:01 +02:00
|
|
|
peer_billboard(true, "We agreed on a closing fee of %"PRIu64" satoshi for tx:%s",
|
|
|
|
offer[LOCAL],
|
|
|
|
type_to_string(tmpctx, struct bitcoin_txid, &closing_txid));
|
2018-02-23 06:53:47 +01:00
|
|
|
|
2018-11-22 03:17:29 +01:00
|
|
|
#if DEVELOPER
|
|
|
|
/* We don't listen for master commands, so always check memleak here */
|
2021-03-15 21:25:54 +01:00
|
|
|
tal_free(wrong_funding);
|
2018-11-22 03:17:29 +01:00
|
|
|
closing_dev_memleak(ctx, scriptpubkey, funding_wscript);
|
|
|
|
#endif
|
|
|
|
|
2017-07-04 02:49:43 +02:00
|
|
|
/* We're done! */
|
2018-05-05 06:57:58 +02:00
|
|
|
/* Properly close the channel first. */
|
2019-06-03 20:11:25 +02:00
|
|
|
if (!socket_close(pps->peer_fd))
|
2018-05-05 06:57:58 +02:00
|
|
|
status_unusual("Closing and draining peerfd gave error: %s",
|
|
|
|
strerror(errno));
|
|
|
|
/* Sending the below will kill us! */
|
2020-08-25 04:15:48 +02:00
|
|
|
wire_sync_write(REQ_FD, take(towire_closingd_complete(NULL)));
|
2017-07-04 02:49:43 +02:00
|
|
|
tal_free(ctx);
|
2018-03-29 04:06:45 +02:00
|
|
|
daemon_shutdown();
|
2017-07-04 02:49:43 +02:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|