Skip to content

Commit

Permalink
funding: enable push_msat
Browse files Browse the repository at this point in the history
it's that time of year (merry xmas!)

enables the ability to push_msat on fundchannel

Changelog-Added: RPC: `fundchannel` and `fundchannel_start` can now accept an optional parameter, `push_msat`, which will gift that amount of satoshis to the peer at channel open.
  • Loading branch information
niftynei committed Dec 24, 2019
1 parent 051b5bd commit 689dd28
Show file tree
Hide file tree
Showing 8 changed files with 75 additions and 8 deletions.
5 changes: 3 additions & 2 deletions contrib/pyln-client/pyln/client/lightning.py
Original file line number Diff line number Diff line change
Expand Up @@ -548,14 +548,15 @@ def fundchannel(self, node_id, *args, **kwargs):
if 'satoshi' in kwargs:
return self._deprecated_fundchannel(node_id, *args, **kwargs)

def _fundchannel(node_id, amount, feerate=None, announce=True, minconf=None, utxos=None):
def _fundchannel(node_id, amount, feerate=None, announce=True, minconf=None, utxos=None, push_msat=None):
payload = {
"id": node_id,
"amount": amount,
"feerate": feerate,
"announce": announce,
"minconf": minconf,
"utxos": utxos
"utxos": utxos,
"push_msat": push_msat
}
return self.call("fundchannel", payload)

Expand Down
8 changes: 7 additions & 1 deletion doc/lightning-fundchannel.7

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 6 additions & 1 deletion doc/lightning-fundchannel.7.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ SYNOPSIS
--------

**fundchannel** *id* *amount* \[*feerate* *announce*\] \[*minconf*\]
\[*utxos*\]
\[*utxos*\] \[*push_msat*\]

DESCRIPTION
-----------
Expand Down Expand Up @@ -49,6 +49,11 @@ outputs should have. Default is 1.
*utxos* specifies the utxos to be used to fund the channel, as an array
of "txid:vout".

*push_msat* is the amount of millisatoshis to push to the channel peer at
open. Note that this is a gift to the peer -- these satoshis are
added to the initial balance of the peer at channel start and are largely
unrecoverable once pushed.

RETURN VALUE
------------

Expand Down
8 changes: 7 additions & 1 deletion doc/lightning-fundchannel_start.7

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 6 additions & 1 deletion doc/lightning-fundchannel_start.7.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ lightning-fundchannel\_start -- Command for initiating channel establishment for
SYNOPSIS
--------

**fundchannel\_start** *id* *amount* \[*feerate* *announce* *close_to*\]
**fundchannel\_start** *id* *amount* \[*feerate* *announce* *close_to* *push_msat*\]

DESCRIPTION
-----------
Expand All @@ -27,6 +27,11 @@ commitment transactions: see **fundchannel**.
on close. Only valid if both peers have negotiated `option_upfront_shutdown_script`.
Returns `close_to` set to closing script iff is negotiated.

*push_msat* is the amount of millisatoshis to push to the channel peer at
open. Note that this is a gift to the peer -- these satoshis are
added to the initial balance of the peer at channel start and are largely
unrecoverable once pushed.

Note that the funding transaction MUST NOT be broadcast until after
channel establishment has been successfully completed by running
`fundchannel_complete`, as the commitment transactions for this channel
Expand Down
13 changes: 11 additions & 2 deletions lightningd/opening_control.c
Original file line number Diff line number Diff line change
Expand Up @@ -1105,6 +1105,7 @@ static struct command_result *json_fund_channel_start(struct command *cmd,

u8 *msg = NULL;
struct amount_sat *amount;
struct amount_msat *push_msat;

fc->cmd = cmd;
fc->cancels = tal_arr(fc, struct command *, 0);
Expand All @@ -1119,6 +1120,7 @@ static struct command_result *json_fund_channel_start(struct command *cmd,
p_opt("feerate", param_feerate, &feerate_per_kw),
p_opt_def("announce", param_bool, &announce_channel, true),
p_opt("close_to", param_bitcoin_address, &fc->our_upfront_shutdown_script),
p_opt("push_msat", param_msat, &push_msat),
NULL))
return command_param_failed();
} else {
Expand All @@ -1132,6 +1134,7 @@ static struct command_result *json_fund_channel_start(struct command *cmd,
p_opt("satoshi", param_sat, &satoshi),
p_opt("feerate", param_feerate, &feerate_per_kw),
p_opt_def("announce", param_bool, &announce_channel, true),
p_opt("push_msat", param_msat, &push_msat),
NULL))
return command_param_failed();

