Browse Source

openingd: support receipt of upfront_shutdown_script.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
htlc_accepted_hook
Rusty Russell 6 years ago
parent
commit
cfebe66762
  1. 1
      common/features.c
  2. 20
      lightningd/opening_control.c
  3. 1
      openingd/Makefile
  4. 6
      openingd/opening_wire.csv
  5. 133
      openingd/openingd.c
  6. 6
      tests/test_connection.py

1
common/features.c

@ -6,6 +6,7 @@
static const u32 our_localfeatures[] = {
LOCAL_DATA_LOSS_PROTECT,
LOCAL_INITIAL_ROUTING_SYNC,
LOCAL_UPFRONT_SHUTDOWN_SCRIPT,
LOCAL_GOSSIP_QUERIES
};

20
lightningd/opening_control.c

@ -152,7 +152,8 @@ wallet_commit_channel(struct lightningd *ld,
struct amount_msat push,
u8 channel_flags,
struct channel_info *channel_info,
u32 feerate)
u32 feerate,
const u8 *remote_upfront_shutdown_script)
{
struct channel *channel;
struct amount_msat our_msat;
@ -226,7 +227,7 @@ wallet_commit_channel(struct lightningd *ld,
NULL,
ld->config.fee_base,
ld->config.fee_per_satoshi,
NULL);
remote_upfront_shutdown_script);
/* Now we finally put it in the database. */
wallet_channel_insert(ld->wallet, channel);
@ -297,6 +298,7 @@ static void opening_funder_finished(struct subd *openingd, const u8 *resp,
struct amount_sat change;
struct channel *channel;
struct lightningd *ld = openingd->ld;
u8 *remote_upfront_shutdown_script;
assert(tal_count(fds) == 2);
@ -317,7 +319,8 @@ static void opening_funder_finished(struct subd *openingd, const u8 *resp,
&channel_info.remote_fundingkey,
&expected_txid,
&feerate,
&fc->uc->our_config.channel_reserve)) {
&fc->uc->our_config.channel_reserve,
&remote_upfront_shutdown_script)) {
log_broken(fc->uc->log,
"bad OPENING_FUNDER_REPLY %s",
tal_hex(resp, resp));
@ -405,7 +408,8 @@ static void opening_funder_finished(struct subd *openingd, const u8 *resp,
fc->push,
fc->channel_flags,
&channel_info,
feerate);
feerate,
remote_upfront_shutdown_script);
if (!channel) {
was_pending(command_fail(fc->cmd, LIGHTNINGD,
"Key generation failure"));
@ -485,6 +489,7 @@ static void opening_fundee_finished(struct subd *openingd,
u32 feerate;
u8 channel_flags;
struct channel *channel;
u8 *remote_upfront_shutdown_script;
log_debug(uc->log, "Got opening_fundee_finish_response");
assert(tal_count(fds) == 2);
@ -510,7 +515,8 @@ static void opening_fundee_finished(struct subd *openingd,
&channel_flags,
&feerate,
&funding_signed,
&uc->our_config.channel_reserve)) {
&uc->our_config.channel_reserve,
&remote_upfront_shutdown_script)) {
log_broken(uc->log, "bad OPENING_FUNDEE_REPLY %s",
tal_hex(reply, reply));
uncommitted_channel_disconnect(uc, "bad OPENING_FUNDEE_REPLY");
@ -534,7 +540,8 @@ static void opening_fundee_finished(struct subd *openingd,
push,
channel_flags,
&channel_info,
feerate);
feerate,
remote_upfront_shutdown_script);
if (!channel) {
uncommitted_channel_disconnect(uc, "Commit channel failed");
goto failed;
@ -825,6 +832,7 @@ void peer_start_openingd(struct peer *peer,
feerate_min(peer->ld, NULL),
feerate_max(peer->ld, NULL),
!peer_active_channel(peer),
peer->localfeatures,
send_msg);
subd_send_msg(uc->openingd, take(msg));
}

1
openingd/Makefile

@ -46,6 +46,7 @@ OPENINGD_COMMON_OBJS := \
common/daemon_conn.o \
common/derive_basepoints.o \
common/dev_disconnect.o \
common/features.o \
common/funding_tx.o \
common/gen_status_wire.o \
common/gen_peer_status_wire.o \

