Skip to content

Commit a8fc1ee

Browse files
authored
Merge branch 'ElementsProject:master' into test-current-feerate-assertion
2 parents c6528da + 1b1274d commit a8fc1ee

106 files changed

Lines changed: 2580 additions & 939 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/ci.yaml

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -312,7 +312,7 @@ jobs:
312312
- name: Test
313313
env:
314314
SLOW_MACHINE: 1
315-
PYTEST_PAR: 10
315+
PYTEST_PAR: 4
316316
TEST_DEBUG: 1
317317
TEST_DB_PROVIDER: ${{ matrix.TEST_DB_PROVIDER }}
318318
TEST_NETWORK: ${{ matrix.TEST_NETWORK }}
@@ -430,7 +430,7 @@ jobs:
430430
COMPAT: 1
431431
CFG: ${{ matrix.CFG }}
432432
SLOW_MACHINE: 1
433-
PYTEST_PAR: 10
433+
PYTEST_PAR: 4
434434
TEST_DEBUG: 1
435435
TEST_DB_PROVIDER: ${{ matrix.TEST_DB_PROVIDER }}
436436
TEST_NETWORK: ${{ matrix.TEST_NETWORK }}
@@ -524,8 +524,9 @@ jobs:
524524
env:
525525
SLOW_MACHINE: 1
526526
TEST_DEBUG: 1
527+
PYTEST_PAR: 2
527528
run: |
528-
VALGRIND=1 uv run eatmydata pytest tests/ -n 3 ${PYTEST_OPTS} ${{ matrix.PYTEST_OPTS }}
529+
VALGRIND=1 uv run eatmydata pytest tests/ -n ${PYTEST_PAR} ${PYTEST_OPTS} ${{ matrix.PYTEST_OPTS }}
529530
- name: Upload test results
530531
if: always()
531532
uses: actions/upload-artifact@v4
@@ -613,8 +614,10 @@ jobs:
613614
run: tar -xvjf cln-compile-clang-sanitizers.tar.bz2
614615

615616
- name: Test
617+
env:
618+
PYTEST_PAR: 2
616619
run: |
617-
uv run eatmydata pytest tests/ -n 2 ${PYTEST_OPTS} ${{ matrix.PYTEST_OPTS }}
620+
uv run eatmydata pytest tests/ -n ${PYTEST_PAR} ${PYTEST_OPTS} ${{ matrix.PYTEST_OPTS }}
618621
- name: Upload test results
619622
if: always()
620623
uses: actions/upload-artifact@v4
@@ -737,7 +740,7 @@ jobs:
737740
COMPAT: 1
738741
CFG: ${{ matrix.CFG }}
739742
SLOW_MACHINE: 1
740-
PYTEST_PAR: 10
743+
PYTEST_PAR: 4
741744
TEST_DEBUG: 1
742745
TEST_DB_PROVIDER: ${{ matrix.TEST_DB_PROVIDER }}
743746
TEST_NETWORK: ${{ matrix.TEST_NETWORK }}

Makefile

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -313,6 +313,10 @@ else
313313
LDLIBS = -L$(CPATH) -lm $(SQLITE3_LDLIBS) $(COVFLAGS)
314314
endif
315315

316+
ifeq ($(HAVE_FUNCTION_SECTIONS),1)
317+
LDLIBS += -Wl,--gc-sections
318+
endif
319+
316320
# If we have the postgres client library we need to link against it as well
317321
ifeq ($(HAVE_POSTGRES),1)
318322
LDLIBS += $(POSTGRES_LDLIBS)
@@ -1152,7 +1156,11 @@ ccan-rune-rune.o: $(CCANDIR)/ccan/rune/rune.c
11521156
ccan-rune-coding.o: $(CCANDIR)/ccan/rune/coding.c
11531157
@$(call VERBOSE, "cc $<", $(CC) $(CFLAGS) -c -o $@ $<)
11541158

