mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-03-03 18:57:06 +01:00
Makefile: update to latest BOLT text.
In particular: - Bolt 4: add route blinding construction - Bolt 4: add blinded payments And this means it's not experimental, so we can turn it on by default! Signed-off-by: Rusty Russell <rusty@rustcorp.com.au> Changelog-Added: Protocol: blinded payments are now supported by default (not just with `--experimental-onion-messages`)
This commit is contained in:
parent
458a85042b
commit
d4ffc75691
13 changed files with 58 additions and 105 deletions
2
Makefile
2
Makefile
|
@ -23,7 +23,7 @@ CCANDIR := ccan
|
||||||
|
|
||||||
# Where we keep the BOLT RFCs
|
# Where we keep the BOLT RFCs
|
||||||
BOLTDIR := ../bolts/
|
BOLTDIR := ../bolts/
|
||||||
DEFAULT_BOLTVERSION := 20066dc2aba906f37f3be5a810ae67040f265377
|
DEFAULT_BOLTVERSION := c4c5a8e5fb30b1b99fa5bb0aba7d0b6b4c831ee5
|
||||||
# Can be overridden on cmdline.
|
# Can be overridden on cmdline.
|
||||||
BOLTVERSION := $(DEFAULT_BOLTVERSION)
|
BOLTVERSION := $(DEFAULT_BOLTVERSION)
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,7 @@ static bool blind_node(const struct privkey *blinding,
|
||||||
SUPERVERBOSE("\t\"blinded_node_id\": \"%s\",\n",
|
SUPERVERBOSE("\t\"blinded_node_id\": \"%s\",\n",
|
||||||
type_to_string(tmpctx, struct pubkey, node_alias));
|
type_to_string(tmpctx, struct pubkey, node_alias));
|
||||||
|
|
||||||
/* BOLT-route-blinding #4:
|
/* BOLT #4:
|
||||||
* - `E(i+1) = SHA256(E(i) || ss(i)) * E(i)`
|
* - `E(i+1) = SHA256(E(i) || ss(i)) * E(i)`
|
||||||
* (NB: `N(i)` MUST NOT learn `e(i)`)
|
* (NB: `N(i)` MUST NOT learn `e(i)`)
|
||||||
*/
|
*/
|
||||||
|
@ -36,7 +36,7 @@ static bool blind_node(const struct privkey *blinding,
|
||||||
SUPERVERBOSE("\t\"E\": \"%s\",\n",
|
SUPERVERBOSE("\t\"E\": \"%s\",\n",
|
||||||
type_to_string(tmpctx, struct pubkey, &blinding_pubkey));
|
type_to_string(tmpctx, struct pubkey, &blinding_pubkey));
|
||||||
|
|
||||||
/* BOLT-route-blinding #4:
|
/* BOLT #4:
|
||||||
* - `e(i+1) = SHA256(E(i) || ss(i)) * e(i)`
|
* - `e(i+1) = SHA256(E(i) || ss(i)) * e(i)`
|
||||||
* (blinding ephemeral private key, only known by `N(r)`)
|
* (blinding ephemeral private key, only known by `N(r)`)
|
||||||
*/
|
*/
|
||||||
|
@ -63,7 +63,7 @@ static u8 *enctlv_from_encmsg_raw(const tal_t *ctx,
|
||||||
/* All-zero npub */
|
/* All-zero npub */
|
||||||
static const unsigned char npub[crypto_aead_chacha20poly1305_ietf_NPUBBYTES];
|
static const unsigned char npub[crypto_aead_chacha20poly1305_ietf_NPUBBYTES];
|
||||||
|
|
||||||
/* BOLT-route-blinding #4:
|
/* BOLT #4:
|
||||||
* - `ss(i) = SHA256(e(i) * N(i)) = SHA256(k(i) * E(i))`
|
* - `ss(i) = SHA256(e(i) * N(i)) = SHA256(k(i) * E(i))`
|
||||||
* (ECDH shared secret known only by `N(r)` and `N(i)`)
|
* (ECDH shared secret known only by `N(r)` and `N(i)`)
|
||||||
*/
|
*/
|
||||||
|
@ -80,7 +80,7 @@ static u8 *enctlv_from_encmsg_raw(const tal_t *ctx,
|
||||||
|
|
||||||
ret = tal_dup_talarr(ctx, u8, raw_encmsg);
|
ret = tal_dup_talarr(ctx, u8, raw_encmsg);
|
||||||
|
|
||||||
/* BOLT-route-blinding #4:
|
/* BOLT #4:
|
||||||
* - `rho(i) = HMAC256("rho", ss(i))`
|
* - `rho(i) = HMAC256("rho", ss(i))`
|
||||||
* (key used to encrypt the payload for `N(i)` by `N(r)`)
|
* (key used to encrypt the payload for `N(i)` by `N(r)`)
|
||||||
*/
|
*/
|
||||||
|
@ -88,10 +88,10 @@ static u8 *enctlv_from_encmsg_raw(const tal_t *ctx,
|
||||||
SUPERVERBOSE("\t\"rho\": \"%s\",\n",
|
SUPERVERBOSE("\t\"rho\": \"%s\",\n",
|
||||||
type_to_string(tmpctx, struct secret, &rho));
|
type_to_string(tmpctx, struct secret, &rho));
|
||||||
|
|
||||||
/* BOLT-route-blinding #4:
|
/* BOLT #4:
|
||||||
* - MUST encrypt each `encrypted_data_tlv(i)` with ChaCha20-Poly1305
|
* - MUST encrypt each `encrypted_data_tlv(i)` with ChaCha20-Poly1305 using
|
||||||
* using the corresponding `rho(i)` key and an all-zero nonce to
|
* the corresponding `rho(i)` key and an all-zero nonce to produce
|
||||||
* produce `encrypted_recipient_data(i)`
|
* `encrypted_recipient_data(i)`
|
||||||
*/
|
*/
|
||||||
/* Encrypt in place */
|
/* Encrypt in place */
|
||||||
towire_pad(&ret, crypto_aead_chacha20poly1305_ietf_ABYTES);
|
towire_pad(&ret, crypto_aead_chacha20poly1305_ietf_ABYTES);
|
||||||
|
@ -132,7 +132,7 @@ bool unblind_onion(const struct pubkey *blinding,
|
||||||
{
|
{
|
||||||
struct secret hmac;
|
struct secret hmac;
|
||||||
|
|
||||||
/* BOLT-route-blinding #4:
|
/* BOLT #4:
|
||||||
* A reader:
|
* A reader:
|
||||||
*...
|
*...
|
||||||
* - MUST compute:
|
* - MUST compute:
|
||||||
|
@ -145,7 +145,7 @@ bool unblind_onion(const struct pubkey *blinding,
|
||||||
/* We instead tweak the *ephemeral* key from the onion and use
|
/* We instead tweak the *ephemeral* key from the onion and use
|
||||||
* our normal privkey: since hsmd knows only how to ECDH with
|
* our normal privkey: since hsmd knows only how to ECDH with
|
||||||
* our real key. IOW: */
|
* our real key. IOW: */
|
||||||
/* BOLT-route-blinding #4:
|
/* BOLT #4:
|
||||||
* - MUST use `b(i)` instead of its private key `k(i)` to decrypt the onion. Note
|
* - MUST use `b(i)` instead of its private key `k(i)` to decrypt the onion. Note
|
||||||
* that the node may instead tweak the onion ephemeral key with
|
* that the node may instead tweak the onion ephemeral key with
|
||||||
* `HMAC256("blinded_node_id", ss(i))` which achieves the same result.
|
* `HMAC256("blinded_node_id", ss(i))` which achieves the same result.
|
||||||
|
@ -165,7 +165,7 @@ static u8 *decrypt_encmsg_raw(const tal_t *ctx,
|
||||||
/* All-zero npub */
|
/* All-zero npub */
|
||||||
static const unsigned char npub[crypto_aead_chacha20poly1305_ietf_NPUBBYTES];
|
static const unsigned char npub[crypto_aead_chacha20poly1305_ietf_NPUBBYTES];
|
||||||
|
|
||||||
/* BOLT-route-blinding #4:
|
/* BOLT #4:
|
||||||
* A reader:
|
* A reader:
|
||||||
*...
|
*...
|
||||||
*- MUST decrypt the `encrypted_data` field using `rho(i)` and use
|
*- MUST decrypt the `encrypted_data` field using `rho(i)` and use
|
||||||
|
@ -222,7 +222,7 @@ bool blindedpath_get_alias(const struct secret *ss,
|
||||||
{
|
{
|
||||||
struct secret node_id_blinding;
|
struct secret node_id_blinding;
|
||||||
|
|
||||||
/* BOLT-route-blinding #4:
|
/* BOLT #4:
|
||||||
* - `B(i) = HMAC256("blinded_node_id", ss(i)) * N(i)`
|
* - `B(i) = HMAC256("blinded_node_id", ss(i)) * N(i)`
|
||||||
* (blinded `node_id` for `N(i)`, private key known only by `N(i)`)
|
* (blinded `node_id` for `N(i)`, private key known only by `N(i)`)
|
||||||
*/
|
*/
|
||||||
|
@ -242,13 +242,13 @@ void blindedpath_next_blinding(const struct tlv_encrypted_data_tlv *enc,
|
||||||
const struct secret *ss,
|
const struct secret *ss,
|
||||||
struct pubkey *next_blinding)
|
struct pubkey *next_blinding)
|
||||||
{
|
{
|
||||||
/* BOLT-route
|
/* BOLT #4:
|
||||||
* - `E(1) = SHA256(E(0) || ss(0)) * E(0)`
|
* - `E(i+1) = SHA256(E(i) || ss(i)) * E(i)`
|
||||||
* ...
|
* ...
|
||||||
* - If `encrypted_data` contains a `next_blinding_override`:
|
* - If `encrypted_data` contains a `next_blinding_override`:
|
||||||
* - MUST use it as the next blinding point instead of `E(1)`
|
* - MUST use it as the next blinding point instead of `E(i+1)`
|
||||||
* - Otherwise:
|
* - Otherwise:
|
||||||
* - MUST use `E(1)` as the next blinding point
|
* - MUST use `E(i+1)` as the next blinding point
|
||||||
*/
|
*/
|
||||||
if (enc->next_blinding_override)
|
if (enc->next_blinding_override)
|
||||||
*next_blinding = *enc->next_blinding_override;
|
*next_blinding = *enc->next_blinding_override;
|
||||||
|
|
|
@ -18,7 +18,7 @@ u8 **blinded_onion_hops(const tal_t *ctx,
|
||||||
bool first = (i == 0);
|
bool first = (i == 0);
|
||||||
bool final = (i == tal_count(onions) - 1);
|
bool final = (i == tal_count(onions) - 1);
|
||||||
|
|
||||||
/* BOLT-route-blinding #4:
|
/* BOLT-blinded-payments #4:
|
||||||
* - For every node inside a blinded route:
|
* - For every node inside a blinded route:
|
||||||
* - MUST include the `encrypted_recipient_data` provided by the
|
* - MUST include the `encrypted_recipient_data` provided by the
|
||||||
* recipient
|
* recipient
|
||||||
|
|
|
@ -174,7 +174,7 @@ static const struct dependency feature_deps[] = {
|
||||||
* `option_anchors_zero_fee_htlc_tx` | ... | ... | `option_static_remotekey`
|
* `option_anchors_zero_fee_htlc_tx` | ... | ... | `option_static_remotekey`
|
||||||
*/
|
*/
|
||||||
{ OPT_ANCHORS_ZERO_FEE_HTLC_TX, OPT_STATIC_REMOTEKEY },
|
{ OPT_ANCHORS_ZERO_FEE_HTLC_TX, OPT_STATIC_REMOTEKEY },
|
||||||
/* BOLT-route-blinding #9:
|
/* BOLT #9:
|
||||||
* Name | Description | Context | Dependencies |
|
* Name | Description | Context | Dependencies |
|
||||||
* ...
|
* ...
|
||||||
* `option_route_blinding` | ... | ... | `var_onion_optin`
|
* `option_route_blinding` | ... | ... | `var_onion_optin`
|
||||||
|
|
|
@ -114,6 +114,7 @@ struct feature_set *feature_set_dup(const tal_t *ctx,
|
||||||
* | 18/19 | `option_support_large_channel` |... IN ...
|
* | 18/19 | `option_support_large_channel` |... IN ...
|
||||||
* | 20/21 | `option_anchor_outputs` |... IN ...
|
* | 20/21 | `option_anchor_outputs` |... IN ...
|
||||||
* | 22/23 | `option_anchors_zero_fee_htlc_tx` |... IN ...
|
* | 22/23 | `option_anchors_zero_fee_htlc_tx` |... IN ...
|
||||||
|
* | 24/25 | `option_route_blinding` |...IN9 ...
|
||||||
* | 26/27 | `option_shutdown_anysegwit` |... IN ...
|
* | 26/27 | `option_shutdown_anysegwit` |... IN ...
|
||||||
* | 44/45 | `option_channel_type` |... IN ...
|
* | 44/45 | `option_channel_type` |... IN ...
|
||||||
* | 48/49 | `option_payment_metadata` |... 9 ...
|
* | 48/49 | `option_payment_metadata` |... 9 ...
|
||||||
|
@ -130,15 +131,11 @@ struct feature_set *feature_set_dup(const tal_t *ctx,
|
||||||
#define OPT_LARGE_CHANNELS 18
|
#define OPT_LARGE_CHANNELS 18
|
||||||
#define OPT_ANCHOR_OUTPUTS 20
|
#define OPT_ANCHOR_OUTPUTS 20
|
||||||
#define OPT_ANCHORS_ZERO_FEE_HTLC_TX 22
|
#define OPT_ANCHORS_ZERO_FEE_HTLC_TX 22
|
||||||
|
#define OPT_ROUTE_BLINDING 24
|
||||||
#define OPT_SHUTDOWN_ANYSEGWIT 26
|
#define OPT_SHUTDOWN_ANYSEGWIT 26
|
||||||
#define OPT_CHANNEL_TYPE 44
|
#define OPT_CHANNEL_TYPE 44
|
||||||
#define OPT_PAYMENT_METADATA 48
|
#define OPT_PAYMENT_METADATA 48
|
||||||
|
|
||||||
/* BOLT-route-blinding #9:
|
|
||||||
* | 24/25 | `option_route_blinding` | Node supports blinded paths | IN9 | `var_onion_optin` | ...
|
|
||||||
*/
|
|
||||||
#define OPT_ROUTE_BLINDING 24
|
|
||||||
|
|
||||||
/* BOLT-f53ca2301232db780843e894f55d95d512f297f9 #9:
|
/* BOLT-f53ca2301232db780843e894f55d95d512f297f9 #9:
|
||||||
* | 28/29 | `option_dual_fund` | ... IN9 ...
|
* | 28/29 | `option_dual_fund` | ... IN9 ...
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
#include <common/sphinx.h>
|
#include <common/sphinx.h>
|
||||||
#include <sodium/crypto_aead_chacha20poly1305.h>
|
#include <sodium/crypto_aead_chacha20poly1305.h>
|
||||||
|
|
||||||
/* BOLT-route-blinding #4:
|
/* BOLT #4:
|
||||||
* - If `encrypted_recipient_data` is present:
|
* - If `encrypted_recipient_data` is present:
|
||||||
*...
|
*...
|
||||||
* - If it is not the final node:
|
* - If it is not the final node:
|
||||||
|
@ -31,7 +31,7 @@ static bool check_nonfinal_tlv(const struct tlv_payload *tlv,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* BOLT-route-blinding #4:
|
/* BOLT #4:
|
||||||
* - If `encrypted_recipient_data` is present:
|
* - If `encrypted_recipient_data` is present:
|
||||||
*...
|
*...
|
||||||
* - If it is the final node:
|
* - If it is the final node:
|
||||||
|
@ -74,7 +74,7 @@ static bool handle_blinded_forward(struct onion_payload *p,
|
||||||
if (!check_nonfinal_tlv(tlv, failtlvtype))
|
if (!check_nonfinal_tlv(tlv, failtlvtype))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
/* BOLT-route-blinding #4:
|
/* BOLT #4:
|
||||||
* - If it is not the final node:
|
* - If it is not the final node:
|
||||||
*...
|
*...
|
||||||
* - MUST return an error if `encrypted_recipient_data` does not
|
* - MUST return an error if `encrypted_recipient_data` does not
|
||||||
|
@ -97,7 +97,7 @@ static bool handle_blinded_forward(struct onion_payload *p,
|
||||||
|
|
||||||
p->total_msat = NULL;
|
p->total_msat = NULL;
|
||||||
|
|
||||||
/* BOLT-route-blinding #4:
|
/* BOLT #4:
|
||||||
* - If it is not the final node:
|
* - If it is not the final node:
|
||||||
*...
|
*...
|
||||||
* - MUST return an error if `encrypted_recipient_data` does not
|
* - MUST return an error if `encrypted_recipient_data` does not
|
||||||
|
@ -125,7 +125,7 @@ static bool handle_blinded_terminal(struct onion_payload *p,
|
||||||
if (!check_final_tlv(tlv, failtlvtype))
|
if (!check_final_tlv(tlv, failtlvtype))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
/* BOLT-route-blinding #4:
|
/* BOLT #4:
|
||||||
* - MUST return an error if `amt_to_forward`, `outgoing_cltv_value`
|
* - MUST return an error if `amt_to_forward`, `outgoing_cltv_value`
|
||||||
* or `total_amount_msat` are not present.
|
* or `total_amount_msat` are not present.
|
||||||
* - MUST return an error if `amt_to_forward` is below what it expects
|
* - MUST return an error if `amt_to_forward` is below what it expects
|
||||||
|
@ -157,7 +157,7 @@ static bool handle_blinded_terminal(struct onion_payload *p,
|
||||||
*p->total_msat = amount_msat(*tlv->total_amount_msat);
|
*p->total_msat = amount_msat(*tlv->total_amount_msat);
|
||||||
} else {
|
} else {
|
||||||
/* BOLT #4:
|
/* BOLT #4:
|
||||||
* - if it is the final node:
|
* - If it is the final node:
|
||||||
* - MUST treat `total_msat` as if it were equal to
|
* - MUST treat `total_msat` as if it were equal to
|
||||||
* `amt_to_forward` if it is not present. */
|
* `amt_to_forward` if it is not present. */
|
||||||
p->total_msat = tal_dup(p, struct amount_msat,
|
p->total_msat = tal_dup(p, struct amount_msat,
|
||||||
|
@ -205,7 +205,7 @@ struct onion_payload *onion_decode(const tal_t *ctx,
|
||||||
return tal_free(p);
|
return tal_free(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* BOLT-route-blinding #4:
|
/* BOLT #4:
|
||||||
*
|
*
|
||||||
* The reader:
|
* The reader:
|
||||||
*
|
*
|
||||||
|
@ -220,7 +220,7 @@ struct onion_payload *onion_decode(const tal_t *ctx,
|
||||||
goto field_bad;
|
goto field_bad;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* BOLT-route-blinding #4:
|
/* BOLT #4:
|
||||||
*
|
*
|
||||||
* - If `blinding_point` is set in the incoming `update_add_htlc`:
|
* - If `blinding_point` is set in the incoming `update_add_htlc`:
|
||||||
* - MUST return an error if `current_blinding_point` is present.
|
* - MUST return an error if `current_blinding_point` is present.
|
||||||
|
@ -244,7 +244,7 @@ struct onion_payload *onion_decode(const tal_t *ctx,
|
||||||
p->tlv->blinding_point);
|
p->tlv->blinding_point);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* BOLT-route-blinding #4:
|
/* BOLT #4:
|
||||||
* The reader:
|
* The reader:
|
||||||
*...
|
*...
|
||||||
* - MUST return an error if `encrypted_recipient_data` does
|
* - MUST return an error if `encrypted_recipient_data` does
|
||||||
|
@ -260,7 +260,7 @@ struct onion_payload *onion_decode(const tal_t *ctx,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (enc->payment_constraints) {
|
if (enc->payment_constraints) {
|
||||||
/* BOLT-route-blinding #4:
|
/* BOLT #4:
|
||||||
* - MUST return an error if:
|
* - MUST return an error if:
|
||||||
* - the expiry is greater than
|
* - the expiry is greater than
|
||||||
* `encrypted_recipient_data.payment_constraints.max_cltv_expiry`.
|
* `encrypted_recipient_data.payment_constraints.max_cltv_expiry`.
|
||||||
|
@ -270,7 +270,7 @@ struct onion_payload *onion_decode(const tal_t *ctx,
|
||||||
goto field_bad;
|
goto field_bad;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* BOLT-route-blinding #4:
|
/* BOLT #4:
|
||||||
* - MUST return an error if:
|
* - MUST return an error if:
|
||||||
*...
|
*...
|
||||||
* - the amount is below
|
* - the amount is below
|
||||||
|
@ -282,8 +282,7 @@ struct onion_payload *onion_decode(const tal_t *ctx,
|
||||||
goto field_bad;
|
goto field_bad;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* BOLT-route-blinding #4:
|
/* BOLT #4:
|
||||||
* - If `allowed_features` is present:
|
|
||||||
* - MUST return an error if:
|
* - MUST return an error if:
|
||||||
*...
|
*...
|
||||||
* - the payment uses a feature not included in
|
* - the payment uses a feature not included in
|
||||||
|
@ -292,8 +291,10 @@ struct onion_payload *onion_decode(const tal_t *ctx,
|
||||||
/* We don't have any features yet... */
|
/* We don't have any features yet... */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* BOLT-route-blinding #4:
|
/* BOLT #4:
|
||||||
* - If `allowed_features` is present:
|
* - If `allowed_features` is missing:
|
||||||
|
* - MUST process the message as if it were present and contained an
|
||||||
|
* empty array.
|
||||||
* - MUST return an error if:
|
* - MUST return an error if:
|
||||||
* - `encrypted_recipient_data.allowed_features.features`
|
* - `encrypted_recipient_data.allowed_features.features`
|
||||||
* contains an unknown feature bit (even if it is odd).
|
* contains an unknown feature bit (even if it is odd).
|
||||||
|
@ -328,7 +329,7 @@ struct onion_payload *onion_decode(const tal_t *ctx,
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* BOLT-route-blinding-fix #4:
|
/* BOLT #4:
|
||||||
* - Otherwise (it is not part of a blinded route):
|
* - Otherwise (it is not part of a blinded route):
|
||||||
* - MUST return an error if `blinding_point` is set in the
|
* - MUST return an error if `blinding_point` is set in the
|
||||||
* incoming `update_add_htlc` or `current_blinding_point`
|
* incoming `update_add_htlc` or `current_blinding_point`
|
||||||
|
@ -341,7 +342,8 @@ struct onion_payload *onion_decode(const tal_t *ctx,
|
||||||
|
|
||||||
/* BOLT #4:
|
/* BOLT #4:
|
||||||
*
|
*
|
||||||
* The reader:
|
* - Otherwise (it is not part of a blinded route):
|
||||||
|
*...
|
||||||
* - MUST return an error if `amt_to_forward` or
|
* - MUST return an error if `amt_to_forward` or
|
||||||
* `outgoing_cltv_value` are not present.
|
* `outgoing_cltv_value` are not present.
|
||||||
*/
|
*/
|
||||||
|
@ -359,10 +361,9 @@ struct onion_payload *onion_decode(const tal_t *ctx,
|
||||||
|
|
||||||
/* BOLT #4:
|
/* BOLT #4:
|
||||||
*
|
*
|
||||||
* The writer:
|
* - if it is not the final node:
|
||||||
*...
|
* - MUST return an error if:
|
||||||
* - For every non-final node:
|
* - `short_channel_id` is not present,
|
||||||
* - MUST include `short_channel_id`
|
|
||||||
*/
|
*/
|
||||||
if (!p->final) {
|
if (!p->final) {
|
||||||
if (!p->tlv->short_channel_id) {
|
if (!p->tlv->short_channel_id) {
|
||||||
|
@ -375,7 +376,7 @@ struct onion_payload *onion_decode(const tal_t *ctx,
|
||||||
} else {
|
} else {
|
||||||
p->forward_channel = NULL;
|
p->forward_channel = NULL;
|
||||||
/* BOLT #4:
|
/* BOLT #4:
|
||||||
* - if it is the final node:
|
* - If it is the final node:
|
||||||
* - MUST treat `total_msat` as if it were equal to
|
* - MUST treat `total_msat` as if it were equal to
|
||||||
* `amt_to_forward` if it is not present. */
|
* `amt_to_forward` if it is not present. */
|
||||||
p->total_msat = tal_dup(p, struct amount_msat,
|
p->total_msat = tal_dup(p, struct amount_msat,
|
||||||
|
|
|
@ -45,8 +45,9 @@ u8 *onion_nonfinal_hop(const tal_t *ctx,
|
||||||
|
|
||||||
/* BOLT #4:
|
/* BOLT #4:
|
||||||
*
|
*
|
||||||
* The writer:
|
* The writer of `tlv_payload`:
|
||||||
* - For every node:
|
*...
|
||||||
|
* - For every node outside of a blinded route:
|
||||||
* - MUST include `amt_to_forward` and `outgoing_cltv_value`.
|
* - MUST include `amt_to_forward` and `outgoing_cltv_value`.
|
||||||
* - For every non-final node:
|
* - For every non-final node:
|
||||||
* - MUST include `short_channel_id`
|
* - MUST include `short_channel_id`
|
||||||
|
@ -74,8 +75,9 @@ u8 *onion_final_hop(const tal_t *ctx,
|
||||||
|
|
||||||
/* BOLT #4:
|
/* BOLT #4:
|
||||||
*
|
*
|
||||||
* The writer:
|
* The writer of `tlv_payload`:
|
||||||
* - For every node:
|
*...
|
||||||
|
* - For every node outside of a blinded route:
|
||||||
* - MUST include `amt_to_forward` and `outgoing_cltv_value`.
|
* - MUST include `amt_to_forward` and `outgoing_cltv_value`.
|
||||||
*...
|
*...
|
||||||
* - For the final node:
|
* - For the final node:
|
||||||
|
|
|
@ -858,6 +858,7 @@ static struct feature_set *default_features(const tal_t *ctx)
|
||||||
OPTIONAL_FEATURE(OPT_SCID_ALIAS),
|
OPTIONAL_FEATURE(OPT_SCID_ALIAS),
|
||||||
OPTIONAL_FEATURE(OPT_ZEROCONF),
|
OPTIONAL_FEATURE(OPT_ZEROCONF),
|
||||||
OPTIONAL_FEATURE(OPT_CHANNEL_TYPE),
|
OPTIONAL_FEATURE(OPT_CHANNEL_TYPE),
|
||||||
|
OPTIONAL_FEATURE(OPT_ROUTE_BLINDING),
|
||||||
#if EXPERIMENTAL_FEATURES
|
#if EXPERIMENTAL_FEATURES
|
||||||
OPTIONAL_FEATURE(OPT_ANCHOR_OUTPUTS),
|
OPTIONAL_FEATURE(OPT_ANCHOR_OUTPUTS),
|
||||||
OPTIONAL_FEATURE(OPT_QUIESCE),
|
OPTIONAL_FEATURE(OPT_QUIESCE),
|
||||||
|
|
|
@ -1064,9 +1064,6 @@ static char *opt_set_onion_messages(struct lightningd *ld)
|
||||||
feature_set_or(ld->our_features,
|
feature_set_or(ld->our_features,
|
||||||
take(feature_set_for_feature(NULL,
|
take(feature_set_for_feature(NULL,
|
||||||
OPTIONAL_FEATURE(OPT_ONION_MESSAGES))));
|
OPTIONAL_FEATURE(OPT_ONION_MESSAGES))));
|
||||||
feature_set_or(ld->our_features,
|
|
||||||
take(feature_set_for_feature(NULL,
|
|
||||||
OPTIONAL_FEATURE(OPT_ROUTE_BLINDING))));
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -311,7 +311,7 @@ static bool check_fwd_amount(struct htlc_in *hin,
|
||||||
* - MUST return an error if:
|
* - MUST return an error if:
|
||||||
* ...
|
* ...
|
||||||
* - `cltv_expiry` - `cltv_expiry_delta` < `outgoing_cltv_value`
|
* - `cltv_expiry` - `cltv_expiry_delta` < `outgoing_cltv_value`
|
||||||
* - if it is the final node:
|
* - If it is the final node:
|
||||||
*...
|
*...
|
||||||
* - MUST return an error if:
|
* - MUST return an error if:
|
||||||
*...
|
*...
|
||||||
|
@ -382,7 +382,7 @@ static void handle_localpay(struct htlc_in *hin,
|
||||||
struct lightningd *ld = hin->key.channel->peer->ld;
|
struct lightningd *ld = hin->key.channel->peer->ld;
|
||||||
|
|
||||||
/* BOLT #4:
|
/* BOLT #4:
|
||||||
* - if it is the final node:
|
* - If it is the final node:
|
||||||
* - MUST treat `total_msat` as if it were equal to `amt_to_forward` if it
|
* - MUST treat `total_msat` as if it were equal to `amt_to_forward` if it
|
||||||
* is not present.
|
* is not present.
|
||||||
* - MUST return an error if:
|
* - MUST return an error if:
|
||||||
|
@ -408,7 +408,7 @@ static void handle_localpay(struct htlc_in *hin,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* BOLT #4:
|
/* BOLT #4:
|
||||||
* - if it is the final node:
|
* - If it is the final node:
|
||||||
* - MUST treat `total_msat` as if it were equal to `amt_to_forward` if it
|
* - MUST treat `total_msat` as if it were equal to `amt_to_forward` if it
|
||||||
* is not present.
|
* is not present.
|
||||||
* - MUST return an error if:
|
* - MUST return an error if:
|
||||||
|
|
|
@ -2081,6 +2081,7 @@ def test_list_features_only(node_factory):
|
||||||
]
|
]
|
||||||
if EXPERIMENTAL_FEATURES:
|
if EXPERIMENTAL_FEATURES:
|
||||||
expected += ['option_anchor_outputs/odd']
|
expected += ['option_anchor_outputs/odd']
|
||||||
|
expected += ['option_route_blinding/odd']
|
||||||
expected += ['option_shutdown_anysegwit/odd']
|
expected += ['option_shutdown_anysegwit/odd']
|
||||||
expected += ['option_quiesce/odd']
|
expected += ['option_quiesce/odd']
|
||||||
expected += ['option_onion_messages/odd']
|
expected += ['option_onion_messages/odd']
|
||||||
|
@ -2089,6 +2090,7 @@ def test_list_features_only(node_factory):
|
||||||
expected += ['option_zeroconf/odd']
|
expected += ['option_zeroconf/odd']
|
||||||
expected += ['supports_open_accept_channel_type']
|
expected += ['supports_open_accept_channel_type']
|
||||||
else:
|
else:
|
||||||
|
expected += ['option_route_blinding/odd']
|
||||||
expected += ['option_shutdown_anysegwit/odd']
|
expected += ['option_shutdown_anysegwit/odd']
|
||||||
expected += ['option_channel_type/odd']
|
expected += ['option_channel_type/odd']
|
||||||
expected += ['option_scid_alias/odd']
|
expected += ['option_scid_alias/odd']
|
||||||
|
|
|
@ -3472,53 +3472,6 @@ def test_reject_invalid_payload(node_factory):
|
||||||
l1.rpc.waitsendpay(inv['payment_hash'])
|
l1.rpc.waitsendpay(inv['payment_hash'])
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.skip("Needs to be updated for modern onion")
|
|
||||||
@unittest.skipIf(not EXPERIMENTAL_FEATURES, "Needs blinding args to sendpay")
|
|
||||||
def test_sendpay_blinding(node_factory):
|
|
||||||
l1, l2, l3, l4 = node_factory.line_graph(4)
|
|
||||||
|
|
||||||
blindedpathtool = os.path.join(os.path.dirname(__file__), "..", "devtools", "blindedpath")
|
|
||||||
|
|
||||||
# Create blinded path l2->l4
|
|
||||||
output = subprocess.check_output(
|
|
||||||
[blindedpathtool, '--simple-output', 'create',
|
|
||||||
l2.info['id'] + "/" + l2.get_channel_scid(l3),
|
|
||||||
l3.info['id'] + "/" + l3.get_channel_scid(l4),
|
|
||||||
l4.info['id']]
|
|
||||||
).decode('ASCII').strip()
|
|
||||||
|
|
||||||
# First line is blinding, then <peerid> then <encblob>.
|
|
||||||
blinding, p1, p1enc, p2, p2enc, p3 = output.split('\n')
|
|
||||||
# First hop can't be blinded!
|
|
||||||
assert p1 == l2.info['id']
|
|
||||||
|
|
||||||
amt = 10**3
|
|
||||||
inv = l4.rpc.invoice(amt, "lbl", "desc")
|
|
||||||
|
|
||||||
route = [{'id': l2.info['id'],
|
|
||||||
'channel': l1.get_channel_scid(l2),
|
|
||||||
'amount_msat': Millisatoshi(1002),
|
|
||||||
'delay': 21,
|
|
||||||
'blinding': blinding,
|
|
||||||
'enctlv': p1enc},
|
|
||||||
{'id': p2,
|
|
||||||
'amount_msat': Millisatoshi(1001),
|
|
||||||
'delay': 15,
|
|
||||||
# FIXME: this is a dummy!
|
|
||||||
'channel': '0x0x0',
|
|
||||||
'enctlv': p2enc},
|
|
||||||
{'id': p3,
|
|
||||||
# FIXME: this is a dummy!
|
|
||||||
'channel': '0x0x0',
|
|
||||||
'amount_msat': Millisatoshi(1000),
|
|
||||||
'delay': 9,
|
|
||||||
'style': 'tlv'}]
|
|
||||||
l1.rpc.sendpay(route=route,
|
|
||||||
payment_hash=inv['payment_hash'],
|
|
||||||
bolt11=inv['bolt11'], payment_secret=inv['payment_secret'])
|
|
||||||
l1.rpc.waitsendpay(inv['payment_hash'])
|
|
||||||
|
|
||||||
|
|
||||||
def test_excluded_adjacent_routehint(node_factory, bitcoind):
|
def test_excluded_adjacent_routehint(node_factory, bitcoind):
|
||||||
"""Test case where we try have a routehint which leads to an adjacent
|
"""Test case where we try have a routehint which leads to an adjacent
|
||||||
node, but the result exceeds our maxfee; we crashed trying to find
|
node, but the result exceeds our maxfee; we crashed trying to find
|
||||||
|
|
|
@ -41,7 +41,7 @@ def hex_bits(features):
|
||||||
|
|
||||||
def expected_peer_features(wumbo_channels=False, extra=[]):
|
def expected_peer_features(wumbo_channels=False, extra=[]):
|
||||||
"""Return the expected peer features hexstring for this configuration"""
|
"""Return the expected peer features hexstring for this configuration"""
|
||||||
features = [1, 5, 7, 8, 11, 13, 14, 17, 27, 45, 47, 51]
|
features = [1, 5, 7, 8, 11, 13, 14, 17, 25, 27, 45, 47, 51]
|
||||||
if EXPERIMENTAL_FEATURES:
|
if EXPERIMENTAL_FEATURES:
|
||||||
# OPT_ONION_MESSAGES
|
# OPT_ONION_MESSAGES
|
||||||
features += [39]
|
features += [39]
|
||||||
|
@ -61,7 +61,7 @@ def expected_peer_features(wumbo_channels=False, extra=[]):
|
||||||
# features for the 'node' and the 'peer' feature sets
|
# features for the 'node' and the 'peer' feature sets
|
||||||
def expected_node_features(wumbo_channels=False, extra=[]):
|
def expected_node_features(wumbo_channels=False, extra=[]):
|
||||||
"""Return the expected node features hexstring for this configuration"""
|
"""Return the expected node features hexstring for this configuration"""
|
||||||
features = [1, 5, 7, 8, 11, 13, 14, 17, 27, 45, 47, 51, 55]
|
features = [1, 5, 7, 8, 11, 13, 14, 17, 25, 27, 45, 47, 51, 55]
|
||||||
if EXPERIMENTAL_FEATURES:
|
if EXPERIMENTAL_FEATURES:
|
||||||
# OPT_ONION_MESSAGES
|
# OPT_ONION_MESSAGES
|
||||||
features += [39]
|
features += [39]
|
||||||
|
|
Loading…
Add table
Reference in a new issue