-
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
Plugin implementation of keysend
spontaneous payments
#3611
Conversation
In order to avoid conflicts I self-assigned featurebit |
Having a bit of trouble with these changes due to a missing dependency from
Trying to debug that at the moment, but hints would be appreciated 😉 |
No luck, I really tried adding the missing header almost everywhere, and the behaviour doesn't change. |
I deleted this comment after making use of my brain (not about linking objects but finding headers), sorry 😅. |
Interestingly this doesn't happen with BTW this seems to work, but I have no idea why:
|
I experienced this too, both for the non-aggressive build and for the addition of the header file in plugins/Makefile (or common/Makefile). |
plugins/Makefile
Outdated
$(PLUGIN_PAY_OBJS) $(PLUGIN_AUTOCLEAN_OBJS) $(PLUGIN_FUNDCHANNEL_OBJS) $(PLUGIN_BCLI_OBJS) $(PLUGIN_LIB_OBJS): $(PLUGIN_LIB_HEADER) | ||
|
||
# Make sure these depend on everything. | ||
ALL_PROGRAMS += plugins/pay plugins/autoclean plugins/fundchannel plugins/bcli | ||
ALL_PROGRAMS += plugins/pay plugins/autoclean plugins/fundchannel plugins/bcli plugins/keysend | ||
ALL_OBJS += $(PLUGIN_PAY_OBJS) $(PLUGIN_AUTOCLEAN_OBJS) $(PLUGIN_FUNDCHANNEL_OBJS) $(PLUGIN_BCLI_OBJS) $(PLUGIN_LIB_OBJS) |
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.
Got it. You forgot to add $(PLUGIN_KEYSEND_OBJS)
here. ALL_OBJS
will later be set to depend on WIRE_HEADERS !
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.
"later" <==> in the main Makefile
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.
Whoa, that's awesome work, thanks a million 👍
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.
Looks good to me, not really tested yet
plugins/keysend.c
Outdated
plugin_main(argv, init, PLUGIN_RESTARTABLE, commands, ARRAY_SIZE(commands), | ||
NULL, 0, hooks, ARRAY_SIZE(hooks), NULL); | ||
plugin_main(argv, init, PLUGIN_RESTARTABLE, NULL, commands, | ||
ARRAY_SIZE(commands), NULL, 0, hooks, ARRAY_SIZE(hooks), |
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.
Duplicated
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.
nvm, resolved innext commit
plugins/keysend.c
Outdated
@@ -3,6 +3,7 @@ | |||
#include <wire/gen_onion_wire.h> | |||
|
|||
#define PREIMAGE_TLV_TYPE 5482373484 | |||
#define KEYSEND_FEATUREBIT 0x81 |
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.
Why isn't it 55 ?
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 presume it's because 'bit 55' corresponds to 0x81 in hex, in other words '55' here is not an integer but a bit-count.
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.
.... that doesn't make sense, @niftynei ? 0x81 == 129. I assume this was supposed to be 0x37?
Maybe this deserves the |
Can we just do #3628 and use that instead please? Then we can remove the tlv option we don't want lightningd to see, and the rest is simple? |
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 really prefer replacing the payload, and just doing the rest using existing infrastructure. See #3628
plugins/keysend.c
Outdated
if (s != max) { | ||
return htlc_accepted_continue(cmd); | ||
} | ||
fromwire_tlv_payload(&rawpayload, &max, payload); |
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.
Should check if this fails?
fromwire_tlv_payload(&rawpayload, &max, payload); | ||
|
||
/* Try looking for the field that contains the preimage */ | ||
for (int i=0; i<tal_count(payload->fields); i++) { |
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.
Prefer size_t for sizes...
e0e4031
to
dfd9f8f
Compare
Ok, I went ahead and changed the plugin to create the invoice itself, modify @rustyrussell's patch didn't work for me, so I disabled checking the payment |
a4e0f74
to
4adba79
Compare
Rebased on top of
|
fce4412
to
a2435c6
Compare
Rebased on top of #3647, hopefully now it doesn't fail when replacing the payload anymore. |
We use the new function `plugins_free` to define the correct deallocation order on shutdown, since under normal operation the allocation tree is organized to allow plugins to terminate and automatically free all dependent resources. During shutdown the deallocation order is under-defined since siblings may get freed in any order, but we implicitly rely on them staying around.
The plugin can basically return whatever it thinks the preimage is, but we weren't handling the case in which it doesn't actually match the hash. If it doesn't match now we just return an error claiming we don't have any matching invoice.
This still uses the experimental TLV-type, but once the type is standardized we can add detection for the new type quite easily. Changelog-Added: pay: The `keysend` plugin implements the ability to receive spontaneous payments (keysend)
The generated wrappers will ignore the raw fields and will only consider the shortcut fields. This function takes the raw fields and serializes them instead.
It currently uses a borrowed sending implementation from the noise plugin, but we'll implement that functionality in the native keysend plugin next.
We must really make sure that we understand the entire payload, not just the fields we are interested in.
Better not duplicate these, we might end up mixing them.
The featurebit isn't quite settled.
These are necessary for the interim keysend plugin
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au> Changelog-added: `htlc_accepted` hook can now offer a replacement onion `payload`.
So far we were relying on `lightningd` to create an ad-hoc invoice when telling it to `resolve` with a given preimage. We now switch to having the plugin create the invoice, remove the mandatory `keysend_preimage` field (which would upset `lightningd` otherwise), and then return the modified payload with the instructions to `continue` instead of resolving. This ties back in with the existing payment/invoice handling code. Invoices are created only if we don't have a label clash (unlikely since we have the nano-time in the label), or the `payment_hash` was already used for another invoice (at which point `lightningd` will automatically reject the payment and we're a bit poorer for it, but meh :-)
As discussed with Christian, prepending the length to the payload returned is awkward, but it's the only way to set a legacy payload. As this will be soon deprecated, simplify the external API. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Trivial rebase onto master. Ack ea931f0 |
Should this plugin have been added to |
Support for receiving and sending KeySend payment is added. For an explanation of the KeySend feature see: ElementsProject/lightning#3611
Support for receiving and sending KeySend payment is added. For an explanation of the KeySend feature see: ElementsProject/lightning#3611
The
keysend
plugin implements the ability to receive spontaneous payments byincluding the
payment_preimage
in the onion payload, thus giving therecipient the ability to claim the payment without having to exchange invoices
first. This sometimes erroneously called a sphinx-send, and can lead to
confusion with the onion routing protocol based on the sphinx paper.
The plugin has the ability to extract the preimage from the payload and will
tell
lightningd
to resolve the HTLC with the provided preimage. As proposedby @rustyrussell, in order to keep track of funds,
lightningd
will create anad-hoc invoice that is immediately fulfilled via the resolved HTLC. This
ensures that we have an entry in the incoming payments, even though we didn't
really have a matching invoice. The ad-hoc invoice is generated whenever a
plugin tells
lightningd
to resolve an HTLC, so that these paymentsterminated by plugins now always leave an accounting entry in the database.
Due to the uniqueness constraint on
payment_hash
in theinvoices
table wecannot always insert an invoice that matches the resolved HTLC, in which case
we will simply not add an entry. This should happen rarely since re-using a
payment_hash
is inherently insecure, e.g., it allows any node involved inrouting the first payment to grab the second payment. Alternatively we could
also reject the payment due to this protocol violation on the sender side,
however that'd be handing the funds to a (so far) well behaved node that
forwarded the payment despite being able to grab it, leaving the sender out of
pocket, and the recipient without the funds it could have gotten.
Since ad-hoc invoices do not need a
features
fields andbolt11
string,which in turn would require asking the
hsmd
for a signature, we made thosetwo fields nullable (changelog warning added).
Sending support for
keysend
payments will be added in a separate pullrequest since it requires abstracting the internals of the
pay
plugin so wecan reuse them here.
As a side note: the keysend plugin will make sure it understands all the
mandatory TLV fields, and issue a
continue
otherwise. This was done in orderto allow alternative plugins to terminate keysends that have additional
information. One example is the
noise
plugin that terminateskeysend
payments that are sent along a chat message (which has a mandatory TLV-type)
and associates the message with the incoming payment.