global: use clock_time in place of time_now().
What changed, and why it matters
This commit swaps most uses of the real-time clock function `time_now()` for a new internal helper called `clock_time()`. The change is infrastructure, not a fix for a known attack. It makes the node’s view of time easier to override for testing and reproducibility, and it reduces the risk that a backward clock jump confuses timers, logs, or payment expiry checks. Tracing is deliberately left on real time. There is no direct security bug being patched here, but the change touches many time-sensitive parts of a payment system, so it has broad defensive value.
Treat as a routine defensive refactor. Review the new `common/clock_time.h` implementation (not shown in the diff) to confirm that `clock_time()` and `clock_time_progresses()` behave correctly under `CLN_DEV_SET_TIME`, especially around invoice/payment expiry and HTLC timeouts. Ensure CI still passes and that no remaining `time_now()` call outside `common/trace.c` was missed by the linter.
Security signals we found
Mass replacement of wall-clock source with an internal, overridable clock abstraction
Makefile lint rule now treats `time_now()` as a discouraged function
Tracing explicitly exempted from the new clock because it needs real wall time
Coin movements use `clock_time_progresses()` to guarantee non-decreasing timestamps
No explicit vulnerability, CVE, or security advisory referenced in commit message
Evidence from the diff
The patch replaces time_now() with clock_time() across ~50 files in Core Lightning. clock_time() is a project abstraction that can return a deterministic/overridden time in dev mode (CLN_DEV_SET_TIME) and a monotonic-like progressing time for coin movements (clock_time_progresses()). The Makefile now flags time_now() as a discouraged function. The only remaining time_now() uses are in common/trace.c, explicitly annotated as wanting non-dev wall time. The change affects invoice expiry, HTLC timestamps, payment timeouts, gossip pruning, channel state changes, rune time checks, and bookkeeping records. It does not alter protocol logic or cryptographic checks; it only changes which clock source is consulted.
Changed components
common/clock_time abstractioncommon/coin_mvt timestamp handlingconnectd gossip timestamp filtergossipd store, pruning, and seekerlightningd channel state, invoices, payments, HTLCs, logs, runesplugins/askrene, autoclean, bkpr, chanbackup, fetchinvoice, keysend, libplugin-pay, offers, pay, renepay, xpaywallet invoices, payments, forwards, network events, coin-move migrationInspect captured patch +146 / −85
diff --git a/Makefile b/Makefile
index 07f1a193..f6cd7c1a 100644
--- a/Makefile
+++ b/Makefile
@@ -603,7 +603,7 @@ check-tmpctx:
@if git grep -n 'tal_free[(]tmpctx)' | grep -Ev '^ccan/|/test/|^common/setup.c:|^common/utils.c:'; then echo "Don't free tmpctx!">&2; exit 1; fi
check-discouraged-functions:
- @if git grep -nE "[^a-z_/](fgets|fputs|gets|scanf|sprintf|randombytes_buf)\(" -- "*.c" "*.h" ":(exclude)ccan/" ":(exclude)contrib/" | grep -Fv '/* discouraged:'; then exit 1; fi
+ @if git grep -nE "[^a-z_/](fgets|fputs|gets|scanf|sprintf|randombytes_buf|time_now)\(" -- "*.c" "*.h" ":(exclude)ccan/" ":(exclude)contrib/" | grep -Fv '/* discouraged:'; then exit 1; fi
check-bad-sprintf:
@if git grep -n "%[*]\.s"; then exit 1; fi
diff --git a/common/coin_mvt.c b/common/coin_mvt.c
index e797758e..21550d61 100644
--- a/common/coin_mvt.c
+++ b/common/coin_mvt.c
@@ -3,7 +3,7 @@
#include <ccan/bitops/bitops.h>
#include <ccan/ccan/cast/cast.h>
#include <ccan/tal/str/str.h>
-#include <ccan/time/time.h>
+#include <common/clock_time.h>
#include <common/coin_mvt.h>
#include <common/node_id.h>
#include <common/utils.h>
@@ -155,6 +155,12 @@ static enum mvt_tag mvt_tag_in_db(enum mvt_tag mvt_tag)
abort();
}
+/* This puts the coin movements in order */
+u64 coinmvt_current_time(void)
+{
+ return clock_time_progresses().ts.tv_sec;
+}
+
const char *mvt_tag_str(enum mvt_tag tag)
{
assert((unsigned)tag < NUM_MVT_TAGS);
@@ -338,7 +344,7 @@ static struct chain_coin_mvt *new_chain_coin_mvt_sat(const tal_t *ctx,
assert(ok);
return new_chain_coin_mvt(ctx, channel, account_name,
- time_now().ts.tv_sec, tx_txid,
+ coinmvt_current_time(), tx_txid,
outpoint, payment_hash,
blockheight, tags, direction, amt_msat,
/* All amounts that are sat are
@@ -393,7 +399,7 @@ struct chain_coin_mvt *new_coin_channel_close(const tal_t *ctx,
tags = mk_mvt_tags(MVT_CHANNEL_CLOSE);
mvt = new_chain_coin_mvt(ctx, channel, alt_account,
- time_now().ts.tv_sec, txid,
+ coinmvt_current_time(), txid,
out, NULL, blockheight,
tags,
COIN_DEBIT, amount,
@@ -421,7 +427,7 @@ struct chain_coin_mvt *new_coin_channel_open_proposed(const tal_t *ctx,
if (is_leased)
mvt_tag_set(&tags, MVT_LEASED);
- mvt = new_chain_coin_mvt(ctx, channel, NULL, time_now().ts.tv_sec,
+ mvt = new_chain_coin_mvt(ctx, channel, NULL, coinmvt_current_time(),
NULL, out, NULL, 0,
tags,
COIN_CREDIT, amount, output_val, 0);
@@ -474,7 +480,7 @@ struct chain_coin_mvt *new_coin_channel_open(const tal_t *ctx,
bool is_leased)
{
return new_coin_channel_open_general(ctx, channel, NULL,
- time_now().ts.tv_sec,
+ coinmvt_current_time(),
out, peer_id, blockheight,
amount, output_val, is_opener, is_leased);
}
@@ -516,7 +522,7 @@ struct chain_coin_mvt *new_coin_external_spend(const tal_t *ctx,
struct mvt_tags tags)
{
return new_chain_coin_mvt(ctx, NULL, ACCOUNT_NAME_EXTERNAL,
- time_now().ts.tv_sec, txid,
+ coinmvt_current_time(), txid,
outpoint, NULL, blockheight,
tags,
COIN_CREDIT, AMOUNT_MSAT(0), amount, 0);
@@ -584,7 +590,7 @@ struct channel_coin_mvt *new_coin_channel_push(const tal_t *ctx,
struct mvt_tags tags)
{
return new_coin_channel_push_general(ctx, channel, NULL,
- time_now().ts.tv_sec,
+ coinmvt_current_time(),
direction, amount, tags);
}
@@ -731,6 +737,10 @@ void fromwire_chain_coin_mvt(const u8 **cursor, size_t *max, struct chain_coin_m
} else
mvt->peer_id = NULL;
mvt->timestamp = fromwire_u64(cursor, max);
+
+ /* Align onchaind's timestamps with ours if we're deterministic */
+ if (clock_time_overridden())
+ mvt->timestamp = coinmvt_current_time();
}
struct mvt_tags mk_mvt_tags_(enum mvt_tag tag, ...)
diff --git a/common/coin_mvt.h b/common/coin_mvt.h
index 822e6e82..b85eaeda 100644
--- a/common/coin_mvt.h
+++ b/common/coin_mvt.h
@@ -346,4 +346,7 @@ bool mvt_tag_parse(const char *buf, size_t len, enum mvt_tag *tag);
void towire_chain_coin_mvt(u8 **pptr, const struct chain_coin_mvt *mvt);
void fromwire_chain_coin_mvt(const u8 **cursor, size_t *max, struct chain_coin_mvt *mvt);
+/* Time helper for deterministic timestamps: always moves forwards */
+u64 coinmvt_current_time(void);
+
#endif /* LIGHTNING_COMMON_COIN_MVT_H */
diff --git a/common/test/Makefile b/common/test/Makefile
index e13bfb3f..ab192ce6 100644
--- a/common/test/Makefile
+++ b/common/test/Makefile
@@ -6,6 +6,7 @@ COMMON_TEST_PROGRAMS := $(COMMON_TEST_OBJS:.o=)
COMMON_TEST_COMMON_OBJS := \
common/autodata.o \
common/randbytes.o \
+ common/clock_time.o \
common/setup.o \
common/utils.o
diff --git a/common/test/run-json.c b/common/test/run-json.c
index 3f1069ee..18130c23 100644
--- a/common/test/run-json.c
+++ b/common/test/run-json.c
@@ -4,6 +4,7 @@
#include <assert.h>
#include <ccan/tal/str/str.h>
#include <common/channel_type.h>
+#include <common/clock_time.h>
#include <common/json_filter.h>
#include <common/randbytes.h>
#include <common/sciddir_or_pubkey.h>
diff --git a/common/test/run-param.c b/common/test/run-param.c
index 1778942a..2f73a70e 100644
--- a/common/test/run-param.c
+++ b/common/test/run-param.c
@@ -7,6 +7,7 @@
#include <assert.h>
#include <ccan/array_size/array_size.h>
#include <common/channel_type.h>
+#include <common/clock_time.h>
#include <common/memleak.h>
#include <common/randbytes.h>
#include <common/setup.h>
diff --git a/common/test/run-route_blinding_test.c b/common/test/run-route_blinding_test.c
index 26b52e60..cbd30ad4 100644
--- a/common/test/run-route_blinding_test.c
+++ b/common/test/run-route_blinding_test.c
@@ -10,6 +10,7 @@
#include <ccan/tal/grab_file/grab_file.h>
#include <ccan/tal/path/path.h>
#include <common/channel_id.h>
+#include <common/clock_time.h>
#include <common/json_parse.h>
#include <common/json_stream.h>
#include <common/randbytes.h>
diff --git a/common/trace.c b/common/trace.c
index e3018a00..793c72e2 100644
--- a/common/trace.c
+++ b/common/trace.c
@@ -75,7 +75,7 @@ static void init_span(struct span *s,
const char *name,
struct span *parent)
{
- struct timeabs now = time_now();
+ struct timeabs now = time_now(); /* discouraged: but tracing wants non-dev time */
s->key = key;
s->id = pseudorand_u64();
@@ -366,7 +366,7 @@ void trace_span_end(const void *key)
trace_check_tree();
- struct timeabs now = time_now();
+ struct timeabs now = time_now(); /* discouraged: but tracing wants non-dev time */
s->end_time = (now.ts.tv_sec * 1000000) + now.ts.tv_nsec / 1000;
DTRACE_PROBE1(lightningd, span_end, s->id);
if (trace_to_file) {
diff --git a/connectd/connectd.c b/connectd/connectd.c
index ffe93821..f1c9a1b7 100644
--- a/connectd/connectd.c
+++ b/connectd/connectd.c
@@ -18,6 +18,7 @@
#include <ccan/tal/str/str.h>
#include <common/bech32.h>
#include <common/bech32_util.h>
+#include <common/clock_time.h>
#include <common/cryptomsg.h>
#include <common/daemon_conn.h>
#include <common/dev_disconnect.h>
@@ -2260,7 +2261,7 @@ static void dev_report_fds(struct daemon *daemon, const u8 *msg)
void update_recent_timestamp(struct daemon *daemon, struct gossmap *gossmap)
{
/* 2 hours allows for some clock drift, not too much gossip */
- u32 recent = time_now().ts.tv_sec - 7200;
+ u32 recent = clock_time().ts.tv_sec - 7200;
/* Only update every minute */
if (daemon->gossip_recent_time + 60 > recent)
diff --git a/devtools/bolt11-cli.c b/devtools/bolt11-cli.c
index 02204fb1..17a7fa6b 100644
--- a/devtools/bolt11-cli.c
+++ b/devtools/bolt11-cli.c
@@ -10,6 +10,7 @@
#include <ccan/time/time.h>
#include <common/bech32.h>
#include <common/bolt11.h>
+#include <common/clock_time.h>
#include <common/features.h>
#include <common/setup.h>
#include <common/utils.h>
@@ -109,7 +110,7 @@ static void encode(const tal_t *ctx,
struct pubkey me;
bool explicit_n = false;
- b11->timestamp = time_now().ts.tv_sec;
+ b11->timestamp = clock_time().ts.tv_sec;
b11->chain = chainparams_for_network("regtest");
b11->expiry = 3600;
b11->min_final_cltv_expiry = DEFAULT_FINAL_CLTV_DELTA;
diff --git a/devtools/gossipwith.c b/devtools/gossipwith.c
index 84b39682..7f85e8ee 100644
--- a/devtools/gossipwith.c
+++ b/devtools/gossipwith.c
@@ -8,6 +8,7 @@
#include <ccan/str/hex/hex.h>
#include <ccan/tal/str/str.h>
#include <ccan/time/time.h>
+#include <common/clock_time.h>
#include <common/cryptomsg.h>
#include <common/features.h>
#include <common/ping.h>
@@ -209,7 +210,7 @@ static struct io_plan *handshake_success(struct io_conn *conn,
msg = towire_gossip_timestamp_filter(NULL,
&chainparams->genesis_blockhash,
all_gossip ? 0
- : no_gossip ? 0xFFFFFFFF : time_now().ts.tv_sec,
+ : no_gossip ? 0xFFFFFFFF : clock_time().ts.tv_sec,
0xFFFFFFFF);
sync_crypto_write(peer_fd, cs, take(msg));
}
diff --git a/gossipd/gossip_store.c b/gossipd/gossip_store.c
index c68e2454..eff86c67 100644
--- a/gossipd/gossip_store.c
+++ b/gossipd/gossip_store.c
@@ -3,6 +3,7 @@
#include <ccan/noerr/noerr.h>
#include <ccan/read_write_all/read_write_all.h>
#include <ccan/tal/str/str.h>
+#include <common/clock_time.h>
#include <common/gossip_store.h>
#include <common/status.h>
#include <common/utils.h>
@@ -341,7 +342,7 @@ static int gossip_store_compact(struct daemon *daemon,
/* If we have any contents, and the file is less than 1 hour
* old, say "seems good" */
- if (st.st_mtime > time_now().ts.tv_sec - 3600 && *total_len > 1) {
+ if (st.st_mtime > clock_time().ts.tv_sec - 3600 && *total_len > 1) {
*populated = true;
}
diff --git a/gossipd/gossipd.c b/gossipd/gossipd.c
index 629059d2..15bd4a46 100644
--- a/gossipd/gossipd.c
+++ b/gossipd/gossipd.c
@@ -12,6 +12,7 @@
*/
#include "config.h"
#include <ccan/tal/str/str.h>
+#include <common/clock_time.h>
#include <common/daemon_conn.h>
#include <common/ecdh_hsmd.h>
#include <common/memleak.h>
@@ -371,7 +372,7 @@ static void master_or_connectd_gone(struct daemon_conn *dc UNUSED)
* our canned tests, and usually old gossip is better than no gossip */
bool timestamp_reasonable(const struct daemon *daemon, u32 timestamp)
{
- u64 now = time_now().ts.tv_sec;
+ u64 now = clock_time().ts.tv_sec;
/* More than one day ahead? */
if (timestamp > now + 24*60*60)
@@ -596,7 +597,7 @@ int main(int argc, char *argv[])
/* Note the use of time_mono() here. That's a monotonic clock, which
* is really useful: it can only be used to measure relative events
* (there's no correspondence to time-since-Ken-grew-a-beard or
- * anything), but unlike time_now(), this will never jump backwards by
+ * anything), but unlike time_now, this will never jump backwards by
* half a second and leave me wondering how my tests failed CI! */
timers_init(&daemon->timers, time_mono());
diff --git a/gossipd/gossmap_manage.c b/gossipd/gossmap_manage.c
index b93c091a..3227465d 100644
--- a/gossipd/gossmap_manage.c
+++ b/gossipd/gossmap_manage.c
@@ -2,6 +2,7 @@
#include <bitcoin/script.h>
#include <ccan/array_size/array_size.h>
#include <ccan/tal/str/str.h>
+#include <common/clock_time.h>
#include <common/daemon_conn.h>
#include <common/gossip_store.h>
#include <common/gossmap.h>
@@ -357,7 +358,7 @@ static bool channel_already_dying(const struct chan_dying dying_channels[],
/* Every half a week we look for dead channels (faster in dev) */
static void prune_network(struct gossmap_manage *gm)
{
- u64 now = time_now().ts.tv_sec;
+ u64 now = clock_time().ts.tv_sec;
/* Anything below this highwater mark ought to be pruned */
const s64 highwater = now - GOSSIP_PRUNE_INTERVAL(gm->daemon->dev_fast_gossip_prune);
const struct gossmap_node *me;
diff --git a/gossipd/seeker.c b/gossipd/seeker.c
index 4ba862e9..c632e8b8 100644
--- a/gossipd/seeker.c
+++ b/gossipd/seeker.c
@@ -3,6 +3,7 @@
#include <ccan/asort/asort.h>
#include <ccan/intmap/intmap.h>
#include <ccan/tal/str/str.h>
+#include <common/clock_time.h>
#include <common/daemon_conn.h>
#include <common/decode_array.h>
#include <common/gossmap.h>
@@ -242,7 +243,7 @@ static void enable_gossip_stream(struct seeker *seeker, struct peer *peer,
start = 0;
} else {
/* Just in case they care */
- start = time_now().ts.tv_sec - GOSSIP_SEEKER_INTERVAL(seeker) * 10;
+ start = clock_time().ts.tv_sec - GOSSIP_SEEKER_INTERVAL(seeker) * 10;
}
status_peer_debug(&peer->id, "seeker: starting gossip (%s)",
diff --git a/gossipd/test/run-check_channel_announcement.c b/gossipd/test/run-check_channel_announcement.c
index d396ebb4..9de5a730 100644
--- a/gossipd/test/run-check_channel_announcement.c
+++ b/gossipd/test/run-check_channel_announcement.c
@@ -33,6 +33,7 @@ In particular, we set feature bit 19. The spec says we should set feature bit 1
#include <assert.h>
#include <common/blinding.h>
#include <common/channel_type.h>
+#include <common/clock_time.h>
#include <common/ecdh.h>
#include <common/json_stream.h>
#include <common/memleak.h>
diff --git a/gossipd/test/run-extended-info.c b/gossipd/test/run-extended-info.c
index d01c93de..c5f3752b 100644
--- a/gossipd/test/run-extended-info.c
+++ b/gossipd/test/run-extended-info.c
@@ -5,6 +5,7 @@
#include <ccan/str/hex/hex.h>
#include <common/blinding.h>
#include <common/channel_type.h>
+#include <common/clock_time.h>
#include <common/ecdh.h>
#include <common/json_parse.h>
#include <common/json_stream.h>
diff --git a/gossipd/test/run-txout_failure.c b/gossipd/test/run-txout_failure.c
index c4c45e1e..d8d54545 100644
--- a/gossipd/test/run-txout_failure.c
+++ b/gossipd/test/run-txout_failure.c
@@ -3,6 +3,7 @@
#include "../common/timeout.c"
#include <common/blinding.h>
#include <common/channel_type.h>
+#include <common/clock_time.h>
#include <common/daemon_conn.h>
#include <common/ecdh.h>
#include <common/json_stream.h>
diff --git a/lightningd/channel.c b/lightningd/channel.c
index 5e754555..622c866d 100644
--- a/lightningd/channel.c
+++ b/lightningd/channel.c
@@ -1,6 +1,7 @@
#include "config.h"
#include <ccan/tal/str/str.h>
#include <common/blockheight_states.h>
+#include <common/clock_time.h>
#include <common/closing_fee.h>
#include <common/fee_states.h>
#include <common/json_command.h>
@@ -1006,7 +1007,7 @@ void channel_set_state(struct channel *channel,
struct channel_state_change *change;
change = new_channel_state_change(channel->state_changes,
- time_now(),
+ clock_time(),
old_state,
state,
reason,
diff --git a/lightningd/channel_gossip.c b/lightningd/channel_gossip.c
index 79b12ffc..6cc92520 100644
--- a/lightningd/channel_gossip.c
+++ b/lightningd/channel_gossip.c
@@ -1,6 +1,7 @@
#include "config.h"
#include <ccan/array_size/array_size.h>
#include <ccan/cast/cast.h>
+#include <common/clock_time.h>
#include <common/memleak.h>
#include <common/timeout.h>
#include <common/wire_error.h>
@@ -580,7 +581,7 @@ static void arm_refresh_timer(struct channel *channel)
{
struct lightningd *ld = channel->peer->ld;
struct channel_gossip *cg = channel->channel_gossip;
- struct timeabs now = time_now(), due;
+ struct timeabs now = clock_time(), due;
u32 timestamp;
if (!channel_update_details(cg->cupdate, ×tamp, NULL)) {
@@ -1186,7 +1187,7 @@ void channel_gossip_init_done(struct lightningd *ld)
static void channel_reestablished_stable(struct channel *channel)
{
channel->stable_conn_timer = NULL;
- channel->last_stable_connection = time_now().ts.tv_sec;
+ channel->last_stable_connection = clock_time().ts.tv_sec;
wallet_channel_save(channel->peer->ld->wallet, channel);
}
diff --git a/lightningd/coin_mvts.c b/lightningd/coin_mvts.c
index dcbc3059..a33037e0 100644
--- a/lightningd/coin_mvts.c
+++ b/lightningd/coin_mvts.c
@@ -1,5 +1,6 @@
#include "config.h"
#include <ccan/tal/str/str.h>
+#include <common/clock_time.h>
#include <common/json_command.h>
#include <lightningd/channel.h>
#include <lightningd/coin_mvts.h>
@@ -10,7 +11,7 @@ struct channel_coin_mvt *new_channel_mvt_invoice_hin(const tal_t *ctx,
const struct htlc_in *hin,
const struct channel *channel)
{
- return new_channel_coin_mvt(ctx, channel, time_now().ts.tv_sec,
+ return new_channel_coin_mvt(ctx, channel, coinmvt_current_time(),
&hin->payment_hash, NULL, NULL,
COIN_CREDIT, hin->msat,
mk_mvt_tags(MVT_INVOICE),
@@ -30,7 +31,7 @@ struct channel_coin_mvt *new_channel_mvt_routed_hin(const tal_t *ctx,
hin->payload->amt_to_forward))
return NULL;
- return new_channel_coin_mvt(ctx, channel, time_now().ts.tv_sec,
+ return new_channel_coin_mvt(ctx, channel, coinmvt_current_time(),
&hin->payment_hash, NULL, NULL,
COIN_CREDIT, hin->msat,
mk_mvt_tags(MVT_ROUTED),
@@ -41,7 +42,7 @@ struct channel_coin_mvt *new_channel_mvt_invoice_hout(const tal_t *ctx,
const struct htlc_out *hout,
const struct channel *channel)
{
- return new_channel_coin_mvt(ctx, channel, time_now().ts.tv_sec,
+ return new_channel_coin_mvt(ctx, channel, coinmvt_current_time(),
&hout->payment_hash,
&hout->partid,
&hout->groupid,
@@ -54,7 +55,7 @@ struct channel_coin_mvt *new_channel_mvt_routed_hout(const tal_t *ctx,
const struct htlc_out *hout,
const struct channel *channel)
{
- return new_channel_coin_mvt(ctx, channel, time_now().ts.tv_sec,
+ return new_channel_coin_mvt(ctx, channel, coinmvt_current_time(),
&hout->payment_hash, NULL, NULL,
COIN_DEBIT, hout->msat,
mk_mvt_tags(MVT_ROUTED),
@@ -66,7 +67,7 @@ struct channel_coin_mvt *new_channel_mvt_penalty_adj(const tal_t *ctx,
struct amount_msat amount,
enum coin_mvt_dir direction)
{
- return new_channel_coin_mvt(ctx, channel, time_now().ts.tv_sec,
+ return new_channel_coin_mvt(ctx, channel, coinmvt_current_time(),
NULL, NULL, NULL,
direction, amount,
mk_mvt_tags(MVT_PENALTY_ADJ),
@@ -107,7 +108,7 @@ void send_account_balance_snapshot(struct lightningd *ld)
struct peer_node_id_map_iter it;
snap->blockheight = get_block_height(ld->topology);
- snap->timestamp = time_now().ts.tv_sec;
+ snap->timestamp = coinmvt_current_time();
snap->node_id = &ld->our_nodeid;
/* Add the 'wallet' account balance */
diff --git a/lightningd/dual_open_control.c b/lightningd/dual_open_control.c
index 1dc4c6a4..ad55ca86 100644
--- a/lightningd/dual_open_control.c
+++ b/lightningd/dual_open_control.c
@@ -8,6 +8,7 @@
#include <ccan/mem/mem.h>
#include <ccan/tal/str/str.h>
#include <common/blockheight_states.h>
+#include <common/clock_time.h>
#include <common/json_channel_type.h>
#include <common/json_command.h>
#include <common/psbt_open.h>
@@ -1333,7 +1334,7 @@ wallet_update_channel_commit(struct lightningd *ld,
&channel->peer->id,
&channel->cid,
channel->scid,
- time_now(),
+ clock_time(),
DUALOPEND_OPEN_COMMIT_READY,
DUALOPEND_OPEN_COMMITTED,
REASON_REMOTE,
@@ -1431,7 +1432,7 @@ wallet_commit_channel(struct lightningd *ld,
&channel->peer->id,
&channel->cid,
channel->scid,
- time_now(),
+ clock_time(),
DUALOPEND_OPEN_INIT,
DUALOPEND_OPEN_COMMIT_READY,
REASON_REMOTE,
diff --git a/lightningd/gossip_generation.c b/lightningd/gossip_generation.c
index 7a59f0e9..433f4fb8 100644
--- a/lightningd/gossip_generation.c
+++ b/lightningd/gossip_generation.c
@@ -1,6 +1,7 @@
#include "config.h"
#include <ccan/cast/cast.h>
#include <ccan/mem/mem.h>
+#include <common/clock_time.h>
#include <lightningd/channel.h>
#include <lightningd/gossip_generation.h>
#include <lightningd/lightningd.h>
@@ -119,7 +120,7 @@ u8 *unsigned_channel_update(const tal_t *ctx,
message_flags |= ROUTING_OPT_DONT_FORWARD;
/* Make sure timestamp changes! */
- timestamp = time_now().ts.tv_sec;
+ timestamp = clock_time().ts.tv_sec;
/* FIXME: @endothermicdev points out that our clock could be
* wrong once, and now we'll keep producing future timestamps.
* We could sanity check that old_timestamp is within 2 weeks and
@@ -412,7 +413,7 @@ u8 *unsigned_node_announcement(const tal_t *ctx,
{
secp256k1_ecdsa_signature sig;
const struct wireaddr *addrs;
- u32 timestamp = time_now().ts.tv_sec;
+ u32 timestamp = clock_time().ts.tv_sec;
addrs = gather_addresses(tmpctx, ld);
/* Even if we're quick, don't duplicate timestamps! */
diff --git a/lightningd/htlc_end.c b/lightningd/htlc_end.c
index e2a06170..82912aeb 100644
--- a/lightningd/htlc_end.c
+++ b/lightningd/htlc_end.c
@@ -1,6 +1,7 @@
#include "config.h"
#include <ccan/cast/cast.h>
#include <ccan/tal/str/str.h>
+#include <common/clock_time.h>
#include <common/htlc_wire.h>
#include <common/utils.h>
#include <lightningd/htlc_end.h>
@@ -158,7 +159,7 @@ struct htlc_in *new_htlc_in(const tal_t *ctx,
hin->we_filled = NULL;
hin->payload = NULL;
- hin->received_time = time_now();
+ hin->received_time = clock_time();
return htlc_in_check(hin, "new_htlc_in");
}
diff --git a/lightningd/invoice.c b/lightningd/invoice.c
index c609508b..dc823919 100644
--- a/lightningd/invoice.c
+++ b/lightningd/invoice.c
@@ -9,6 +9,7 @@
#include <common/bolt11_json.h>
#include <common/bolt12_id.h>
#include <common/bolt12_merkle.h>
+#include <common/clock_time.h>
#include <common/json_command.h>
#include <common/randbytes.h>
#include <common/random_select.h>
@@ -1189,7 +1190,7 @@ static struct command_result *json_invoice(struct command *cmd,
info->b11 = new_bolt11(info, msatoshi_val);
info->b11->chain = chainparams;
- info->b11->timestamp = time_now().ts.tv_sec;
+ info->b11->timestamp = clock_time().ts.tv_sec;
info->b11->payment_hash = rhash;
info->b11->receiver_id = cmd->ld->our_nodeid;
info->b11->min_final_cltv_expiry = *cltv;
diff --git a/lightningd/log.c b/lightningd/log.c
index 5b5bcd5a..8e12a6a1 100644
--- a/lightningd/log.c
+++ b/lightningd/log.c
@@ -5,6 +5,7 @@
#include <ccan/str/hex/hex.h>
#include <ccan/tal/link/link.h>
#include <ccan/tal/str/str.h>
+#include <common/clock_time.h>
#include <common/configvar.h>
#include <common/json_command.h>
#include <common/memleak.h>
@@ -398,7 +399,7 @@ struct log_book *new_log_book(struct lightningd *ld, size_t max_mem)
log_book->prefix = tal_strdup(log_book, "");
list_head_init(&log_book->print_filters);
list_head_init(&log_book->loggers);
- log_book->init_time = time_now();
+ log_book->init_time = clock_time();
log_book->ld = ld;
log_book->cache = tal(log_book, struct node_id_map);
node_id_map_init(log_book->cache);
@@ -523,7 +524,7 @@ static struct log_entry *new_log_entry(struct logger *log, enum log_level level,
tal_resize(&log->log_book->log, tal_count(log->log_book->log) * 2);
l = &log->log_book->log[log->log_book->num_entries];
- l->time = time_now();
+ l->time = clock_time();
l->level = level;
l->skipped = 0;
l->prefix = log_prefix_get(log->prefix);
@@ -1012,7 +1013,7 @@ void log_backtrace_exit(void)
int fd;
char timebuf[sizeof("YYYYmmddHHMMSS")];
char logfile[sizeof("/tmp/lightning-crash.log.") + sizeof(timebuf)];
- struct timeabs time = time_now();
+ struct timeabs time = clock_time();
strftime(timebuf, sizeof(timebuf), "%Y%m%d%H%M%S", gmtime(&time.ts.tv_sec));
diff --git a/lightningd/opening_control.c b/lightningd/opening_control.c
index 8570160a..eaa806ca 100644
--- a/lightningd/opening_control.c
+++ b/lightningd/opening_control.c
@@ -5,6 +5,7 @@
#include <ccan/tal/str/str.h>
#include <common/addr.h>
#include <common/blockheight_states.h>
+#include <common/clock_time.h>
#include <common/fee_states.h>
#include <common/json_channel_type.h>
#include <common/json_command.h>
@@ -240,7 +241,7 @@ wallet_commit_channel(struct lightningd *ld,
wallet_channel_insert(ld->wallet, channel);
/* Notify that channel state changed (from non existant to existant) */
- timestamp = time_now();
+ timestamp = clock_time();
notify_channel_state_changed(ld, &channel->peer->id,
&channel->cid,
channel->scid, /* NULL */
diff --git a/lightningd/pay.c b/lightningd/pay.c
index 068e142e..17a41a2e 100644
--- a/lightningd/pay.c
+++ b/lightningd/pay.c
@@ -4,6 +4,7 @@
#include <ccan/tal/str/str.h>
#include <common/blinding.h>
#include <common/bolt12_merkle.h>
+#include <common/clock_time.h>
#include <common/json_command.h>
#include <common/onion_decode.h>
#include <common/onionreply.h>
@@ -1147,7 +1148,7 @@ send_payment_core(struct lightningd *ld,
payment = wallet_add_payment(cmd,
ld->wallet,
- time_now().ts.tv_sec,
+ clock_time().ts.tv_sec,
NULL,
rhash,
partid,
@@ -1461,7 +1462,7 @@ static struct command_result *self_payment(struct lightningd *ld,
payment = wallet_add_payment(tmpctx,
ld->wallet,
- time_now().ts.tv_sec,
+ clock_time().ts.tv_sec,
NULL,
rhash,
partid,
@@ -1791,7 +1792,7 @@ static void register_payment_and_waiter(struct command *cmd,
{
wallet_add_payment(cmd,
cmd->ld->wallet,
- time_now().ts.tv_sec,
+ clock_time().ts.tv_sec,
NULL,
payment_hash,
partid,
diff --git a/lightningd/runes.c b/lightningd/runes.c
index 70821bcb..36a4b10d 100644
--- a/lightningd/runes.c
+++ b/lightningd/runes.c
@@ -4,6 +4,7 @@
#include <ccan/json_escape/json_escape.h>
#include <ccan/tal/str/str.h>
#include <common/bolt12.h>
+#include <common/clock_time.h>
#include <common/json_command.h>
#include <common/overflows.h>
#include <hsmd/hsmd_wiregen.h>
@@ -939,7 +940,7 @@ static struct command_result *json_checkrune(struct command *cmd,
cinfo.buf = buffer;
cinfo.method = method;
cinfo.params = methodparams;
- cinfo.now = time_now();
+ cinfo.now = clock_time();
strmap_init(&cinfo.cached_params);
err = rune_is_ours(cmd->ld, ras->rune);
diff --git a/plugins/askrene/askrene.c b/plugins/askrene/askrene.c
index d76afa68..d25fc4ae 100644
--- a/plugins/askrene/askrene.c
+++ b/plugins/askrene/askrene.c
@@ -9,7 +9,7 @@
#include "config.h"
#include <ccan/array_size/array_size.h>
#include <ccan/tal/str/str.h>
-#include <ccan/time/time.h>
+#include <common/clock_time.h>
#include <common/dijkstra.h>
#include <common/gossmap.h>
#include <common/gossmods_listpeerchannels.h>
@@ -1061,7 +1061,7 @@ static struct command_result *json_askrene_inform_channel(struct command *cmd,
*amount = AMOUNT_MSAT(0);
if (command_check_only(cmd))
return command_check_done(cmd);
- c = layer_add_constraint(layer, scidd, time_now().ts.tv_sec,
+ c = layer_add_constraint(layer, scidd, clock_time().ts.tv_sec,
NULL, amount);
goto output;
case INFORM_UNCONSTRAINED:
@@ -1069,7 +1069,7 @@ static struct command_result *json_askrene_inform_channel(struct command *cmd,
* that no reserves were used) */
if (command_check_only(cmd))
return command_check_done(cmd);
- c = layer_add_constraint(layer, scidd, time_now().ts.tv_sec,
+ c = layer_add_constraint(layer, scidd, clock_time().ts.tv_sec,
amount, NULL);
goto output;
case INFORM_SUCCEEDED:
@@ -1130,7 +1130,7 @@ static struct command_result *json_askrene_bias_channel(struct command *cmd,
plugin_log(cmd->plugin, LOG_TRACE, "%s called: %.*s", __func__,
json_tok_full_len(params), json_tok_full(buffer, params));
- timestamp = time_now().ts.tv_sec;
+ timestamp = clock_time().ts.tv_sec;
b = layer_set_bias(layer, scidd, description, *bias, *relative,
timestamp);
response = jsonrpc_stream_success(cmd);
@@ -1167,7 +1167,7 @@ static struct command_result *json_askrene_bias_node(struct command *cmd,
plugin_log(cmd->plugin, LOG_TRACE, "%s called: %.*s", __func__,
json_tok_full_len(params), json_tok_full(buffer, params));
- timestamp = time_now().ts.tv_sec;
+ timestamp = clock_time().ts.tv_sec;
b = layer_set_node_bias(layer, node, description, *bias, *relative,
*out_dir, timestamp);
response = jsonrpc_stream_success(cmd);
diff --git a/plugins/askrene/layer.c b/plugins/askrene/layer.c
index 043b9168..2ef27d8f 100644
--- a/plugins/askrene/layer.c
+++ b/plugins/askrene/layer.c
@@ -3,6 +3,7 @@
#include <ccan/htable/htable_type.h>
#include <ccan/json_out/json_out.h>
#include <ccan/tal/str/str.h>
+#include <common/clock_time.h>
#include <common/gossmap.h>
#include <common/json_stream.h>
#include <common/memleak.h>
@@ -696,7 +697,7 @@ static void load_channel_bias(struct plugin *plugin,
s8 bias_factor;
/* If we read an old version without timestamp, just put the current
* time. */
- u64 timestamp = time_now().ts.tv_sec;
+ u64 timestamp = clock_time().ts.tv_sec;
fromwire_short_channel_id_dir(cursor, len, &scidd);
bias_factor = fromwire_s8(cursor, len);
diff --git a/plugins/autoclean.c b/plugins/autoclean.c
index e4601cb0..70aa12f4 100644
--- a/plugins/autoclean.c
+++ b/plugins/autoclean.c
@@ -2,6 +2,7 @@
#include <ccan/array_size/array_size.h>
#include <ccan/mem/mem.h>
#include <ccan/tal/str/str.h>
+#include <common/clock_time.h>
#include <common/json_param.h>
#include <common/json_stream.h>
#include <common/memleak.h>
@@ -546,7 +547,7 @@ static struct command_result *list_done(struct command *cmd,
const struct subsystem_ops *ops = get_subsystem_ops(subsystem);
const jsmntok_t *t, *inv = json_get_member(buf, result, ops->arr_name);
size_t i;
- u64 now = time_now().ts.tv_sec;
+ u64 now = clock_time().ts.tv_sec;
json_for_each_arr(i, t, inv) {
struct per_variant *variant;
diff --git a/plugins/bkpr/bookkeeper.c b/plugins/bkpr/bookkeeper.c
index bba69efb..7521b210 100644
--- a/plugins/bkpr/bookkeeper.c
+++ b/plugins/bkpr/bookkeeper.c
@@ -9,6 +9,7 @@
#include <ccan/time/time.h>
#include <common/bolt11.h>
#include <common/bolt12.h>
+#include <common/clock_time.h>
#include <common/coin_mvt.h>
#include <common/json_param.h>
#include <common/json_stream.h>
diff --git a/plugins/bkpr/incomestmt.c b/plugins/bkpr/incomestmt.c
index d9041f56..2b5cb334 100644
--- a/plugins/bkpr/incomestmt.c
+++ b/plugins/bkpr/incomestmt.c
@@ -4,6 +4,7 @@
#include <ccan/array_size/array_size.h>
#include <ccan/json_escape/json_escape.h>
#include <ccan/tal/str/str.h>
+#include <common/clock_time.h>
#include <common/coin_mvt.h>
#include <common/json_parse_simple.h>
#include <common/json_stream.h>
@@ -438,7 +439,7 @@ const char *csv_filename(const tal_t *ctx, const struct csv_fmt *fmt)
{
return tal_fmt(ctx, "cln_incomestmt_%s_%lu.csv",
fmt->fmt_name,
- (unsigned long)time_now().ts.tv_sec);
+ (unsigned long)clock_time().ts.tv_sec);
}
static void cointrack_header(FILE *csvf)
diff --git a/plugins/bkpr/test/run-recorder.c b/plugins/bkpr/test/run-recorder.c
index bc2177e7..84859349 100644
--- a/plugins/bkpr/test/run-recorder.c
+++ b/plugins/bkpr/test/run-recorder.c
@@ -4,6 +4,7 @@
#include <bitcoin/tx.h>
#include <ccan/tal/str/str.h>
+#include <common/clock_time.h>
#include <common/coin_mvt.h>
#include <common/daemon.h>
#include <common/deprecation.h>
diff --git a/plugins/bkpr/test/run-sql.c b/plugins/bkpr/test/run-sql.c
index 28da98b7..665c4d0e 100644
--- a/plugins/bkpr/test/run-sql.c
+++ b/plugins/bkpr/test/run-sql.c
@@ -3,6 +3,7 @@
#include "plugins/bkpr/sql.c"
#include "plugins/libplugin.c"
+#include <common/clock_time.h>
#include <common/json_filter.h>
#include <common/json_stream.h>
#include <common/fee_states.h>
diff --git a/plugins/chanbackup.c b/plugins/chanbackup.c
index 09afcb75..3b0d1286 100644
--- a/plugins/chanbackup.c
+++ b/plugins/chanbackup.c
@@ -6,6 +6,7 @@
#include <ccan/read_write_all/read_write_all.h>
#include <ccan/tal/grab_file/grab_file.h>
#include <ccan/tal/str/str.h>
+#include <common/clock_time.h>
#include <common/json_param.h>
#include <common/json_stream.h>
#include <common/memleak.h>
@@ -137,7 +138,7 @@ static void write_scb(struct plugin *p,
struct modern_scb_chan **scb_chan_arr)
{
const struct chanbackup *cb = chanbackup(p);
- u32 timestamp = time_now().ts.tv_sec;
+ u32 timestamp = clock_time().ts.tv_sec;
u8 *decrypted_scb = towire_static_chan_backup_with_tlvs(tmpctx,
VERSION,
diff --git a/plugins/fetchinvoice.c b/plugins/fetchinvoice.c
index 64414b9e..7a71eb44 100644
--- a/plugins/fetchinvoice.c
+++ b/plugins/fetchinvoice.c
@@ -5,6 +5,7 @@
#include <ccan/tal/str/str.h>
#include <common/bolt12_id.h>
#include <common/bolt12_merkle.h>
+#include <common/clock_time.h>
#include <common/features.h>
#include <common/gossmap.h>
#include <common/json_param.h>
@@ -744,7 +745,7 @@ static struct command_result *invreq_done(struct command *cmd,
}
if (base) {
- u64 period_start, period_end, now = time_now().ts.tv_sec;
+ u64 period_start, period_end, now = clock_time().ts.tv_sec;
offer_period_paywindow(recurrence,
sent->invreq->offer_recurrence_paywindow,
sent->invreq->offer_recurrence_base,
@@ -942,7 +943,7 @@ struct command_result *json_fetchinvoice(struct command *cmd,
* (i.e. continuing an existing offer with recurrence is ok)
*/
if (sent->offer->offer_absolute_expiry
- && time_now().ts.tv_sec > *sent->offer->offer_absolute_expiry
+ && clock_time().ts.tv_sec > *sent->offer->offer_absolute_expiry
&& (!recurrence_counter || *recurrence_counter == 0)) {
return command_fail(cmd, OFFER_EXPIRED, "Offer expired");
}
@@ -1581,7 +1582,7 @@ struct command_result *json_sendinvoice(struct command *cmd,
* `invreq_chain`.
*/
sent->inv->invoice_created_at = tal(sent->inv, u64);
- *sent->inv->invoice_created_at = time_now().ts.tv_sec;
+ *sent->inv->invoice_created_at = clock_time().ts.tv_sec;
/* FIXME: Support blinded paths, in which case use fake nodeid */
diff --git a/plugins/keysend.c b/plugins/keysend.c
index 30de252e..56b3b368 100644
--- a/plugins/keysend.c
+++ b/plugins/keysend.c
@@ -3,6 +3,7 @@
#include <ccan/asort/asort.h>
#include <ccan/cast/cast.h>
#include <ccan/tal/str/str.h>
+#include <common/clock_time.h>
#include <common/features.h>
#include <common/json_param.h>
#include <common/json_stream.h>
@@ -446,7 +447,8 @@ static struct command_result *htlc_accepted_call(struct command *cmd,
bigsize_t s;
struct keysend_in *ki;
struct out_req *req;
- struct timeabs now = time_now();
+ /* Even with CLN_DEV_SET_TIME, we need this to change */
+ struct timeabs now = clock_time_progresses();
const char *err;
u64 *allowed;
size_t err_off;
diff --git a/plugins/libplugin-pay.c b/plugins/libplugin-pay.c
index 40814352..58deb4d0 100644
--- a/plugins/libplugin-pay.c
+++ b/plugins/libplugin-pay.c
@@ -3,6 +3,7 @@
#include <ccan/tal/str/str.h>
#include <common/blindedpay.h>
#include <common/bolt11.h>
+#include <common/clock_time.h>
#include <common/daemon.h>
#include <common/dijkstra.h>
#include <common/features.h>
@@ -88,7 +89,7 @@ struct payment *payment_new(tal_t *ctx, struct command *cmd,
p->modifiers = mods;
p->cmd = cmd;
p->finished = false;
- p->start_time = time_now();
+ p->start_time = clock_time();
p->result = NULL;
p->why = NULL;
p->getroute = tal(p, struct getroute_request);
@@ -429,7 +430,7 @@ static void channel_hints_update(struct payment *p,
/* Local channels must have an HTLC budget */
assert(!local || htlc_budget != NULL);
- channel_hint_set_add(root->hints, time_now().ts.tv_sec, scidd, enabled,
+ channel_hint_set_add(root->hints, clock_time().ts.tv_sec, scidd, enabled,
estimated_capacity, overall_capacity, htlc_budget);
hint = channel_hint_set_find(root->hints, scidd);
@@ -1638,7 +1639,7 @@ payment_waitsendpay_finished(struct command *cmd,
assert(p->route != NULL);
- p->end_time = time_now();
+ p->end_time = clock_time();
p->result = tal_sendpay_result_from_json(p, buffer, toks);
if (p->result == NULL) {
@@ -2333,7 +2334,7 @@ void payment_set_step(struct payment *p, enum payment_step newstep)
/* Any final state needs an end_time */
if (p->step >= PAYMENT_STEP_SPLIT)
- p->end_time = time_now();
+ p->end_time = clock_time();
}
struct command_result *payment_continue(struct payment *p)
@@ -2392,7 +2393,7 @@ struct command_result *payment_abort(struct payment *p, enum jsonrpc_errcode cod
va_list ap;
struct payment *root = payment_root(p);
payment_set_step(p, PAYMENT_STEP_FAILED);
- p->end_time = time_now();
+ p->end_time = clock_time();
/* We can fail twice, it seems. */
tal_free(p->failreason);
@@ -2419,7 +2420,7 @@ struct command_result *payment_abort(struct payment *p, enum jsonrpc_errcode cod
struct command_result *payment_fail(struct payment *p, const char *fmt, ...)
{
va_list ap;
- p->end_time = time_now();
+ p->end_time = clock_time();
payment_set_step(p, PAYMENT_STEP_FAILED);
/* We can fail twice, it seems. */
tal_free(p->failreason);
@@ -2645,7 +2646,7 @@ local_channel_hints_listpeerchannels(struct command *cmd,
* observations, and should re-enable some channels that would
* otherwise start out as excluded and remain so until
* forever. */
- channel_hint_set_update(payment_root(p)->hints, time_now());
+ channel_hint_set_update(payment_root(p)->hints, clock_time());
p->mods = gossmods_from_listpeerchannels(
p, p->local_id, buffer, toks, true, gossmod_add_localchan, NULL);
diff --git a/plugins/offers.c b/plugins/offers.c
index 383beff0..735ba87b 100644
--- a/plugins/offers.c
+++ b/plugins/offers.c
@@ -8,6 +8,7 @@
#include <common/bolt11_json.h>
#include <common/bolt12_id.h>
#include <common/bolt12_merkle.h>
+#include <common/clock_time.h>
#include <common/features.h>
#include <common/gossmap.h>
#include <common/iso4217.h>
@@ -1321,7 +1322,7 @@ static void json_add_rune(struct command *cmd, struct json_stream *js, const str
u64 t = atol(alt->value);
if (t) {
- u64 diff, now = time_now().ts.tv_sec;
+ u64 diff, now = clock_time().ts.tv_sec;
/* Need a non-const during construction */
char *v;
diff --git a/plugins/offers_inv_hook.c b/plugins/offers_inv_hook.c
index 3e72fae0..b1f859d4 100644
--- a/plugins/offers_inv_hook.c
+++ b/plugins/offers_inv_hook.c
@@ -3,6 +3,7 @@
#include <ccan/tal/str/str.h>
#include <common/bolt12_id.h>
#include <common/bolt12_merkle.h>
+#include <common/clock_time.h>
#include <common/features.h>
#include <common/json_stream.h>
#include <plugins/offers.h>
@@ -312,7 +313,7 @@ struct command_result *handle_invoice(struct command *cmd,
invexpiry = *inv->inv->invoice_created_at + *inv->inv->invoice_relative_expiry;
else
invexpiry = *inv->inv->invoice_created_at + BOLT12_DEFAULT_REL_EXPIRY;
- if (time_now().ts.tv_sec > invexpiry)
+ if (clock_time().ts.tv_sec > invexpiry)
return fail_inv(cmd, inv, "Expired invoice");
/* BOLT #12:
diff --git a/plugins/offers_invreq_hook.c b/plugins/offers_invreq_hook.c
index 16dd717e..6f8bcc10 100644
--- a/plugins/offers_invreq_hook.c
+++ b/plugins/offers_invreq_hook.c
@@ -5,6 +5,7 @@
#include <common/bech32_util.h>
#include <common/bolt12_id.h>
#include <common/bolt12_merkle.h>
+#include <common/clock_time.h>
#include <common/features.h>
#include <common/gossmap.h>
#include <common/iso4217.h>
@@ -890,7 +891,7 @@ static struct command_result *listoffers_done(struct command *cmd,
if (ir->invreq->offer_absolute_expiry
&& (!ir->invreq->invreq_recurrence_counter
|| *ir->invreq->invreq_recurrence_counter == 0)
- && time_now().ts.tv_sec >= *ir->invreq->offer_absolute_expiry) {
+ && clock_time().ts.tv_sec >= *ir->invreq->offer_absolute_expiry) {
return fail_invreq(cmd, ir, "Offer expired");
}
@@ -1000,7 +1001,7 @@ static struct command_result *listoffers_done(struct command *cmd,
* Midnight 1 January 1970, UTC when the invoice was created.
*/
ir->inv->invoice_created_at = tal(ir->inv, u64);
- *ir->inv->invoice_created_at = time_now().ts.tv_sec;
+ *ir->inv->invoice_created_at = clock_time().ts.tv_sec;
/* BOLT #12:
* - MUST set `invoice_payment_hash` to the SHA256 hash of the
diff --git a/plugins/pay.c b/plugins/pay.c
index 4f44b5e3..a0ef430a 100644
--- a/plugins/pay.c
+++ b/plugins/pay.c
@@ -3,6 +3,7 @@
#include <ccan/cast/cast.h>
#include <ccan/tal/str/str.h>
#include <common/bolt12_merkle.h>
+#include <common/clock_time.h>
#include <common/features.h>
#include <common/gossmap.h>
#include <common/json_param.h>
@@ -143,7 +144,7 @@ static void paystatus_add_payment(struct json_stream *s, const struct payment *p
json_add_string(s, "strategy", p->why);
json_add_string(s, "start_time", timestr);
json_add_u64(s, "age_in_seconds",
- time_to_sec(time_between(time_now(), p->start_time)));
+ time_to_sec(time_between(clock_time(), p->start_time)));
/* Any final state will have an end time. */
if (p->step >= PAYMENT_STEP_SPLIT) {
@@ -1417,7 +1418,7 @@ static struct command_result *json_pay(struct command *cmd,
p->payment_secret = NULL;
}
- if (time_now().ts.tv_sec > invexpiry)
+ if (clock_time().ts.tv_sec > invexpiry)
return command_fail(cmd, PAY_INVOICE_EXPIRED, "Invoice expired");
if (invmsat) {
@@ -1540,7 +1541,7 @@ static struct command_result *handle_channel_hint_update(struct command *cmd,
fmt_amount_msat(tmpctx, hint->estimated_capacity),
fmt_amount_msat(tmpctx, hint->capacity)
);
- channel_hint_set_add(global_hints, time_now().ts.tv_sec, &hint->scid,
+ channel_hint_set_add(global_hints, clock_time().ts.tv_sec, &hint->scid,
hint->enabled, &hint->estimated_capacity,
hint->capacity, NULL);
tal_free(hint);
diff --git a/plugins/renepay/main.c b/plugins/renepay/main.c
index 8d92ea78..21790f26 100644
--- a/plugins/renepay/main.c
+++ b/plugins/renepay/main.c
@@ -5,6 +5,7 @@
#include <ccan/tal/str/str.h>
#include <common/bolt11.h>
#include <common/bolt12_merkle.h>
+#include <common/clock_time.h>
#include <common/features.h>
#include <common/gossmap.h>
#include <common/gossmods_listpeerchannels.h>
@@ -312,7 +313,7 @@ static struct command_result *json_renepay(struct command *cmd, const char *buf,
/* === Is it expired? === */
- const u64 now_sec = time_now().ts.tv_sec;
+ const u64 now_sec = clock_time().ts.tv_sec;
if (now_sec > invexpiry)
return command_fail(cmd, PAY_INVOICE_EXPIRED,
"Invoice expired");
diff --git a/plugins/renepay/mods.c b/plugins/renepay/mods.c
index 34e50581..30d6314a 100644
--- a/plugins/renepay/mods.c
+++ b/plugins/renepay/mods.c
@@ -3,6 +3,7 @@
#include <ccan/bitmap/bitmap.h>
#include <common/amount.h>
#include <common/bolt11.h>
+#include <common/clock_time.h>
#include <common/gossmods_listpeerchannels.h>
#include <common/json_stream.h>
#include <plugins/renepay/json.h>
@@ -917,7 +918,7 @@ REGISTER_PAYMENT_MODIFIER(end, end_cb);
static struct command_result *checktimeout_cb(struct payment *payment)
{
- if (time_after(time_now(), payment->payment_info.stop_time)) {
+ if (time_after(clock_time(), payment->payment_info.stop_time)) {
return payment_fail(payment, PAY_STOPPED_RETRYING, "Timed out");
}
return payment_continue(payment);
@@ -1129,7 +1130,7 @@ REGISTER_PAYMENT_MODIFIER(pendingsendpays, pendingsendpays_cb);
static struct command_result *knowledgerelax_cb(struct payment *payment)
{
- const u64 now_sec = time_now().ts.tv_sec;
+ const u64 now_sec = clock_time().ts.tv_sec;
enum renepay_errorcode err = uncertainty_relax(
pay_plugin->uncertainty, now_sec - pay_plugin->last_time);
if (err)
diff --git a/plugins/renepay/payment.c b/plugins/renepay/payment.c
index 02566b01..c732ecca 100644
--- a/plugins/renepay/payment.c
+++ b/plugins/renepay/payment.c
@@ -3,6 +3,7 @@
#include <bitcoin/privkey.h>
#include <ccan/tal/str/str.h>
#include <ccan/tal/tal.h>
+#include <common/clock_time.h>
#include <common/json_stream.h>
#include <common/memleak.h>
#include <plugins/renepay/json.h>
@@ -96,7 +97,7 @@ bool payment_refresh(struct payment *p){
p->retry = false;
p->waitresult_timer = tal_free(p->waitresult_timer);
- pinfo->start_time = time_now();
+ pinfo->start_time = clock_time();
pinfo->stop_time =
timeabs_add(pinfo->start_time, time_from_sec(pinfo->retryfor));
diff --git a/plugins/renepay/test/run-bottleneck.c b/plugins/renepay/test/run-bottleneck.c
index ec1e934f..eff7f81d 100644
--- a/plugins/renepay/test/run-bottleneck.c
+++ b/plugins/renepay/test/run-bottleneck.c
@@ -14,6 +14,7 @@
#include <bitcoin/chainparams.h>
#include <bitcoin/preimage.h>
#include <ccan/str/hex/hex.h>
+#include <common/clock_time.h>
#include <common/randbytes.h>
#include <common/setup.h>
#include <common/utils.h>
@@ -221,7 +222,7 @@ int main(int argc, char *argv[])
pinfo.maxdelay = 100;
pinfo.final_cltv = 5;
- pinfo.start_time = time_now();
+ pinfo.start_time = clock_time();
pinfo.stop_time = timeabs_add(pinfo.start_time, time_from_sec(10000));
pinfo.base_fee_penalty = 1e-5;
diff --git a/plugins/xpay/xpay.c b/plugins/xpay/xpay.c
index 56dde142..aa59feae 100644
--- a/plugins/xpay/xpay.c
+++ b/plugins/xpay/xpay.c
@@ -7,6 +7,7 @@
#include <ccan/tal/str/str.h>
#include <common/bolt11.h>
#include <common/bolt12.h>
+#include <common/clock_time.h>
#include <common/daemon.h>
#include <common/dijkstra.h>
#include <common/features.h>
@@ -1947,7 +1948,7 @@ static struct command_result *xpay_core(struct command *cmd,
payment->requests = tal_arr(payment, struct out_req *, 0);
payment->prior_results = tal_strdup(payment, "");
payment->deadline = timemono_add(time_mono(), time_from_sec(retryfor));
- payment->start_time = time_now();
+ payment->start_time = clock_time();
payment->start_blockheight = xpay->blockheight;
payment->pay_compat = as_pay;
payment->invstring = tal_strdup(payment, invstring);
@@ -2056,7 +2057,7 @@ static struct command_result *xpay_core(struct command *cmd,
invexpiry = b11->timestamp + b11->expiry;
}
- now = time_now().ts.tv_sec;
+ now = clock_time().ts.tv_sec;
if (now > invexpiry)
return command_fail(cmd, PAY_INVOICE_EXPIRED,
"Invoice expired %"PRIu64" seconds ago",
@@ -2173,7 +2174,7 @@ static struct command_result *age_layer(struct command *timer_cmd, void *unused)
plugin_broken_cb,
NULL);
json_add_string(req->js, "layer", "xpay");
- json_add_u64(req->js, "cutoff", time_now().ts.tv_sec - 3600);
+ json_add_u64(req->js, "cutoff", clock_time().ts.tv_sec - 3600);
return send_outreq(req);
}
diff --git a/tools/bench-gossipd.sh b/tools/bench-gossipd.sh
index 9b4ff526..4bea1552 100755
--- a/tools/bench-gossipd.sh
+++ b/tools/bench-gossipd.sh
@@ -78,7 +78,7 @@ if ! bitcoin-cli -regtest ping >/dev/null 2>&1; then
while ! bitcoin-cli -regtest ping >/dev/null 2>&1; do sleep 1; done
fi
-LIGHTNINGD="./lightningd/lightningd --developer --network=regtest --dev-gossip-time=1550513768"
+LIGHTNINGD="CLN_DEV_SET_TIME=1550513768 ./lightningd/lightningd --developer --network=regtest"
LCLI1="./cli/lightning-cli --lightning-dir=$DIR -R"
if [ -z "$DIR" ]; then
diff --git a/wallet/invoices.c b/wallet/invoices.c
index 0376f179..085618c7 100644
--- a/wallet/invoices.c
+++ b/wallet/invoices.c
@@ -1,5 +1,6 @@
#include "config.h"
#include <ccan/tal/str/str.h>
+#include <common/clock_time.h>
#include <common/timeout.h>
#include <db/bindings.h>
#include <db/common.h>
@@ -178,7 +179,7 @@ static u64 *expired_ids(const tal_t *ctx,
static void trigger_expiration(struct invoices *invoices)
{
u64 *inv_dbids;
- u64 now = time_now().ts.tv_sec;
+ u64 now = clock_time().ts.tv_sec;
struct db_stmt *stmt;
/* Free current expiration timer */
@@ -213,7 +214,7 @@ static void install_expiration_timer(struct invoices *invoices)
struct db_stmt *stmt;
struct timerel rel;
struct timeabs expiry;
- struct timeabs now = time_now();
+ struct timeabs now = clock_time();
assert(!invoices->expiration_timer);
@@ -274,7 +275,7 @@ bool invoices_create(struct invoices *invoices,
{
struct db_stmt *stmt;
u64 expiry_time;
- u64 now = time_now().ts.tv_sec;
+ u64 now = clock_time().ts.tv_sec;
if (invoices_find_by_label(invoices, inv_dbid, label)) {
if (taken(msat))
@@ -608,7 +609,7 @@ bool invoices_resolve(struct invoices *invoices,
/* Assign a pay-index. */
pay_index = get_next_pay_index(invoices->wallet->db);
- paid_timestamp = time_now().ts.tv_sec;
+ paid_timestamp = clock_time().ts.tv_sec;
/* Update database. */
stmt = db_prepare_v2(invoices->wallet->db, SQL("UPDATE invoices"
diff --git a/wallet/wallet.c b/wallet/wallet.c
index 780aba24..4de784e9 100644
--- a/wallet/wallet.c
+++ b/wallet/wallet.c
@@ -5,6 +5,7 @@
#include <ccan/mem/mem.h>
#include <ccan/tal/str/str.h>
#include <channeld/channeld_wiregen.h>
+#include <common/clock_time.h>
#include <common/memleak.h>
#include <common/onionreply.h>
#include <common/trace.h>
@@ -24,6 +25,7 @@
#include <wallet/invoices.h>
#include <wallet/txfilter.h>
#include <wallet/wallet.h>
+#include <wally_bip32.h>
#define SQLITE_MAX_UINT 0x7FFFFFFFFFFFFFFF
#define DIRECTION_INCOMING 0
@@ -4195,7 +4197,7 @@ void wallet_payment_set_status(struct wallet *wallet,
u32 completed_at = 0;
if (newstatus != PAYMENT_PENDING)
- completed_at = time_now().ts.tv_sec;
+ completed_at = clock_time().ts.tv_sec;
stmt = db_prepare_v2(wallet->db,
SQL("UPDATE payments SET status=?, completed_at=?, updated_index=? "
@@ -5350,7 +5352,7 @@ void wallet_forwarded_payment_add(struct wallet *w, const struct htlc_in *in,
if (state == FORWARD_SETTLED || state == FORWARD_FAILED) {
resolved_time = tal(tmpctx, struct timeabs);
- *resolved_time = time_now();
+ *resolved_time = clock_time();
} else {
resolved_time = NULL;
}
@@ -7584,7 +7586,7 @@ void wallet_save_network_event(struct lightningd *ld,
db_bind_u64(stmt, id);
db_bind_node_id(stmt, peer_id);
db_bind_int(stmt, network_event_in_db(etype));
- db_bind_u64(stmt, time_now().ts.tv_sec);
+ db_bind_u64(stmt, clock_time().ts.tv_sec);
if (reason)
db_bind_text(stmt, reason);
else
@@ -7786,7 +7788,7 @@ void migrate_setup_coinmoves(struct lightningd *ld, struct db *db)
{
struct utxo **utxos = db_get_unspent_utxos(tmpctx, db);
struct db_stmt *stmt;
- u64 base_timestamp = time_now().ts.tv_sec - 2;
+ u64 base_timestamp = clock_time().ts.tv_sec - 2;
for (size_t i = 0; i < tal_count(utxos); i++) {
struct chain_coin_mvt *mvt;
Why this scored 34/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.