6
openingd/opening_wire.csv

@ -18,6 +18,8 @@ opening_init,,minimum_depth,u32
opening_init,,min_feerate,u32
opening_init,,max_feerate,u32
opening_init,,can_open_channel,bool
opening_init,,lfeatures_len,u16
opening_init,,lfeatures,lfeatures_len*u8
# Optional msg to send.
opening_init,,len,u16
opening_init,,msg,len*u8
@ -57,6 +59,8 @@ opening_funder_reply,,remote_fundingkey,struct pubkey
opening_funder_reply,,funding_txid,struct bitcoin_txid
opening_funder_reply,,feerate_per_kw,u32
opening_funder_reply,,our_channel_reserve_satoshis,struct amount_sat
opening_funder_reply,,shutdown_len,u16
opening_funder_reply,,shutdown_scriptpubkey,shutdown_len*u8
# Openingd->master: we failed to negotiation channel
opening_funder_failed,6004
@ -85,6 +89,8 @@ opening_fundee,,feerate_per_kw,u32
opening_fundee,,msglen,u16
opening_fundee,,funding_signed_msg,msglen*u8
opening_fundee,,our_channel_reserve_satoshis,struct amount_sat
opening_fundee,,shutdown_len,u16
opening_fundee,,shutdown_scriptpubkey,shutdown_len*u8
# master -> openingd: do you have a memleak?
opening_dev_memleak,6033

Can't render this file because it has a wrong number of fields in line 5.

133
openingd/openingd.c

