-
Notifications
You must be signed in to change notification settings - Fork 912
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
routing: Added IRC announcement glue
Added channel announcement serialization and parsing, as well as the entrypoints for the IRC peer discovery. Announcements are signed by the sending endpoint and signatures are verified before adding the channels to the local view of the topology. We do not yet verify the existence of the anchor transaction.
- Loading branch information
Showing
8 changed files
with
219 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,155 @@ | ||
#include "bitcoin/privkey.h" | ||
#include "bitcoin/signature.h" | ||
#include "daemon/chaintopology.h" | ||
#include "daemon/irc_announce.h" | ||
#include "daemon/lightningd.h" | ||
#include "daemon/log.h" | ||
#include "daemon/peer.h" | ||
#include "daemon/routing.h" | ||
#include "daemon/secrets.h" | ||
#include "daemon/timeout.h" | ||
#include "utils.h" | ||
|
||
#include <ccan/list/list.h> | ||
#include <ccan/str/hex/hex.h> | ||
|
||
static bool announce_channel(const tal_t *ctx, struct ircstate *state, struct peer *p) | ||
{ | ||
char txid[65]; | ||
int siglen; | ||
u8 der[72]; | ||
struct signature sig; | ||
struct privmsg *msg = talz(ctx, struct privmsg); | ||
struct txlocator *loc = locate_tx(ctx, state->dstate, &p->anchor.txid); | ||
|
||
if (loc == NULL) | ||
return false; | ||
|
||
bitcoin_txid_to_hex(&p->anchor.txid, txid, sizeof(txid)); | ||
msg->channel = "#lightning-nodes"; | ||
msg->msg = tal_fmt( | ||
msg, "CHAN %s %s %s %d %d %d %d %d", | ||
pubkey_to_hexstr(msg, state->dstate->secpctx, &state->dstate->id), | ||
pubkey_to_hexstr(msg, state->dstate->secpctx, p->id), | ||
txid, | ||
loc->blkheight, | ||
loc->index, | ||
state->dstate->config.fee_base, | ||
state->dstate->config.fee_per_satoshi, | ||
p->remote.locktime.locktime | ||
); | ||
|
||
privkey_sign(state->dstate, msg->msg, strlen(msg->msg), &sig); | ||
siglen = signature_to_der(state->dstate->secpctx, der, &sig); | ||
msg->msg = tal_fmt(msg, "%s %s", tal_hexstr(ctx, der, siglen), msg->msg); | ||
|
||
irc_send_msg(state, msg); | ||
return true; | ||
} | ||
|
||
static void announce_channels(struct ircstate *state) | ||
{ | ||
tal_t *ctx = tal(state, tal_t); | ||
struct peer *p; | ||
|
||
list_for_each(&state->dstate->peers, p, list) { | ||
|
||
if (!state_is_normal(p->state)) | ||
continue; | ||
announce_channel(ctx, state, p); | ||
} | ||
tal_free(ctx); | ||
|
||
new_reltimer(state->dstate, state, time_from_sec(60), announce_channels, state); | ||
} | ||
|
||
/* Reconnect to IRC server upon disconnection. */ | ||
static void handle_irc_disconnect(struct ircstate *state) | ||
{ | ||
new_reltimer(state->dstate, state, state->reconnect_timeout, irc_connect, state); | ||
} | ||
|
||
/* | ||
* Handle an incoming message by checking if it is a channel | ||
* announcement, parse it and add the channel to the topology if yes. | ||
* | ||
* The format for a valid announcement is: | ||
* <sig> CHAN <pk1> <pk2> <anchor txid> <block height> <tx position> <base_fee> | ||
* <proportional_fee> <locktime> | ||
*/ | ||
static void handle_irc_privmsg(struct ircstate *istate, const struct privmsg *msg) | ||
{ | ||
int blkheight; | ||
char **splits = tal_strsplit(msg, msg->msg + 1, " ", STR_NO_EMPTY); | ||
|
||
if (tal_count(splits) != 11 || !streq(splits[1], "CHAN")) | ||
return; | ||
|
||
int siglen = hex_data_size(strlen(splits[0])); | ||
u8 *der = tal_hexdata(msg, splits[0], strlen(splits[0])); | ||
if (der == NULL) | ||
return; | ||
|
||
struct signature sig; | ||
struct sha256_double hash; | ||
char *content = strchr(msg->msg, ' ') + 1; | ||
if (!signature_from_der(istate->dstate->secpctx, der, siglen, &sig)) | ||
return; | ||
|
||
sha256_double(&hash, content, strlen(content)); | ||
splits++; | ||
|
||
struct pubkey *pk1 = talz(msg, struct pubkey); | ||
struct pubkey *pk2 = talz(msg, struct pubkey); | ||
struct sha256_double *txid = talz(msg, struct sha256_double); | ||
int index; | ||
|
||
bool ok = true; | ||
ok &= pubkey_from_hexstr(istate->dstate->secpctx, splits[1], strlen(splits[1]), pk1); | ||
ok &= pubkey_from_hexstr(istate->dstate->secpctx, splits[2], strlen(splits[2]), pk2); | ||
ok &= bitcoin_txid_from_hex(splits[3], strlen(splits[3]), txid); | ||
blkheight = atoi(splits[4]); | ||
index = atoi(splits[5]); | ||
if (!ok || index < 0 || blkheight < 0) { | ||
log_debug(istate->dstate->base_log, "Unable to parse channel announcent."); | ||
return; | ||
} | ||
|
||
if (!check_signed_hash(istate->dstate->secpctx, &hash, &sig, pk1)) { | ||
log_debug(istate->log, | ||
"Ignoring announcement from %s, signature check failed.", | ||
splits[1]); | ||
return; | ||
} | ||
|
||
/* | ||
* FIXME Check in topology that the tx is in the block and | ||
* that the endpoints match. | ||
*/ | ||
|
||
add_connection(istate->dstate, pk1, pk2, atoi(splits[6]), | ||
atoi(splits[7]), atoi(splits[8]), 6); | ||
} | ||
|
||
void setup_irc_connection(struct lightningd_state *dstate) | ||
{ | ||
// Register callback | ||
irc_privmsg_cb = *handle_irc_privmsg; | ||
irc_disconnect_cb = *handle_irc_disconnect; | ||
|
||
struct ircstate *state = talz(dstate, struct ircstate); | ||
state->dstate = dstate; | ||
state->server = "irc.freenode.net"; | ||
state->reconnect_timeout = time_from_sec(15); | ||
state->log = new_log(state, state->dstate->log_record, "%s:irc", | ||
log_prefix(state->dstate->base_log)); | ||
|
||
/* Truncate nick at 13 bytes, would be imposed by freenode anyway */ | ||
state->nick = tal_fmt( | ||
state, | ||
"N%.12s", | ||
pubkey_to_hexstr(state, dstate->secpctx, &dstate->id) + 1); | ||
|
||
irc_connect(state); | ||
announce_channels(state); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
#ifndef LIGHTNING_DAEMON_IRC_ANNOUNCE_H | ||
#define LIGHTNING_DAEMON_IRC_ANNOUNCE_H | ||
#include "config.h" | ||
#include "irc.h" | ||
|
||
// Main entrypoint for the lightning daemon | ||
void setup_irc_connection(struct lightningd_state *dstate); | ||
|
||
#endif /* LIGHTNING_DAEMON_IRC_ANNOUNCE_H */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,13 @@ | ||
#ifndef LIGHTNING_UTILS_H | ||
#define LIGHTNING_UTILS_H | ||
#include "config.h" | ||
#include <ccan/short_types/short_types.h> | ||
#include <ccan/tal/tal.h> | ||
|
||
/* Allocate and fill in a hex-encoded string of this data. */ | ||
char *tal_hexstr(const tal_t *ctx, const void *data, size_t len); | ||
|
||
/* Allocate and fill a buffer with the data of this hex string. */ | ||
u8 *tal_hexdata(const tal_t *ctx, const void *str, size_t len); | ||
|
||
#endif /* LIGHTNING_UTILS_H */ |