common/clock_time: wrapper for time_now() so we can override it.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
Rusty Russell
2025-11-13 15:43:31 +10:30
parent 522457a12b
commit dc9b425035
4 changed files with 67 additions and 1 deletions

View File

@@ -21,6 +21,7 @@ COMMON_SRC_NOGEN := \
common/channel_config.c \ common/channel_config.c \
common/channel_id.c \ common/channel_id.c \
common/channel_type.c \ common/channel_type.c \
common/clock_time.c \
common/close_tx.c \ common/close_tx.c \
common/codex32.c \ common/codex32.c \
common/coin_mvt.c \ common/coin_mvt.c \

36
common/clock_time.c Normal file
View File

@@ -0,0 +1,36 @@
#include "config.h"
#include <assert.h>
#include <common/clock_time.h>
static bool used = false;
static struct timeabs dev_override;
bool clock_time_overridden(void)
{
return dev_override.ts.tv_sec != 0;
}
struct timeabs clock_time(void)
{
used = true;
if (!clock_time_overridden())
return time_now(); /* discouraged: use clock_time so we can override */
return dev_override;
}
struct timeabs clock_time_progresses_(u64 *progress)
{
if (!clock_time_overridden())
return clock_time();
return timeabs_add(dev_override, time_from_sec((*progress)++));
}
void dev_override_clock_time(struct timeabs now)
{
assert(!used);
dev_override = now;
assert(clock_time_overridden());
}

19
common/clock_time.h Normal file
View File

@@ -0,0 +1,19 @@
#ifndef LIGHTNING_COMMON_CLOCK_TIME_H
#define LIGHTNING_COMMON_CLOCK_TIME_H
#include "config.h"
#include <ccan/short_types/short_types.h>
#include <ccan/time/time.h>
/* We use this instead of time_now, for overriding when we want reproducibility */
struct timeabs clock_time(void);
/* If you need a clock that progresses even when reproducible, use this. */
#define clock_time_progresses() ({static u64 progress; clock_time_progresses_(&progress);})
struct timeabs clock_time_progresses_(u64 *progress);
/* dev setting to override time */
void dev_override_clock_time(struct timeabs now);
/* Did someone override time? */
bool clock_time_overridden(void);
#endif /* LIGHTNING_COMMON_CLOCK_TIME_H */

View File

@@ -8,6 +8,7 @@
#include <ccan/err/err.h> #include <ccan/err/err.h>
#include <ccan/io/io.h> #include <ccan/io/io.h>
#include <ccan/tal/str/str.h> #include <ccan/tal/str/str.h>
#include <common/clock_time.h>
#include <common/daemon.h> #include <common/daemon.h>
#include <common/memleak.h> #include <common/memleak.h>
#include <common/randbytes.h> #include <common/randbytes.h>
@@ -202,7 +203,7 @@ void daemon_shutdown(void)
bool daemon_developer_mode(char *argv[]) bool daemon_developer_mode(char *argv[])
{ {
bool developer = false, debug = false; bool developer = false, debug = false;
const char *entropy_override; const char *entropy_override, *time_override;
for (int i = 1; argv[i]; i++) { for (int i = 1; argv[i]; i++) {
if (streq(argv[i], "--dev-debug-self")) if (streq(argv[i], "--dev-debug-self"))
@@ -233,6 +234,15 @@ bool daemon_developer_mode(char *argv[])
if (entropy_override) if (entropy_override)
dev_override_randbytes(argv[0], atol(entropy_override)); dev_override_randbytes(argv[0], atol(entropy_override));
/* We can also control TIME ITSELF! */
time_override = getenv("CLN_DEV_SET_TIME");
if (time_override) {
struct timeabs t;
t.ts.tv_nsec = 0;
t.ts.tv_sec = atol(time_override);
dev_override_clock_time(t);
}
/* This checks for any tal_steal loops, but it's not free: /* This checks for any tal_steal loops, but it's not free:
* only use if we're already using the fairly heavy memleak * only use if we're already using the fairly heavy memleak
* detection. */ * detection. */