mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-03-15 11:59:16 +01:00
gossipd: dev-set-max-scids-encode-size to artificially force "full" replies.
We cap each reply at a single one, which forces the code into our recursion logic. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
parent
118f099dd8
commit
9e51e196c1
4 changed files with 76 additions and 1 deletions
|
@ -101,6 +101,10 @@ HTABLE_DEFINE_TYPE(struct important_peerid,
|
|||
important_peerid_eq,
|
||||
important_peerid_map);
|
||||
|
||||
#if DEVELOPER
|
||||
static u32 max_scids_encode_bytes = -1U;
|
||||
#endif
|
||||
|
||||
struct daemon {
|
||||
/* Who am I? */
|
||||
struct pubkey id;
|
||||
|
@ -439,6 +443,10 @@ static void encode_add_short_channel_id(u8 **encoded,
|
|||
|
||||
static bool encode_short_channel_ids_end(u8 **encoded, size_t max_bytes)
|
||||
{
|
||||
#if DEVELOPER
|
||||
if (tal_len(*encoded) > max_scids_encode_bytes)
|
||||
return false;
|
||||
#endif
|
||||
return tal_len(*encoded) <= max_bytes;
|
||||
}
|
||||
|
||||
|
@ -2291,6 +2299,17 @@ fail:
|
|||
NULL)));
|
||||
goto out;
|
||||
}
|
||||
|
||||
static struct io_plan *dev_set_max_scids_encode_size(struct io_conn *conn,
|
||||
struct daemon *daemon,
|
||||
const u8 *msg)
|
||||
{
|
||||
if (!fromwire_gossip_dev_set_max_scids_encode_size(msg,
|
||||
&max_scids_encode_bytes))
|
||||
master_badmsg(WIRE_GOSSIP_DEV_SET_MAX_SCIDS_ENCODE_SIZE, msg);
|
||||
|
||||
return daemon_conn_read_next(conn, &daemon->master);
|
||||
}
|
||||
#endif /* DEVELOPER */
|
||||
|
||||
static int make_listen_fd(int domain, void *addr, socklen_t len, bool mayfail)
|
||||
|
@ -3518,11 +3537,15 @@ static struct io_plan *recv_req(struct io_conn *conn, struct daemon_conn *master
|
|||
case WIRE_GOSSIP_QUERY_CHANNEL_RANGE:
|
||||
return query_channel_range(conn, daemon, daemon->master.msg_in);
|
||||
|
||||
case WIRE_GOSSIP_DEV_SET_MAX_SCIDS_ENCODE_SIZE:
|
||||
return dev_set_max_scids_encode_size(conn, daemon,
|
||||
daemon->master.msg_in);
|
||||
#else
|
||||
case WIRE_GOSSIP_PING:
|
||||
case WIRE_GOSSIP_QUERY_SCIDS:
|
||||
case WIRE_GOSSIP_SEND_TIMESTAMP_FILTER:
|
||||
case WIRE_GOSSIP_QUERY_CHANNEL_RANGE:
|
||||
case WIRE_GOSSIP_DEV_SET_MAX_SCIDS_ENCODE_SIZE:
|
||||
break;
|
||||
#endif /* !DEVELOPER */
|
||||
|
||||
|
@ -3581,7 +3604,6 @@ int main(int argc, char *argv[])
|
|||
timers_init(&daemon->timers, time_mono());
|
||||
daemon->broadcast_interval = 30000;
|
||||
daemon->last_announce_timestamp = 0;
|
||||
|
||||
/* stdin == control */
|
||||
daemon_conn_init(daemon, &daemon->master, STDIN_FILENO, recv_req,
|
||||
master_gone);
|
||||
|
|
|
@ -186,6 +186,10 @@ gossip_query_channel_range_reply,,final_complete,bool
|
|||
gossip_query_channel_range_reply,,num,u16
|
||||
gossip_query_channel_range_reply,,scids,num*struct short_channel_id
|
||||
|
||||
# Set artificial maximum reply_channel_range size. Master->gossipd
|
||||
gossip_dev_set_max_scids_encode_size,3030
|
||||
gossip_dev_set_max_scids_encode_size,,max,u32
|
||||
|
||||
# Given a short_channel_id, return the endpoints
|
||||
gossip_resolve_channel_request,3009
|
||||
gossip_resolve_channel_request,,channel_id,struct short_channel_id
|
||||
|
|
|
|
@ -139,6 +139,7 @@ static unsigned gossip_msg(struct subd *gossip, const u8 *msg, const int *fds)
|
|||
case WIRE_GOSSIP_QUERY_SCIDS:
|
||||
case WIRE_GOSSIP_QUERY_CHANNEL_RANGE:
|
||||
case WIRE_GOSSIP_SEND_TIMESTAMP_FILTER:
|
||||
case WIRE_GOSSIP_DEV_SET_MAX_SCIDS_ENCODE_SIZE:
|
||||
case WIRE_GOSSIPCTL_PEER_DISCONNECT:
|
||||
case WIRE_GOSSIPCTL_PEER_IMPORTANT:
|
||||
case WIRE_GOSSIPCTL_PEER_DISCONNECTED:
|
||||
|
@ -761,4 +762,37 @@ static const struct json_command dev_query_channel_range_command = {
|
|||
"Query {peerid} for short_channel_ids for {first} block + {num} blocks"
|
||||
};
|
||||
AUTODATA(json_command, &dev_query_channel_range_command);
|
||||
|
||||
static void json_dev_set_max_scids_encode_size(struct command *cmd,
|
||||
const char *buffer,
|
||||
const jsmntok_t *params)
|
||||
{
|
||||
u8 *msg;
|
||||
jsmntok_t *maxtok;
|
||||
u32 max;
|
||||
|
||||
if (!json_get_params(cmd, buffer, params,
|
||||
"max", &maxtok,
|
||||
NULL)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!json_tok_number(buffer, maxtok, &max)) {
|
||||
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
||||
"max must be a number");
|
||||
return;
|
||||
}
|
||||
|
||||
msg = towire_gossip_dev_set_max_scids_encode_size(NULL, max);
|
||||
subd_send_msg(cmd->ld->gossip, take(msg));
|
||||
|
||||
command_success(cmd, null_response(cmd));
|
||||
}
|
||||
|
||||
static const struct json_command dev_set_max_scids_encode_size = {
|
||||
"dev-set-max-scids-encode-size",
|
||||
json_dev_set_max_scids_encode_size,
|
||||
"Set {max} bytes of short_channel_ids per reply_channel_range"
|
||||
};
|
||||
AUTODATA(json_command, &dev_set_max_scids_encode_size);
|
||||
#endif /* DEVELOPER */
|
||||
|
|
|
@ -2714,6 +2714,21 @@ class LightningDTests(BaseLightningDTests):
|
|||
assert ret['final_complete']
|
||||
assert len(ret['short_channel_ids']) == 0
|
||||
|
||||
# Make l2 split reply into two.
|
||||
l2.rpc.dev_set_max_scids_encode_size(max=9)
|
||||
ret = l1.rpc.dev_query_channel_range(id=l2.info['id'],
|
||||
first=0,
|
||||
num=1000000)
|
||||
|
||||
# It should definitely have split
|
||||
assert ret['final_first_block'] != 0 or ret['final_num_blocks'] != 1000000
|
||||
assert ret['final_complete']
|
||||
assert len(ret['short_channel_ids']) == 2
|
||||
assert ret['short_channel_ids'][0] == scid12
|
||||
assert ret['short_channel_ids'][1] == scid23
|
||||
|
||||
l2.daemon.wait_for_log('queue_channel_ranges full: splitting')
|
||||
|
||||
@unittest.skipIf(not DEVELOPER, "needs DEVELOPER=1")
|
||||
def test_query_short_channel_id(self):
|
||||
l1 = self.node_factory.get_node(options={'log-level': 'io'})
|
||||
|
|
Loading…
Add table
Reference in a new issue