@ -18,6 +18,7 @@
#include <ccan/tal/str/str.h>
#include <common/crypto_sync.h>
#include <common/derive_basepoints.h>
#include <common/features.h>
#include <common/funding_tx.h>
#include <common/gen_peer_status_wire.h>
#include <common/initial_channel.h>
@ -58,6 +59,9 @@ struct state {
* featured in BOLT #8) */
struct crypto_state cs;
/* Features they offered */
u8 *localfeatures;
/* Constraints on a channel they open. */
u32 minimum_depth;
u32 min_feerate, max_feerate;
@ -84,6 +88,8 @@ struct state {
u32 feerate_per_kw;
struct bitcoin_txid funding_txid;
u16 funding_txout;
/* If set, this is the scriptpubkey they *must* close with */
u8 *remote_upfront_shutdown_script;
/* This is a cluster of fields in open_channel and accept_channel which
* indicate the restrictions each side places on the channel. */
@ -481,8 +487,19 @@ static u8 *funder_channel(struct state *state,
"push-msat must be < %s",
type_to_string(tmpctx, struct amount_sat,
&state->funding));
msg = towire_open_channel(NULL,
/* BOLT #2:
*
* - if both nodes advertised the `option_upfront_shutdown_script`
* feature:
* - MUST include either a valid `shutdown_scriptpubkey` as required
* by `shutdown` `scriptpubkey`, or a zero-length
* `shutdown_scriptpubkey`.
* - otherwise:
* - MAY include a`shutdown_scriptpubkey`.
*/
/* We don't use shutdown_scriptpubkey (at least for now), so leave it
* NULL. */
msg = towire_open_channel_option_upfront_shutdown_script(NULL,
&state->chainparams->genesis_blockhash,
&state->channel_id,
state->funding,
@ -500,7 +517,7 @@ static u8 *funder_channel(struct state *state,
&state->our_points.delayed_payment,
&state->our_points.htlc,
&state->first_per_commitment_point[LOCAL],
channel_flags);
channel_flags, NULL);
sync_crypto_write(&state->cs, PEER_FD, take(msg));
/* This is usually a very transient state... */
@ -511,6 +528,10 @@ static u8 *funder_channel(struct state *state,
if (!msg)
goto fail;
/* Default is no shutdown_scriptpubkey: free any leftover one. */
state->remote_upfront_shutdown_script
= tal_free(state->remote_upfront_shutdown_script);
/* BOLT #2:
*
* The receiving node MUST fail the channel if:
@ -519,7 +540,28 @@ static u8 *funder_channel(struct state *state,
* `payment_basepoint`, or `delayed_payment_basepoint` are not
* valid DER-encoded compressed secp256k1 pubkeys.
*/
if (!fromwire_accept_channel(msg, &id_in,
if (local_feature_negotiated(state->localfeatures,
LOCAL_UPFRONT_SHUTDOWN_SCRIPT)) {
if (!fromwire_accept_channel_option_upfront_shutdown_script(state,
msg, &id_in,
&state->remoteconf.dust_limit,
&state->remoteconf.max_htlc_value_in_flight,
&state->remoteconf.channel_reserve,
&state->remoteconf.htlc_minimum,
&minimum_depth,
&state->remoteconf.to_self_delay,
&state->remoteconf.max_accepted_htlcs,
&their_funding_pubkey,
&theirs.revocation,
&theirs.payment,
&theirs.delayed_payment,
&theirs.htlc,
&state->first_per_commitment_point[REMOTE],
&state->remote_upfront_shutdown_script))
peer_failed(&state->cs,
&state->channel_id,
"Parsing accept_channel with option_upfront_shutdown_script %s", tal_hex(msg, msg));
} else if (!fromwire_accept_channel(msg, &id_in,
&state->remoteconf.dust_limit,
&state->remoteconf.max_htlc_value_in_flight,
&state->remoteconf.channel_reserve,
@ -822,7 +864,8 @@ static u8 *funder_channel(struct state *state,
&their_funding_pubkey,
&state->funding_txid,
state->feerate_per_kw,
state->localconf.channel_reserve);
state->localconf.channel_reserve,
state->remote_upfront_shutdown_script);
fail_2:
tal_free(wscript);
@ -847,6 +890,10 @@ static u8 *fundee_channel(struct state *state, const u8 *open_channel_msg)
u8 channel_flags;
char* err_reason;
/* Default is no shutdown_scriptpubkey: free any leftover one. */
state->remote_upfront_shutdown_script
= tal_free(state->remote_upfront_shutdown_script);
/* BOLT #2:
*
* The receiving node MUST fail the channel if:
@ -855,24 +902,49 @@ static u8 *fundee_channel(struct state *state, const u8 *open_channel_msg)
* `payment_basepoint`, or `delayed_payment_basepoint` are not valid
* DER-encoded compressed secp256k1 pubkeys.
*/
if (!fromwire_open_channel(open_channel_msg, &chain_hash,
&state->channel_id,
&state->funding,
&state->push_msat,
&state->remoteconf.dust_limit,
&state->remoteconf.max_htlc_value_in_flight,
&state->remoteconf.channel_reserve,
&state->remoteconf.htlc_minimum,
&state->feerate_per_kw,
&state->remoteconf.to_self_delay,
&state->remoteconf.max_accepted_htlcs,
&their_funding_pubkey,
&theirs.revocation,
&theirs.payment,
&theirs.delayed_payment,
&theirs.htlc,
&state->first_per_commitment_point[REMOTE],
&channel_flags))
if (local_feature_negotiated(state->localfeatures,
LOCAL_UPFRONT_SHUTDOWN_SCRIPT)) {
if (!fromwire_open_channel_option_upfront_shutdown_script(state,
open_channel_msg, &chain_hash,
&state->channel_id,
&state->funding,
&state->push_msat,
&state->remoteconf.dust_limit,
&state->remoteconf.max_htlc_value_in_flight,
&state->remoteconf.channel_reserve,
&state->remoteconf.htlc_minimum,
&state->feerate_per_kw,
&state->remoteconf.to_self_delay,
&state->remoteconf.max_accepted_htlcs,
&their_funding_pubkey,
&theirs.revocation,
&theirs.payment,
&theirs.delayed_payment,
&theirs.htlc,
&state->first_per_commitment_point[REMOTE],
&channel_flags,
&state->remote_upfront_shutdown_script))
peer_failed(&state->cs,
&state->channel_id,
"Parsing open_channel with option_upfront_shutdown_script %s", tal_hex(tmpctx, open_channel_msg));
} else if (!fromwire_open_channel(open_channel_msg, &chain_hash,
&state->channel_id,
&state->funding,
&state->push_msat,
&state->remoteconf.dust_limit,
&state->remoteconf.max_htlc_value_in_flight,
&state->remoteconf.channel_reserve,
&state->remoteconf.htlc_minimum,
&state->feerate_per_kw,
&state->remoteconf.to_self_delay,
&state->remoteconf.max_accepted_htlcs,
&their_funding_pubkey,
&theirs.revocation,
&theirs.payment,
&theirs.delayed_payment,
&theirs.htlc,
&state->first_per_commitment_point[REMOTE],
&channel_flags))
peer_failed(&state->cs, NULL,
"Bad open_channel %s",
tal_hex(open_channel_msg, open_channel_msg));
@ -994,7 +1066,7 @@ static u8 *fundee_channel(struct state *state, const u8 *open_channel_msg)
return NULL;
/* OK, we accept! */
msg = towire_accept_channel(NULL, &state->channel_id,
msg = towire_accept_channel_option_upfront_shutdown_script(NULL, &state->channel_id,
state->localconf.dust_limit,
state->localconf.max_htlc_value_in_flight,
state->localconf.channel_reserve,
@ -1007,7 +1079,8 @@ static u8 *fundee_channel(struct state *state, const u8 *open_channel_msg)
&state->our_points.payment,
&state->our_points.delayed_payment,
&state->our_points.htlc,
&state->first_per_commitment_point[LOCAL]);
&state->first_per_commitment_point[LOCAL],
NULL);
sync_crypto_write(&state->cs, PEER_FD, take(msg));
@ -1174,7 +1247,8 @@ static u8 *fundee_channel(struct state *state, const u8 *open_channel_msg)
channel_flags,
state->feerate_per_kw,
msg,
state->localconf.channel_reserve);
state->localconf.channel_reserve,
state->remote_upfront_shutdown_script);
}
/*~ Standard "peer sent a message, handle it" demuxer. Though it really only
@ -1367,7 +1441,7 @@ int main(int argc, char *argv[])
/*~ The very first thing we read from lightningd is our init msg */
msg = wire_sync_read(tmpctx, REQ_FD);
if (!fromwire_opening_init(tmpctx, msg,
if (!fromwire_opening_init(state, msg,
&chain_hash,
&state->localconf,
&state->max_to_self_delay,
@ -1378,6 +1452,7 @@ int main(int argc, char *argv[])
&state->minimum_depth,
&state->min_feerate, &state->max_feerate,
&state->can_accept_channel,
&state->localfeatures,
&inner))
master_badmsg(WIRE_OPENING_INIT, msg);
@ -1386,6 +1461,7 @@ int main(int argc, char *argv[])
if (inner != NULL) {
sync_crypto_write(&state->cs, PEER_FD, inner);
fail_if_all_error(inner);
tal_free(inner);
}
/*~ Even though I only care about bitcoin, there's still testnet and
@ -1397,6 +1473,9 @@ int main(int argc, char *argv[])
memset(&state->channel_id, 0, sizeof(state->channel_id));
state->channel = NULL;
/*~ We set this to NULL, meaning no requirements on shutdown */
state->remote_upfront_shutdown_script = NULL;
/*~ We need an initial per-commitment point whether we're funding or
* they are, and lightningd has reserved a unique dbid for us already,
* so we might as well get the hsm daemon to generate it now. */

6
tests/test_connection.py

@ -1081,7 +1081,7 @@ def test_forget_channel(node_factory):
def test_peerinfo(node_factory, bitcoind):
l1, l2 = node_factory.line_graph(2, fundchannel=False, opts={'may_reconnect': True})
lfeatures = '8a'
lfeatures = 'aa'
# Gossiping but no node announcement yet
assert l1.rpc.getpeer(l2.info['id'])['connected']
assert len(l1.rpc.getpeer(l2.info['id'])['channels']) == 0
@ -1338,8 +1338,8 @@ def test_dataloss_protection(node_factory, bitcoind):
"0000"
# lflen == 1
"0001"
# Local features 1, 3 and 7 (0x8a).
"8a")
# Local features 1, 3, 5 and 7 (0xaa).
"aa")
l1.fund_channel(l2, 10**6)
l2.stop()

Loading…
Cancel
Save