-
Notifications
You must be signed in to change notification settings - Fork 912
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
add a funder
plugin
#4489
add a funder
plugin
#4489
Conversation
When an RPC originates from a plugin, and there's no associated command, it's useful to be able to signal that you're finished.
openingd/dualopend.c
Outdated
/* Set the channel_id back to what they originally sent us, | ||
* in open_channel2, since they won't know the combined | ||
* channel_id yet for errors */ | ||
state->channel_id = tmp_chan_id; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems like we should only be updating the channel_id field when we send the reply?
lightningd/dual_open_control.c
Outdated
@@ -244,6 +244,10 @@ struct openchannel2_payload { | |||
/* What's the maximum amount of funding | |||
* this channel can hold */ | |||
struct amount_sat channel_max; | |||
/* Snapshot of our current utxo set, available */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure this is actually that useful: it's more accurate for them to count utxos themselves and take into account the feerate. It's a little more work, but I think the plug-in should listutxos itself...
Here's proposed patch for the tmp_channel_id issue: spec should probably be updated too? dualopend: don't use final channel_id for accepter_start2
The other side doesn't know it until *after* it parses this msg. We
add a quick hack to still allow old nodes to work (for now!).
This also fixes a bug (spotted by @niftynei) where any errors we sent
before accepter_start2 would have the new (unknowable!) channel_id
rather than the temp one.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
diff --git a/openingd/dualopend.c b/openingd/dualopend.c
index ad8d5420e..d753dff8e 100644
--- a/openingd/dualopend.c
+++ b/openingd/dualopend.c
@@ -1897,7 +1897,6 @@ static void accepter_start(struct state *state, const u8 *oc2_msg)
struct bitcoin_blkid chain_hash;
struct tlv_opening_tlvs *open_tlv;
char *err_reason;
- struct channel_id tmp_chan_id;
u8 *msg;
struct amount_sat total;
enum dualopend_wire msg_type;
@@ -1939,7 +1938,7 @@ static void accepter_start(struct state *state, const u8 *oc2_msg)
* `open_channel2`), a temporary `channel_id` should be found
* by using a zeroed out basepoint for the unknown peer.
*/
- derive_tmp_channel_id(&tmp_chan_id,
+ derive_tmp_channel_id(&state->channel_id,
&state->their_points.revocation);
if (!channel_id_eq(&state->channel_id, &tmp_chan_id))
negotiation_failed(state, "open_channel2 channel_id incorrect."
@@ -1949,12 +1948,6 @@ static void accepter_start(struct state *state, const u8 *oc2_msg)
type_to_string(tmpctx, struct channel_id,
&state->channel_id));
- /* Everything's ok. Let's figure out the actual channel_id now */
- derive_channel_id_v2(&state->channel_id,
- &state->our_points.revocation,
- &state->their_points.revocation);
-
-
/* Save feerate on the state as well */
state->feerate_per_kw_funding = tx_state->feerate_per_kw_funding;
@@ -2105,6 +2098,11 @@ static void accepter_start(struct state *state, const u8 *oc2_msg)
&state->first_per_commitment_point[LOCAL],
a_tlv);
+ /* Everything's ok. Let's figure out the actual channel_id now */
+ derive_channel_id_v2(&state->channel_id,
+ &state->our_points.revocation,
+ &state->their_points.revocation);
+
sync_crypto_write(state->pps, msg);
peer_billboard(false, "channel open: accept sent, waiting for reply");
@@ -2479,6 +2477,23 @@ static void opener_start(struct state *state, u8 *msg)
open_err_fatal(state, "Parsing accept_channel2 %s",
tal_hex(msg, msg));
+ if (!channel_id_eq(&cid, &state->channel_id)) {
+ struct channel_id future_chan_id;
+ /* FIXME: v0.10.0 actually replied with the complete channel id here,
+ * so we need to accept it for now */
+ derive_channel_id_v2(&future_chan_id,
+ &state->our_points.revocation,
+ &state->their_points.revocation);
+ if (!channel_id_eq(&cid, &future_chan_id)) {
+ peer_failed_err(state->pps, &cid,
+ "accept_channel2 ids don't match: "
+ "expected %s, got %s",
+ type_to_string(msg, struct channel_id,
+ &state->channel_id),
+ type_to_string(msg, struct channel_id, &cid));
+ }
+ }
+
if (a_tlv->option_upfront_shutdown_script) {
state->upfront_shutdown_script[REMOTE]
= tal_steal(state,
@@ -2492,14 +2507,6 @@ static void opener_start(struct state *state, u8 *msg)
&state->our_points.revocation,
&state->their_points.revocation);
- if (!channel_id_eq(&cid, &state->channel_id))
- peer_failed_err(state->pps, &cid,
- "accept_channel2 ids don't match: "
- "expected %s, got %s",
- type_to_string(msg, struct channel_id,
- &state->channel_id),
- type_to_string(msg, struct channel_id, &cid));
-
/* Check that total funding doesn't overflow */
if (!amount_sat_add(&total, tx_state->opener_funding,
tx_state->accepter_funding)) |
These are now included in all builds
We removed/changed the fields on the openchannel2 hook but never updated this test (which doesn't run with the CI for #reasons)
69aca6a
to
f773987
Compare
The other side doesn't know it until *after* it parses this msg. We add a quick hack to still allow old nodes to work (for now!). This also fixes a bug (spotted by @niftynei) where any errors we sent before accepter_start2 would have the new (unknowable!) channel_id rather than the temp one. Authored-by: Rusty Russell <rusty@rustcorp.com.au>
f773987
to
fc77f51
Compare
Ok, patches have been applied (and already folded in mea culpa). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor fixes only...
/* Signals that we've completed a command. Useful for when | ||
* there's no `cmd` present */ | ||
struct command_result *command_done(void); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Drop this commit. The one place you end up using it, you do indeed have a command. You just don't use it!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't want to actually do anything with the command though. There's no response to send on our side when this completes, it's a 'silent no-op'?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, this is because the "cmd" is actually a notification, which doesn't want a response. It does, however, want to be freed!
I'll submit a followup PR which cleans this up everywhere...
plugins/funder.c
Outdated
err, json_tok_full_len(result), | ||
json_tok_full(buf, result)); | ||
|
||
/* we skip resrved funds */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Need to buy a vwl?
plugins/funder_policy.c
Outdated
@@ -89,6 +89,32 @@ default_funder_policy(enum funder_opt policy, | |||
100); | |||
} | |||
|
|||
char *funder_check_policy(struct funder_policy *policy) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
const struct funder_policy?
err = funder_check_policy(¤t_policy); | ||
if (err) | ||
return command_done_err(cmd, JSONRPC2_INVALID_PARAMS, | ||
err, NULL); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you need to modify a copy, then assign it back to current_policy at the end.
Otherwise, setting a bad value causes an error, but sticks around...
plugins/funder.c
Outdated
return command_finished(cmd, res); | ||
} | ||
|
||
const struct plugin_command commands[] = { { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
static const struct plugin_command commands?
doc/PLUGINS.md
Outdated
@@ -1157,7 +1157,8 @@ requests an RBF for a channel funding transaction. | |||
"funding_feerate_per_kw": 7500, | |||
"feerate_our_max": 10000, | |||
"feerate_our_min": 253, | |||
"locktime": 2453, | |||
"channel_max": "200000msat", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It will never be this value though, so it's misleading.
@@ -206,6 +209,8 @@ rbf_channel_hook_serialize(struct rbf_channel_payload *payload, | |||
payload->feerate_our_min); | |||
json_add_num(stream, "funding_feerate_per_kw", | |||
payload->funding_feerate_per_kw); | |||
json_add_amount_sat_only(stream, "channel_max", | |||
payload->channel_max); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since this converts to msat, and that fails for UINT64_MAX, this channel_max will actually only appear for non-wumbo channels. Which is probably OK, but should be documented.
Field should also be called "channel_max_msat".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ACK. also updated the channel_max
field that exist on openchannel2
hook.
fc77f51
to
de7bbf0
Compare
Changelog-Added: Plugins: add a `channel_max_msat` value to the `openchannel2` hook. Tells you the total max funding this channel is allowed to have.
For dual-funding's accepter plugin, we only want to send psbts that need to be signed to `signpsbt`; this lets us quickly check if they're "signable"
You gotta send over an amount if you send a psbt!
This is set by the peer and is non-negotiable. We're not even going to check if you got it right. You were told about it via `openchannel2`. It is what it is.
For scaling/multiplying sats
Behold! An immaculately concepted plugin for configuring your node to do amazing things* *fund channel open requests Changelog-Added: Plugins: Add `funder` plugin, which allows you to setup a policy for funding v2 channel open requests. Requres --experimental-dual-fund option
Compute available_funds locally, instead of getting it from the openchannel2 hook payload. Suggested-By: Rusty Russell @rustyrussell
If you're using the regtest node, turn on dual funding and automatically attempt to dual fund at a 100% match for every channel open that you do.
Error out if we've got the wrong info
Changelog-Added: Plugins: `funder` plugin now has new command `funderupdate` which will show current funding configuration and allow you to modify them
Changelog-Added: Plugins: `rbf_channel` hook has `channel_max_msat` parameter
Fund an RBF same as you would an open. We dont' do anything fancy with our inputs -- we dont' have a copy of the last PSBT that was sent.
Dual-funded channels won't match the old amount check. Good news is we're already returning the outnum so we just use that.
de7bbf0
to
de9102a
Compare
Updated, as per comments. |
Ack de9102a |
Plugin to democratize a peer's ability to contribute funds to incoming openchannel request.
Current knobs include:
*assuming races never happen
Future work: we don't take feerates into account right now we calculating the total available funds to add.