mirror of
https://github.com/aljazceru/lightning.git
synced 2025-12-19 15:14:23 +01:00
common/onion: enforce payment constraints.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
@@ -2,6 +2,7 @@
|
|||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <ccan/array_size/array_size.h>
|
#include <ccan/array_size/array_size.h>
|
||||||
#include <ccan/cast/cast.h>
|
#include <ccan/cast/cast.h>
|
||||||
|
#include <ccan/mem/mem.h>
|
||||||
#include <common/blindedpath.h>
|
#include <common/blindedpath.h>
|
||||||
#include <common/ecdh.h>
|
#include <common/ecdh.h>
|
||||||
#include <common/onion.h>
|
#include <common/onion.h>
|
||||||
@@ -312,7 +313,49 @@ struct onion_payload *onion_decode(const tal_t *ctx,
|
|||||||
goto field_bad;
|
goto field_bad;
|
||||||
}
|
}
|
||||||
|
|
||||||
p->payment_constraints = tal_steal(p, enc->payment_constraints);
|
if (enc->payment_constraints) {
|
||||||
|
/* BOLT-route-blinding #4:
|
||||||
|
* - MUST return an error if the expiry is greater than
|
||||||
|
* `encrypted_recipient_data.payment_constraints.max_cltv_expiry`.
|
||||||
|
*/
|
||||||
|
if (cltv_expiry > enc->payment_constraints->max_cltv_expiry) {
|
||||||
|
*failtlvtype = TLV_TLV_PAYLOAD_ENCRYPTED_RECIPIENT_DATA;
|
||||||
|
goto field_bad;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* BOLT-route-blinding #4:
|
||||||
|
* - MUST return an error if the amount is below
|
||||||
|
* `encrypted_recipient_data.payment_constraints.htlc_minimum_msat`.
|
||||||
|
*/
|
||||||
|
if (amount_msat_less(amount_in,
|
||||||
|
amount_msat(enc->payment_constraints->htlc_minimum_msat))) {
|
||||||
|
*failtlvtype = TLV_TLV_PAYLOAD_ENCRYPTED_RECIPIENT_DATA;
|
||||||
|
goto field_bad;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* BOLT-route-blinding #4:
|
||||||
|
* - MUST return an error if the payment uses a feature
|
||||||
|
* not included in
|
||||||
|
* `encrypted_recipient_data.payment_constraints.allowed_features`.
|
||||||
|
*/
|
||||||
|
/* We don't have any features yet... */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* BOLT-route-blinding #4:
|
||||||
|
* - If `allowed_features` is present:
|
||||||
|
* - MUST return an error if:
|
||||||
|
* - `encrypted_recipient_data.allowed_features.features`
|
||||||
|
* contains an unknown feature bit (even if it is odd).
|
||||||
|
* - the payment uses a feature not included in
|
||||||
|
* `encrypted_recipient_data.allowed_features.features`.
|
||||||
|
*/
|
||||||
|
/* No features, this is easy */
|
||||||
|
if (!memeqzero(enc->allowed_features,
|
||||||
|
tal_bytelen(enc->allowed_features))) {
|
||||||
|
*failtlvtype = TLV_TLV_PAYLOAD_ENCRYPTED_RECIPIENT_DATA;
|
||||||
|
goto field_bad;
|
||||||
|
}
|
||||||
|
|
||||||
if (rs->nextcase == ONION_FORWARD) {
|
if (rs->nextcase == ONION_FORWARD) {
|
||||||
if (!handle_blinded_forward(p, amount_in, cltv_expiry,
|
if (!handle_blinded_forward(p, amount_in, cltv_expiry,
|
||||||
tlv, enc, failtlvtype))
|
tlv, enc, failtlvtype))
|
||||||
@@ -390,7 +433,6 @@ struct onion_payload *onion_decode(const tal_t *ctx,
|
|||||||
p->payment_metadata = NULL;
|
p->payment_metadata = NULL;
|
||||||
|
|
||||||
p->blinding = NULL;
|
p->blinding = NULL;
|
||||||
p->payment_constraints = NULL;
|
|
||||||
|
|
||||||
p->tlv = tal_steal(p, tlv);
|
p->tlv = tal_steal(p, tlv);
|
||||||
return p;
|
return p;
|
||||||
@@ -405,3 +447,4 @@ fail_no_tlv:
|
|||||||
tal_free(p);
|
tal_free(p);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,6 @@ struct onion_payload {
|
|||||||
struct short_channel_id *forward_channel;
|
struct short_channel_id *forward_channel;
|
||||||
struct secret *payment_secret;
|
struct secret *payment_secret;
|
||||||
u8 *payment_metadata;
|
u8 *payment_metadata;
|
||||||
struct tlv_encrypted_data_tlv_payment_constraints *payment_constraints;
|
|
||||||
|
|
||||||
/* If blinding is set, blinding_ss is the shared secret.*/
|
/* If blinding is set, blinding_ss is the shared secret.*/
|
||||||
struct pubkey *blinding;
|
struct pubkey *blinding;
|
||||||
|
|||||||
@@ -24,6 +24,9 @@ struct amount_msat amount_msat(u64 millisatoshis UNNEEDED)
|
|||||||
/* Generated stub for amount_msat_eq */
|
/* Generated stub for amount_msat_eq */
|
||||||
bool amount_msat_eq(struct amount_msat a UNNEEDED, struct amount_msat b UNNEEDED)
|
bool amount_msat_eq(struct amount_msat a UNNEEDED, struct amount_msat b UNNEEDED)
|
||||||
{ fprintf(stderr, "amount_msat_eq called!\n"); abort(); }
|
{ fprintf(stderr, "amount_msat_eq called!\n"); abort(); }
|
||||||
|
/* Generated stub for amount_msat_less */
|
||||||
|
bool amount_msat_less(struct amount_msat a UNNEEDED, struct amount_msat b UNNEEDED)
|
||||||
|
{ fprintf(stderr, "amount_msat_less called!\n"); abort(); }
|
||||||
/* Generated stub for amount_sat */
|
/* Generated stub for amount_sat */
|
||||||
struct amount_sat amount_sat(u64 satoshis UNNEEDED)
|
struct amount_sat amount_sat(u64 satoshis UNNEEDED)
|
||||||
{ fprintf(stderr, "amount_sat called!\n"); abort(); }
|
{ fprintf(stderr, "amount_sat called!\n"); abort(); }
|
||||||
|
|||||||
@@ -34,6 +34,9 @@ struct amount_msat amount_msat(u64 millisatoshis UNNEEDED)
|
|||||||
/* Generated stub for amount_msat_eq */
|
/* Generated stub for amount_msat_eq */
|
||||||
bool amount_msat_eq(struct amount_msat a UNNEEDED, struct amount_msat b UNNEEDED)
|
bool amount_msat_eq(struct amount_msat a UNNEEDED, struct amount_msat b UNNEEDED)
|
||||||
{ fprintf(stderr, "amount_msat_eq called!\n"); abort(); }
|
{ fprintf(stderr, "amount_msat_eq called!\n"); abort(); }
|
||||||
|
/* Generated stub for amount_msat_less */
|
||||||
|
bool amount_msat_less(struct amount_msat a UNNEEDED, struct amount_msat b UNNEEDED)
|
||||||
|
{ fprintf(stderr, "amount_msat_less called!\n"); abort(); }
|
||||||
/* Generated stub for amount_sat */
|
/* Generated stub for amount_sat */
|
||||||
struct amount_sat amount_sat(u64 satoshis UNNEEDED)
|
struct amount_sat amount_sat(u64 satoshis UNNEEDED)
|
||||||
{ fprintf(stderr, "amount_sat called!\n"); abort(); }
|
{ fprintf(stderr, "amount_sat called!\n"); abort(); }
|
||||||
|
|||||||
@@ -20,6 +20,9 @@ struct amount_msat amount_msat(u64 millisatoshis UNNEEDED)
|
|||||||
/* Generated stub for amount_msat_eq */
|
/* Generated stub for amount_msat_eq */
|
||||||
bool amount_msat_eq(struct amount_msat a UNNEEDED, struct amount_msat b UNNEEDED)
|
bool amount_msat_eq(struct amount_msat a UNNEEDED, struct amount_msat b UNNEEDED)
|
||||||
{ fprintf(stderr, "amount_msat_eq called!\n"); abort(); }
|
{ fprintf(stderr, "amount_msat_eq called!\n"); abort(); }
|
||||||
|
/* Generated stub for amount_msat_less */
|
||||||
|
bool amount_msat_less(struct amount_msat a UNNEEDED, struct amount_msat b UNNEEDED)
|
||||||
|
{ fprintf(stderr, "amount_msat_less called!\n"); abort(); }
|
||||||
/* Generated stub for amount_sat */
|
/* Generated stub for amount_sat */
|
||||||
struct amount_sat amount_sat(u64 satoshis UNNEEDED)
|
struct amount_sat amount_sat(u64 satoshis UNNEEDED)
|
||||||
{ fprintf(stderr, "amount_sat called!\n"); abort(); }
|
{ fprintf(stderr, "amount_sat called!\n"); abort(); }
|
||||||
|
|||||||
Reference in New Issue
Block a user