[c-lightning] Feature: run scripts on incoming transactions

Christian Decker decker.christian at gmail.com
Thu Jun 21 19:56:06 AEST 2018

Excellent work Corné, this has been on my wish list for a long time now :-)

Corné Plooy <corne at bitonic.nl> writes:
> I'm working on an experimental feature for C-Lightning where a custom
> (Sphinx) message in an incoming transaction can trigger the execution of
> a script. The script can receive information about the transaction
> (hash, time-out, amount, message data etc.), do anything it wants, and
> reply to lightningd whether this incoming transaction should be accepted
> or canceled. The incoming transaction does not have to correspond to an
> invoice created in this Lightning node: it can also be that a
> higher-level application needs to forward the payment to some other
> party, in an application-specific way, to gain access to the preimage.
> The (unfinished) code is available at:
> https://github.com/bitonic-cjp/lightning/tree/application_connection
> By its very nature, the code involves some API changes. So far, the
> design is roughly as follows:
> * The 'sendpay' command allows optional extra attributes 'realm' and
> 'data' in individual route steps. These override the normal realm value
> (0) and data (channel ID, amount, time-out) that would otherwise be put
> into the routing data given to a node.
> * If an incoming transaction contains a realm number that would
> otherwise not be supported (currently, realm 0 is the only one defined
> by the RFC and supported by C-Lightning), lightningd tries to execute a
> script "handle_realm_<realmnumber>" in the Lightning directory. It
> receives information about the transaction on STDIN (format: TBD), and
> sends a single number back on STDOUT indicating whether the transaction
> should be accepted or rejected.

I would probably not use a naming convention to route to different
handlers here, but rather have a script that acts as a router,
distinguishing which script to call next based on the information passed
in. This can be either a helper listening to a socket, as Rusty
suggested, or be a script that is called by `lightningd` and specified
on the command line. Singling out the realm byte and not, for example, the
next hop node ID seems strange.

I can immagine that even realm 0 calling out to a script might be
interesting since it allows for entirely different transport protocols
(I always wanted to use lightning over e-Mail ^^).

> * Currently, if such a script hangs, lightningd hangs. I'm not
> completely happy with this, but what would be the alternatives? Not have
> the script send any data back? Asynchronous communication with the
> script? You potentially have a "process leak" problem: an attacker may
> crash a machine by triggering huge numbers of parallel script
> executions. For now, this problem does not exist, and "don't make buggy
> scripts" is an obvious solution to stop lightningd from hanging.

Is this is one-shot, as in yay or nay, or is the script called upon HTLC
add and we can report HTLC resolution back? If we have a long time until
we decide how to resolve the HTLC then we might want to make this
asynchronous, since otherwise we might hang the entire node indefinitely.

> * Extra RPC commands will be added to allow applications to give a
> transaction preimage to lightningd (inherently safe) and to indicate
> that a certain payment will be canceled (unsafe - the application needs
> to ensure that any outgoing goods/services/assets are stopped, before
> canceling the incoming funds).

This seems to suggest that indeed the above is already async, so that's
definitely good :-)

More information about the c-lightning mailing list