mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-02-21 22:31:48 +01:00
openingd: support receipt of upfront_shutdown_script.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
parent
7ead29b695
commit
cfebe66762
6 changed files with 131 additions and 36 deletions
|
@ -6,6 +6,7 @@
|
|||
static const u32 our_localfeatures[] = {
|
||||
LOCAL_DATA_LOSS_PROTECT,
|
||||
LOCAL_INITIAL_ROUTING_SYNC,
|
||||
LOCAL_UPFRONT_SHUTDOWN_SCRIPT,
|
||||
LOCAL_GOSSIP_QUERIES
|
||||
};
|
||||
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -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 \
|
||||
|
|
|
@ -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
|
||||
|
|
|
|
@ -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. */
|
||||
|
|
|
@ -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…
Add table
Reference in a new issue