df: Pass new feerate options through to plugin, set reasonable bounds

We let the plugin decide what feerate to accept/whether or not to add
funds to the open. To aid this decision, we also send the plugin what we
(c-lightning) currently have as our max and min acceptable feerates.

We also now use these as our default for max/min acceptable feerate
range when sending an openchannel offer to a peer.

In the future, it might be a good idea to make these more easily
changeable, either via a config setting (?) or a command param.
This commit is contained in:
niftynei 2020-10-26 12:48:42 -05:00 committed by neil saitug
parent 97fd18f0b5
commit 4ea9d9e928
6 changed files with 145 additions and 58 deletions

View file

@ -77,8 +77,12 @@ struct openchannel2_payload {
struct amount_sat dust_limit_satoshis; struct amount_sat dust_limit_satoshis;
struct amount_msat max_htlc_value_in_flight_msat; struct amount_msat max_htlc_value_in_flight_msat;
struct amount_msat htlc_minimum_msat; struct amount_msat htlc_minimum_msat;
u32 feerate_per_kw_funding; u32 funding_feerate_max;
u32 feerate_per_kw; u32 funding_feerate_min;
u32 funding_feerate_best;
u32 feerate_our_max;
u32 feerate_our_min;
u32 commitment_feerate_per_kw;
u16 to_self_delay; u16 to_self_delay;
u16 max_accepted_htlcs; u16 max_accepted_htlcs;
u8 channel_flags; u8 channel_flags;
@ -87,6 +91,7 @@ struct openchannel2_payload {
/* FIXME: include the podle? */ /* FIXME: include the podle? */
struct amount_sat accepter_funding; struct amount_sat accepter_funding;
u32 funding_feerate_per_kw;
struct wally_psbt *psbt; struct wally_psbt *psbt;
const u8 *our_shutdown_scriptpubkey; const u8 *our_shutdown_scriptpubkey;
}; };
@ -105,9 +110,18 @@ openchannel2_hook_serialize(struct openchannel2_payload *payload,
payload->max_htlc_value_in_flight_msat); payload->max_htlc_value_in_flight_msat);
json_add_amount_msat_only(stream, "htlc_minimum_msat", json_add_amount_msat_only(stream, "htlc_minimum_msat",
payload->htlc_minimum_msat); payload->htlc_minimum_msat);
json_add_num(stream, "feerate_per_kw_funding", json_add_num(stream, "funding_feerate_max",
payload->feerate_per_kw_funding); payload->funding_feerate_max);
json_add_num(stream, "feerate_per_kw", payload->feerate_per_kw); json_add_num(stream, "funding_feerate_min",
payload->funding_feerate_min);
json_add_num(stream, "funding_feerate_best",
payload->funding_feerate_best);
json_add_num(stream, "feerate_our_max",
payload->feerate_our_max);
json_add_num(stream, "feerate_our_min",
payload->feerate_our_min);
json_add_num(stream, "commitment_feerate_per_kw",
payload->commitment_feerate_per_kw);
json_add_num(stream, "to_self_delay", payload->to_self_delay); json_add_num(stream, "to_self_delay", payload->to_self_delay);
json_add_num(stream, "max_accepted_htlcs", payload->max_accepted_htlcs); json_add_num(stream, "max_accepted_htlcs", payload->max_accepted_htlcs);
json_add_num(stream, "channel_flags", payload->channel_flags); json_add_num(stream, "channel_flags", payload->channel_flags);
@ -369,10 +383,31 @@ openchannel2_hook_deserialize(struct openchannel2_payload *payload,
fatal("Plugin supplied PSBT that's missing required fields. %s", fatal("Plugin supplied PSBT that's missing required fields. %s",
type_to_string(tmpctx, struct wally_psbt, payload->psbt)); type_to_string(tmpctx, struct wally_psbt, payload->psbt));
if (!hook_extract_amount(dualopend, buffer, toks, "accepter_funding_msat", if (!hook_extract_amount(dualopend, buffer, toks,
"accepter_funding_msat",
&payload->accepter_funding)) &payload->accepter_funding))
fatal("Plugin failed to supply accepter_funding_msat field"); fatal("Plugin failed to supply accepter_funding_msat field");
const jsmntok_t *t = json_get_member(buffer, toks, "funding_feerate");
/* If they don't return a feerate, we use the best */
if (!t)
payload->funding_feerate_per_kw = payload->funding_feerate_best;
else {
if (!json_to_number(buffer, t,
&payload->funding_feerate_per_kw))
fatal("Unable to parse 'funding-feerate'");
if (payload->funding_feerate_per_kw
< payload->funding_feerate_min
|| payload->funding_feerate_per_kw
> payload->funding_feerate_max)
/* FIXME: return an error instead of failing? */
fatal("Plugin supplied invalid funding feerate %d."
" Outside valid range %d - %d",
payload->funding_feerate_per_kw,
payload->funding_feerate_min,
payload->funding_feerate_max);
}
if (!payload->psbt && if (!payload->psbt &&
!amount_sat_eq(payload->accepter_funding, AMOUNT_SAT(0))) { !amount_sat_eq(payload->accepter_funding, AMOUNT_SAT(0))) {
/* Gotta give a PSBT if you set the accepter_funding amount */ /* Gotta give a PSBT if you set the accepter_funding amount */
@ -386,6 +421,7 @@ static void
openchannel2_hook_cb(struct openchannel2_payload *payload STEALS) openchannel2_hook_cb(struct openchannel2_payload *payload STEALS)
{ {
struct subd *dualopend = payload->dualopend; struct subd *dualopend = payload->dualopend;
u8 *msg;
/* Free payload regardless of what happens next */ /* Free payload regardless of what happens next */
tal_steal(tmpctx, payload); tal_steal(tmpctx, payload);
@ -396,13 +432,19 @@ openchannel2_hook_cb(struct openchannel2_payload *payload STEALS)
tal_del_destructor2(dualopend, openchannel2_remove_dualopend, payload); tal_del_destructor2(dualopend, openchannel2_remove_dualopend, payload);
/* If there's no plugin, the funding_feerate_per_kw will be zero.
* In this case, we set the funding_feerate_per_kw to the default,
* the 'best' */
if (payload->funding_feerate_per_kw == 0)
payload->funding_feerate_per_kw = payload->funding_feerate_best;
/* If there's no plugin, the psbt will be NULL. We should pass an empty /* If there's no plugin, the psbt will be NULL. We should pass an empty
* PSBT over, in this case */ * PSBT over, in this case */
subd_send_msg(dualopend, msg = towire_dual_open_got_offer_reply(NULL, payload->accepter_funding,
take(towire_dual_open_got_offer_reply(NULL, payload->funding_feerate_per_kw,
payload->accepter_funding, payload->psbt,
payload->psbt, payload->our_shutdown_scriptpubkey);
payload->our_shutdown_scriptpubkey))); subd_send_msg(dualopend, take(msg));
} }
/* dualopend dies? Remove dualopend ptr from payload */ /* dualopend dies? Remove dualopend ptr from payload */
@ -956,8 +998,10 @@ static void accepter_got_offer(struct subd *dualopend,
&payload->dust_limit_satoshis, &payload->dust_limit_satoshis,
&payload->max_htlc_value_in_flight_msat, &payload->max_htlc_value_in_flight_msat,
&payload->htlc_minimum_msat, &payload->htlc_minimum_msat,
&payload->feerate_per_kw_funding, &payload->funding_feerate_max,
&payload->feerate_per_kw, &payload->funding_feerate_min,
&payload->funding_feerate_best,
&payload->commitment_feerate_per_kw,
&payload->to_self_delay, &payload->to_self_delay,
&payload->max_accepted_htlcs, &payload->max_accepted_htlcs,
&payload->channel_flags, &payload->channel_flags,
@ -969,6 +1013,17 @@ static void accepter_got_offer(struct subd *dualopend,
return; return;
} }
/* As a convenience to the plugin, we provide our current known
* min + max feerates. Ideally, the plugin will fail to
* contribute funds if the peer's feerate range is outside of
* this acceptable range, but we delegate that decision to
* the plugin's logic */
payload->feerate_our_min = feerate_min(dualopend->ld, NULL);
payload->feerate_our_max = feerate_max(dualopend->ld, NULL);
/* Set the inital to feerate to zero, in case there is no plugin */
payload->funding_feerate_per_kw = 0;
tal_add_destructor2(dualopend, openchannel2_remove_dualopend, payload); tal_add_destructor2(dualopend, openchannel2_remove_dualopend, payload);
plugin_hook_call_openchannel2(dualopend->ld, payload); plugin_hook_call_openchannel2(dualopend->ld, payload);
} }

View file

@ -1200,40 +1200,20 @@ static u8 *accepter_start(struct state *state, const u8 *oc2_msg)
return NULL; return NULL;
} }
/* BOLT #2:
*
* The receiving node MUST fail the channel if:
*...
* - it considers `feerate_per_kw` too small for timely processing or
* unreasonably large.
*/
if (state->feerate_per_kw_funding < state->min_feerate) {
negotiation_failed(state, false,
"feerate_per_kw_funding %u below minimum %u",
state->feerate_per_kw_funding, state->min_feerate);
return NULL;
}
if (state->feerate_per_kw_funding > state->max_feerate) {
negotiation_failed(state, false,
"feerate_per_kw_funding %u above maximum %u",
state->feerate_per_kw_funding, state->max_feerate);
return NULL;
}
/* We can figure out the channel id now */ /* We can figure out the channel id now */
derive_channel_id_v2(&state->channel_id, derive_channel_id_v2(&state->channel_id,
&state->our_points.revocation, &state->our_points.revocation,
&state->their_points.revocation); &state->their_points.revocation);
/* FIXME: pass the podle back also */ /* FIXME: pass the podle back also */
/* FIXME: pass back the feerate options */
msg = towire_dual_open_got_offer(NULL, msg = towire_dual_open_got_offer(NULL,
state->opener_funding, state->opener_funding,
state->remoteconf.dust_limit, state->remoteconf.dust_limit,
state->remoteconf.max_htlc_value_in_flight, state->remoteconf.max_htlc_value_in_flight,
state->remoteconf.htlc_minimum, state->remoteconf.htlc_minimum,
state->feerate_per_kw_funding, feerate_max,
feerate_min,
feerate_best,
state->feerate_per_kw, state->feerate_per_kw,
state->remoteconf.to_self_delay, state->remoteconf.to_self_delay,
state->remoteconf.max_accepted_htlcs, state->remoteconf.max_accepted_htlcs,
@ -1254,7 +1234,9 @@ static u8 *accepter_start(struct state *state, const u8 *oc2_msg)
return NULL; return NULL;
} }
if (!fromwire_dual_open_got_offer_reply(state, msg, if (!fromwire_dual_open_got_offer_reply(state, msg,
&state->accepter_funding, &psbt, &state->accepter_funding,
&state->feerate_per_kw_funding,
&psbt,
&state->upfront_shutdown_script[LOCAL])) &state->upfront_shutdown_script[LOCAL]))
master_badmsg(WIRE_DUAL_OPEN_GOT_OFFER_REPLY, msg); master_badmsg(WIRE_DUAL_OPEN_GOT_OFFER_REPLY, msg);
@ -1318,8 +1300,6 @@ static u8 *accepter_start(struct state *state, const u8 *oc2_msg)
tal_count(state->upfront_shutdown_script[LOCAL]), 0); tal_count(state->upfront_shutdown_script[LOCAL]), 0);
} }
/* FIXME: actually look up a good feerate */
state->feerate_per_kw_funding = feerate_best;
msg = towire_accept_channel2(tmpctx, &state->channel_id, msg = towire_accept_channel2(tmpctx, &state->channel_id,
state->accepter_funding, state->accepter_funding,
state->feerate_per_kw_funding, state->feerate_per_kw_funding,
@ -1551,7 +1531,6 @@ static u8 *opener_start(struct state *state, u8 *msg)
secp256k1_ecdsa_signature *htlc_sigs; secp256k1_ecdsa_signature *htlc_sigs;
u32 feerate_min, feerate_max, feerate_best; u32 feerate_min, feerate_max, feerate_best;
/* FIXME: get these from opener !? */
if (!fromwire_dual_open_opener_init(state, msg, if (!fromwire_dual_open_opener_init(state, msg,
&psbt, &psbt,
&state->opener_funding, &state->opener_funding,
@ -1565,8 +1544,26 @@ static u8 *opener_start(struct state *state, u8 *msg)
state->tx_locktime = psbt->tx->locktime; state->tx_locktime = psbt->tx->locktime;
open_tlv = tlv_opening_tlvs_new(tmpctx); open_tlv = tlv_opening_tlvs_new(tmpctx);
feerate_min = state->feerate_per_kw_funding - 1; feerate_min = state->min_feerate;
feerate_max = state->feerate_per_kw_funding + 1; feerate_max = state->max_feerate;
if (state->feerate_per_kw_funding > state->max_feerate) {
status_info("Selected funding feerate %d is greater than"
" current suggested max %d, adjusing max upwards"
" to match.",
state->feerate_per_kw_funding,
state->max_feerate);
feerate_max = state->feerate_per_kw_funding;
}
if (state->feerate_per_kw_funding < state->min_feerate) {
status_info("Selected funding feerate %d is less than"
" current suggested min %d, adjusing min downwards"
" to match.",
state->feerate_per_kw_funding,
state->min_feerate);
feerate_min = state->feerate_per_kw_funding;
}
feerate_best = state->feerate_per_kw_funding; feerate_best = state->feerate_per_kw_funding;
if (state->upfront_shutdown_script[LOCAL]) { if (state->upfront_shutdown_script[LOCAL]) {

View file

@ -36,7 +36,9 @@ msgdata,dual_open_got_offer,opener_funding,amount_sat,
msgdata,dual_open_got_offer,dust_limit_satoshis,amount_sat, msgdata,dual_open_got_offer,dust_limit_satoshis,amount_sat,
msgdata,dual_open_got_offer,max_htlc_value_in_flight_msat,amount_msat, msgdata,dual_open_got_offer,max_htlc_value_in_flight_msat,amount_msat,
msgdata,dual_open_got_offer,htlc_minimum_msat,amount_msat, msgdata,dual_open_got_offer,htlc_minimum_msat,amount_msat,
msgdata,dual_open_got_offer,feerate_per_kw_funding,u32, msgdata,dual_open_got_offer,feerate_funding_max,u32,
msgdata,dual_open_got_offer,feerate_funding_min,u32,
msgdata,dual_open_got_offer,feerate_funding_best,u32,
msgdata,dual_open_got_offer,feerate_per_kw,u32, msgdata,dual_open_got_offer,feerate_per_kw,u32,
msgdata,dual_open_got_offer,to_self_delay,u16, msgdata,dual_open_got_offer,to_self_delay,u16,
msgdata,dual_open_got_offer,max_accepted_htlcs,u16, msgdata,dual_open_got_offer,max_accepted_htlcs,u16,
@ -48,6 +50,7 @@ msgdata,dual_open_got_offer,shutdown_scriptpubkey,u8,shutdown_len
# master->dualopend: reply back with our first funding info/contribs # master->dualopend: reply back with our first funding info/contribs
msgtype,dual_open_got_offer_reply,7105 msgtype,dual_open_got_offer_reply,7105
msgdata,dual_open_got_offer_reply,accepter_funding,amount_sat, msgdata,dual_open_got_offer_reply,accepter_funding,amount_sat,
msgdata,dual_open_got_offer_reply,feerate_funding,u32,
msgdata,dual_open_got_offer_reply,psbt,wally_psbt, msgdata,dual_open_got_offer_reply,psbt,wally_psbt,
msgdata,dual_open_got_offer_reply,shutdown_len,u16, msgdata,dual_open_got_offer_reply,shutdown_len,u16,
msgdata,dual_open_got_offer_reply,our_shutdown_scriptpubkey,?u8,shutdown_len msgdata,dual_open_got_offer_reply,our_shutdown_scriptpubkey,?u8,shutdown_len

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

View file

@ -130,7 +130,7 @@ bool fromwire_dual_open_init(const tal_t *ctx, const void *p, const struct chain
/* WIRE: DUAL_OPEN_GOT_OFFER */ /* WIRE: DUAL_OPEN_GOT_OFFER */
/* dualopend->master: they offered channel */ /* dualopend->master: they offered channel */
u8 *towire_dual_open_got_offer(const tal_t *ctx, struct amount_sat opener_funding, struct amount_sat dust_limit_satoshis, struct amount_msat max_htlc_value_in_flight_msat, struct amount_msat htlc_minimum_msat, u32 feerate_per_kw_funding, u32 feerate_per_kw, u16 to_self_delay, u16 max_accepted_htlcs, u8 channel_flags, u32 locktime, const u8 *shutdown_scriptpubkey) u8 *towire_dual_open_got_offer(const tal_t *ctx, struct amount_sat opener_funding, struct amount_sat dust_limit_satoshis, struct amount_msat max_htlc_value_in_flight_msat, struct amount_msat htlc_minimum_msat, u32 feerate_funding_max, u32 feerate_funding_min, u32 feerate_funding_best, u32 feerate_per_kw, u16 to_self_delay, u16 max_accepted_htlcs, u8 channel_flags, u32 locktime, const u8 *shutdown_scriptpubkey)
{ {
u16 shutdown_len = tal_count(shutdown_scriptpubkey); u16 shutdown_len = tal_count(shutdown_scriptpubkey);
u8 *p = tal_arr(ctx, u8, 0); u8 *p = tal_arr(ctx, u8, 0);
@ -140,7 +140,9 @@ u8 *towire_dual_open_got_offer(const tal_t *ctx, struct amount_sat opener_fundin
towire_amount_sat(&p, dust_limit_satoshis); towire_amount_sat(&p, dust_limit_satoshis);
towire_amount_msat(&p, max_htlc_value_in_flight_msat); towire_amount_msat(&p, max_htlc_value_in_flight_msat);
towire_amount_msat(&p, htlc_minimum_msat); towire_amount_msat(&p, htlc_minimum_msat);
towire_u32(&p, feerate_per_kw_funding); towire_u32(&p, feerate_funding_max);
towire_u32(&p, feerate_funding_min);
towire_u32(&p, feerate_funding_best);
towire_u32(&p, feerate_per_kw); towire_u32(&p, feerate_per_kw);
towire_u16(&p, to_self_delay); towire_u16(&p, to_self_delay);
towire_u16(&p, max_accepted_htlcs); towire_u16(&p, max_accepted_htlcs);
@ -151,7 +153,7 @@ u8 *towire_dual_open_got_offer(const tal_t *ctx, struct amount_sat opener_fundin
return memcheck(p, tal_count(p)); return memcheck(p, tal_count(p));
} }
bool fromwire_dual_open_got_offer(const tal_t *ctx, const void *p, struct amount_sat *opener_funding, struct amount_sat *dust_limit_satoshis, struct amount_msat *max_htlc_value_in_flight_msat, struct amount_msat *htlc_minimum_msat, u32 *feerate_per_kw_funding, u32 *feerate_per_kw, u16 *to_self_delay, u16 *max_accepted_htlcs, u8 *channel_flags, u32 *locktime, u8 **shutdown_scriptpubkey) bool fromwire_dual_open_got_offer(const tal_t *ctx, const void *p, struct amount_sat *opener_funding, struct amount_sat *dust_limit_satoshis, struct amount_msat *max_htlc_value_in_flight_msat, struct amount_msat *htlc_minimum_msat, u32 *feerate_funding_max, u32 *feerate_funding_min, u32 *feerate_funding_best, u32 *feerate_per_kw, u16 *to_self_delay, u16 *max_accepted_htlcs, u8 *channel_flags, u32 *locktime, u8 **shutdown_scriptpubkey)
{ {
u16 shutdown_len; u16 shutdown_len;
@ -164,7 +166,9 @@ bool fromwire_dual_open_got_offer(const tal_t *ctx, const void *p, struct amount
*dust_limit_satoshis = fromwire_amount_sat(&cursor, &plen); *dust_limit_satoshis = fromwire_amount_sat(&cursor, &plen);
*max_htlc_value_in_flight_msat = fromwire_amount_msat(&cursor, &plen); *max_htlc_value_in_flight_msat = fromwire_amount_msat(&cursor, &plen);
*htlc_minimum_msat = fromwire_amount_msat(&cursor, &plen); *htlc_minimum_msat = fromwire_amount_msat(&cursor, &plen);
*feerate_per_kw_funding = fromwire_u32(&cursor, &plen); *feerate_funding_max = fromwire_u32(&cursor, &plen);
*feerate_funding_min = fromwire_u32(&cursor, &plen);
*feerate_funding_best = fromwire_u32(&cursor, &plen);
*feerate_per_kw = fromwire_u32(&cursor, &plen); *feerate_per_kw = fromwire_u32(&cursor, &plen);
*to_self_delay = fromwire_u16(&cursor, &plen); *to_self_delay = fromwire_u16(&cursor, &plen);
*max_accepted_htlcs = fromwire_u16(&cursor, &plen); *max_accepted_htlcs = fromwire_u16(&cursor, &plen);
@ -179,20 +183,21 @@ bool fromwire_dual_open_got_offer(const tal_t *ctx, const void *p, struct amount
/* WIRE: DUAL_OPEN_GOT_OFFER_REPLY */ /* WIRE: DUAL_OPEN_GOT_OFFER_REPLY */
/* master->dualopend: reply back with our first funding info/contribs */ /* master->dualopend: reply back with our first funding info/contribs */
u8 *towire_dual_open_got_offer_reply(const tal_t *ctx, struct amount_sat accepter_funding, const struct wally_psbt *psbt, const u8 *our_shutdown_scriptpubkey) u8 *towire_dual_open_got_offer_reply(const tal_t *ctx, struct amount_sat accepter_funding, u32 feerate_funding, const struct wally_psbt *psbt, const u8 *our_shutdown_scriptpubkey)
{ {
u16 shutdown_len = tal_count(our_shutdown_scriptpubkey); u16 shutdown_len = tal_count(our_shutdown_scriptpubkey);
u8 *p = tal_arr(ctx, u8, 0); u8 *p = tal_arr(ctx, u8, 0);
towire_u16(&p, WIRE_DUAL_OPEN_GOT_OFFER_REPLY); towire_u16(&p, WIRE_DUAL_OPEN_GOT_OFFER_REPLY);
towire_amount_sat(&p, accepter_funding); towire_amount_sat(&p, accepter_funding);
towire_u32(&p, feerate_funding);
towire_wally_psbt(&p, psbt); towire_wally_psbt(&p, psbt);
towire_u16(&p, shutdown_len); towire_u16(&p, shutdown_len);
towire_u8_array(&p, our_shutdown_scriptpubkey, shutdown_len); towire_u8_array(&p, our_shutdown_scriptpubkey, shutdown_len);
return memcheck(p, tal_count(p)); return memcheck(p, tal_count(p));
} }
bool fromwire_dual_open_got_offer_reply(const tal_t *ctx, const void *p, struct amount_sat *accepter_funding, struct wally_psbt **psbt, u8 **our_shutdown_scriptpubkey) bool fromwire_dual_open_got_offer_reply(const tal_t *ctx, const void *p, struct amount_sat *accepter_funding, u32 *feerate_funding, struct wally_psbt **psbt, u8 **our_shutdown_scriptpubkey)
{ {
u16 shutdown_len; u16 shutdown_len;
@ -202,6 +207,7 @@ bool fromwire_dual_open_got_offer_reply(const tal_t *ctx, const void *p, struct
if (fromwire_u16(&cursor, &plen) != WIRE_DUAL_OPEN_GOT_OFFER_REPLY) if (fromwire_u16(&cursor, &plen) != WIRE_DUAL_OPEN_GOT_OFFER_REPLY)
return false; return false;
*accepter_funding = fromwire_amount_sat(&cursor, &plen); *accepter_funding = fromwire_amount_sat(&cursor, &plen);
*feerate_funding = fromwire_u32(&cursor, &plen);
*psbt = fromwire_wally_psbt(ctx, &cursor, &plen); *psbt = fromwire_wally_psbt(ctx, &cursor, &plen);
shutdown_len = fromwire_u16(&cursor, &plen); shutdown_len = fromwire_u16(&cursor, &plen);
// 2nd case our_shutdown_scriptpubkey // 2nd case our_shutdown_scriptpubkey
@ -479,4 +485,4 @@ bool fromwire_dual_open_dev_memleak_reply(const void *p, bool *leak)
*leak = fromwire_bool(&cursor, &plen); *leak = fromwire_bool(&cursor, &plen);
return cursor != NULL; return cursor != NULL;
} }
// SHA256STAMP:b1bf5b7fc522f2b0d940704f6f9e1699db093da76ca88d3ce7c925d40569ab14 // SHA256STAMP:f08f0c25f359d5c8f843d78c94eca9b0543b39e62a34983f6572adf92ff02aaa

View file

@ -59,13 +59,13 @@ bool fromwire_dual_open_init(const tal_t *ctx, const void *p, const struct chain
/* WIRE: DUAL_OPEN_GOT_OFFER */ /* WIRE: DUAL_OPEN_GOT_OFFER */
/* dualopend->master: they offered channel */ /* dualopend->master: they offered channel */
u8 *towire_dual_open_got_offer(const tal_t *ctx, struct amount_sat opener_funding, struct amount_sat dust_limit_satoshis, struct amount_msat max_htlc_value_in_flight_msat, struct amount_msat htlc_minimum_msat, u32 feerate_per_kw_funding, u32 feerate_per_kw, u16 to_self_delay, u16 max_accepted_htlcs, u8 channel_flags, u32 locktime, const u8 *shutdown_scriptpubkey); u8 *towire_dual_open_got_offer(const tal_t *ctx, struct amount_sat opener_funding, struct amount_sat dust_limit_satoshis, struct amount_msat max_htlc_value_in_flight_msat, struct amount_msat htlc_minimum_msat, u32 feerate_funding_max, u32 feerate_funding_min, u32 feerate_funding_best, u32 feerate_per_kw, u16 to_self_delay, u16 max_accepted_htlcs, u8 channel_flags, u32 locktime, const u8 *shutdown_scriptpubkey);
bool fromwire_dual_open_got_offer(const tal_t *ctx, const void *p, struct amount_sat *opener_funding, struct amount_sat *dust_limit_satoshis, struct amount_msat *max_htlc_value_in_flight_msat, struct amount_msat *htlc_minimum_msat, u32 *feerate_per_kw_funding, u32 *feerate_per_kw, u16 *to_self_delay, u16 *max_accepted_htlcs, u8 *channel_flags, u32 *locktime, u8 **shutdown_scriptpubkey); bool fromwire_dual_open_got_offer(const tal_t *ctx, const void *p, struct amount_sat *opener_funding, struct amount_sat *dust_limit_satoshis, struct amount_msat *max_htlc_value_in_flight_msat, struct amount_msat *htlc_minimum_msat, u32 *feerate_funding_max, u32 *feerate_funding_min, u32 *feerate_funding_best, u32 *feerate_per_kw, u16 *to_self_delay, u16 *max_accepted_htlcs, u8 *channel_flags, u32 *locktime, u8 **shutdown_scriptpubkey);
/* WIRE: DUAL_OPEN_GOT_OFFER_REPLY */ /* WIRE: DUAL_OPEN_GOT_OFFER_REPLY */
/* master->dualopend: reply back with our first funding info/contribs */ /* master->dualopend: reply back with our first funding info/contribs */
u8 *towire_dual_open_got_offer_reply(const tal_t *ctx, struct amount_sat accepter_funding, const struct wally_psbt *psbt, const u8 *our_shutdown_scriptpubkey); u8 *towire_dual_open_got_offer_reply(const tal_t *ctx, struct amount_sat accepter_funding, u32 feerate_funding, const struct wally_psbt *psbt, const u8 *our_shutdown_scriptpubkey);
bool fromwire_dual_open_got_offer_reply(const tal_t *ctx, const void *p, struct amount_sat *accepter_funding, struct wally_psbt **psbt, u8 **our_shutdown_scriptpubkey); bool fromwire_dual_open_got_offer_reply(const tal_t *ctx, const void *p, struct amount_sat *accepter_funding, u32 *feerate_funding, struct wally_psbt **psbt, u8 **our_shutdown_scriptpubkey);
/* WIRE: DUAL_OPEN_COMMIT_RCVD */ /* WIRE: DUAL_OPEN_COMMIT_RCVD */
/* dualopend->master: ready to commit channel open to database and */ /* dualopend->master: ready to commit channel open to database and */
@ -109,4 +109,4 @@ bool fromwire_dual_open_dev_memleak_reply(const void *p, bool *leak);
#endif /* LIGHTNING_OPENINGD_DUALOPEND_WIREGEN_H */ #endif /* LIGHTNING_OPENINGD_DUALOPEND_WIREGEN_H */
// SHA256STAMP:b1bf5b7fc522f2b0d940704f6f9e1699db093da76ca88d3ce7c925d40569ab14 // SHA256STAMP:f08f0c25f359d5c8f843d78c94eca9b0543b39e62a34983f6572adf92ff02aaa

View file

@ -44,13 +44,38 @@ def get_script(bech_addr):
return bytes([wit_ver + 0x50 if wit_ver > 0 else wit_ver, len(wprog)] + wprog) return bytes([wit_ver + 0x50 if wit_ver > 0 else wit_ver, len(wprog)] + wprog)
def find_feerate(best, their_min, their_max, our_min, our_max):
if best >= our_min and best <= our_max:
return best
if their_max < our_min or their_min > our_max:
return False
if best < our_min:
return our_min
# best > our_max:
return our_max
@plugin.hook('openchannel2') @plugin.hook('openchannel2')
def on_openchannel(openchannel2, plugin, **kwargs): def on_openchannel(openchannel2, plugin, **kwargs):
# We mirror what the peer does, wrt to funding amount # We mirror what the peer does, wrt to funding amount ...
amount = openchannel2['their_funding'] amount = openchannel2['their_funding']
feerate = openchannel2['feerate_per_kw_funding']
locktime = openchannel2['locktime'] locktime = openchannel2['locktime']
# ...unless they send us totally unacceptable feerates.
feerate = find_feerate(openchannel2['funding_feerate_best'],
openchannel2['funding_feerate_min'],
openchannel2['funding_feerate_max'],
openchannel2['feerate_our_min'],
openchannel2['feerate_our_max'])
# Their feerate range is out of bounds, we're not going to
# participate.
if not feerate:
return {'result': 'continue'}
funding = plugin.rpc.fundpsbt(amount, ''.join([str(feerate), 'perkw']), 0, reserve=True, funding = plugin.rpc.fundpsbt(amount, ''.join([str(feerate), 'perkw']), 0, reserve=True,
locktime=locktime) locktime=locktime)
psbt_obj = psbt_from_base64(funding['psbt']) psbt_obj = psbt_from_base64(funding['psbt'])
@ -65,7 +90,8 @@ def on_openchannel(openchannel2, plugin, **kwargs):
psbt_add_output_at(psbt_obj, 0, 0, output) psbt_add_output_at(psbt_obj, 0, 0, output)
return {'result': 'continue', 'psbt': psbt_to_base64(psbt_obj, 0), return {'result': 'continue', 'psbt': psbt_to_base64(psbt_obj, 0),
'accepter_funding_msat': amount} 'accepter_funding_msat': amount,
'funding_feerate': feerate}
@plugin.hook('openchannel2_changed') @plugin.hook('openchannel2_changed')