[c-lightning] Plug-in design requirements
Rusty Russell
rusty at rustcorp.com.au
Mon Dec 10 15:37:02 AEDT 2018
Corné Plooy <corne at bitonic.nl> writes:
> Hi,
>
> From a side discussion during the Lightning summit I understood that my
> input
> is wanted for the design of the plug-in system of C-Lightning. In this
> e-mail
> I'll sketch what I'd like to have. In various places, I'll quote structure
> names from BOLT 4.
Great!
> # Sending node behavior
>
> Application-specific code on the sending node must be able to send out a
> payment
> to the receiving node with an onion packet that is different from a regular
> onion packet in the following ways:
>
> * The onion data received by the receiving node indicates that, instead of
> following the regular behavior of a Lightning node, the receiving node
> must
> follow certain application-specific behavior. The preferred way of
> indicating
> this is through a non-default `realm` number, but other methods have been
> proposed as well (such as a non-existing `short_channel_id`).
> * The `per_hop` data received by the receiving node contains
> application-specific data instead of, or in addition to, the regular
> `per_hop`
> data.
Looks like we're headed to TLV data for the onion padding for 1.1, and
realm being a simple counter of number of extra fields. This should fit
nicely with a JSON API which allows arbitrary data, I think...
> Obviously, if the `realm` number is used as indicator, and the
> application-specific data completely replaces the regular `per_hop`
> data, this
> maximizes the amount of application-specific data that can be sent.
>
> If more data needs to be sent than fits in a single `per_hop` element, the
> application might require the use of multiple `per_hop` elements, at the
> cost of
> reducing the maximum transaction route length. However, for my
> application that
> does not seem to be needed. Specifically, my application needs the following
> data in the onion:
> * 8 bytes: the amount to be forwarded in an application-specific way
> * ? bytes: an ID related to some data shared between sender and receiver.
> Can be RIPEMD160 (20 bytes).
Assuming that this API disabled multipart payments (at least, to start
with) it could completely define the final TLV contents. lightningd
would use enough hops_data to fit whatever the API hands in.
The definition of 'application-specific data' would be 'a TLV we don't
understand'. I think the 'chainhop' and 'multipart' and a few other TLV
values have been proposed so far; we'd handle 'multipart' internally.
> # Receiving node behavior
>
> On receiving an incoming transaction that indicates application-specific
> behavior (as described above), the receiving node must do one of the
> following:
>
> * If no application-specific handler is present, fail the incoming
> transaction.
I think this should actually now depend on the odd/even rule: we would
be fine with odd bits we don't understand, and fail even ones.
> * If an application-specific handler is present, accept the incoming HTLC,
> notify the handler of the incoming transaction and pass it the following
> information:
>
> - Incoming amount
> - Incoming CLTV
> - Incoming payment hash
> - `realm` number
> - `per_hop` data
>
> If more data needs to be sent than fits in a single `per_hop` element, the
> entire `hops_data` structure may need to be passed; TBD is whether the
> remaining
> hops need to be decrypted in a certain way. As far as my application
> goes, this
> will not be needed, since its data fits in a single `per_hop` element.
We'd hand all the hop data, I think. The `realm` effectively encodes
the length, so may be redundant.
> If the application-specific code neither fails nor finishes the transaction,
> the Lightning node should respect the lock time of the incoming HTLC.
> To prevent the peer from closing the channel, the incoming transaction
> should be
> failed some short time before its lock time; we may want to make this time
> difference configurable, maybe even on a per-application basis.
Yes, this is similar to how we handle forwarded HTLCs, and I think
similar logic applies.
> To aid in crash recovery, it is recommended to add an extra interface
> (function)
> between application and Lightning node, to allow the Lightning node to query
> the application about ongoing transactions after application restart.
> Informally, the Lightning node asks "are you handling this
> transaction?", and
> the application answers yes or no. If it answers no, the Lightning node may
> fail the incoming transaction. The advantage is that transactions are failed
> faster than when waiting for the HTLC time-out.
In practice I think c-lightning would re-submit them on startup; plugins
should handle this case.
> Automatic restarting of the application may be desirable, but following
> the UNIX
> philosophy of "do one simple thing, and do it well" I don't think it
> should be
> the responsibility of the Lightning node. In fact, the whole concept of a
> persistent application process can be application-specific; for some
> applications, it might be better suited to kick off a new (script)
> process on
> every incoming transaction.
Yes, I think the plugin should be responsible for its own dispatch.
> On the receiver side, the decision of what signals "application-specific
> handling" may be delegated to application-specific code. It may be seen as a
> chain of handlers: an incoming transaction is offered to the handlers one by
> one, until a handler accepts the transaction. The last handler in the
> chain is
> always the default built-in handler of C-Lightning; it can not refuse a
> transaction, only accept it or fail it immediately. So the handler chain
> always
> has at least length one.
Well, this works quite neatly with the idea of TLV odd and even. The
default behaviour is then correct; the application chooses whether its
option is compulsory or not.
Cheers,
Rusty.
More information about the c-lightning
mailing list