Expand All @@ -1153,6 +1156,13 @@ static struct command_result *json_fund_channel_start(struct command *cmd,
type_to_string(tmpctx, struct amount_sat,
&chainparams->max_funding));

if (push_msat && amount_msat_greater_sat(*push_msat, *amount))
return command_fail(cmd, FUND_CANNOT_AFFORD,
"Requested to push_msat of %s is greater than "
"available funding amount %s",
type_to_string(tmpctx, struct amount_msat, push_msat),
type_to_string(tmpctx, struct amount_sat, amount));

fc->funding = *amount;
if (!feerate_per_kw) {
feerate_per_kw = tal(cmd, u32);
Expand Down Expand Up @@ -1192,8 +1202,7 @@ static struct command_result *json_fund_channel_start(struct command *cmd,
return command_fail(cmd, LIGHTNINGD, "Already funding channel");
}

/* FIXME: Support push_msat? */
fc->push = AMOUNT_MSAT(0);
fc->push = push_msat ? *push_msat : AMOUNT_MSAT(0);
fc->channel_flags = OUR_CHANNEL_FLAGS;
if (!*announce_channel) {
fc->channel_flags &= ~CHANNEL_FLAGS_ANNOUNCE_CHANNEL;
Expand Down
6 changes: 6 additions & 0 deletions plugins/fundchannel.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ struct funding_req {
const char *funding_str;
const char *utxo_str;
bool funding_all;
struct amount_msat *push_msat;

bool *announce_channel;
u32 *minconf;
Expand Down Expand Up @@ -322,6 +323,9 @@ static struct command_result *fundchannel_start(struct command *cmd,
json_out_addstr(ret, "feerate", fr->feerate_str);
if (fr->announce_channel)
json_out_addbool(ret, "announce", *fr->announce_channel);
if (fr->push_msat)
json_out_addstr(ret, "push_msat",
type_to_string(tmpctx, struct amount_msat, fr->push_msat));

json_out_end(ret, '}');
json_out_finished(ret);
Expand Down Expand Up @@ -450,6 +454,7 @@ static struct command_result *json_fundchannel(struct command *cmd,
p_opt_def("announce", param_bool, &fr->announce_channel, true),
p_opt_def("minconf", param_number, &fr->minconf, 1),
p_opt("utxos", param_string, &fr->utxo_str),
p_opt("push_msat", param_msat, &fr->push_msat),
NULL))
return command_param_failed();
} else {
Expand All @@ -462,6 +467,7 @@ static struct command_result *json_fundchannel(struct command *cmd,
p_opt_def("announce", param_bool, &fr->announce_channel, true),
p_opt_def("minconf", param_number, &fr->minconf, 1),
p_opt("utxos", param_string, &fr->utxo_str),
p_opt("push_msat", param_msat, &fr->push_msat),
NULL))
return command_param_failed();

Expand Down
29 changes: 29 additions & 0 deletions tests/test_connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -911,6 +911,35 @@ def test_funding_toolarge(node_factory, bitcoind):
l1.rpc.fundchannel(l2.info['id'], amount)


def test_funding_push(node_factory, bitcoind):
""" Try to push peer some sats """
l1 = node_factory.get_node()
l2 = node_factory.get_node()

l1.rpc.connect(l2.info['id'], 'localhost', l2.port)

# Send funds.
amount = 2**24
push_sat = 20000
bitcoind.rpc.sendtoaddress(l1.rpc.newaddr()['bech32'], amount / 10**8 + 0.01)
bitcoind.generate_block(1)

# Wait for it to arrive.
wait_for(lambda: len(l1.rpc.listfunds()['outputs']) > 0)

# Fail to open (try to push too much)
with pytest.raises(RpcError, match=r'Requested to push_msat of 20000000msat is greater than available funding amount 10000sat'):
l1.rpc.fundchannel(l2.info['id'], 10000, push_msat=push_sat * 1000)

# This should work.
amount = amount - 1
l1.rpc.fundchannel(l2.info['id'], amount, push_msat=push_sat * 1000)
bitcoind.generate_block(1)
sync_blockheight(bitcoind, [l1])
funds = only_one(l1.rpc.listfunds()['channels'])
assert funds['channel_sat'] + push_sat == funds['channel_total_sat']


def test_funding_by_utxos(node_factory, bitcoind):
"""Fund a channel with specific utxos"""
l1, l2, l3 = node_factory.line_graph(3, fundchannel=False)
Expand Down

0 comments on commit 689dd28

Please sign in to comment.