diff --git a/gossipd/gossip_wire.csv b/gossipd/gossip_wire.csv index 63392d87b..b9c988fb8 100644 --- a/gossipd/gossip_wire.csv +++ b/gossipd/gossip_wire.csv @@ -15,6 +15,10 @@ msgdata,gossipctl_init,num_announcable,u16, msgdata,gossipctl_init,announcable,wireaddr,num_announcable msgdata,gossipctl_init,dev_gossip_time,?u32, +# In developer mode, we can mess with time. +msgtype,gossip_dev_set_time,3001 +msgdata,gossip_dev_set_time,dev_gossip_time,u32, + # Pass JSON-RPC getnodes call through msgtype,gossip_getnodes_request,3005 msgdata,gossip_getnodes_request,id,?node_id, diff --git a/gossipd/gossipd.c b/gossipd/gossipd.c index cbf2acdde..81d0ea5f3 100644 --- a/gossipd/gossipd.c +++ b/gossipd/gossipd.c @@ -3065,6 +3065,22 @@ static struct io_plan *dev_compact_store(struct io_conn *conn, done))); return daemon_conn_read_next(conn, daemon->master); } + +static struct io_plan *dev_gossip_set_time(struct io_conn *conn, + struct daemon *daemon, + const u8 *msg) +{ + u32 time; + + if (!fromwire_gossip_dev_set_time(msg, &time)) + master_badmsg(WIRE_GOSSIP_DEV_SET_TIME, msg); + if (!daemon->rstate->gossip_time) + daemon->rstate->gossip_time = tal(daemon->rstate, struct timeabs); + daemon->rstate->gossip_time->ts.tv_sec = time; + daemon->rstate->gossip_time->ts.tv_nsec = 0; + + return daemon_conn_read_next(conn, daemon->master); +} #endif /* DEVELOPER */ /*~ lightningd: so, tell me about this channel, so we can forward to it. */ @@ -3339,6 +3355,8 @@ static struct io_plan *recv_req(struct io_conn *conn, return dev_gossip_memleak(conn, daemon, msg); case WIRE_GOSSIP_DEV_COMPACT_STORE: return dev_compact_store(conn, daemon, msg); + case WIRE_GOSSIP_DEV_SET_TIME: + return dev_gossip_set_time(conn, daemon, msg); #else case WIRE_GOSSIP_QUERY_SCIDS: case WIRE_GOSSIP_SEND_TIMESTAMP_FILTER: @@ -3347,6 +3365,7 @@ static struct io_plan *recv_req(struct io_conn *conn, case WIRE_GOSSIP_DEV_SUPPRESS: case WIRE_GOSSIP_DEV_MEMLEAK: case WIRE_GOSSIP_DEV_COMPACT_STORE: + case WIRE_GOSSIP_DEV_SET_TIME: break; #endif /* !DEVELOPER */ diff --git a/gossipd/test/run-crc32_of_update.c b/gossipd/test/run-crc32_of_update.c index 900cbdb98..f84f4b90f 100644 --- a/gossipd/test/run-crc32_of_update.c +++ b/gossipd/test/run-crc32_of_update.c @@ -59,6 +59,9 @@ bool fromwire_gossipctl_init(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, /* Generated stub for fromwire_gossip_dev_set_max_scids_encode_size */ bool fromwire_gossip_dev_set_max_scids_encode_size(const void *p UNNEEDED, u32 *max UNNEEDED) { fprintf(stderr, "fromwire_gossip_dev_set_max_scids_encode_size called!\n"); abort(); } +/* Generated stub for fromwire_gossip_dev_set_time */ +bool fromwire_gossip_dev_set_time(const void *p UNNEEDED, u32 *dev_gossip_time UNNEEDED) +{ fprintf(stderr, "fromwire_gossip_dev_set_time called!\n"); abort(); } /* Generated stub for fromwire_gossip_dev_suppress */ bool fromwire_gossip_dev_suppress(const void *p UNNEEDED) { fprintf(stderr, "fromwire_gossip_dev_suppress called!\n"); abort(); } diff --git a/gossipd/test/run-extended-info.c b/gossipd/test/run-extended-info.c index 2542ddb22..df9b9eaa2 100644 --- a/gossipd/test/run-extended-info.c +++ b/gossipd/test/run-extended-info.c @@ -82,6 +82,9 @@ bool fromwire_gossipctl_init(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, /* Generated stub for fromwire_gossip_dev_set_max_scids_encode_size */ bool fromwire_gossip_dev_set_max_scids_encode_size(const void *p UNNEEDED, u32 *max UNNEEDED) { fprintf(stderr, "fromwire_gossip_dev_set_max_scids_encode_size called!\n"); abort(); } +/* Generated stub for fromwire_gossip_dev_set_time */ +bool fromwire_gossip_dev_set_time(const void *p UNNEEDED, u32 *dev_gossip_time UNNEEDED) +{ fprintf(stderr, "fromwire_gossip_dev_set_time called!\n"); abort(); } /* Generated stub for fromwire_gossip_dev_suppress */ bool fromwire_gossip_dev_suppress(const void *p UNNEEDED) { fprintf(stderr, "fromwire_gossip_dev_suppress called!\n"); abort(); } diff --git a/lightningd/gossip_control.c b/lightningd/gossip_control.c index caf2d6b03..3ebecac89 100644 --- a/lightningd/gossip_control.c +++ b/lightningd/gossip_control.c @@ -151,6 +151,7 @@ static unsigned gossip_msg(struct subd *gossip, const u8 *msg, const int *fds) case WIRE_GOSSIP_LOCAL_CHANNEL_CLOSE: case WIRE_GOSSIP_DEV_MEMLEAK: case WIRE_GOSSIP_DEV_COMPACT_STORE: + case WIRE_GOSSIP_DEV_SET_TIME: /* This is a reply, so never gets through to here. */ case WIRE_GOSSIP_GETNODES_REPLY: case WIRE_GOSSIP_GETROUTE_REPLY: @@ -762,4 +763,31 @@ static const struct json_command dev_compact_gossip_store = { "Ask gossipd to rewrite the gossip store." }; AUTODATA(json_command, &dev_compact_gossip_store); + +static struct command_result *json_dev_gossip_set_time(struct command *cmd, + const char *buffer, + const jsmntok_t *obj UNNEEDED, + const jsmntok_t *params) +{ + u8 *msg; + u32 *time; + + if (!param(cmd, buffer, params, + p_req("time", param_number, &time), + NULL)) + return command_param_failed(); + + msg = towire_gossip_dev_set_time(NULL, *time); + subd_send_msg(cmd->ld->gossip, take(msg)); + + return command_success(cmd, json_stream_success(cmd)); +} + +static const struct json_command dev_gossip_set_time = { + "dev-gossip-set-time", + "developer", + json_dev_gossip_set_time, + "Ask gossipd to update the current time." +}; +AUTODATA(json_command, &dev_gossip_set_time); #endif /* DEVELOPER */