From d812a6481f9ff08cc16ab94807483205040de53b Mon Sep 17 00:00:00 2001 From: ZmnSCPxj jxPCSnmZ Date: Tue, 14 Mar 2023 23:17:57 +0800 Subject: [PATCH] LSPS2: JIT Channels. --- LSPS2/README.md | 952 ++++++++++++++++++++++++++++++++++++++++++++++++ README.md | 3 +- 2 files changed, 954 insertions(+), 1 deletion(-) create mode 100644 LSPS2/README.md diff --git a/LSPS2/README.md b/LSPS2/README.md new file mode 100644 index 0000000..9637054 --- /dev/null +++ b/LSPS2/README.md @@ -0,0 +1,952 @@ +# LSPS2 JIT Channel Negotiation + +|Name | `jit_channels` | +|--------|--------------------------| +|Version | 1 | +|Status | For Implementation | + +## Motivation + +A "JIT Channel" is a channel opened in response to an incoming payment +from the public network to a client, via the LSP. +This allows a client with no Lightning channels to start receiving on +Lightning, and have the cost of their inbound liquidity be deducted from their +first received payment. + +### Trust Models + +As of this version, there are two trust models: + +* The LSP trusts clients to actually claim their payment once the channel is + opened and the payment is forwarded. +* The client trusts LSPs to actually open a real channel with a valid funding + transaction and valid funding outpoint. + +If the client does not claim the payment, and the funding transaction confirms, +then the LSP will have its funds locked in a channel that was not paid for. +Even if the LSP disables all other use of the channel until the payment paying +for the channel is claimed, the client may then refuse all mutual close attempts +in retaliation (by disconnecting), and force the LSP to unilaterally close, +which locks the funds until the `to_self_delay` (indicated by the client, and +imposed on the LSP) has passed. +The LSP can protect against this (i.e. LSP does not trust the client) by simply +not broadcasting the funding transaction until after it gets the preimage. + +Similarly, the LSP may provide a random number for the transaction ID of the +funding transaction during opening, and then refuse to forward any Lightning +transactions out of the channel, then forwarding as "normal" over the +invalid channel and then receiving the preimage. +The client is then unable to claim its received funds, even though the LSP +would be able to claim the funds from incoming forward. +Even if the client wanted to unilaterally drop the channel on-chain, as the +funding transaction is not valid and will never appear on the blockchain, +it will be unable to claim the funds. +The client can protect against this (i.e. client does not trust the LSP) by +simply not providing the preimage until it sees the funding transaction has +been broadcast and is in its own local mempool. + +Additional protection for the client against the LSP double-spending an +unconfirmed funding transaction can be had by utilizing [LSPS3][], if the +LSP supports this. + +[LSPS3]: ../LSPS3/README.md + +If neither the client nor the LSP trust each other, they will deadlock: the +untrusting LSP withholds the funding transaction until it sees the payment +preimage, the untrusting client withholds the preimage until it sees the +funding transaction. +(Or with [LSPS3][], the LSP withholds the LSPS3 response, the client waits +for the LSPS3 response) + +The only way to break this deadlock without invoking trust, is to use the +blockchain to ensure confirmation of some contract that ensures that the +funding transaction is broadcastable if and only if the preimage is +provided to the LSP. +This can be done trivially by using an HTLC where the hashlock branch is +signed by both LSP and client, and the LSP provides the witness required +to spend from the hashlock branch into the channel funding outpoint, with +the client providing its signature and the preimage in order to get the +channel funding outpoint confirmed. + +Unfotunately, an inherent assumption of JIT channels is that the channel is +unconfirmed and the payment immediately routed to the client. +This prevents use of the slow blockchain layer to handle trust. +With that option not useable, either the LSP trusts the client, or the +client trusts the LSP. + +The LSP SHOULD default to "LSP trusts client" model. +In particular, a too-trusting LSP being attacked may treat its losses as +part of the cost of doing business (effectively losing just on-chain fees +and the use of capital while locked in an unpaid channel), whereas a +too-trusting client being attacked would face actual loss of funds. + +The LSP MAY signal a "client trusts LSP" model, and a field is specified +for the LSP to do this. +The LSP might do this for example if it detects that it is being attacked +and needs to protect its funds, even though most of the time it is in +"LSP trusts client" model. + +A client that does not want to trust any LSP can simply refuse to use an +LSP that signals "client trusts LSP". + +LSPs that implement this API SHOULD include mitigations to allow them to +determine if clients can be trusted, or to detect and protect against attacks +on the LSP. +How those mitigations are performed is beyond the scope of this specification. + +### Actors + +The 'LSP' is the API provider. +The 'client' is the API client. +The 'payer' is who pays for the initial receive of the client. + +## Flow (LSP Trusts Client Model) + +Overview: + +* The client determines that it would like to receive over Lightning, but + it has no inbound capacity, and the client cannot pre-buy this capacity + (for instance, it also has no outbound capacity or on-chain funds). +* The client determines the parameters of a particular LSP via a + `lsps2.getinfo` request. + * The LSP also indicates how long those parameters are valid for, + which also defines a timeout for the rest of this flow; if the + flow does not complete in that timeout, the parameters are no + longer valid and the LSP will refuse to open the channel. +* The client requests for a JIT channel, specifying how much it will + receive, via a `lsps2.buy` request. +* The LSP returns an SCID, which identifies this request to the LSP. +* The client generates an invoice, which includes the above SCID and the + LSP node ID as a routehint. +* The client hands the invoice to whoever it will receive funds from. +* The payment is forwarded to the LSP. +* The LSP recognizes the next hop SCID as being a JIT channel request, + and opens a 0-confirmation channel to the client, which must be + connected to the LSP at that time. +* The LSP forwards the payment to the client, deducting the channel + opening fee. +* The client claims the payment. + +> **Rationale** An alternative flow would be for the client to provide a +> payment hash for the LSP to recognize, instead of the LSP providing a +> SCID for the client to use in its invoice. +> However, this has drawbacks for some future modifications of the Lightning +> protocol: +> +> - Protocols where the payer generates the payment preimage and gives +> the preimage to the payee inside the encrypted onion are incompatible +> with having the client (the payee) provide the payment hash to the +> LSP beforehand. +> - Current plans for asynchronous receive use such a scheme. +> - PTLCs are supposed to improve privacy by having each hop have a +> different blinding factor, but for the LSP to recognize the payment +> point, it would have to know the blinding factor towards the client, +> which reduces the privacy of the client in a multipath payment. +> - PTLCs would allow a payer to buy a private key from a payee +> (client in this context); normally the per-hop blinding factors +> would hide the sold private key from forwarding nodes, but due to +> the LSP having to know the exact payment point and the blinding +> factor towards the client / payee, it would also learn the sold +> private key. + +### 0. API Version + +The client can determine the versions supported by the LSP via the +`lsps2.getversions` call. + +This call takes no parameters `{}` and has no defined errors. + +`lsps2.getversions` has a result like the below: + +```JSON +{ + "versions": [1] +} +``` + +`versions` is the set of LSPS2 versions the LSP supports. +When the client later contacts the LSP, it indicates a single specific +version, which MUST be one of those indicated in this set. + +The client MUST determine protocol compatibility (if it supports a +`version` that the LSP also supports). + +### 1. API Information + +`lsps2.getinfo` is the entrypoint for each client using the API. +It indicates supported versions of this protocol, as well as any limits the +LSP imposes, and parameters for payment. + +The client MUST request `lsps2.getinfo` to read the `opening_fee` of the +LSP and its related parameters. + +`lsps2.getinfo` takes the parameters: + +```JSON +{ + "version": 1, + "token": "SECRETDISCOUNTCOUPON100" +} +``` + +`version` is the version of this spec that will be used for this +interaction. + +`token` is an *optional*, arbitrary JSON string. +This parameter is intended for use between the client and the LSP; it +may be used to negotiate for a better feerate than the LSP otherwise +offers (i.e. a "discount coupon"), or for the LSP to actually offer +this service to the client (i.e. an "API key") instead of failing to +provide any offers, or for any other purpose. + +`lsps2.getinfo` has the following errors defined (error code numbers +in parantheses): + +* `unsupported_version` (1) - the LSP does not support the `version` + indicated by the client. +* `unrecognized_or_stale_token` (2) - the client provided the `token`, + and the LSP does not recognize it, or the token has expired. + +Example `lsps2.getinfo` result: + +```JSON +{ + "opening_fee_params_menu": [ + { + "min_fee_msat": "546000", + "proportional": 1200, + "valid_until": "2023-02-23T08:47:30.511Z", + "min_lifetime": 1008, + "max_client_to_self_delay": 2016, + "promise": "abcdefghijklmnopqrstuvwxyz" + }, + { + "min_fee_msat": "1092000", + "proportional": 2400, + "valid_until": "2023-02-27T21:23:57.984Z", + "min_lifetime": 1008, + "max_client_to_self_delay": 2016, + "promise": "abcdefghijklmnopqrstuvwxyz" + } + ], + "min_payment_size_msat": "1000", + "max_payment_size_msat": "1000000", +} +``` +The `opening_fee_params_menu` is an array of `opening_fee_params` +objects. +The LSP MAY return an empty array; in which case, the client currently +cannot use JIT Channels with this LSP. + +An `opening_fee_params` object describes how much the LSP will charge +for a channel open, and until when the described feerates will be +considered valid. +An `opening_fee_params` object MUST have all of the following fields, +and MUST NOT have any additional fields: + +* `min_fee_msat` is the minimum fee to be paid by the client to the + LSP. + It is a string containing the decimal encoding of a number of + millisatoshis. +* `proportional` is a parts-per-million number that describes how many + millisatoshis to charge for every 1 million millisatoshis of payment + size for the first payment. + If the proportional fee is less than the `min_fee_msat`, then the + `min_fee_msat` is paid instead of the proportional times payment size + divided by 1 million. +* `valid_until` is a datetime (as an ISO8601 string) up to which this specific + `opening_fee_params` is valid, and also serves as the timeout for the JIT + Channel flow, if this particular object is selected. +* `min_lifetime` is a number of blocks that the LSP promises it will keep the + channel alive without closing, after confirmation. + The LSP MUST NOT close the channel if both conditions below are satisfied: + * It was paid via a JIT channel payment to open this channel (i.e. the + client released the preimage to the HTLC(s) that have had the value of + the opening feee deducted), AND + * The channel funding transaction confirmation depth is below the + `min_lifetime`. +* `max_client_to_self_delay` is a maximum number of blocks that the client + is allowed to set its `to_self_delay` parameter. + The client-side `to_self_delay` is the delay imposed on the LSP to recover + the funds in case the LSP has to perform a unilateral close on the channel + and defines the security of the client against malign or hacked LSPs. +* `promise` is an arbitrary LSP-generated string that proves to the LSP that + it has promised a specific `opening_fee_params` with the specific + `min_fee_msat`, `proportional`, `valid_until`, `min_lifetime`, and + `max_client_to_self_delay`. + +> **Rationale** A "minimum" fee is used instead of an additive base fee as +> this mimics similar financial services. +> +> A time limit (`valid_until`) on the offerred feerates is +> needed as channel opening is an on-chain activity, and on-chain feerates +> need to be reflected in the channel opening feerates the LSP charges. +> The LSP cannot predict future on-chain feerates, and thus must estimate +> how long its current on-chain feerate estimates are valid for. +> The LSP may offer multiple parameter sets with varying time limits. +> +> Both `min_lifetime` and `max_client_to_self_delay` in total impose a +> maximum limit on how long a client can lock the funds of the LSP without +> giving the LSP any opportunity to earn from forwards. +> Both parameters are placed in the `opening_fee_params` object as they +> are part of the service that the LSP is promising. +> Although neither parameter is necessary to compute `opening_fee`, they +> do define what the client is paying for with that fee. + +The LSP, when ordering the `opening_fee_params_menu` array, MUST order by +the following rules: + +* The 0th item MAY have any parameters. +* Each succeeding item MUST, compared to the previous item: + * Have a larger `min_fee_msat`, and equal `proportional`. + * Have a larger `proportional`, and equal `min_fee_msat`. + * Have a larger `min_fee_msat`, AND larger `proportional`. + +> **Rationale** This simplifies how the client expresses the expected +> opening fee to the user, as it assures the client that the order of +> the feerates is strictly increasing. + +The LSP, when generating the `promise` field: + +* SHOULD use a cryptographically-verifiable method of generating + `promise`, such as a MAC of some deterministic serialization of the + other `opening_fee_params` keys, then encoded in hexadecimal, base64, + or other text encoding. + The specific requirements are: + * Verifiable - the LSP must be able to verify that it issued the + `promise` before. + It does not have to be third-party-verifiable (i.e. it is OK + if only the LSP can do this verification using private information + only the LSP knows). + * Unforgeable - only the LSP can generate the `promise`. + Knowledge of the `promise` for one set of parameters should not + allow anyone else to generate the `promise` for a different set + of parameters. + * Committing - the `promise` commits to a specific set of parameters; + if any of the parameters is changed, the `promise` validation would + fail. +* MUST ensure the promise is no longer than 512 bytes (not including the + `"` delimiters) when encoded as a UTF8-encoded JSON string. +* MUST avoid characters outside of the printable ASCII range. +* MUST avoid characters that would require escapes in JSON format. + +> **Rationale** The method to generate `promise` is left vague in order +> to allow LSP implementors the flexibility to structure their code +> as necessary. +> The above specification suggests the use of any MAC, which would cover +> the above requirements, and requires a symmetric key known only by +> the LSP. +> Alternately, an LSP might be componentized and use private-public +> key cryptography, with a signature as the `promise`, so that the +> component that generates `opening_fee_params` objects is the only +> one with access to a specific private key, while the rest of the LSP, +> including the `lsps2.buy` component, only knows the public key. +> Another alternative for a componentized LSP would be to have the +> `opening_fee_params` generator know the public key of the +> `opening_fee_params` validator; the generator creates an ephemeral +> keypair and uses the ephemeral privkey with the validator pubkey +> in a Diffie-Hellman scheme to create a session key for a MAC, then +> concatenate the ephemeral pubkey with the MAC as the `promise`; the +> validator takes its private key and uses it with the ephemeral pubkey +> in a Diffie-Hellman scheme to regenerate the same session key and +> validates the MAC. + +Clients, when reading the `promise` feild: + +* MUST abort this flow if `promise` exceeds 512 bytes (not including the + `"` delimiters) when encoded as a UTF8-encoded JSON string. +* MUST NOT parse or interpret this string, and only provide it + verbatim later. + +> **Rationale** By using a promise that must be remembered by the +> client, the LSP does not have to remember what it offered via this +> API, reducing state storage, especially if the client then decides +> that the resulting `opening_fee` is too high and ultimately decides +> not to continue this flow. +> By using a cryptographically-verifiable method, the LSP can ensure +> that it will only honour `opening_fee_params` it actually offered. +> A size limit is imposed so that LSPs cannot burden clients with +> unreasonable storage requirements. + +LSPs MUST NOT add any other fields to an `opening_fee_params` object. + +Clients MUST fail and abort the flow if a `opening_fee_params` +object has unrecognized fields. + +> **Rationale** If additional fields are deemed necessary for a +> future version of this specification, then the `version` should +> be increased, and a new schema defined for the later `version`. +> +> Clients that expect this `version` of LSPS2 will compute the +> `opening_fee` in the manner indicated in this specification, and +> any additional fields may imply an extension that may mislead +> the client into computing the wrong `opening_fee`. +> +> If the LSP wants to include other information in the +> `opening_fee_params`, and that information does not affect how +> the `opening_fee` is calculated, then the LSP can actually just +> embed this information in the `promise`; the LSP can also commit +> to that additional information in the MAC or signature or whatever +> cryptographic construct it uses to validate, and the length of +> the `promise` can be used to determine whether this information +> exists or not, and the LSP can cut the added information in this +> `promise` from the cryptographic commitment. + +`min_payment_size_msat` and `max_payment_size_msat` are the limits of the +payment size, inclusive. +These are strings containing decimal numbers, in millisatoshis. +The payment size is the amount that the payer will send to the +client, not including the forwarding fees of nodes along the way. + +The client now takes the `opening_fee_params` and the expected +`payment_size_msat`, to compute the `opening_fee`, and determine if the +resulting `opening_fee` is reasonable. + +#### Computing The `opening_fee` + +For a given `payment_size_msat` (in millisatoshis) and a selected +`opening_fee_params` object, both client and LSP MUST compute the +`opening_fee` (in millisatoshis) as follows: + + opening_fee = ((payment_size_msat * proportional) + 999999) / 10000000 + if opening_fee < min_fee_msat: + opening_fee = min_fee_msat + +* All numbers MUST be computed in unsigned 64-bit integers. + * Clients and LSPs MAY use arbitarry-precision integers, such as + Haskell `Integer` type or bignums in Lisplike languages, IF AND + ONLY IF they check for overflow of unsigned 64-bit at each basic + arithmetic operation. +* Integer division MUST round down; the `+ 9999999` causes this to + round up. +* Arithmetic overflow MUST cause the computation to fail and abort + this flow (the client SHOULD report the failure to the user, the + LSP SHOULD error the client request in the next step). + * Unsigned integer division cannot overflow. + * Addition overflow can be detected by comparing the sum to an + addend: + if the sum is less than one addend, overflow has occurred and + the flow must be aborted. + * Multiplication overflow can be detected by checking that the + first factor is nonzero, and dividing the product by the first + factor does not result in the second factor. + * The check MUST be done on EACH addition and multiplication + operation, including those with constants. + +The C routine `compute_opening_fee` below performs the computation, +and indicates an error (returns `-1`) and sets `errno` if the +computation fails, otherwise returns `0` on success. + +```C +#include +#include + +static inline int +ov_add (uint64_t *sum, uint64_t a, uint64_t b) { + *sum = a + b; + if (*sum < a) + { + errno = EDOM; + return -1; + } + return 0; +} +static inline int +ov_mul (uint64_t *prod, uint64_t a, uint64_t b) { + *prod = a * b; + if ((a != 0) && ((*prod / a) != b)) + { + errno = EDOM; + return -1; + } + return 0; +} + +int +compute_opening_fee(uint64_t* opening_fee, uint64_t payment_size_msat, + uinr64_t opening_fee_min_fee_msat, + uint64_t opening_fee_proportional) { + uint64_t tmp; + if (0 != ov_mul (&tmp, payment_size_msat, opening_fee_proportional)) + return -1; + if (0 != ov_add (&tmp, tmp, 999999)) + return -1; + /* C specifies division rounds towards 0. */ + tmp = tmp / 1000000; + *opening_fee = tmp; + if (*opening_fee < opening_fee_min_fee_msat) + *opening_fee = opening_fee_min_fee_msat; + return 0; +} +``` + +Below is a similar implementation in Rust, with overflow errors +signalled as `None`: + +```rust +fn compute_opening_fee(payment_size_msat: u64, + opening_fee_min_fee_msat: u64, + opening_fee_proportional: u64) -> Option { + let t1 = payment_size_msat.checked_mul(opening_fee_proportional)?; + let t2 = t1.checked_add(999999)?; + let t3 = t2.checked_div(1000000)?; + let t4 = std::cmp::max(t3, opening_fee_min_fee_msat); + Some(t4) +} +``` + +> **Rationale** The computation is described in excruciating detail +> in order to ensure that both LSP and client agree on the result +> of computation of the `opening_fee`. +> In C, signed integer overflow is undefined behavior, and even if +> neither LSP nor client is written in C, they may be written in a +> language whose implementation is an interpreter written in C or +> using C libraries, which may also trigger the same undefined +> behavior on signed integer overflow, thus unsigned integers are +> specified, which, in C, are specifically modulo 2 to the number +> of bits. +> Arithmetic overflow is problematic and may lead to unexpectedly +> low `opening_fee` charges for high `payment_size_msat` and high +> `opening_fee_params.proportional`, thus must be specifically +> detected and cause an abort in this flow rather than continue +> and cause problems for the LSP. +> Most modern microprocessors have dedicated instructions to detect +> overflow, and most modern compilers can recognize the above code +> and optimize those down to these dedicated instructions at high +> optimization settings; in particular, the division in the +> overflow-detecting multiplication routine is optimized away +> and replaced with a simple overflow-flag check. + +### 2. Request JIT Channel + +The client constructs a request body for a `lsps2.buy` request, +depending on their need. + +The client is identified by the LSP from the BOLT8 connection +that this LSPS API is used on, which identifies and authenticates +the client node ID (also known as client identity public key). +The LSP identifies the client as "connected" if there is a BOLT8 +tunnel that has been identified as having the same peer as the +client node ID. + +Example `lsps2.buy` request parameters: + +```JSON +{ + "version": 1, + "opening_fee_params": { + "base_msat": "546000", + "proportional": 1200, + "valid_until": "2023-02-23T08:47:30.511Z", + "min_lifetime": 1008, + "max_client_to_self_delay": 2016, + "promise": "abcdefghijklmnopqrstuvwxyz" + }, + "payment_size_msat": "42000" +} +``` + +`version` is the version of this spec that will be used for this +interaction. + +`opening_fee_params` is the object acquired from the previous +step. +Clients MUST copy it verbatim from an entry of `opening_fee_params_menu` +from a result of a `lsps2.getinfo` call. +LSPs MUST check that the `opening_fee_params.promise` does in fact +prove that it previously promised the specified `opening_fee_params`. +LSPs MUST check that the `opening_fee_params.valid_until` is not a +past datetime. + +`payment_size_msat` is an *optional* amount denominated in millisatoshis +that the client wants to receive: + +* If the client wants to issue a variable-amount invoice ("0-amount + invoice") the client MUST leave out this parameter, but MUST indicate + to the payer to **NOT** use multipath payments. + * "no-MPP+var-invoice" mode. +* If the client wants to issue a fixed-amount invoice, the client + SHOULD provide this parameter, and if it does, MAY indicate to the + payer to **USE** multipath payments. + * "MPP+fixed-invoice" mode. + +The client MUST ensure that `payment_size_msat` is within the previous +`min_payment_size_msat` and `max_payment_size_msat` parameters from the LSP. +The LSP MUST validate that the `payment_size_msat` is within the previous +`min_payment_size_msat` and `max_payment_size_msat` parameters from the LSP. + +If the `payment_size_msat` is specified in the request, the LSP: + +* MUST compute the `opening_fee` and check that the computation + did not hit an overflow failure. + * MUST check that the resulting `opening_fee` is strictly less + than the `payment_size_msat`. +* SHOULD check that it has sufficient incoming liquidity from the + public network to be able to receive at least `payment_size_msat`, + if it was specified. + +The following errors are specified for `lsps2.buy`: + +* `unsupported_version` (1) - the LSP does not support the + specified `version`. +* `invalid_opening_fee_params` (2) - the `valid_until` field + of the `opening_fee_params` is already past, **OR** the `promise` + did not match the parameters. +* `payment_size_too_small` (3) - the `payment_size_msat` was specified, + and the resulting `opening_fee` is equal or greater than the + `payment_size_msat`. +* `payment_size_too_large` (4) - the `payment_size_msat` was specified, + and the LSP hit an overflow error while calculating the + `opening_fee`, **OR** the LSP has insufficient incoming liquidity + from the public network to receive the `payment_size_msat`. + +If there were no errors, the LSP then provides a normal +result to the `lsps2.buy` API. + +Example successful `lsps2.buy` result: + +```JSON +{ + "jit_channel_scid": "1x4815x29451", + "lsp_cltv_expiry_delta" : 144, + "client_trusts_lsp": false +} +``` + +`jit_channel_scid` is the SCID to use for creating the routehint in +the invoice, and `lsp_cltv_expiry_delta` is the CLTV delta for that +routehint hop. + +`client_trusts_lsp` is an *optional* Boolean. +If not specified, it defaults to `false`. +If specified and `true`, the client MUST trust the LSP to actually +create and confirm a valid channel funding transaction. + +The client MAY abort the flow if the LSP specified `client_trusts_lsp` +as `true` in the result. + +### 3. Invoice Generation + +The client MAY then generate a [BOLT11][] invoice. + +[BOLT11]: https://github.com/lightning/bolts/blob/f7dcc32694b8cd4f3a1768b904f58cb177168f29/11-payment-encoding.md + +If the client generates a BOLT11 invoice, the client MUST set +the following: + +* The sum of `timestamp` and `x`/`expiry` fields is equal to + or less than `opening_fee_params.valid_until`. +* `n` is the client node ID, or any public key whose private + key the client knows. +* `r` contains a single routehint with a single hop: + * `pubkey` is the LSP public node ID. + * `short_channel_id` is the `jit_channel_scid`. + * `fee_base_msat` and `fee_proportional_millionths` are 0. + * `cltv_expiry_delta` is `lsp_cltv_expiry_delta`. +* `c` contains a `min_final_cltv_expiry_delta` that is at least + +2 higher than its normal setting. + * The client MUST impose its normal setting on actual received + payment. + For example, suppose the client normally uses a + `min_final_cltv_expiry_delta` of 144. + For a JIT Channels invoice, it sets it to 146 in the invoice, + but only still expects 144 when the payment reaches it + even for JIT Channels invoices. +* Depending on if the client specified a `payment_size_msat` in + the previous `lsps2.buy` call: + * If `payment_size_msat` specified ("MPP+fixed-invoice" mode), + set the invoice amount to `payment_size_msat` and enable + the `basic_mpp` feature. + * If `payment_size_msat` unspecified ("no-MPP+var-invoice" mode), + do not specify an invoice amount, and disable the + `basic_mpp` feature. + +All other fields are to be filled in by the client. + +> **Rationale** In-Lightning feerates can be folded into the +> `opening_fee` for the initial payment. +> The channel is not open yet, thus the client cannot know +> what the actual feerates the LSP would impose at the time +> this invoice is generated, so it must be fixed at this +> point. +> Multipart payments are specifically disallowed, as the +> total amount of a multipart payment is encrypted in the +> onion such that only the rceiver (the client) can decode +> it, and the LSP cannot thus determine what the total amount +> from the payer would be. +> By forcing a non-multipart payment, the LSP can treat the +> first arriving HTLC to be forwarded to the `jit_channel_scid` +> as the total payment. +> +> Bitcoin blocks may be mined at any time. +> When a payer sends out a payment, it must "lock in" a specific +> blockheight for the timeout of the HTLC arriving to the client, +> but if a block is mined between when the payer sends out the +> payment and when the client receives it, then the timeout may +> now be below the normal `min_final_cltv_expiry_delta` of the +> client. +> BOLT requires that the payee fail this with +> `incorrect_or_unknown_payment_details` with a `height` indicating +> the new current blockheight, but the LSP cannot differentiate +> between this failure (which would cause the payer to retry with +> renewed timeouts), versus a deliberate attempt by the payer +> and client to waste LSP resources (which should cause the LSP to +> deny future service to this client). +> By adding a small +2 margin here, we greatly reduce the incidence +> of such an accident. + +#### Forward Compatibility With Post-BOLT11 Payment Schemes + +Ultimately, the client MUST provide the information below to +the payer: + +* The client node ID (or any public key whose private key the + client knows). +* The `jit_channel_scid`. +* The LSP node ID. +* The `lsp_cltv_expiry_delta`. +* The expiry for the payment. +* Whether it can use MPP or not. + +However, the client MAY provide this information to the payer +by means other than BOLT11 invoice, including in a form that +is not decodable by the payer, but which can be decoded by +another LN participant. + +The only necessary requirement is for the LSP to see an incoming +HTLC onion that indicates the `jit_channel_scid` as the next hop, +and as long as the client is able to cause the payer to do this, +it is would be compatible with this protocol. + +> **Non-normative** For example, the client node ID, the +> `jit_channel_scid`, the LSP node ID, and the +> `lsp_cltv_expiry_delta` can be encoded as the last hop of +> a blinded path, for example in a BOLT12 offer or invoice. +> The payer would not have direct access to the information, +> but the introduction point of the blinded path would be able +> to start the decoding of the blinded path. + +### 4. Payment + +The client MAY issue the generated invoice to the payer of the +client, or equivalently inform the payer of the necessary +information. + +The payer can then generate an outgoing payment part to +deliver the paid amount to the LSP. +If the client selected "MPP+fixed-invoice" mode, the payer can +generate multiple outgoing payments parts. + +In "MPP+fixed-invoice" mode, the LSP, if it receives a forward +where the next hop is `jit_channel_scid`: + +* SHOULD wait for payment parts of a single payment hash until all + parts sum up to at least `payment_size_msat`. +* MUST NOT fail with `mpp_timeout`, as the final hop is the client + and that error is only allowed at the final hop. +* MUST fail with `unknown_next_peer` if all parts have **NOT** + summed up to at least `payment_size_msat` **AND** + `opening_fee_params.valid_until` has passed. +* MAY fail with `unknown_next_peer` if it receives too many payment + parts. +* When all conditions below are true, MUST continue to the next + step: + * The current time is strictly less than + `opening_fee_params.valid_until`. + * All received payment parts sum up to at least `payment_size_msat` + plus `opening_fee`. + * The client is connected. + +In "no-MPP+var-invoice" mode, the LSP, if it receives a forward +where the next hop is `jit_channel_scid`, before +`opening_fee_params.valid_until`: + +* MUST set `payment_size_msat` as the forwarded value of the HTLC. +* MUST compute the `opening_fee` based on the `payment_size_msat`, and + if the computation overflows, MUST fail with `unknown_next_peer`. +* MUST check that `opening_fee + htlc_minimum_msat < payment_size_msat`, + and if that fails, MUST fail with `unknown_next_peer`. + +### 5. Channel Opening And Forwarding + +The LSP requests a channel open to the client. + +The LSP selects the channel size. +The LSP MUST ensure the channel is large enough to transmit the +`payment_size_msat - opening_fee`, plus any reserve needed on the LSP +side. + +The LSP and client MUST negotiate these options and parameters: + +* `option_zeroconf` is set. +* `option_scid_alias` is set. +* `announce_channel` is `false`. +* The client-provided `to_self_delay` is less than or equal to + the agreed-upon `max_client_to_self_delay`. + +> **Rationale** `option_zeroconf` is set so that the payment can +> be immediately forwarded to the client and resolved as soon as +> the opening negotiation completes; if the client and LSP had to +> wait for confirmation, the incoming payment would have to be +> locked for an extended period, which is indistinguishable from +> a channel jamming attack. +> `option_zeroconf` cannot be set unless `announce_channel` is +> `false`. +> `option_scid_alias` needs to be set so that the channel can be +> referred to on future invoices before the channel confirms. +> +> Future versions of this API may be able to utilize Asynchronous +> Receive (currently being developed as of this version) to +> be able to get around the `option_zeroconf` requirement, by +> treating the receiver / client as offline until the client is +> online *and* the JIT channel to it is deeply confirmed, if the +> LSP and client negotiate a non-`option_zeroconf` channel for +> the JIT channel. +> A non-`option_zeroconf` JIT channel could also be later +> published with `announce_channel = true`. + +Clients MAY reject the channel open attempt if any other +parameters or options are not desired by the client (for example, +it MAY reject non-zero channel reserve requirements imposed on +the client by the LSP). +Rejection is via the `error` Lightning BOLT message. + +LSPs MUST fail the payment with `unknown_next_peer` in case the +client rejects the channel open via an `error`. + +If the client disconnects before the LSP can receive `funding_signed` +from the client, the LSP MUST fail the incoming payment parts with +`temporary_channel_failure`, then return to the previous step (waiting +for payment). + +> **Rationale** The client might have crashed at this point, and +> recovery might take an inordinate amount of time. +> However, use of the `temporary_channel_failure` error informs the +> payer that the error is temporary and it can retry later, if the +> client is online at that point. +> +> Client disconnection will prevent the LSP from broadcasting the +> funding transaction and the LSP may re-allocate the UTXOs spent +> in the funding transaction for a different payment. +> Thus, the correct behavior is to abort the payment, so that the +> LSP funds may be re-used in a new channel to the same client if +> the payer retries, or so that the LSP funds may be re-used for a +> different client if the payer gives up on paying the client. + +Clients MUST NOT expect that `jit_channel_scid` is the same as +the `alias` SCID. +Clients MUST NOT expect that `jit_channel_scid` is different from +the `alias` SCID. + +Depending on the `client_trusts_lsp` from the `lsps2.buy` result, +after the client has sent `funding_signed`: + +* If `client_trusts_lsp` is specified and `true`: + * The LSP MAY wait for the client to send the preimage to the + incoming payment via a `update_fulfill_htlc` before broadcasting + the funding transaction. + * If the LSP supports [LSPS3][]. the LSP MUST fail a + `lsps3.getpromise` call of the channel funding transaction with + the error `conditions_apply`. + * The client MUST NOT wait for the LSP to broadcast the funding + transaction before sending the preimage via a + `update_fulfill_htlc`. + * The client and LSP MUST immediately send `channel_ready`. +* If `client_trusts_lsp` is unspecified or `false`: + * The client MAY wait for the funding transaction to appear in + its mempool or the mempool of a trusted node, or confirmed in a + block, before sending `channel_ready`. + * If the LSP supports [LSPS3][], the LSP MUST succeed the + `lsps3.getpromise` call of the channel funding transaction. + * If the LSP supports [LSPS3][], the client MAY call the + `lsps3.getpromise` API on the channel funding transaction, + and MAY wait for a response to that call before sending + `channel_ready`. + * The LSP MUST immediately broadcast the channel funding + transaction and send `channel_ready`. + * The client MAY immediately send `channel_ready` (i.e. the + client trusts the LSP, even though the LSP does not require + that trust). + +As soon as both client and LSP have sent `channel_ready` for the +new channel, the LSP then forwards payment parts to the client. +In "no-MPP+var-invoice" mode there is only one payment part. + +The LSP generates non-standard forwards, where the amount received +by the client is smaller than specified in the onion; +the client MUST accept the non-standard forward(s), provided they +sum to at least `payment_size_msat - opening_fee`. + +The LSP MUST ensure that each forwarded part forwards at least +`htlc_minimum_msat` millisatoshis. +The LSP MUST ensure that all parts forwarded sum up to at least +`payment_size_msat - opening_fee`. + +For example, the LSP can use the algorithm below to determine +how much to forward for each incoming payment part, while ensuring +that both the above properties are preserved. + +* Put the payment parts in an array in arbitrary order. +* For each part: + * Get the `part_amount`, the incoming amount for the part. + * If `part_amount - htlc_minimum_msat >= opening_fee`, then forward + `part_amount - opening_fee` for this part, then forward + the rest of the parts verbatim, if any. + * Else subtract `opening_fee = opening_fee - (part_amount - htlc_minimum_msat)`, + then forward `htlc_minimum_msat` for this part. +* The above loop will not reach past the last part unless + the number of parts times `htlc_minimum_msat` exceeds the + `payment_size_msat`. + This case should be checked beforehand and cause the payment + to be failed due to too many payment parts. + +Once the client has received payment parts that sum up to at +least `payment_size_msat`, it MUST claim at least one payment part. +Once that is done, the protocol flow is considered complete. + +The parts that the client receives are non-standard, as the amount +in the onion would not be the same as the amount sent by the LSP. +Clients MUST suppress such checks for parts it recognizes as having +been received to pay for a JIT Channel open. +Clients would need some mechanism to recognize such payments, such as +by flagging such payments in its invoice database, putting such +payments in a separate invoice database, or adding special flags inside +the `metadata` or `payment_secret` of the invoice, or by changing how +`payment_secret` is computed based on whether the invoice is to pay for +a JIT Channel or not and trying both ways. + +### 6. Post-opening Normal Operation + +After the channel has been opened and an `alias` has been specified, +the client MUST use the `alias` for future invoices on the +channel, as normal for users of zero-confirmation channels. +Note that use of `alias` forces the `alias` to always be used, even +after the channel is confirmed. + +Invoices issued after the channel open MUST use the feerates +negotiated for the new channel. + +> **Rationale** While it is desirable that the client would be able +> to issue multiple invoices before the channel is opened, this may +> require that the `alias` be identical to the `jit_channel_scid`, +> which might not be feasible under some setups. +> In particular, `jit_channel_scid` may be stored in a database that +> has strict time limits from the `opening_fee_params.valid_until`, +> while the `alias` SCID would remain valid while the channel is +> open. +> In addition, the "normal" Lightning base and proportional channel +> fees would need to be applied to the initial payment(s). +> This version of this API therefore requires that the client first +> be paid once via the `jit_channel_scid` before it can be issue +> further invoices with the `alias`. +> +> Future versions of this API may allow for more flexibility on the +> client side, including support for variable-amount invoices, +> multiple incoming payments being stalled until the `opening_fee` +> is achieved and the channel can be opened, and so on. + +LSPs MUST consider the `jit_channel_scid` as yet another alias +for the specified client, up to until the `valid_until` time +selected. +LSPs MUST consider this alias not just for forwarded payments, but +also for onion messages. diff --git a/README.md b/README.md index 43d4821..b0a7f33 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,8 @@ Describes the basics of how clients and LSPs communicate to each other. ### **LSPS.1** [Channel Request](channel-request.md) A unified channel request API standard for services to buy channels from LSP. This spec supports both just in time channel openings and pre paid channels - +### **LSPS2** [JIT Channels](LSPS2/README.md) +Describes how a client can buy channels from an LSP, by paying via a deduction from their incoming payments, creating a channel just-in-time to receive the incoming payment. ## Services List of Lightning Service Providers in alphabetic order that currently or will support LSP specs in future.