1155-
print-binary-sizes: $(ALL_PROGRAMS) $(ALL_TEST_PROGRAMS)
1156-
@find $(ALL_PROGRAMS) $(ALL_TEST_PROGRAMS) -printf '%p\t%s\n'
1157-
@echo 'Total program size: '`find $(ALL_PROGRAMS) -printf '%s\n' | awk '{TOTAL+= $$1} END {print TOTAL}'`
1158-
@echo 'Total tests size: '`find $(ALL_TEST_PROGRAMS) -printf '%s\n' | awk '{TOTAL+= $$1} END {print TOTAL}'`
1159+
canned-gossmap: devtools/gossmap-compress
1160+
DATE=`date +%Y-%m-%d` && devtools/gossmap-compress compress --output-node-map /tmp/gossip_store tests/data/gossip-store-$$DATE.compressed > tests/data/gossip-store-$$DATE-node-map && xz -9 tests/data/gossip-store-$$DATE-node-map && ls -l tests/data/gossip-store-$$DATE*
1161+
1162+
print-binary-sizes: $(ALL_PROGRAMS) $(ALL_TEST_PROGRAMS) $(BIN_PROGRAMS)
1163+
@echo User programs:
1164+
@size -t $(PKGLIBEXEC_PROGRAMS) $(filter-out tools/reckless,$(BIN_PROGRAMS)) $(PLUGINS)
1165+
@echo All programs:
1166+
@size -t $(ALL_PROGRAMS) $(ALL_TEST_PROGRAMS) | tail -n1

common/bolt12.c

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,7 @@ struct tlv_offer *offer_decode(const tal_t *ctx,
171171
const u8 *data;
172172
size_t dlen;
173173
const struct tlv_field *badf;
174+
const struct recurrence *recurr;
174175

175176
data = string_to_data(tmpctx, b12, b12len, "lno", &dlen, fail);
176177
if (!data)
@@ -221,6 +222,16 @@ struct tlv_offer *offer_decode(const tal_t *ctx,
221222
return tal_free(offer);
222223
}
223224

225+
/* BOLT #12:
226+
*
227+
* - if `offer_currency` is set and `offer_amount` is not set:
228+
* - MUST NOT respond to the offer.
229+
*/
230+
if (offer->offer_currency && !offer->offer_amount) {
231+
*fail = tal_strdup(ctx, "Offer contains a currency with no amount");
232+
return tal_free(offer);
233+
}
234+
224235
/* BOLT #12:
225236
*
226237
* - if neither `offer_issuer_id` nor `offer_paths` are set:
@@ -242,6 +253,46 @@ struct tlv_offer *offer_decode(const tal_t *ctx,
242253
}
243254
}
244255

256+
/* BOLT-recurrence #12
257+
* - if `offer_recurrence_optional` or `offer_recurrence_compulsory` are set:
258+
* - if `time_unit` is not one of 0, 1, or 2:
259+
* - MUST NOT respond to the offer.
260+
* - if `period` is 0:
261+
* - MUST NOT respond to the offer.
262+
* - if `offer_recurrence_limit` is set and `max_period_index` is 0:
263+
* - MUST NOT respond to the offer.
264+
*/
265+
recurr = offer_recurrence(offer);
266+
if (recurr) {
267+
if (recurr->time_unit != 0
268+
&& recurr->time_unit != 1
269+
&& recurr->time_unit != 2) {
270+
*fail = tal_fmt(ctx, "Offer contains invalid recurrence time_unit %u", recurr->time_unit);
271+
return tal_free(offer);
272+
}
273+
if (recurr->period == 0) {
274+
*fail = tal_fmt(ctx, "Offer contains invalid recurrence period %u", recurr->period);
275+
return tal_free(offer);
276+
}
277+
if (offer->offer_recurrence_limit && *offer->offer_recurrence_limit == 0) {
278+
*fail = tal_fmt(ctx, "Offer contains invalid recurrence limit %u",
279+
*offer->offer_recurrence_limit);
280+
return tal_free(offer);
281+
}
282+
} else {
283+
/* BOLT-recurrence #12
284+
* - otherwise: (no recurrence):
285+
* - if it `offer_recurrence_paywindow`, `offer_recurrence_limit` or `offer_recurrence_base` are set:
286+
* - MUST NOT respond to the offer.
287+
*/
288+
if (offer->offer_recurrence_paywindow
289+
|| offer->offer_recurrence_limit
290+
|| offer->offer_recurrence_base) {
291+
*fail = tal_strdup(ctx, "Offer contains recurrence fields but no recurrence");
292+
return tal_free(offer);
293+
}
294+
}
295+
245296
return offer;
246297
}
247298

