mirror of
https://github.com/aljazceru/lightning.git
synced 2025-12-19 15:14:23 +01:00
setchannel: add minhtlc
Suggested by @m-schmook, I realized that if we append it later I'll never get it right: I expect parameters min and max, not max and min! Signed-off-by: Rusty Russell <rusty@rustcorp.com.au> Changelog-Added: Protocol: you can now alter the `htlc_minimum_msat` and `htlc_maximum_msat` your node advertizes.
This commit is contained in:
@@ -124,7 +124,9 @@ struct peer {
|
|||||||
* the channel_updates. */
|
* the channel_updates. */
|
||||||
u32 fee_base;
|
u32 fee_base;
|
||||||
u32 fee_per_satoshi;
|
u32 fee_per_satoshi;
|
||||||
struct amount_msat htlc_maximum_msat;
|
/* Note: the real min constraint is channel->config[REMOTE].htlc_minimum:
|
||||||
|
* they could kill the channel if we violate that! */
|
||||||
|
struct amount_msat htlc_minimum_msat, htlc_maximum_msat;
|
||||||
|
|
||||||
/* The scriptpubkey to use for shutting down. */
|
/* The scriptpubkey to use for shutting down. */
|
||||||
u32 *final_index;
|
u32 *final_index;
|
||||||
@@ -361,7 +363,7 @@ static void send_channel_update(struct peer *peer, int disable_flag)
|
|||||||
disable_flag
|
disable_flag
|
||||||
== ROUTING_FLAGS_DISABLED,
|
== ROUTING_FLAGS_DISABLED,
|
||||||
peer->cltv_delta,
|
peer->cltv_delta,
|
||||||
peer->channel->config[REMOTE].htlc_minimum,
|
peer->htlc_minimum_msat,
|
||||||
peer->fee_base,
|
peer->fee_base,
|
||||||
peer->fee_per_satoshi,
|
peer->fee_per_satoshi,
|
||||||
peer->htlc_maximum_msat);
|
peer->htlc_maximum_msat);
|
||||||
@@ -3429,10 +3431,13 @@ static void handle_blockheight(struct peer *peer, const u8 *inmsg)
|
|||||||
static void handle_config_channel(struct peer *peer, const u8 *inmsg)
|
static void handle_config_channel(struct peer *peer, const u8 *inmsg)
|
||||||
{
|
{
|
||||||
u32 *base, *ppm;
|
u32 *base, *ppm;
|
||||||
struct amount_msat *htlc_max;
|
struct amount_msat *htlc_min, *htlc_max;
|
||||||
bool changed;
|
bool changed;
|
||||||
|
|
||||||
if (!fromwire_channeld_config_channel(inmsg, inmsg, &base, &ppm, &htlc_max))
|
if (!fromwire_channeld_config_channel(inmsg, inmsg,
|
||||||
|
&base, &ppm,
|
||||||
|
&htlc_min,
|
||||||
|
&htlc_max))
|
||||||
master_badmsg(WIRE_CHANNELD_CONFIG_CHANNEL, inmsg);
|
master_badmsg(WIRE_CHANNELD_CONFIG_CHANNEL, inmsg);
|
||||||
|
|
||||||
/* only send channel updates if values actually changed */
|
/* only send channel updates if values actually changed */
|
||||||
@@ -3445,6 +3450,10 @@ static void handle_config_channel(struct peer *peer, const u8 *inmsg)
|
|||||||
peer->fee_per_satoshi = *ppm;
|
peer->fee_per_satoshi = *ppm;
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
|
if (htlc_min && !amount_msat_eq(*htlc_min, peer->htlc_minimum_msat)) {
|
||||||
|
peer->htlc_minimum_msat = *htlc_min;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
if (htlc_max && !amount_msat_eq(*htlc_max, peer->htlc_maximum_msat)) {
|
if (htlc_max && !amount_msat_eq(*htlc_max, peer->htlc_maximum_msat)) {
|
||||||
peer->htlc_maximum_msat = *htlc_max;
|
peer->htlc_maximum_msat = *htlc_max;
|
||||||
changed = true;
|
changed = true;
|
||||||
@@ -3755,6 +3764,7 @@ static void init_channel(struct peer *peer)
|
|||||||
&opener,
|
&opener,
|
||||||
&peer->fee_base,
|
&peer->fee_base,
|
||||||
&peer->fee_per_satoshi,
|
&peer->fee_per_satoshi,
|
||||||
|
&peer->htlc_minimum_msat,
|
||||||
&peer->htlc_maximum_msat,
|
&peer->htlc_maximum_msat,
|
||||||
&local_msat,
|
&local_msat,
|
||||||
&points[LOCAL],
|
&points[LOCAL],
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ msgdata,channeld_init,old_remote_per_commit,pubkey,
|
|||||||
msgdata,channeld_init,opener,enum side,
|
msgdata,channeld_init,opener,enum side,
|
||||||
msgdata,channeld_init,fee_base,u32,
|
msgdata,channeld_init,fee_base,u32,
|
||||||
msgdata,channeld_init,fee_proportional,u32,
|
msgdata,channeld_init,fee_proportional,u32,
|
||||||
|
msgdata,channeld_init,htlc_minimum_msat,amount_msat,
|
||||||
msgdata,channeld_init,htlc_maximum_msat,amount_msat,
|
msgdata,channeld_init,htlc_maximum_msat,amount_msat,
|
||||||
msgdata,channeld_init,local_msatoshi,amount_msat,
|
msgdata,channeld_init,local_msatoshi,amount_msat,
|
||||||
msgdata,channeld_init,our_basepoints,basepoints,
|
msgdata,channeld_init,our_basepoints,basepoints,
|
||||||
@@ -220,6 +221,7 @@ msgdata,channeld_fail_fallen_behind,remote_per_commitment_point,?pubkey,
|
|||||||
msgtype,channeld_config_channel,1029
|
msgtype,channeld_config_channel,1029
|
||||||
msgdata,channeld_config_channel,feerate_base,?u32,
|
msgdata,channeld_config_channel,feerate_base,?u32,
|
||||||
msgdata,channeld_config_channel,feerate_ppm,?u32,
|
msgdata,channeld_config_channel,feerate_ppm,?u32,
|
||||||
|
msgdata,channeld_config_channel,htlc_minimum,?amount_msat,
|
||||||
msgdata,channeld_config_channel,htlc_maximum,?amount_msat,
|
msgdata,channeld_config_channel,htlc_maximum,?amount_msat,
|
||||||
|
|
||||||
# When we receive announcement_signatures for channel announce
|
# When we receive announcement_signatures for channel announce
|
||||||
|
|||||||
|
Can't render this file because it has a wrong number of fields in line 14.
|
@@ -1176,7 +1176,7 @@ class LightningRpc(UnixDomainSocketRpc):
|
|||||||
}
|
}
|
||||||
return self.call("setchannelfee", payload)
|
return self.call("setchannelfee", payload)
|
||||||
|
|
||||||
def setchannel(self, id, feebase=None, feeppm=None, htlcmax=None, enforcedelay=None):
|
def setchannel(self, id, feebase=None, feeppm=None, htlcmin=None, htlcmax=None, enforcedelay=None):
|
||||||
"""Set configuration a channel/peer {id} (or 'all').
|
"""Set configuration a channel/peer {id} (or 'all').
|
||||||
|
|
||||||
{feebase} is a value in millisatoshi that is added as base fee
|
{feebase} is a value in millisatoshi that is added as base fee
|
||||||
@@ -1185,6 +1185,9 @@ class LightningRpc(UnixDomainSocketRpc):
|
|||||||
{feeppm} is a value added proportionally per-millionths to any
|
{feeppm} is a value added proportionally per-millionths to any
|
||||||
routed payment volume in satoshi.
|
routed payment volume in satoshi.
|
||||||
|
|
||||||
|
{htlcmin} is the minimum (outgoing) htlc amount to allow and
|
||||||
|
advertize.
|
||||||
|
|
||||||
{htlcmax} is the maximum (outgoing) htlc amount to allow and
|
{htlcmax} is the maximum (outgoing) htlc amount to allow and
|
||||||
advertize.
|
advertize.
|
||||||
|
|
||||||
@@ -1196,6 +1199,7 @@ class LightningRpc(UnixDomainSocketRpc):
|
|||||||
"id": id,
|
"id": id,
|
||||||
"feebase": feebase,
|
"feebase": feebase,
|
||||||
"feeppm": feeppm,
|
"feeppm": feeppm,
|
||||||
|
"htlcmin": htlcmin,
|
||||||
"htlcmax": htlcmax,
|
"htlcmax": htlcmax,
|
||||||
"enforcedelay": enforcedelay,
|
"enforcedelay": enforcedelay,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -87,6 +87,7 @@ On success, an object containing **peers** is returned. It is an array of objec
|
|||||||
- **spendable_msat** (msat, optional): total we could send through channel
|
- **spendable_msat** (msat, optional): total we could send through channel
|
||||||
- **receivable_msat** (msat, optional): total peer could send through channel
|
- **receivable_msat** (msat, optional): total peer could send through channel
|
||||||
- **minimum_htlc_in_msat** (msat, optional): the minimum amount HTLC we accept
|
- **minimum_htlc_in_msat** (msat, optional): the minimum amount HTLC we accept
|
||||||
|
- **minimum_htlc_out_msat** (msat, optional): the minimum amount HTLC we will send
|
||||||
- **maximum_htlc_out_msat** (msat, optional): the maximum amount HTLC we will send
|
- **maximum_htlc_out_msat** (msat, optional): the maximum amount HTLC we will send
|
||||||
- **their_to_self_delay** (u32, optional): the number of blocks before they can take their funds if they unilateral close
|
- **their_to_self_delay** (u32, optional): the number of blocks before they can take their funds if they unilateral close
|
||||||
- **our_to_self_delay** (u32, optional): the number of blocks before we can take our funds if we unilateral close
|
- **our_to_self_delay** (u32, optional): the number of blocks before we can take our funds if we unilateral close
|
||||||
@@ -379,4 +380,4 @@ Main web site: <https://github.com/ElementsProject/lightning> Lightning
|
|||||||
RFC site (BOLT \#9):
|
RFC site (BOLT \#9):
|
||||||
<https://github.com/lightningnetwork/lightning-rfc/blob/master/09-features.md>
|
<https://github.com/lightningnetwork/lightning-rfc/blob/master/09-features.md>
|
||||||
|
|
||||||
[comment]: # ( SHA256STAMP:8e30caf48aed46acc7c053a355867dc8b8624035dba4ea7668d30d86b8d827cd)
|
[comment]: # ( SHA256STAMP:147b7008c8f4acb031df625e0731614339a75ee5861cb9f40cd542b1017e3660)
|
||||||
|
|||||||
@@ -1,20 +1,24 @@
|
|||||||
lightning-setchannel -- Command for configuring fees / maximum htlc on a lightning channel
|
lightning-setchannel -- Command for configuring fees / htlc range advertized for a channel
|
||||||
===========================================================================================
|
===========================================================================================
|
||||||
|
|
||||||
SYNOPSIS
|
SYNOPSIS
|
||||||
--------
|
--------
|
||||||
|
|
||||||
**setchannel** *id* [*feebase*] [*feeppm*] [*htlcmax*] [*enforcedelay*]
|
**setchannel** *id* [*feebase*] [*feeppm*] [*htlcmin*] [*htlcmax*] [*enforcedelay*]
|
||||||
|
|
||||||
DESCRIPTION
|
DESCRIPTION
|
||||||
-----------
|
-----------
|
||||||
|
|
||||||
The **setchannel** RPC command sets channel specific routing fees, and
|
The **setchannel** RPC command sets channel specific routing fees, and
|
||||||
`htlc_maximum_msat` as defined in BOLT \#7. The channel has to be in
|
`htlc_minimum_msat` or `htlc_maximum_msat` as defined in BOLT \#7. The channel has to be in
|
||||||
normal or awaiting state. This can be checked by **listpeers**
|
normal or awaiting state. This can be checked by **listpeers**
|
||||||
reporting a *state* of CHANNELD\_NORMAL or CHANNELD\_AWAITING\_LOCKIN
|
reporting a *state* of CHANNELD\_NORMAL or CHANNELD\_AWAITING\_LOCKIN
|
||||||
for the channel.
|
for the channel.
|
||||||
|
|
||||||
|
These changes (for a public channel) will be broadcast to the rest of
|
||||||
|
the network (though many nodes limit the rate of such changes they
|
||||||
|
will accept: we allow 2 a day, with a few extra occasionally).
|
||||||
|
|
||||||
*id* is required and should contain a scid (short channel ID), channel
|
*id* is required and should contain a scid (short channel ID), channel
|
||||||
id or peerid (pubkey) of the channel to be modified. If *id* is set to
|
id or peerid (pubkey) of the channel to be modified. If *id* is set to
|
||||||
"all", the updates are applied to all channels in states
|
"all", the updates are applied to all channels in states
|
||||||
@@ -31,6 +35,13 @@ to any routed payment volume in satoshi. For example, if ppm is 1,000
|
|||||||
and 1,000,000 satoshi is being routed through the channel, an
|
and 1,000,000 satoshi is being routed through the channel, an
|
||||||
proportional fee of 1,000 satoshi is added, resulting in a 0.1% fee.
|
proportional fee of 1,000 satoshi is added, resulting in a 0.1% fee.
|
||||||
|
|
||||||
|
*htlcmin* is an optional value that limits how small an HTLC we will
|
||||||
|
send: if omitted, it is unchanged (the default is no lower limit). It
|
||||||
|
can be a whole number, or a whole number ending in *msat* or *sat*, or
|
||||||
|
a number with three decimal places ending in *sat*, or a number with 1
|
||||||
|
to 11 decimal places ending in *btc*. The peer also enforces a
|
||||||
|
minimum for the channel: setting it below will be ignored.
|
||||||
|
|
||||||
*htlcmax* is an optional value that limits how large an HTLC we will
|
*htlcmax* is an optional value that limits how large an HTLC we will
|
||||||
send: if omitted, it is unchanged (the default is no effective
|
send: if omitted, it is unchanged (the default is no effective
|
||||||
limit). It can be a whole number, or a whole number ending in *msat*
|
limit). It can be a whole number, or a whole number ending in *msat*
|
||||||
@@ -55,8 +66,11 @@ On success, an object containing **channels** is returned. It is an array of ob
|
|||||||
- **channel_id** (hex): The channel_id of the channel (always 64 characters)
|
- **channel_id** (hex): The channel_id of the channel (always 64 characters)
|
||||||
- **fee_base_msat** (msat): The resulting feebase (this is the BOLT #7 name)
|
- **fee_base_msat** (msat): The resulting feebase (this is the BOLT #7 name)
|
||||||
- **fee_proportional_millionths** (u32): The resulting feeppm (this is the BOLT #7 name)
|
- **fee_proportional_millionths** (u32): The resulting feeppm (this is the BOLT #7 name)
|
||||||
|
- **minimum_htlc_out_msat** (msat): The resulting htlcmin we will advertize (the BOLT #7 name is htlc_minimum_msat)
|
||||||
- **maximum_htlc_out_msat** (msat): The resulting htlcmax we will advertize (the BOLT #7 name is htlc_maximum_msat)
|
- **maximum_htlc_out_msat** (msat): The resulting htlcmax we will advertize (the BOLT #7 name is htlc_maximum_msat)
|
||||||
- **short_channel_id** (short_channel_id, optional): the short_channel_id (if locked in)
|
- **short_channel_id** (short_channel_id, optional): the short_channel_id (if locked in)
|
||||||
|
- the following warnings are possible:
|
||||||
|
- **warning_htlcmin_too_low**: The requested htlcmin was too low for this peer, so we set it to the minimum they will allow
|
||||||
|
|
||||||
[comment]: # (GENERATE-FROM-SCHEMA-END)
|
[comment]: # (GENERATE-FROM-SCHEMA-END)
|
||||||
|
|
||||||
@@ -86,4 +100,4 @@ RESOURCES
|
|||||||
|
|
||||||
Main web site: <https://github.com/ElementsProject/lightning>
|
Main web site: <https://github.com/ElementsProject/lightning>
|
||||||
|
|
||||||
[comment]: # ( SHA256STAMP:25c6733af784e8a21a8eed4bcb0f12767ae49d16fe623187ae5313b5bb5cdd80)
|
[comment]: # ( SHA256STAMP:0f153e7dddce61bc921b3743472f11316c5984b9b1459cac1b201d6f51ec1be1)
|
||||||
|
|||||||
@@ -418,6 +418,10 @@
|
|||||||
"type": "msat",
|
"type": "msat",
|
||||||
"description": "the minimum amount HTLC we accept"
|
"description": "the minimum amount HTLC we accept"
|
||||||
},
|
},
|
||||||
|
"minimum_htlc_out_msat": {
|
||||||
|
"type": "msat",
|
||||||
|
"description": "the minimum amount HTLC we will send"
|
||||||
|
},
|
||||||
"maximum_htlc_out_msat": {
|
"maximum_htlc_out_msat": {
|
||||||
"type": "msat",
|
"type": "msat",
|
||||||
"description": "the maximum amount HTLC we will send"
|
"description": "the maximum amount HTLC we will send"
|
||||||
@@ -776,6 +780,7 @@
|
|||||||
"spendable_msat": {},
|
"spendable_msat": {},
|
||||||
"receivable_msat": {},
|
"receivable_msat": {},
|
||||||
"minimum_htlc_in_msat": {},
|
"minimum_htlc_in_msat": {},
|
||||||
|
"minimum_htlc_out_msat": {},
|
||||||
"maximum_htlc_out_msat": {},
|
"maximum_htlc_out_msat": {},
|
||||||
"spendable_msatoshi": {},
|
"spendable_msatoshi": {},
|
||||||
"receivable_msatoshi": {},
|
"receivable_msatoshi": {},
|
||||||
@@ -864,6 +869,7 @@
|
|||||||
"spendable_msat": {},
|
"spendable_msat": {},
|
||||||
"receivable_msat": {},
|
"receivable_msat": {},
|
||||||
"minimum_htlc_in_msat": {},
|
"minimum_htlc_in_msat": {},
|
||||||
|
"minimum_htlc_out_msat": {},
|
||||||
"maximum_htlc_out_msat": {},
|
"maximum_htlc_out_msat": {},
|
||||||
"spendable_msatoshi": {},
|
"spendable_msatoshi": {},
|
||||||
"receivable_msatoshi": {},
|
"receivable_msatoshi": {},
|
||||||
@@ -953,6 +959,7 @@
|
|||||||
"spendable_msat": {},
|
"spendable_msat": {},
|
||||||
"receivable_msat": {},
|
"receivable_msat": {},
|
||||||
"minimum_htlc_in_msat": {},
|
"minimum_htlc_in_msat": {},
|
||||||
|
"minimum_htlc_out_msat": {},
|
||||||
"maximum_htlc_out_msat": {},
|
"maximum_htlc_out_msat": {},
|
||||||
"spendable_msatoshi": {},
|
"spendable_msatoshi": {},
|
||||||
"receivable_msatoshi": {},
|
"receivable_msatoshi": {},
|
||||||
@@ -1041,6 +1048,7 @@
|
|||||||
"spendable_msat": {},
|
"spendable_msat": {},
|
||||||
"receivable_msat": {},
|
"receivable_msat": {},
|
||||||
"minimum_htlc_in_msat": {},
|
"minimum_htlc_in_msat": {},
|
||||||
|
"minimum_htlc_out_msat": {},
|
||||||
"maximum_htlc_out_msat": {},
|
"maximum_htlc_out_msat": {},
|
||||||
"spendable_msatoshi": {},
|
"spendable_msatoshi": {},
|
||||||
"receivable_msatoshi": {},
|
"receivable_msatoshi": {},
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
"channel_id",
|
"channel_id",
|
||||||
"fee_base_msat",
|
"fee_base_msat",
|
||||||
"fee_proportional_millionths",
|
"fee_proportional_millionths",
|
||||||
|
"minimum_htlc_out_msat",
|
||||||
"maximum_htlc_out_msat"
|
"maximum_htlc_out_msat"
|
||||||
],
|
],
|
||||||
"properties": {
|
"properties": {
|
||||||
@@ -42,6 +43,14 @@
|
|||||||
"type": "u32",
|
"type": "u32",
|
||||||
"description": "The resulting feeppm (this is the BOLT #7 name)"
|
"description": "The resulting feeppm (this is the BOLT #7 name)"
|
||||||
},
|
},
|
||||||
|
"minimum_htlc_out_msat": {
|
||||||
|
"type": "msat",
|
||||||
|
"description": "The resulting htlcmin we will advertize (the BOLT #7 name is htlc_minimum_msat)"
|
||||||
|
},
|
||||||
|
"warning_htlcmin_too_low": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "The requested htlcmin was too low for this peer, so we set it to the minimum they will allow"
|
||||||
|
},
|
||||||
"maximum_htlc_out_msat": {
|
"maximum_htlc_out_msat": {
|
||||||
"type": "msat",
|
"type": "msat",
|
||||||
"description": "The resulting htlcmax we will advertize (the BOLT #7 name is htlc_maximum_msat)"
|
"description": "The resulting htlcmax we will advertize (the BOLT #7 name is htlc_maximum_msat)"
|
||||||
|
|||||||
@@ -410,10 +410,11 @@ struct channel *new_channel(struct peer *peer, u64 dbid,
|
|||||||
secp256k1_ecdsa_signature *lease_commit_sig STEALS,
|
secp256k1_ecdsa_signature *lease_commit_sig STEALS,
|
||||||
u32 lease_chan_max_msat,
|
u32 lease_chan_max_msat,
|
||||||
u16 lease_chan_max_ppt,
|
u16 lease_chan_max_ppt,
|
||||||
|
struct amount_msat htlc_minimum_msat,
|
||||||
struct amount_msat htlc_maximum_msat)
|
struct amount_msat htlc_maximum_msat)
|
||||||
{
|
{
|
||||||
struct channel *channel = tal(peer->ld, struct channel);
|
struct channel *channel = tal(peer->ld, struct channel);
|
||||||
struct amount_msat htlc_max;
|
struct amount_msat htlc_min, htlc_max;
|
||||||
|
|
||||||
assert(dbid != 0);
|
assert(dbid != 0);
|
||||||
channel->peer = peer;
|
channel->peer = peer;
|
||||||
@@ -509,8 +510,12 @@ struct channel *new_channel(struct peer *peer, u64 dbid,
|
|||||||
channel->blockheight_states = dup_height_states(channel, height_states);
|
channel->blockheight_states = dup_height_states(channel, height_states);
|
||||||
channel->channel_update = NULL;
|
channel->channel_update = NULL;
|
||||||
|
|
||||||
/* DB migration, for example, sets this to bignum; correct
|
/* DB migration, for example, sets min to 0, max to large: fixup */
|
||||||
* here */
|
htlc_min = channel->channel_info.their_config.htlc_minimum;
|
||||||
|
if (amount_msat_greater(htlc_min, htlc_minimum_msat))
|
||||||
|
channel->htlc_minimum_msat = htlc_min;
|
||||||
|
else
|
||||||
|
channel->htlc_minimum_msat = htlc_minimum_msat;
|
||||||
htlc_max = htlc_max_possible_send(channel);
|
htlc_max = htlc_max_possible_send(channel);
|
||||||
if (amount_msat_less(htlc_max, htlc_maximum_msat))
|
if (amount_msat_less(htlc_max, htlc_maximum_msat))
|
||||||
channel->htlc_maximum_msat = htlc_max;
|
channel->htlc_maximum_msat = htlc_max;
|
||||||
|
|||||||
@@ -196,8 +196,8 @@ struct channel {
|
|||||||
* peer via option_data_loss_protect? */
|
* peer via option_data_loss_protect? */
|
||||||
const struct pubkey *future_per_commitment_point;
|
const struct pubkey *future_per_commitment_point;
|
||||||
|
|
||||||
/* Max htlc amount allowed in channel. */
|
/* Min/max htlc amount allowed in channel. */
|
||||||
struct amount_msat htlc_maximum_msat;
|
struct amount_msat htlc_minimum_msat, htlc_maximum_msat;
|
||||||
|
|
||||||
/* Feerate per channel */
|
/* Feerate per channel */
|
||||||
u32 feerate_base, feerate_ppm;
|
u32 feerate_base, feerate_ppm;
|
||||||
@@ -205,7 +205,7 @@ struct channel {
|
|||||||
/* But allow these feerates/htlcs up until this time. */
|
/* But allow these feerates/htlcs up until this time. */
|
||||||
struct timeabs old_feerate_timeout;
|
struct timeabs old_feerate_timeout;
|
||||||
u32 old_feerate_base, old_feerate_ppm;
|
u32 old_feerate_base, old_feerate_ppm;
|
||||||
struct amount_msat old_htlc_maximum_msat;
|
struct amount_msat old_htlc_minimum_msat, old_htlc_maximum_msat;
|
||||||
|
|
||||||
/* If they used option_upfront_shutdown_script. */
|
/* If they used option_upfront_shutdown_script. */
|
||||||
const u8 *remote_upfront_shutdown_script;
|
const u8 *remote_upfront_shutdown_script;
|
||||||
@@ -315,6 +315,7 @@ struct channel *new_channel(struct peer *peer, u64 dbid,
|
|||||||
secp256k1_ecdsa_signature *lease_commit_sig STEALS,
|
secp256k1_ecdsa_signature *lease_commit_sig STEALS,
|
||||||
u32 lease_chan_max_msat,
|
u32 lease_chan_max_msat,
|
||||||
u16 lease_chan_max_ppt,
|
u16 lease_chan_max_ppt,
|
||||||
|
struct amount_msat htlc_minimum_msat,
|
||||||
struct amount_msat htlc_maximum_msat);
|
struct amount_msat htlc_maximum_msat);
|
||||||
|
|
||||||
/* new_inflight - Create a new channel_inflight for a channel */
|
/* new_inflight - Create a new channel_inflight for a channel */
|
||||||
|
|||||||
@@ -702,6 +702,7 @@ void peer_start_channeld(struct channel *channel,
|
|||||||
channel->opener,
|
channel->opener,
|
||||||
channel->feerate_base,
|
channel->feerate_base,
|
||||||
channel->feerate_ppm,
|
channel->feerate_ppm,
|
||||||
|
channel->htlc_minimum_msat,
|
||||||
channel->htlc_maximum_msat,
|
channel->htlc_maximum_msat,
|
||||||
channel->our_msat,
|
channel->our_msat,
|
||||||
&channel->local_basepoints,
|
&channel->local_basepoints,
|
||||||
|
|||||||
@@ -1110,6 +1110,7 @@ wallet_update_channel(struct lightningd *ld,
|
|||||||
channel->msat_to_us_min = our_msat;
|
channel->msat_to_us_min = our_msat;
|
||||||
channel->msat_to_us_max = our_msat;
|
channel->msat_to_us_max = our_msat;
|
||||||
channel->lease_expiry = lease_expiry;
|
channel->lease_expiry = lease_expiry;
|
||||||
|
channel->htlc_minimum_msat = channel->channel_info.their_config.htlc_minimum;
|
||||||
channel->htlc_maximum_msat = htlc_max_possible_send(channel);
|
channel->htlc_maximum_msat = htlc_max_possible_send(channel);
|
||||||
|
|
||||||
tal_free(channel->lease_commit_sig);
|
tal_free(channel->lease_commit_sig);
|
||||||
@@ -1253,6 +1254,7 @@ wallet_commit_channel(struct lightningd *ld,
|
|||||||
|
|
||||||
channel->lease_chan_max_msat = lease_chan_max_msat;
|
channel->lease_chan_max_msat = lease_chan_max_msat;
|
||||||
channel->lease_chan_max_ppt = lease_chan_max_ppt;
|
channel->lease_chan_max_ppt = lease_chan_max_ppt;
|
||||||
|
channel->htlc_minimum_msat = channel_info->their_config.htlc_minimum;
|
||||||
channel->htlc_maximum_msat = htlc_max_possible_send(channel);
|
channel->htlc_maximum_msat = htlc_max_possible_send(channel);
|
||||||
|
|
||||||
/* Now we finally put it in the database. */
|
/* Now we finally put it in the database. */
|
||||||
|
|||||||
@@ -210,6 +210,7 @@ wallet_commit_channel(struct lightningd *ld,
|
|||||||
take(new_height_states(NULL, uc->fc ? LOCAL : REMOTE,
|
take(new_height_states(NULL, uc->fc ? LOCAL : REMOTE,
|
||||||
&lease_start_blockheight)),
|
&lease_start_blockheight)),
|
||||||
0, NULL, 0, 0, /* No leases on v1s */
|
0, NULL, 0, 0, /* No leases on v1s */
|
||||||
|
AMOUNT_MSAT(0), /* No htlc_minimum_msat */
|
||||||
AMOUNT_MSAT(-1ULL)); /* No htlc_maximum_msat */
|
AMOUNT_MSAT(-1ULL)); /* No htlc_maximum_msat */
|
||||||
|
|
||||||
/* Now we finally put it in the database. */
|
/* Now we finally put it in the database. */
|
||||||
|
|||||||
@@ -861,6 +861,9 @@ static void json_add_channel(struct lightningd *ld,
|
|||||||
channel->our_config.htlc_minimum,
|
channel->our_config.htlc_minimum,
|
||||||
"htlc_minimum_msat",
|
"htlc_minimum_msat",
|
||||||
"minimum_htlc_in_msat");
|
"minimum_htlc_in_msat");
|
||||||
|
json_add_amount_msat_only(response,
|
||||||
|
"minimum_htlc_out_msat",
|
||||||
|
channel->htlc_minimum_msat);
|
||||||
json_add_amount_msat_only(response,
|
json_add_amount_msat_only(response,
|
||||||
"maximum_htlc_out_msat",
|
"maximum_htlc_out_msat",
|
||||||
channel->htlc_maximum_msat);
|
channel->htlc_maximum_msat);
|
||||||
@@ -2010,21 +2013,27 @@ static struct command_result *param_msat_u32(struct command *cmd,
|
|||||||
static void set_channel_config(struct command *cmd, struct channel *channel,
|
static void set_channel_config(struct command *cmd, struct channel *channel,
|
||||||
u32 *base,
|
u32 *base,
|
||||||
u32 *ppm,
|
u32 *ppm,
|
||||||
|
struct amount_msat *htlc_min,
|
||||||
struct amount_msat *htlc_max,
|
struct amount_msat *htlc_max,
|
||||||
u32 delaysecs,
|
u32 delaysecs,
|
||||||
struct json_stream *response,
|
struct json_stream *response,
|
||||||
bool add_details)
|
bool add_details)
|
||||||
{
|
{
|
||||||
|
bool warn_cannot_set_min = false;
|
||||||
|
|
||||||
/* We only need to defer values if we *increase* fees (or drop
|
/* We only need to defer values if we *increase* fees (or drop
|
||||||
* max); we always allow users to overpay fees. */
|
* max, increase min); we always allow users to overpay fees. */
|
||||||
if ((base && *base > channel->feerate_base)
|
if ((base && *base > channel->feerate_base)
|
||||||
|| (ppm && *ppm > channel->feerate_ppm)
|
|| (ppm && *ppm > channel->feerate_ppm)
|
||||||
|
|| (htlc_min
|
||||||
|
&& amount_msat_greater(*htlc_min, channel->htlc_minimum_msat))
|
||||||
|| (htlc_max
|
|| (htlc_max
|
||||||
&& amount_msat_less(*htlc_max, channel->htlc_maximum_msat))) {
|
&& amount_msat_less(*htlc_max, channel->htlc_maximum_msat))) {
|
||||||
channel->old_feerate_timeout
|
channel->old_feerate_timeout
|
||||||
= timeabs_add(time_now(), time_from_sec(delaysecs));
|
= timeabs_add(time_now(), time_from_sec(delaysecs));
|
||||||
channel->old_feerate_base = channel->feerate_base;
|
channel->old_feerate_base = channel->feerate_base;
|
||||||
channel->old_feerate_ppm = channel->feerate_ppm;
|
channel->old_feerate_ppm = channel->feerate_ppm;
|
||||||
|
channel->old_htlc_minimum_msat = channel->htlc_minimum_msat;
|
||||||
channel->old_htlc_maximum_msat = channel->htlc_maximum_msat;
|
channel->old_htlc_maximum_msat = channel->htlc_maximum_msat;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2033,6 +2042,17 @@ static void set_channel_config(struct command *cmd, struct channel *channel,
|
|||||||
channel->feerate_base = *base;
|
channel->feerate_base = *base;
|
||||||
if (ppm)
|
if (ppm)
|
||||||
channel->feerate_ppm = *ppm;
|
channel->feerate_ppm = *ppm;
|
||||||
|
if (htlc_min) {
|
||||||
|
struct amount_msat actual_min;
|
||||||
|
|
||||||
|
/* We can't send something they'll refuse: check that here. */
|
||||||
|
actual_min = channel->channel_info.their_config.htlc_minimum;
|
||||||
|
if (amount_msat_less(*htlc_min, actual_min)) {
|
||||||
|
warn_cannot_set_min = true;
|
||||||
|
channel->htlc_minimum_msat = actual_min;
|
||||||
|
} else
|
||||||
|
channel->htlc_minimum_msat = *htlc_min;
|
||||||
|
}
|
||||||
if (htlc_max)
|
if (htlc_max)
|
||||||
channel->htlc_maximum_msat = *htlc_max;
|
channel->htlc_maximum_msat = *htlc_max;
|
||||||
|
|
||||||
@@ -2040,7 +2060,7 @@ static void set_channel_config(struct command *cmd, struct channel *channel,
|
|||||||
if (channel->owner && streq(channel->owner->name, "channeld"))
|
if (channel->owner && streq(channel->owner->name, "channeld"))
|
||||||
subd_send_msg(channel->owner,
|
subd_send_msg(channel->owner,
|
||||||
take(towire_channeld_config_channel(NULL, base, ppm,
|
take(towire_channeld_config_channel(NULL, base, ppm,
|
||||||
htlc_max)));
|
htlc_min, htlc_max)));
|
||||||
|
|
||||||
/* save values to database */
|
/* save values to database */
|
||||||
wallet_channel_save(cmd->ld->wallet, channel);
|
wallet_channel_save(cmd->ld->wallet, channel);
|
||||||
@@ -2059,6 +2079,12 @@ static void set_channel_config(struct command *cmd, struct channel *channel,
|
|||||||
amount_msat(channel->feerate_base));
|
amount_msat(channel->feerate_base));
|
||||||
json_add_u32(response, "fee_proportional_millionths",
|
json_add_u32(response, "fee_proportional_millionths",
|
||||||
channel->feerate_ppm);
|
channel->feerate_ppm);
|
||||||
|
json_add_amount_msat_only(response,
|
||||||
|
"minimum_htlc_out_msat",
|
||||||
|
channel->htlc_minimum_msat);
|
||||||
|
if (warn_cannot_set_min)
|
||||||
|
json_add_string(response, "warning_htlcmin_too_low",
|
||||||
|
"Set minimum_htlc_out_msat to minimum allowed by peer");
|
||||||
json_add_amount_msat_only(response,
|
json_add_amount_msat_only(response,
|
||||||
"maximum_htlc_out_msat",
|
"maximum_htlc_out_msat",
|
||||||
channel->htlc_maximum_msat);
|
channel->htlc_maximum_msat);
|
||||||
@@ -2110,13 +2136,13 @@ static struct command_result *json_setchannelfee(struct command *cmd,
|
|||||||
channel->state != CHANNELD_AWAITING_LOCKIN &&
|
channel->state != CHANNELD_AWAITING_LOCKIN &&
|
||||||
channel->state != DUALOPEND_AWAITING_LOCKIN)
|
channel->state != DUALOPEND_AWAITING_LOCKIN)
|
||||||
continue;
|
continue;
|
||||||
set_channel_config(cmd, channel, base, ppm, NULL,
|
set_channel_config(cmd, channel, base, ppm, NULL, NULL,
|
||||||
*delaysecs, response, false);
|
*delaysecs, response, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* single channel should be updated */
|
/* single channel should be updated */
|
||||||
} else {
|
} else {
|
||||||
set_channel_config(cmd, channel, base, ppm, NULL,
|
set_channel_config(cmd, channel, base, ppm, NULL, NULL,
|
||||||
*delaysecs, response, false);
|
*delaysecs, response, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2149,13 +2175,14 @@ static struct command_result *json_setchannel(struct command *cmd,
|
|||||||
struct peer *peer;
|
struct peer *peer;
|
||||||
struct channel *channel;
|
struct channel *channel;
|
||||||
u32 *base, *ppm, *delaysecs;
|
u32 *base, *ppm, *delaysecs;
|
||||||
struct amount_msat *htlc_max;
|
struct amount_msat *htlc_min, *htlc_max;
|
||||||
|
|
||||||
/* Parse the JSON command */
|
/* Parse the JSON command */
|
||||||
if (!param(cmd, buffer, params,
|
if (!param(cmd, buffer, params,
|
||||||
p_req("id", param_channel_or_all, &channel),
|
p_req("id", param_channel_or_all, &channel),
|
||||||
p_opt("feebase", param_msat_u32, &base),
|
p_opt("feebase", param_msat_u32, &base),
|
||||||
p_opt("feeppm", param_number, &ppm),
|
p_opt("feeppm", param_number, &ppm),
|
||||||
|
p_opt("htlcmin", param_msat, &htlc_min),
|
||||||
p_opt("htlcmax", param_msat, &htlc_max),
|
p_opt("htlcmax", param_msat, &htlc_max),
|
||||||
p_opt_def("enforcedelay", param_number, &delaysecs, 600),
|
p_opt_def("enforcedelay", param_number, &delaysecs, 600),
|
||||||
NULL))
|
NULL))
|
||||||
@@ -2182,13 +2209,15 @@ static struct command_result *json_setchannel(struct command *cmd,
|
|||||||
channel->state != CHANNELD_AWAITING_LOCKIN &&
|
channel->state != CHANNELD_AWAITING_LOCKIN &&
|
||||||
channel->state != DUALOPEND_AWAITING_LOCKIN)
|
channel->state != DUALOPEND_AWAITING_LOCKIN)
|
||||||
continue;
|
continue;
|
||||||
set_channel_config(cmd, channel, base, ppm, htlc_max,
|
set_channel_config(cmd, channel, base, ppm,
|
||||||
|
htlc_min, htlc_max,
|
||||||
*delaysecs, response, true);
|
*delaysecs, response, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* single channel should be updated */
|
/* single channel should be updated */
|
||||||
} else {
|
} else {
|
||||||
set_channel_config(cmd, channel, base, ppm, htlc_max,
|
set_channel_config(cmd, channel, base, ppm,
|
||||||
|
htlc_min, htlc_max,
|
||||||
*delaysecs, response, true);
|
*delaysecs, response, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -656,16 +656,18 @@ static void forward_htlc(struct htlc_in *hin,
|
|||||||
"Allowing payment using older feerate");
|
"Allowing payment using older feerate");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (amount_msat_greater(amt_to_forward, next->htlc_maximum_msat)) {
|
if (amount_msat_greater(amt_to_forward, next->htlc_maximum_msat)
|
||||||
/* Are we in old-max grace-period? */
|
|| amount_msat_less(amt_to_forward, next->htlc_minimum_msat)) {
|
||||||
|
/* Are we in old-range grace-period? */
|
||||||
if (!time_before(time_now(), next->old_feerate_timeout)
|
if (!time_before(time_now(), next->old_feerate_timeout)
|
||||||
|
|| amount_msat_less(amt_to_forward, next->old_htlc_minimum_msat)
|
||||||
|| amount_msat_greater(amt_to_forward, next->old_htlc_maximum_msat)) {
|
|| amount_msat_greater(amt_to_forward, next->old_htlc_maximum_msat)) {
|
||||||
failmsg = towire_temporary_channel_failure(tmpctx,
|
failmsg = towire_temporary_channel_failure(tmpctx,
|
||||||
get_channel_update(next));
|
get_channel_update(next));
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
log_info(hin->key.channel->log,
|
log_info(hin->key.channel->log,
|
||||||
"Allowing large htlc using older htlc_maximum_msat");
|
"Allowing htlc using older htlc_minimum/maximum_msat");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!check_cltv(hin, cltv_expiry, outgoing_cltv_value,
|
if (!check_cltv(hin, cltv_expiry, outgoing_cltv_value,
|
||||||
|
|||||||
@@ -114,6 +114,8 @@ routehint_candidates(const tal_t *ctx,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* FIXME: we don't actually check htlc_minimum_msat! */
|
||||||
|
|
||||||
/* If they set an htlc_maximum_msat, consider that the
|
/* If they set an htlc_maximum_msat, consider that the
|
||||||
* capacity ceiling. We *could* do multiple HTLCs,
|
* capacity ceiling. We *could* do multiple HTLCs,
|
||||||
* but presumably that would defeat the spirit of the
|
* but presumably that would defeat the spirit of the
|
||||||
|
|||||||
@@ -626,7 +626,7 @@ void towire_bigsize(u8 **pptr UNNEEDED, const bigsize_t val UNNEEDED)
|
|||||||
void towire_channel_id(u8 **pptr UNNEEDED, const struct channel_id *channel_id UNNEEDED)
|
void towire_channel_id(u8 **pptr UNNEEDED, const struct channel_id *channel_id UNNEEDED)
|
||||||
{ fprintf(stderr, "towire_channel_id called!\n"); abort(); }
|
{ fprintf(stderr, "towire_channel_id called!\n"); abort(); }
|
||||||
/* Generated stub for towire_channeld_config_channel */
|
/* Generated stub for towire_channeld_config_channel */
|
||||||
u8 *towire_channeld_config_channel(const tal_t *ctx UNNEEDED, u32 *feerate_base UNNEEDED, u32 *feerate_ppm UNNEEDED, struct amount_msat *htlc_maximum UNNEEDED)
|
u8 *towire_channeld_config_channel(const tal_t *ctx UNNEEDED, u32 *feerate_base UNNEEDED, u32 *feerate_ppm UNNEEDED, struct amount_msat *htlc_minimum UNNEEDED, struct amount_msat *htlc_maximum UNNEEDED)
|
||||||
{ fprintf(stderr, "towire_channeld_config_channel called!\n"); abort(); }
|
{ fprintf(stderr, "towire_channeld_config_channel called!\n"); abort(); }
|
||||||
/* Generated stub for towire_channeld_dev_memleak */
|
/* Generated stub for towire_channeld_dev_memleak */
|
||||||
u8 *towire_channeld_dev_memleak(const tal_t *ctx UNNEEDED)
|
u8 *towire_channeld_dev_memleak(const tal_t *ctx UNNEEDED)
|
||||||
|
|||||||
@@ -1882,7 +1882,7 @@ def test_setchannel_usage(node_factory, bitcoind):
|
|||||||
|
|
||||||
def channel_get_config(scid):
|
def channel_get_config(scid):
|
||||||
return l1.db.query(
|
return l1.db.query(
|
||||||
'SELECT feerate_base, feerate_ppm, htlc_maximum_msat FROM channels '
|
'SELECT feerate_base, feerate_ppm, htlc_minimum_msat, htlc_maximum_msat FROM channels '
|
||||||
'WHERE short_channel_id=\'{}\';'.format(scid))
|
'WHERE short_channel_id=\'{}\';'.format(scid))
|
||||||
|
|
||||||
# get short channel id
|
# get short channel id
|
||||||
@@ -1900,8 +1900,8 @@ def test_setchannel_usage(node_factory, bitcoind):
|
|||||||
assert peers[0]['channels'][0]['fee_proportional_millionths'] == DEF_PPM
|
assert peers[0]['channels'][0]['fee_proportional_millionths'] == DEF_PPM
|
||||||
assert peers[0]['channels'][0]['maximum_htlc_out_msat'] == MAX_HTLC
|
assert peers[0]['channels'][0]['maximum_htlc_out_msat'] == MAX_HTLC
|
||||||
|
|
||||||
# custom setchannel scid <feebase> <feeppm> <htlcmax>
|
# custom setchannel scid <feebase> <feeppm> <htlcmin> <htlcmax>
|
||||||
result = l1.rpc.setchannel(scid, 1337, 137, 133337)
|
result = l1.rpc.setchannel(scid, 1337, 137, 17, 133337)
|
||||||
|
|
||||||
# check result format
|
# check result format
|
||||||
assert(len(result['channels']) == 1)
|
assert(len(result['channels']) == 1)
|
||||||
@@ -1910,22 +1910,26 @@ def test_setchannel_usage(node_factory, bitcoind):
|
|||||||
assert(result['channels'][0]['short_channel_id'] == scid)
|
assert(result['channels'][0]['short_channel_id'] == scid)
|
||||||
assert(result['channels'][0]['fee_base_msat'] == 1337)
|
assert(result['channels'][0]['fee_base_msat'] == 1337)
|
||||||
assert(result['channels'][0]['fee_proportional_millionths'] == 137)
|
assert(result['channels'][0]['fee_proportional_millionths'] == 137)
|
||||||
|
assert(result['channels'][0]['minimum_htlc_out_msat'] == 17)
|
||||||
assert(result['channels'][0]['maximum_htlc_out_msat'] == 133337)
|
assert(result['channels'][0]['maximum_htlc_out_msat'] == 133337)
|
||||||
|
|
||||||
# check if custom values made it into the database
|
# check if custom values made it into the database
|
||||||
db_fees = channel_get_config(scid)
|
db_fees = channel_get_config(scid)
|
||||||
assert(db_fees[0]['feerate_base'] == 1337)
|
assert(db_fees[0]['feerate_base'] == 1337)
|
||||||
assert(db_fees[0]['feerate_ppm'] == 137)
|
assert(db_fees[0]['feerate_ppm'] == 137)
|
||||||
|
assert(db_fees[0]['htlc_minimum_msat'] == 17)
|
||||||
assert(db_fees[0]['htlc_maximum_msat'] == 133337)
|
assert(db_fees[0]['htlc_maximum_msat'] == 133337)
|
||||||
# also check for updated values in `listpeers`
|
# also check for updated values in `listpeers`
|
||||||
peers = l1.rpc.listpeers()['peers']
|
peers = l1.rpc.listpeers()['peers']
|
||||||
assert peers[0]['channels'][0]['fee_base_msat'] == Millisatoshi(1337)
|
assert peers[0]['channels'][0]['fee_base_msat'] == Millisatoshi(1337)
|
||||||
assert peers[0]['channels'][0]['fee_proportional_millionths'] == 137
|
assert peers[0]['channels'][0]['fee_proportional_millionths'] == 137
|
||||||
|
assert peers[0]['channels'][0]['minimum_htlc_out_msat'] == 17
|
||||||
assert peers[0]['channels'][0]['maximum_htlc_out_msat'] == 133337
|
assert peers[0]['channels'][0]['maximum_htlc_out_msat'] == 133337
|
||||||
|
|
||||||
# wait for gossip and check if l1 sees new fees in listchannels
|
# wait for gossip and check if l1 sees new fees in listchannels
|
||||||
wait_for(lambda: [c['base_fee_millisatoshi'] for c in l1.rpc.listchannels(scid)['channels']] == [DEF_BASE, 1337])
|
wait_for(lambda: [c['base_fee_millisatoshi'] for c in l1.rpc.listchannels(scid)['channels']] == [DEF_BASE, 1337])
|
||||||
wait_for(lambda: [c['fee_per_millionth'] for c in l1.rpc.listchannels(scid)['channels']] == [DEF_PPM, 137])
|
wait_for(lambda: [c['fee_per_millionth'] for c in l1.rpc.listchannels(scid)['channels']] == [DEF_PPM, 137])
|
||||||
|
wait_for(lambda: [c['htlc_minimum_msat'] for c in l1.rpc.listchannels(scid)['channels']] == [0, 17])
|
||||||
wait_for(lambda: [c['htlc_maximum_msat'] for c in l1.rpc.listchannels(scid)['channels']] == [MAX_HTLC, 133337])
|
wait_for(lambda: [c['htlc_maximum_msat'] for c in l1.rpc.listchannels(scid)['channels']] == [MAX_HTLC, 133337])
|
||||||
|
|
||||||
# also test with named and missing parameters
|
# also test with named and missing parameters
|
||||||
@@ -1935,6 +1939,7 @@ def test_setchannel_usage(node_factory, bitcoind):
|
|||||||
assert(result['channels'][0]['short_channel_id'] == scid)
|
assert(result['channels'][0]['short_channel_id'] == scid)
|
||||||
assert(result['channels'][0]['fee_base_msat'] == 1337)
|
assert(result['channels'][0]['fee_base_msat'] == 1337)
|
||||||
assert(result['channels'][0]['fee_proportional_millionths'] == 42)
|
assert(result['channels'][0]['fee_proportional_millionths'] == 42)
|
||||||
|
assert result['channels'][0]['minimum_htlc_out_msat'] == 17
|
||||||
assert(result['channels'][0]['maximum_htlc_out_msat'] == 133337)
|
assert(result['channels'][0]['maximum_htlc_out_msat'] == 133337)
|
||||||
|
|
||||||
result = l1.rpc.setchannel(feebase=43, id=scid)
|
result = l1.rpc.setchannel(feebase=43, id=scid)
|
||||||
@@ -1943,6 +1948,16 @@ def test_setchannel_usage(node_factory, bitcoind):
|
|||||||
assert(result['channels'][0]['short_channel_id'] == scid)
|
assert(result['channels'][0]['short_channel_id'] == scid)
|
||||||
assert(result['channels'][0]['fee_base_msat'] == 43)
|
assert(result['channels'][0]['fee_base_msat'] == 43)
|
||||||
assert(result['channels'][0]['fee_proportional_millionths'] == 42)
|
assert(result['channels'][0]['fee_proportional_millionths'] == 42)
|
||||||
|
assert result['channels'][0]['minimum_htlc_out_msat'] == 17
|
||||||
|
assert(result['channels'][0]['maximum_htlc_out_msat'] == 133337)
|
||||||
|
|
||||||
|
result = l1.rpc.setchannel(htlcmin=45, id=scid)
|
||||||
|
assert(len(result['channels']) == 1)
|
||||||
|
assert(re.match('^[0-9a-f]{64}$', result['channels'][0]['channel_id']))
|
||||||
|
assert(result['channels'][0]['short_channel_id'] == scid)
|
||||||
|
assert(result['channels'][0]['fee_base_msat'] == 43)
|
||||||
|
assert(result['channels'][0]['fee_proportional_millionths'] == 42)
|
||||||
|
assert result['channels'][0]['minimum_htlc_out_msat'] == 45
|
||||||
assert(result['channels'][0]['maximum_htlc_out_msat'] == 133337)
|
assert(result['channels'][0]['maximum_htlc_out_msat'] == 133337)
|
||||||
|
|
||||||
result = l1.rpc.setchannel(htlcmax=43333, id=scid)
|
result = l1.rpc.setchannel(htlcmax=43333, id=scid)
|
||||||
@@ -1951,6 +1966,7 @@ def test_setchannel_usage(node_factory, bitcoind):
|
|||||||
assert(result['channels'][0]['short_channel_id'] == scid)
|
assert(result['channels'][0]['short_channel_id'] == scid)
|
||||||
assert(result['channels'][0]['fee_base_msat'] == 43)
|
assert(result['channels'][0]['fee_base_msat'] == 43)
|
||||||
assert(result['channels'][0]['fee_proportional_millionths'] == 42)
|
assert(result['channels'][0]['fee_proportional_millionths'] == 42)
|
||||||
|
assert result['channels'][0]['minimum_htlc_out_msat'] == 45
|
||||||
assert(result['channels'][0]['maximum_htlc_out_msat'] == 43333)
|
assert(result['channels'][0]['maximum_htlc_out_msat'] == 43333)
|
||||||
|
|
||||||
# check if negative fees raise error and DB keeps values
|
# check if negative fees raise error and DB keeps values
|
||||||
@@ -2079,6 +2095,7 @@ def test_setchannel_routing(node_factory, bitcoind):
|
|||||||
DEF_BASE = 1
|
DEF_BASE = 1
|
||||||
DEF_PPM = 10
|
DEF_PPM = 10
|
||||||
MAX_HTLC = Millisatoshi(int(FUNDAMOUNT * 1000 * 0.99))
|
MAX_HTLC = Millisatoshi(int(FUNDAMOUNT * 1000 * 0.99))
|
||||||
|
MIN_HTLC = Millisatoshi(0)
|
||||||
|
|
||||||
l1, l2, l3 = node_factory.line_graph(
|
l1, l2, l3 = node_factory.line_graph(
|
||||||
3, announce_channels=True, wait_for_announce=True,
|
3, announce_channels=True, wait_for_announce=True,
|
||||||
@@ -2089,11 +2106,12 @@ def test_setchannel_routing(node_factory, bitcoind):
|
|||||||
scid = l2.get_channel_scid(l3)
|
scid = l2.get_channel_scid(l3)
|
||||||
|
|
||||||
# TEST CUSTOM VALUES
|
# TEST CUSTOM VALUES
|
||||||
l2.rpc.setchannel(scid, 1337, 137, 4000000, enforcedelay=0)
|
l2.rpc.setchannel(scid, 1337, 137, 17, 4000000, enforcedelay=0)
|
||||||
|
|
||||||
# wait for l1 to see updated channel via gossip
|
# wait for l1 to see updated channel via gossip
|
||||||
wait_for(lambda: [c['base_fee_millisatoshi'] for c in l1.rpc.listchannels(scid)['channels']] == [1337, DEF_BASE])
|
wait_for(lambda: [c['base_fee_millisatoshi'] for c in l1.rpc.listchannels(scid)['channels']] == [1337, DEF_BASE])
|
||||||
wait_for(lambda: [c['fee_per_millionth'] for c in l1.rpc.listchannels(scid)['channels']] == [137, DEF_PPM])
|
wait_for(lambda: [c['fee_per_millionth'] for c in l1.rpc.listchannels(scid)['channels']] == [137, DEF_PPM])
|
||||||
|
wait_for(lambda: [c['htlc_minimum_msat'] for c in l1.rpc.listchannels(scid)['channels']] == [17, MIN_HTLC])
|
||||||
wait_for(lambda: [c['htlc_maximum_msat'] for c in l1.rpc.listchannels(scid)['channels']] == [4000000, MAX_HTLC])
|
wait_for(lambda: [c['htlc_maximum_msat'] for c in l1.rpc.listchannels(scid)['channels']] == [4000000, MAX_HTLC])
|
||||||
|
|
||||||
# test fees are applied to HTLC forwards
|
# test fees are applied to HTLC forwards
|
||||||
@@ -2136,7 +2154,7 @@ def test_setchannel_routing(node_factory, bitcoind):
|
|||||||
|
|
||||||
# In case l3 includes a routehint, we need to make sure they also know
|
# In case l3 includes a routehint, we need to make sure they also know
|
||||||
# about the new fees, otherwise we may end up with the old feerate
|
# about the new fees, otherwise we may end up with the old feerate
|
||||||
wait_for(lambda: [(c['base_fee_millisatoshi'], c['fee_per_millionth'], c['htlc_maximum_msat'], c['active']) for c in l3.rpc.listchannels(scid)['channels']] == [(1337, 137, 4000000, True), (DEF_BASE, DEF_PPM, MAX_HTLC, True)])
|
wait_for(lambda: [(c['base_fee_millisatoshi'], c['fee_per_millionth'], c['htlc_minimum_msat'], c['htlc_maximum_msat'], c['active']) for c in l3.rpc.listchannels(scid)['channels']] == [(1337, 137, 17, 4000000, True), (DEF_BASE, DEF_PPM, MIN_HTLC, MAX_HTLC, True)])
|
||||||
|
|
||||||
# do and check actual payment
|
# do and check actual payment
|
||||||
inv = l3.rpc.invoice(4000000, 'test_setchannel_2', 'desc')
|
inv = l3.rpc.invoice(4000000, 'test_setchannel_2', 'desc')
|
||||||
@@ -2153,9 +2171,33 @@ def test_setchannel_routing(node_factory, bitcoind):
|
|||||||
l1.rpc.sendpay(route_ok, inv['payment_hash'], payment_secret=inv['payment_secret'])
|
l1.rpc.sendpay(route_ok, inv['payment_hash'], payment_secret=inv['payment_secret'])
|
||||||
l1.rpc.waitsendpay(inv['payment_hash'])
|
l1.rpc.waitsendpay(inv['payment_hash'])
|
||||||
|
|
||||||
|
# Now try below minimum
|
||||||
|
route_ok = l1.rpc.getroute(l3.info['id'], 17, 1)["route"]
|
||||||
|
assert len(route_ok) == 2
|
||||||
|
assert route_ok[0]['msatoshi'] == 1337 + 17
|
||||||
|
assert route_ok[1]['msatoshi'] == 17
|
||||||
|
|
||||||
|
route_bad = copy.deepcopy(route_ok)
|
||||||
|
route_bad[0]['msatoshi'] = 1337 + 16
|
||||||
|
route_bad[1]['msatoshi'] = 16
|
||||||
|
route_bad[0]['amount_msat'] = Millisatoshi(1337 + 16)
|
||||||
|
route_bad[1]['amount_msat'] = Millisatoshi(16)
|
||||||
|
assert route_bad != route_ok
|
||||||
|
|
||||||
|
inv = l3.rpc.invoice(17, 'test_setchannel_3', 'desc')
|
||||||
|
|
||||||
|
# This will fail.
|
||||||
|
l1.rpc.sendpay(route_bad, inv['payment_hash'], payment_secret=inv['payment_secret'])
|
||||||
|
with pytest.raises(RpcError, match='WIRE_TEMPORARY_CHANNEL_FAILURE'):
|
||||||
|
l1.rpc.waitsendpay(inv['payment_hash'])
|
||||||
|
|
||||||
|
# This will succeed
|
||||||
|
l1.rpc.sendpay(route_ok, inv['payment_hash'], payment_secret=inv['payment_secret'])
|
||||||
|
l1.rpc.waitsendpay(inv['payment_hash'])
|
||||||
|
|
||||||
# Check that this one warns about capacity!
|
# Check that this one warns about capacity!
|
||||||
inv = l3.rpc.call('invoice', {'msatoshi': 4001793,
|
inv = l3.rpc.call('invoice', {'msatoshi': 4001793,
|
||||||
'label': 'test_setchannel_3',
|
'label': 'test_setchannel_4',
|
||||||
'description': 'desc'})
|
'description': 'desc'})
|
||||||
assert 'warning_capacity' in inv
|
assert 'warning_capacity' in inv
|
||||||
|
|
||||||
@@ -2213,6 +2255,7 @@ def test_setchannel_restart(node_factory, bitcoind):
|
|||||||
# - l1 routing can be made to l3 and global (1 10) fees are applied
|
# - l1 routing can be made to l3 and global (1 10) fees are applied
|
||||||
DEF_BASE = 1
|
DEF_BASE = 1
|
||||||
DEF_PPM = 10
|
DEF_PPM = 10
|
||||||
|
MIN_HTLC = Millisatoshi(0)
|
||||||
MAX_HTLC = Millisatoshi(int(FUNDAMOUNT * 1000 * 0.99))
|
MAX_HTLC = Millisatoshi(int(FUNDAMOUNT * 1000 * 0.99))
|
||||||
OPTS = {'may_reconnect': True, 'fee-base': DEF_BASE, 'fee-per-satoshi': DEF_PPM}
|
OPTS = {'may_reconnect': True, 'fee-base': DEF_BASE, 'fee-per-satoshi': DEF_PPM}
|
||||||
|
|
||||||
@@ -2223,7 +2266,7 @@ def test_setchannel_restart(node_factory, bitcoind):
|
|||||||
scid23 = l2.get_channel_scid(l3)
|
scid23 = l2.get_channel_scid(l3)
|
||||||
|
|
||||||
# l2 set custom fees
|
# l2 set custom fees
|
||||||
l2.rpc.setchannel(scid23, 1337, 137, 500001)
|
l2.rpc.setchannel(scid23, 1337, 137, 17, 500001)
|
||||||
|
|
||||||
# restart l2 and reconnect
|
# restart l2 and reconnect
|
||||||
l2.restart()
|
l2.restart()
|
||||||
@@ -2234,11 +2277,11 @@ def test_setchannel_restart(node_factory, bitcoind):
|
|||||||
wait_for(lambda: [c['active'] for c in l1.rpc.listchannels(scid12)['channels']] == [True, True])
|
wait_for(lambda: [c['active'] for c in l1.rpc.listchannels(scid12)['channels']] == [True, True])
|
||||||
|
|
||||||
# l1 wait for channel update from l2
|
# l1 wait for channel update from l2
|
||||||
wait_for(lambda: [(c['base_fee_millisatoshi'], c['fee_per_millionth'], c['htlc_maximum_msat'], c['active']) for c in l1.rpc.listchannels(scid23)['channels']] == [(1337, 137, 500001, True), (DEF_BASE, DEF_PPM, MAX_HTLC, True)])
|
wait_for(lambda: [(c['base_fee_millisatoshi'], c['fee_per_millionth'], c['htlc_minimum_msat'], c['htlc_maximum_msat'], c['active']) for c in l1.rpc.listchannels(scid23)['channels']] == [(1337, 137, 17, 500001, True), (DEF_BASE, DEF_PPM, MIN_HTLC, MAX_HTLC, True)])
|
||||||
|
|
||||||
# In case l3 includes a routehint, we need to make sure they also know
|
# In case l3 includes a routehint, we need to make sure they also know
|
||||||
# about the new fees, otherwise we may end up with the old feerate
|
# about the new fees, otherwise we may end up with the old feerate
|
||||||
wait_for(lambda: [(c['base_fee_millisatoshi'], c['fee_per_millionth'], c['htlc_maximum_msat'], c['active']) for c in l3.rpc.listchannels(scid23)['channels']] == [(1337, 137, 500001, True), (DEF_BASE, DEF_PPM, MAX_HTLC, True)])
|
wait_for(lambda: [(c['base_fee_millisatoshi'], c['fee_per_millionth'], c['htlc_minimum_msat'], c['htlc_maximum_msat'], c['active']) for c in l3.rpc.listchannels(scid23)['channels']] == [(1337, 137, 17, 500001, True), (DEF_BASE, DEF_PPM, MIN_HTLC, MAX_HTLC, True)])
|
||||||
|
|
||||||
# l1 can make payment to l3 with custom fees being applied
|
# l1 can make payment to l3 with custom fees being applied
|
||||||
# Note: BOLT #7 math works out to 1405 msat fees
|
# Note: BOLT #7 math works out to 1405 msat fees
|
||||||
@@ -2269,7 +2312,7 @@ def test_setchannel_all(node_factory, bitcoind):
|
|||||||
scid3 = l1.get_channel_scid(l3)
|
scid3 = l1.get_channel_scid(l3)
|
||||||
|
|
||||||
# now try to set all (two) channels using wildcard syntax
|
# now try to set all (two) channels using wildcard syntax
|
||||||
result = l1.rpc.setchannel("all", 0xDEAD, 0xBEEF, 0xCAFE)
|
result = l1.rpc.setchannel("all", 0xDEAD, 0xBEEF, 0xBAD, 0xCAFE)
|
||||||
|
|
||||||
wait_for(lambda: [c['base_fee_millisatoshi'] for c in l1.rpc.listchannels(scid2)['channels']] == [DEF_BASE, 0xDEAD])
|
wait_for(lambda: [c['base_fee_millisatoshi'] for c in l1.rpc.listchannels(scid2)['channels']] == [DEF_BASE, 0xDEAD])
|
||||||
wait_for(lambda: [c['fee_per_millionth'] for c in l1.rpc.listchannels(scid2)['channels']] == [DEF_PPM, 0xBEEF])
|
wait_for(lambda: [c['fee_per_millionth'] for c in l1.rpc.listchannels(scid2)['channels']] == [DEF_PPM, 0xBEEF])
|
||||||
@@ -2281,11 +2324,13 @@ def test_setchannel_all(node_factory, bitcoind):
|
|||||||
assert result['channels'][0]['short_channel_id'] == scid2
|
assert result['channels'][0]['short_channel_id'] == scid2
|
||||||
assert result['channels'][0]['fee_base_msat'] == 0xDEAD
|
assert result['channels'][0]['fee_base_msat'] == 0xDEAD
|
||||||
assert result['channels'][0]['fee_proportional_millionths'] == 0xBEEF
|
assert result['channels'][0]['fee_proportional_millionths'] == 0xBEEF
|
||||||
|
assert result['channels'][0]['minimum_htlc_out_msat'] == 0xBAD
|
||||||
assert result['channels'][0]['maximum_htlc_out_msat'] == 0xCAFE
|
assert result['channels'][0]['maximum_htlc_out_msat'] == 0xCAFE
|
||||||
assert result['channels'][1]['peer_id'] == l3.info['id']
|
assert result['channels'][1]['peer_id'] == l3.info['id']
|
||||||
assert result['channels'][1]['short_channel_id'] == scid3
|
assert result['channels'][1]['short_channel_id'] == scid3
|
||||||
assert result['channels'][1]['fee_base_msat'] == 0xDEAD
|
assert result['channels'][1]['fee_base_msat'] == 0xDEAD
|
||||||
assert result['channels'][1]['fee_proportional_millionths'] == 0xBEEF
|
assert result['channels'][1]['fee_proportional_millionths'] == 0xBEEF
|
||||||
|
assert result['channels'][1]['minimum_htlc_out_msat'] == 0xBAD
|
||||||
assert result['channels'][1]['maximum_htlc_out_msat'] == 0xCAFE
|
assert result['channels'][1]['maximum_htlc_out_msat'] == 0xCAFE
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -871,6 +871,7 @@ static struct migration dbmigrations[] = {
|
|||||||
{SQL("ALTER TABLE channel_funding_inflights ADD lease_fee BIGINT DEFAULT 0"), NULL},
|
{SQL("ALTER TABLE channel_funding_inflights ADD lease_fee BIGINT DEFAULT 0"), NULL},
|
||||||
/* Default is too big; we set to max after loading */
|
/* Default is too big; we set to max after loading */
|
||||||
{SQL("ALTER TABLE channels ADD htlc_maximum_msat BIGINT DEFAULT 2100000000000000"), NULL},
|
{SQL("ALTER TABLE channels ADD htlc_maximum_msat BIGINT DEFAULT 2100000000000000"), NULL},
|
||||||
|
{SQL("ALTER TABLE channels ADD htlc_minimum_msat BIGINT DEFAULT 0"), NULL},
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -694,7 +694,7 @@ void topology_add_sync_waiter_(const tal_t *ctx UNNEEDED,
|
|||||||
u8 *towire_channel_disabled(const tal_t *ctx UNNEEDED)
|
u8 *towire_channel_disabled(const tal_t *ctx UNNEEDED)
|
||||||
{ fprintf(stderr, "towire_channel_disabled called!\n"); abort(); }
|
{ fprintf(stderr, "towire_channel_disabled called!\n"); abort(); }
|
||||||
/* Generated stub for towire_channeld_config_channel */
|
/* Generated stub for towire_channeld_config_channel */
|
||||||
u8 *towire_channeld_config_channel(const tal_t *ctx UNNEEDED, u32 *feerate_base UNNEEDED, u32 *feerate_ppm UNNEEDED, struct amount_msat *htlc_maximum UNNEEDED)
|
u8 *towire_channeld_config_channel(const tal_t *ctx UNNEEDED, u32 *feerate_base UNNEEDED, u32 *feerate_ppm UNNEEDED, struct amount_msat *htlc_minimum UNNEEDED, struct amount_msat *htlc_maximum UNNEEDED)
|
||||||
{ fprintf(stderr, "towire_channeld_config_channel called!\n"); abort(); }
|
{ fprintf(stderr, "towire_channeld_config_channel called!\n"); abort(); }
|
||||||
/* Generated stub for towire_channeld_dev_memleak */
|
/* Generated stub for towire_channeld_dev_memleak */
|
||||||
u8 *towire_channeld_dev_memleak(const tal_t *ctx UNNEEDED)
|
u8 *towire_channeld_dev_memleak(const tal_t *ctx UNNEEDED)
|
||||||
@@ -1598,6 +1598,7 @@ static bool test_channel_inflight_crud(struct lightningd *ld, const tal_t *ctx)
|
|||||||
100,
|
100,
|
||||||
lease_commit_sig,
|
lease_commit_sig,
|
||||||
7777, 22,
|
7777, 22,
|
||||||
|
AMOUNT_MSAT(0),
|
||||||
AMOUNT_MSAT(-1ULL));
|
AMOUNT_MSAT(-1ULL));
|
||||||
db_begin_transaction(w->db);
|
db_begin_transaction(w->db);
|
||||||
CHECK(!wallet_err);
|
CHECK(!wallet_err);
|
||||||
|
|||||||
@@ -1263,7 +1263,7 @@ static struct channel *wallet_stmt2channel(struct wallet *w, struct db_stmt *stm
|
|||||||
struct pubkey local_funding_pubkey;
|
struct pubkey local_funding_pubkey;
|
||||||
struct pubkey *future_per_commitment_point;
|
struct pubkey *future_per_commitment_point;
|
||||||
struct amount_sat funding_sat, our_funding_sat;
|
struct amount_sat funding_sat, our_funding_sat;
|
||||||
struct amount_msat push_msat, our_msat, msat_to_us_min, msat_to_us_max, htlc_maximum_msat;
|
struct amount_msat push_msat, our_msat, msat_to_us_min, msat_to_us_max, htlc_minimum_msat, htlc_maximum_msat;
|
||||||
struct channel_type *type;
|
struct channel_type *type;
|
||||||
secp256k1_ecdsa_signature *lease_commit_sig;
|
secp256k1_ecdsa_signature *lease_commit_sig;
|
||||||
u32 lease_chan_max_msat;
|
u32 lease_chan_max_msat;
|
||||||
@@ -1403,6 +1403,7 @@ static struct channel *wallet_stmt2channel(struct wallet *w, struct db_stmt *stm
|
|||||||
db_col_amount_msat(stmt, "msatoshi_local", &our_msat);
|
db_col_amount_msat(stmt, "msatoshi_local", &our_msat);
|
||||||
db_col_amount_msat(stmt, "msatoshi_to_us_min", &msat_to_us_min);
|
db_col_amount_msat(stmt, "msatoshi_to_us_min", &msat_to_us_min);
|
||||||
db_col_amount_msat(stmt, "msatoshi_to_us_max", &msat_to_us_max);
|
db_col_amount_msat(stmt, "msatoshi_to_us_max", &msat_to_us_max);
|
||||||
|
db_col_amount_msat(stmt, "htlc_minimum_msat", &htlc_minimum_msat);
|
||||||
db_col_amount_msat(stmt, "htlc_maximum_msat", &htlc_maximum_msat);
|
db_col_amount_msat(stmt, "htlc_maximum_msat", &htlc_maximum_msat);
|
||||||
|
|
||||||
if (!db_col_is_null(stmt, "lease_commit_sig")) {
|
if (!db_col_is_null(stmt, "lease_commit_sig")) {
|
||||||
@@ -1480,6 +1481,7 @@ static struct channel *wallet_stmt2channel(struct wallet *w, struct db_stmt *stm
|
|||||||
lease_commit_sig,
|
lease_commit_sig,
|
||||||
lease_chan_max_msat,
|
lease_chan_max_msat,
|
||||||
lease_chan_max_ppt,
|
lease_chan_max_ppt,
|
||||||
|
htlc_minimum_msat,
|
||||||
htlc_maximum_msat);
|
htlc_maximum_msat);
|
||||||
|
|
||||||
if (!wallet_channel_load_inflights(w, chan)) {
|
if (!wallet_channel_load_inflights(w, chan)) {
|
||||||
@@ -1574,6 +1576,7 @@ static bool wallet_channels_load_active(struct wallet *w)
|
|||||||
", lease_commit_sig"
|
", lease_commit_sig"
|
||||||
", lease_chan_max_msat"
|
", lease_chan_max_msat"
|
||||||
", lease_chan_max_ppt"
|
", lease_chan_max_ppt"
|
||||||
|
", htlc_minimum_msat"
|
||||||
", htlc_maximum_msat"
|
", htlc_maximum_msat"
|
||||||
" FROM channels"
|
" FROM channels"
|
||||||
" WHERE state != ?;")); //? 0
|
" WHERE state != ?;")); //? 0
|
||||||
@@ -1855,8 +1858,9 @@ void wallet_channel_save(struct wallet *w, struct channel *chan)
|
|||||||
" lease_commit_sig=?," // 39
|
" lease_commit_sig=?," // 39
|
||||||
" lease_chan_max_msat=?," // 40
|
" lease_chan_max_msat=?," // 40
|
||||||
" lease_chan_max_ppt=?," // 41
|
" lease_chan_max_ppt=?," // 41
|
||||||
" htlc_maximum_msat=?" // 42
|
" htlc_minimum_msat=?," // 42
|
||||||
" WHERE id=?")); // 43
|
" htlc_maximum_msat=?" // 43
|
||||||
|
" WHERE id=?")); // 44
|
||||||
db_bind_u64(stmt, 0, chan->their_shachain.id);
|
db_bind_u64(stmt, 0, chan->their_shachain.id);
|
||||||
if (chan->scid)
|
if (chan->scid)
|
||||||
db_bind_short_channel_id(stmt, 1, chan->scid);
|
db_bind_short_channel_id(stmt, 1, chan->scid);
|
||||||
@@ -1919,8 +1923,9 @@ void wallet_channel_save(struct wallet *w, struct channel *chan)
|
|||||||
db_bind_null(stmt, 40);
|
db_bind_null(stmt, 40);
|
||||||
db_bind_null(stmt, 41);
|
db_bind_null(stmt, 41);
|
||||||
}
|
}
|
||||||
db_bind_amount_msat(stmt, 42, &chan->htlc_maximum_msat);
|
db_bind_amount_msat(stmt, 42, &chan->htlc_minimum_msat);
|
||||||
db_bind_u64(stmt, 43, chan->dbid);
|
db_bind_amount_msat(stmt, 43, &chan->htlc_maximum_msat);
|
||||||
|
db_bind_u64(stmt, 44, chan->dbid);
|
||||||
db_exec_prepared_v2(take(stmt));
|
db_exec_prepared_v2(take(stmt));
|
||||||
|
|
||||||
wallet_channel_config_save(w, &chan->channel_info.their_config);
|
wallet_channel_config_save(w, &chan->channel_info.their_config);
|
||||||
|
|||||||
Reference in New Issue
Block a user