diff --git a/common/Makefile b/common/Makefile index e5d3fa69d..333e3321c 100644 --- a/common/Makefile +++ b/common/Makefile @@ -21,6 +21,7 @@ COMMON_SRC_NOGEN := \ common/channel_config.c \ common/channel_id.c \ common/channel_type.c \ + common/clock_time.c \ common/close_tx.c \ common/codex32.c \ common/coin_mvt.c \ diff --git a/common/clock_time.c b/common/clock_time.c new file mode 100644 index 000000000..e3a982d77 --- /dev/null +++ b/common/clock_time.c @@ -0,0 +1,36 @@ +#include "config.h" +#include +#include + +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()); +} diff --git a/common/clock_time.h b/common/clock_time.h new file mode 100644 index 000000000..a267abf46 --- /dev/null +++ b/common/clock_time.h @@ -0,0 +1,19 @@ +#ifndef LIGHTNING_COMMON_CLOCK_TIME_H +#define LIGHTNING_COMMON_CLOCK_TIME_H +#include "config.h" +#include +#include + +/* 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 */ diff --git a/common/daemon.c b/common/daemon.c index f7170ace9..822b715ad 100644 --- a/common/daemon.c +++ b/common/daemon.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -202,7 +203,7 @@ void daemon_shutdown(void) bool daemon_developer_mode(char *argv[]) { bool developer = false, debug = false; - const char *entropy_override; + const char *entropy_override, *time_override; for (int i = 1; argv[i]; i++) { if (streq(argv[i], "--dev-debug-self")) @@ -233,6 +234,15 @@ bool daemon_developer_mode(char *argv[]) if (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: * only use if we're already using the fairly heavy memleak * detection. */