Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions gossipd/gossip.c
Original file line number Diff line number Diff line change
Expand Up @@ -1811,6 +1811,34 @@ seed_resolve_addr(const tal_t *ctx, const struct pubkey *id, const u16 port)
}
}

/* Resolve using gossiped wireaddr stored in routemap. */
static struct addrhint *
gossip_resolve_addr(const tal_t *ctx,
struct routing_state *rstate,
const struct pubkey *id)
{
struct node *node;
struct addrhint *a;

/* Get from routing state. */
node = get_node(rstate, id);

/* No matching node? */
if (!node)
return NULL;
/* Node has no addresses? */
if (tal_count(node->addresses) == 0)
return NULL;

/* FIXME: When struct addrhint can contain more than one address,
* we should copy all addresses.
* For now getting first address should be fine. */
a = tal(ctx, struct addrhint);
a->addr = node->addresses[0];

return a;
}

static void try_reach_peer(struct daemon *daemon, const struct pubkey *id,
bool master_needs_response)
{
Expand Down Expand Up @@ -1847,6 +1875,11 @@ static void try_reach_peer(struct daemon *daemon, const struct pubkey *id,

a = find_addrhint(daemon, id);

if (!a)
a = gossip_resolve_addr(tmpctx,
daemon->rstate,
id);

if (!a)
a = seed_resolve_addr(tmpctx, id, 9735);

Expand Down
30 changes: 29 additions & 1 deletion tests/test_lightningd.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,8 +109,12 @@ def __init__(self, testname, bitcoind, executor):
self.executor = executor
self.bitcoind = bitcoind

def get_next_port(self):
return 16330 + self.next_id

def get_node(self, disconnect=None, options=None, may_fail=False, may_reconnect=False, random_hsm=False, fake_bitcoin_cli=False):
node_id = self.next_id
port = self.get_next_port()
self.next_id += 1

lightning_dir = os.path.join(
Expand All @@ -120,7 +124,6 @@ def get_node(self, disconnect=None, options=None, may_fail=False, may_reconnect=
shutil.rmtree(lightning_dir)

socket_path = os.path.join(lightning_dir, "lightning-rpc").format(node_id)
port = 16330 + node_id
daemon = utils.LightningD(lightning_dir, self.bitcoind.bitcoin_dir, port=port, random_hsm=random_hsm)
# If we have a disconnect string, dump it to a file for daemon.
if disconnect:
Expand Down Expand Up @@ -633,6 +636,31 @@ def test_connect(self):
"Cryptographic handshake: ",
l1.rpc.connect, '032cf15d1ad9c4a08d26eab1918f732d8ef8fdc6abb9640bf3db174372c491304e', 'localhost', l2.info['port'])

def test_connect_by_gossip(self):
"""Test connecting to an unknown peer using node gossip
"""
l1 = self.node_factory.get_node()
l2 = self.node_factory.get_node()
# Force l3 to give its address.
l3port = self.node_factory.get_next_port()
l3 = self.node_factory.get_node(options={"ipaddr": "127.0.0.1:{}".format(l3port)})

l2.rpc.connect(l3.info['id'], 'localhost', l3.info['port'])

# Nodes are gossiped only if they have channels
chanid = self.fund_channel(l2, l3, 10**6)
# Let channel reach announcement depth
self.wait_for_routes(l2, [chanid])
# Make sure l3 has given node announcement to l2.
l2.daemon.wait_for_logs(['Received node_announcement for node {}'.format(l3.info['id'])])

# Let l1 learn of l3 by node gossip
l1.rpc.connect(l2.info['id'], 'localhost', l2.info['port'])
l1.daemon.wait_for_logs(['Received node_announcement for node {}'.format(l3.info['id'])])

# Have l1 connect to l3 without explicit host and port.
l1.rpc.connect(l3.info['id'])

def test_connect_standard_addr(self):
"""Test standard node@host:port address
"""
Expand Down