mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-01-17 19:03:42 +01:00
daemon: dev-mocktime command
Useful for precise timing control for testing. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
parent
f3c5aa7634
commit
a3e3f83d9f
@ -15,6 +15,7 @@ DAEMON_LIB_OBJS := $(DAEMON_LIB_SRC:.c=.o)
|
||||
|
||||
DAEMON_SRC := \
|
||||
daemon/bitcoind.c \
|
||||
daemon/controlled_time.c \
|
||||
daemon/cryptopkt.c \
|
||||
daemon/dns.c \
|
||||
daemon/jsonrpc.c \
|
||||
@ -39,6 +40,7 @@ DAEMON_JSMN_HEADERS := daemon/jsmn/jsmn.h
|
||||
DAEMON_HEADERS := \
|
||||
daemon/bitcoind.h \
|
||||
daemon/configdir.h \
|
||||
daemon/controlled_time.h \
|
||||
daemon/cryptopkt.h \
|
||||
daemon/dns.h \
|
||||
daemon/json.h \
|
||||
|
52
daemon/controlled_time.c
Normal file
52
daemon/controlled_time.c
Normal file
@ -0,0 +1,52 @@
|
||||
#include "controlled_time.h"
|
||||
#include "jsonrpc.h"
|
||||
#include "lightningd.h"
|
||||
#include "log.h"
|
||||
#include <inttypes.h>
|
||||
#include <stdio.h>
|
||||
|
||||
static struct timeabs mock_time;
|
||||
|
||||
struct timeabs controlled_time(void)
|
||||
{
|
||||
if (mock_time.ts.tv_sec)
|
||||
return mock_time;
|
||||
return time_now();
|
||||
}
|
||||
|
||||
static void json_mocktime(struct command *cmd,
|
||||
const char *buffer, const jsmntok_t *params)
|
||||
{
|
||||
struct json_result *response = new_json_result(cmd);
|
||||
jsmntok_t *mocktimetok;
|
||||
u64 prev_time, mocktime;
|
||||
char mocktimestr[STR_MAX_CHARS(int64_t)];
|
||||
|
||||
json_get_params(buffer, params,
|
||||
"mocktime", &mocktimetok,
|
||||
NULL);
|
||||
|
||||
prev_time = controlled_time().ts.tv_sec;
|
||||
if (!mocktimetok || !json_tok_u64(buffer, mocktimetok, &mocktime)) {
|
||||
command_fail(cmd, "Need valid mocktime");
|
||||
return;
|
||||
}
|
||||
mock_time.ts.tv_sec = mocktime;
|
||||
|
||||
json_object_start(response, NULL);
|
||||
sprintf(mocktimestr, "%"PRIi64,
|
||||
(s64)controlled_time().ts.tv_sec - prev_time);
|
||||
json_add_string(response, "offset", mocktimestr);
|
||||
json_object_end(response);
|
||||
|
||||
log_unusual(cmd->dstate->base_log,
|
||||
"mocktime set to %"PRIu64, (u64)mock_time.ts.tv_sec);
|
||||
command_success(cmd, response);
|
||||
}
|
||||
|
||||
const struct json_command mocktime_command = {
|
||||
"dev-mocktime",
|
||||
json_mocktime,
|
||||
"Set current time to {mocktime} seconds (0 to return to normal)",
|
||||
"Returns the offset on success"
|
||||
};
|
9
daemon/controlled_time.h
Normal file
9
daemon/controlled_time.h
Normal file
@ -0,0 +1,9 @@
|
||||
#ifndef LIGHTNING_DAEMON_CONTROLLED_TIME_H
|
||||
#define LIGHTNING_DAEMON_CONTROLLED_TIME_H
|
||||
#include "config.h"
|
||||
#include <ccan/short_types/short_types.h>
|
||||
#include <ccan/time/time.h>
|
||||
|
||||
struct timeabs controlled_time(void);
|
||||
|
||||
#endif /* LIGHTNING_DAEMON_CONTROLLED_TIME_H */
|
@ -244,6 +244,7 @@ static const struct json_command *cmdlist[] = {
|
||||
/* Developer/debugging options. */
|
||||
&echo_command,
|
||||
&rhash_command,
|
||||
&mocktime_command
|
||||
};
|
||||
|
||||
static void json_help(struct command *cmd,
|
||||
|
@ -61,4 +61,5 @@ extern const struct json_command getpeers_command;
|
||||
extern const struct json_command newhtlc_command;
|
||||
extern const struct json_command fulfillhtlc_command;
|
||||
extern const struct json_command failhtlc_command;
|
||||
extern const struct json_command mocktime_command;
|
||||
#endif /* LIGHTNING_DAEMON_JSONRPC_H */
|
||||
|
@ -2,6 +2,7 @@
|
||||
* Helper to submit via JSON-RPC and get back response.
|
||||
*/
|
||||
#include "configdir.h"
|
||||
#include "controlled_time.h"
|
||||
#include "json.h"
|
||||
#include "version.h"
|
||||
#include <ccan/err/err.h>
|
||||
@ -39,6 +40,11 @@ static void tal_freefn(void *ptr)
|
||||
tal_free(ptr);
|
||||
}
|
||||
|
||||
struct timeabs controlled_time(void)
|
||||
{
|
||||
return time_now();
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int fd, i, off;
|
||||
|
@ -1,5 +1,6 @@
|
||||
#include "bitcoind.h"
|
||||
#include "configdir.h"
|
||||
#include "controlled_time.h"
|
||||
#include "jsonrpc.h"
|
||||
#include "lightningd.h"
|
||||
#include "log.h"
|
||||
@ -147,7 +148,7 @@ static struct lightningd_state *lightningd_state(void)
|
||||
"lightningd(%u):", (int)getpid());
|
||||
|
||||
list_head_init(&dstate->peers);
|
||||
timers_init(&dstate->timers, time_now());
|
||||
timers_init(&dstate->timers, controlled_time());
|
||||
txwatch_hash_init(&dstate->txwatches);
|
||||
txowatch_hash_init(&dstate->txowatches);
|
||||
dstate->secpctx = secp256k1_context_create(SECP256K1_CONTEXT_VERIFY
|
||||
@ -240,6 +241,9 @@ int main(int argc, char *argv[])
|
||||
/* Create timer to do watches. */
|
||||
setup_watch_timer(dstate);
|
||||
|
||||
/* Make sure we use the artificially-controlled time for timers */
|
||||
io_time_override(controlled_time);
|
||||
|
||||
log_info(dstate->base_log, "Hello world!");
|
||||
|
||||
/* If io_loop returns NULL, either a timer expired, or all fds closed */
|
||||
|
@ -1,3 +1,4 @@
|
||||
#include "controlled_time.h"
|
||||
#include "log.h"
|
||||
#include "pseudorand.h"
|
||||
#include <ccan/array_size/array_size.h>
|
||||
@ -102,7 +103,7 @@ struct log_record *new_log_record(const tal_t *ctx,
|
||||
lr->max_mem = max_mem;
|
||||
lr->print = log_default_print;
|
||||
lr->print_level = printlevel;
|
||||
lr->init_time = time_now();
|
||||
lr->init_time = controlled_time();
|
||||
list_head_init(&lr->log);
|
||||
|
||||
return lr;
|
||||
@ -183,7 +184,7 @@ static struct log_entry *new_log_entry(struct log *log, enum log_level level)
|
||||
{
|
||||
struct log_entry *l = tal(log->lr, struct log_entry);
|
||||
|
||||
l->time = time_now();
|
||||
l->time = controlled_time();
|
||||
l->level = level;
|
||||
l->skipped = 0;
|
||||
l->prefix = log->prefix;
|
||||
|
@ -1,3 +1,4 @@
|
||||
#include "controlled_time.h"
|
||||
#include "lightningd.h"
|
||||
#include "timeout.h"
|
||||
|
||||
@ -14,7 +15,7 @@ void refresh_timeout(struct lightningd_state *dstate, struct timeout *t)
|
||||
{
|
||||
timer_del(&dstate->timers, &t->timer);
|
||||
timer_add(&dstate->timers, &t->timer,
|
||||
timeabs_add(time_now(), t->interval));
|
||||
timeabs_add(controlled_time(), t->interval));
|
||||
}
|
||||
|
||||
/* FIXME: Make all timers one-shot! */
|
||||
|
Loading…
Reference in New Issue
Block a user