Skip to content

Commit

Permalink
common/wire: update, don't replace fields array in TLV structures.
Browse files Browse the repository at this point in the history
Regnerating them entirely loses unknown fields.

Signed-off-by: Rusty Russell <[email protected]>
  • Loading branch information
rustyrussell committed Jul 23, 2024
1 parent ea4025b commit c342f20
Show file tree
Hide file tree
Showing 5 changed files with 36 additions and 14 deletions.
2 changes: 1 addition & 1 deletion common/test/run-bolt12_merkle.c
Original file line number Diff line number Diff line change
Expand Up @@ -326,7 +326,7 @@ int main(int argc, char *argv[])
invreq->invreq_metadata = tal_arrz(invreq, u8, 8);

/* Populate ->fields array, for merkle routine */
invreq->fields = tlv_make_fields(invreq, tlv_invoice_request);
tlv_update_fields(invreq, tlv_invoice_request, &invreq->fields);
merkle_tlv(invreq->fields, &test_m);

/* BOLT-offers #12:
Expand Down
3 changes: 1 addition & 2 deletions lightningd/invoice.c
Original file line number Diff line number Diff line change
Expand Up @@ -1684,8 +1684,7 @@ static void add_stub_blindedpath(const tal_t *ctx,
inv->invoice_blindedpay[0]->features = NULL;

/* Recalc ->fields */
tal_free(inv->fields);
inv->fields = tlv_make_fields(inv, tlv_invoice);
tlv_update_fields(inv, tlv_invoice, &inv->fields);
}

static struct command_result *json_createinvoice(struct command *cmd,
Expand Down
2 changes: 1 addition & 1 deletion lightningd/offer.c
Original file line number Diff line number Diff line change
Expand Up @@ -467,7 +467,7 @@ static struct command_result *json_createinvoicerequest(struct command *cmd,
* [Signature Calculation](#signature-calculation) using the `invreq_payer_id`.
*/
/* This populates the ->fields from our entries */
invreq->fields = tlv_make_fields(invreq, tlv_invoice_request);
tlv_update_fields(invreq, tlv_invoice_request, &invreq->fields);
merkle_tlv(invreq->fields, &merkle);
invreq->signature = tal(invreq, struct bip340sig);
hsm_sign_b12(cmd->ld, "invoice_request", "signature",
Expand Down
30 changes: 26 additions & 4 deletions wire/tlvstream.c
Original file line number Diff line number Diff line change
Expand Up @@ -365,17 +365,30 @@ void towire_tlv(u8 **pptr,

}

struct tlv_field *tlv_make_fields_(const struct tlv_record_type *types,
size_t num_types,
const void *record)
void tlv_update_fields_(const struct tlv_record_type *types,
size_t num_types,
const void *record,
struct tlv_field **tlv_fields)
{
/* We merge unknown fields from record */
const struct tlv_field *field, *end;
struct tlv_field *fields = tal_arr(record, struct tlv_field, 0);

field = first_unknown_field(*tlv_fields, &end);

for (size_t i = 0; i < num_types; i++) {
struct tlv_field f;
u8 *val;
if (i != 0)
assert(types[i].type > types[i-1].type);

/* Add any unknowns which precede this. */
while (field && field->numtype < types[i].type) {
tal_steal(fields, field->value);
tal_arr_expand(&fields, *field);
field = next_unknown_field(field, end);
}

val = types[i].towire(NULL, record);
if (!val)
continue;
Expand All @@ -386,5 +399,14 @@ struct tlv_field *tlv_make_fields_(const struct tlv_record_type *types,
f.value = tal_steal(fields, val);
tal_arr_expand(&fields, f);
}
return fields;

/* Add any unknowns at the end. */
while (field) {
tal_steal(fields, field->value);
tal_arr_expand(&fields, *field);
field = next_unknown_field(field, end);
}

tal_free(*tlv_fields);
*tlv_fields = fields;
}
13 changes: 7 additions & 6 deletions wire/tlvstream.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,14 @@ struct tlv_field {
/* Given any tlvstream serialize the raw fields (untyped ones). */
void towire_tlvstream_raw(u8 **pptr, struct tlv_field *fields);

/* Given a tlv record with manually-set fields, populate ->fields */
#define tlv_make_fields(tlv, type) \
tlv_make_fields_(tlvs_##type, TLVS_ARRAY_SIZE_##type, (tlv))
/* Given a tlv record with manually-set fields, repopulate ->fields (maintaining any unknowns)*/
#define tlv_update_fields(tlv, type, tlv_fields) \
tlv_update_fields_(tlvs_##type, TLVS_ARRAY_SIZE_##type, (tlv), (tlv_fields))

struct tlv_field *tlv_make_fields_(const struct tlv_record_type *types,
size_t num_types,
const void *record);
void tlv_update_fields_(const struct tlv_record_type *types,
size_t num_types,
const void *record,
struct tlv_field **tlv_fields);

/**
* fromwire_tlv: generic TLV decode engine
Expand Down

0 comments on commit c342f20

Please sign in to comment.