common/configvar.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include <ccan/tal/str/str.h>
55
#include <common/configvar.h>
66
#include <common/utils.h>
7+
#include <unistd.h>
78

89
struct configvar *configvar_new(const tal_t *ctx,
910
enum configvar_src src,

common/gossmap.c

Lines changed: 23 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -503,16 +503,14 @@ static struct gossmap_chan *add_channel(struct gossmap *map,
503503
return chan;
504504
}
505505

506-
/* Does not set hc->nodeidx! */
507-
static void fill_from_update(struct gossmap *map,
506+
/* Does not set hc->nodeidx!
507+
* Returns false if it doesn't fit in our representation: this happens
508+
* on the real network, as people set absurd fees
509+
*/
510+
static bool fill_from_update(struct gossmap *map,
508511
struct short_channel_id_dir *scidd,
509512
struct half_chan *hc,
510-
u64 cupdate_off,
511-
void (*logcb)(void *cbarg,
512-
enum log_level level,
513-
const char *fmt,
514-
...),
515-
void *cbarg)
513+
u64 cupdate_off)
516514
{
517515
/* Note that first two bytes are message type */
518516
const u64 scid_off = cupdate_off + 2 + (64 + 32);
@@ -543,18 +541,15 @@ static void fill_from_update(struct gossmap *map,
543541
hc->proportional_fee = proportional_fee;
544542
hc->delay = delay;
545543

546-
/* Check they fit: we turn off if not, log (at debug, it happens!). */
544+
/* Check they fit: we turn off if not. */
547545
if (hc->base_fee != base_fee
548546
|| hc->proportional_fee != proportional_fee
549547
|| hc->delay != delay) {
550548
hc->htlc_max = 0;
551549
hc->enabled = false;
552-
if (logcb)
553-
logcb(cbarg, LOG_DBG,
554-
"Bad cupdate for %s, ignoring (delta=%u, fee=%u/%u)",
555-
fmt_short_channel_id_dir(tmpctx, scidd),
556-
delay, base_fee, proportional_fee);
550+
return false;
557551
}
552+
return true;
558553
}
559554

560555
/* BOLT #7:
@@ -572,23 +567,24 @@ static void fill_from_update(struct gossmap *map,
572567
* * [`u32`:`fee_proportional_millionths`]
573568
* * [`u64`:`htlc_maximum_msat`]
574569
*/
575-
static void update_channel(struct gossmap *map, u64 cupdate_off)
570+
static bool update_channel(struct gossmap *map, u64 cupdate_off)
576571
{
577572
struct short_channel_id_dir scidd;
578573
struct gossmap_chan *chan;
579574
struct half_chan hc;
575+
bool ret;
580576

581-
fill_from_update(map, &scidd, &hc, cupdate_off,
582-
map->logcb, map->cbarg);
577+
ret = fill_from_update(map, &scidd, &hc, cupdate_off);
583578
chan = gossmap_find_chan(map, &scidd.scid);
584579
/* This can happen if channel gets deleted! */
585580
if (!chan)
586-
return;
581+
return ret;
587582

588583
/* Preserve this */
589584
hc.nodeidx = chan->half[scidd.dir].nodeidx;
590585
chan->half[scidd.dir] = hc;
591586
chan->cupdate_off[scidd.dir] = cupdate_off;
587+
return ret;
592588
}
593589

594590
static void remove_channel_by_deletemsg(struct gossmap *map, u64 del_off)
@@ -677,7 +673,7 @@ static bool csum_matches(const struct gossmap *map,
677673
/* Returns false only if must_be_clean is true. */
678674
static bool map_catchup(struct gossmap *map, bool must_be_clean, bool *changed)
679675
{
680-
size_t reclen;
676+
size_t reclen, num_bad_cupdates = 0;
681677

682678
*changed = false;
683679

@@ -749,7 +745,7 @@ static bool map_catchup(struct gossmap *map, bool must_be_clean, bool *changed)
749745
if (redundant && must_be_clean)
750746
return false;
751747
} else if (type == WIRE_CHANNEL_UPDATE)
752-
update_channel(map, off);
748+
num_bad_cupdates += update_channel(map, off);
753749
else if (type == WIRE_GOSSIP_STORE_DELETE_CHAN)
754750
remove_channel_by_deletemsg(map, off);
755751
else if (type == WIRE_NODE_ANNOUNCEMENT)
@@ -775,6 +771,12 @@ static bool map_catchup(struct gossmap *map, bool must_be_clean, bool *changed)
775771
*changed = true;
776772
}
777773

774+
if (num_bad_cupdates != 0)
775+
map->logcb(map->cbarg,
776+
LOG_DBG,
777+
"Got %zu bad cupdates, ignoring them (expected on mainnet)",
778+
num_bad_cupdates);
779+
778780
return true;
779781
}
780782

@@ -1168,7 +1170,7 @@ void gossmap_apply_localmods(struct gossmap *map,
11681170
off = insert_local_space(&map->local_updates, tal_bytelen(cupdatemsg));
11691171
memcpy(map->local_updates + off, cupdatemsg, tal_bytelen(cupdatemsg));
11701172
chan->cupdate_off[h] = map->map_size + tal_bytelen(map->local_announces) + off;
1171-
fill_from_update(map, &scidd, &chan->half[h], chan->cupdate_off[h], NULL, NULL);
1173+
fill_from_update(map, &scidd, &chan->half[h], chan->cupdate_off[h]);
11721174

11731175
/* We wrote the right update, correct? */
11741176
assert(short_channel_id_eq(scidd.scid, mod->scid));

common/jsonrpc_errors.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ enum jsonrpc_errcode {
116116
OFFER_BAD_INVREQ_REPLY = 1004,
117117
OFFER_TIMEOUT = 1005,
118118
OFFER_ALREADY_ENABLED = 1006,
119+
OFFER_USED_SINGLE_USE = 1007,
119120

120121
/* Errors from datastore command */
121122
DATASTORE_DEL_DOES_NOT_EXIST = 1200,

common/onion_encode.h

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,7 @@
77
struct route_step;
88
struct tlv_encrypted_data_tlv_payment_relay;
99

10-
enum onion_payload_type {
11-
ONION_V0_PAYLOAD = 0,
12-
ONION_TLV_PAYLOAD = 1,
13-
};
14-
1510
struct onion_payload {
16-
enum onion_payload_type type;
1711
/* Is this the final hop? */
1812
bool final;
1913

common/sphinx.c

Lines changed: 6 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -677,54 +677,13 @@ struct route_step *process_onionpacket(
677677
/* Any of these could fail, falling thru with cursor == NULL */
678678
payload_size = fromwire_bigsize(&cursor, &max);
679679

680-
/* Legacy! 0 length payload means fixed 32 byte structure */
681-
if (payload_size == 0 && max >= 32) {
682-
struct tlv_payload *legacy = tlv_payload_new(tmpctx);
683-
const u8 *legacy_cursor = cursor;
684-
size_t legacy_max = 32;
685-
u8 *onwire_tlv;
686-
687-
legacy->amt_to_forward = tal(legacy, u64);
688-
legacy->outgoing_cltv_value = tal(legacy, u32);
689-
legacy->short_channel_id = tal(legacy, struct short_channel_id);
690-
691-
/* BOLT-obsolete #4:
692-
* ## Legacy `hop_data` payload format
693-
*
694-
* The `hop_data` format is identified by a single `0x00`-byte
695-
* length, for backward compatibility. Its payload is defined
696-
* as:
697-
*
698-
* 1. type: `hop_data` (for `realm` 0)
699-
* 2. data:
700-
* * [`short_channel_id`:`short_channel_id`]
701-
* * [`u64`:`amt_to_forward`]
702-
* * [`u32`:`outgoing_cltv_value`]
703-
* * [`12*byte`:`padding`]
704-
*/
705-
*legacy->short_channel_id = fromwire_short_channel_id(&legacy_cursor, &legacy_max);
706-
*legacy->amt_to_forward = fromwire_u64(&legacy_cursor, &legacy_max);
707-
*legacy->outgoing_cltv_value = fromwire_u32(&legacy_cursor, &legacy_max);
708-
709-
/* Re-linearize it as a modern TLV! */
710-
onwire_tlv = tal_arr(tmpctx, u8, 0);
711-
towire_tlv_payload(&onwire_tlv, legacy);
712-
713-
/* Length, then tlv */
714-
step->raw_payload = tal_arr(step, u8, 0);
715-
towire_bigsize(&step->raw_payload, tal_bytelen(onwire_tlv));
716-
towire_u8_array(&step->raw_payload, onwire_tlv, tal_bytelen(onwire_tlv));
680+
/* FIXME: raw_payload *includes* the length, which is redundant and
681+
* means we can't just ust fromwire_tal_arrn. */
682+
fromwire_pad(&cursor, &max, payload_size);
683+
if (cursor != NULL)
684+
step->raw_payload = tal_dup_arr(step, u8, paddedheader,
685+
cursor - paddedheader, 0);
717686

718-
payload_size = 32;
719-
fromwire_pad(&cursor, &max, payload_size);
720-
} else {
721-
/* FIXME: raw_payload *includes* the length, which is redundant and
722-
* means we can't just ust fromwire_tal_arrn. */
723-
fromwire_pad(&cursor, &max, payload_size);
724-
if (cursor != NULL)
725-
step->raw_payload = tal_dup_arr(step, u8, paddedheader,
726-
cursor - paddedheader, 0);
727-
}
728687
fromwire_hmac(&cursor, &max, &step->next->hmac);
729688

730689
/* BOLT #4:

common/utils.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,15 @@ char *str_lowering(const void *ctx, const char *string TAKES)
215215
return ret;
216216
}
217217

218+
char *str_uppering(const void *ctx, const char *string TAKES)
219+
{
220+
char *ret;
221+
222+
ret = tal_strdup(ctx, string);
223+
for (char *p = ret; *p; p++) *p = toupper(*p);
224+
return ret;
225+
}
226+
218227
/* Realloc helper for tal membufs */
219228
void *membuf_tal_resize(struct membuf *mb, void *rawelems, size_t newsize)
220229
{

common/utils.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,15 @@ void *membuf_tal_resize(struct membuf *mb, void *rawelems, size_t newsize);
188188
*/
189189
char *str_lowering(const void *ctx, const char *string TAKES);
190190

191+
/**
192+
* tal_struppering - return the same string by in upper case.
193+
* @ctx: the context to tal from (often NULL)
194+
* @string: the string that is going to be UPPERED (can be take())
195+
*
196+
* FIXME: move this in ccan
197+
*/
198+
char *str_uppering(const void *ctx, const char *string TAKES);
199+
191200
/**
192201
* Assign two different structs which are the same size.
193202
* We use this for assigning secrets <-> sha256 for example.

0 commit comments

Comments
 (0)