mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-03-12 18:49:42 +01:00
wallet: save last known address.
If we connected out, remember that address. We always remember the last address, but that may be an incoming address. This is explicitly the last outgoing address which worked. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
parent
64af5db45c
commit
68feb55dbf
11 changed files with 77 additions and 8 deletions
|
@ -601,6 +601,18 @@ struct secret *db_col_secret_arr(const tal_t *ctx,
|
|||
return db_col_arr(ctx, stmt, colname, struct secret);
|
||||
}
|
||||
|
||||
struct wireaddr *db_col_wireaddr(const tal_t *ctx,
|
||||
struct db_stmt *stmt,
|
||||
const char *colname)
|
||||
{
|
||||
struct wireaddr *waddr = tal(ctx, struct wireaddr);
|
||||
const u8 *wire = db_col_arr(tmpctx, stmt, colname, u8);
|
||||
size_t len = tal_bytelen(wire);
|
||||
if (!fromwire_wireaddr(&wire, &len, waddr))
|
||||
return tal_free(waddr);
|
||||
return waddr;
|
||||
}
|
||||
|
||||
void db_col_txid(struct db_stmt *stmt, const char *colname, struct bitcoin_txid *t)
|
||||
{
|
||||
db_col_sha256d(stmt, colname, &t->shad);
|
||||
|
|
|
@ -103,6 +103,9 @@ struct bitcoin_tx *db_col_psbt_to_tx(const tal_t *ctx, struct db_stmt *stmt, con
|
|||
|
||||
struct onionreply *db_col_onionreply(const tal_t *ctx,
|
||||
struct db_stmt *stmt, const char *colname);
|
||||
struct wireaddr *db_col_wireaddr(const tal_t *ctx,
|
||||
struct db_stmt *stmt,
|
||||
const char *colname);
|
||||
|
||||
#define db_col_arr(ctx, stmt, colname, type) \
|
||||
((type *)db_col_arr_((ctx), (stmt), (colname), \
|
||||
|
|
|
@ -1496,6 +1496,7 @@ static struct channel *stub_chan(struct command *cmd,
|
|||
&nodeid,
|
||||
&wint,
|
||||
NULL,
|
||||
NULL,
|
||||
false);
|
||||
}
|
||||
|
||||
|
|
|
@ -91,6 +91,7 @@ void peer_set_dbid(struct peer *peer, u64 dbid)
|
|||
struct peer *new_peer(struct lightningd *ld, u64 dbid,
|
||||
const struct node_id *id,
|
||||
const struct wireaddr_internal *addr,
|
||||
const struct wireaddr *last_known_addr,
|
||||
const u8 *their_features,
|
||||
bool connected_incoming)
|
||||
{
|
||||
|
@ -102,6 +103,7 @@ struct peer *new_peer(struct lightningd *ld, u64 dbid,
|
|||
peer->id = *id;
|
||||
peer->uncommitted_channel = NULL;
|
||||
peer->addr = *addr;
|
||||
peer->last_known_addr = tal_dup_or_null(peer, struct wireaddr, last_known_addr);
|
||||
peer->connected_incoming = connected_incoming;
|
||||
peer->remote_addr = NULL;
|
||||
list_head_init(&peer->channels);
|
||||
|
@ -1673,6 +1675,7 @@ void peer_connected(struct lightningd *ld, const u8 *msg)
|
|||
struct peer_connected_hook_payload *hook_payload;
|
||||
u64 connectd_counter;
|
||||
const char *cmd_id;
|
||||
struct wireaddr *last_known_addr;
|
||||
|
||||
hook_payload = tal(NULL, struct peer_connected_hook_payload);
|
||||
hook_payload->ld = ld;
|
||||
|
@ -1691,15 +1694,31 @@ void peer_connected(struct lightningd *ld, const u8 *msg)
|
|||
* now it's reconnected, we've gotta force them out. */
|
||||
peer_channels_cleanup(ld, &id);
|
||||
|
||||
/* If we connected, and it's a normal address */
|
||||
if (!hook_payload->incoming
|
||||
&& hook_payload->addr.itype == ADDR_INTERNAL_WIREADDR
|
||||
&& !hook_payload->addr.u.wireaddr.is_websocket) {
|
||||
last_known_addr = &hook_payload->addr.u.wireaddr.wireaddr;
|
||||
} else {
|
||||
last_known_addr = NULL;
|
||||
}
|
||||
|
||||
/* If we're already dealing with this peer, hand off to correct
|
||||
* subdaemon. Otherwise, we'll hand to openingd to wait there. */
|
||||
peer = peer_by_id(ld, &id);
|
||||
if (!peer)
|
||||
if (!peer) {
|
||||
/* If we connected to them, we know this is a good address. */
|
||||
peer = new_peer(ld, 0, &id, &hook_payload->addr,
|
||||
last_known_addr,
|
||||
take(their_features), hook_payload->incoming);
|
||||
else {
|
||||
} else {
|
||||
tal_free(peer->their_features);
|
||||
peer->their_features = tal_steal(peer, their_features);
|
||||
|
||||
/* Update known address. */
|
||||
tal_free(peer->last_known_addr);
|
||||
peer->last_known_addr = tal_dup_or_null(peer, struct wireaddr,
|
||||
last_known_addr);
|
||||
}
|
||||
|
||||
/* We track this, because messages can race between connectd and us.
|
||||
|
|
|
@ -53,6 +53,9 @@ struct peer {
|
|||
struct wireaddr_internal addr;
|
||||
bool connected_incoming;
|
||||
|
||||
/* If we ever successfully connected out to an address, this is non-NULL */
|
||||
struct wireaddr *last_known_addr;
|
||||
|
||||
/* They send what they see as our address as remote_addr */
|
||||
struct wireaddr *remote_addr;
|
||||
|
||||
|
@ -71,6 +74,7 @@ struct peer *find_peer_by_dbid(struct lightningd *ld, u64 dbid);
|
|||
struct peer *new_peer(struct lightningd *ld, u64 dbid,
|
||||
const struct node_id *id,
|
||||
const struct wireaddr_internal *addr,
|
||||
const struct wireaddr *last_known_addr,
|
||||
const u8 *their_features TAKES,
|
||||
bool connected_incoming);
|
||||
|
||||
|
|
|
@ -92,6 +92,9 @@ u8 fromwire_u8(const u8 **cursor UNNEEDED, size_t *max UNNEEDED)
|
|||
/* Generated stub for fromwire_u8_array */
|
||||
void fromwire_u8_array(const u8 **cursor UNNEEDED, size_t *max UNNEEDED, u8 *arr UNNEEDED, size_t num UNNEEDED)
|
||||
{ fprintf(stderr, "fromwire_u8_array called!\n"); abort(); }
|
||||
/* Generated stub for fromwire_wireaddr */
|
||||
bool fromwire_wireaddr(const u8 **cursor UNNEEDED, size_t *max UNNEEDED, struct wireaddr *addr UNNEEDED)
|
||||
{ fprintf(stderr, "fromwire_wireaddr called!\n"); abort(); }
|
||||
/* Generated stub for fromwire_wirestring */
|
||||
char *fromwire_wirestring(const tal_t *ctx UNNEEDED, const u8 **cursor UNNEEDED, size_t *max UNNEEDED)
|
||||
{ fprintf(stderr, "fromwire_wirestring called!\n"); abort(); }
|
||||
|
|
|
@ -98,6 +98,9 @@ u8 fromwire_u8(const u8 **cursor UNNEEDED, size_t *max UNNEEDED)
|
|||
/* Generated stub for fromwire_u8_array */
|
||||
void fromwire_u8_array(const u8 **cursor UNNEEDED, size_t *max UNNEEDED, u8 *arr UNNEEDED, size_t num UNNEEDED)
|
||||
{ fprintf(stderr, "fromwire_u8_array called!\n"); abort(); }
|
||||
/* Generated stub for fromwire_wireaddr */
|
||||
bool fromwire_wireaddr(const u8 **cursor UNNEEDED, size_t *max UNNEEDED, struct wireaddr *addr UNNEEDED)
|
||||
{ fprintf(stderr, "fromwire_wireaddr called!\n"); abort(); }
|
||||
/* Generated stub for fromwire_wirestring */
|
||||
char *fromwire_wirestring(const tal_t *ctx UNNEEDED, const u8 **cursor UNNEEDED, size_t *max UNNEEDED)
|
||||
{ fprintf(stderr, "fromwire_wirestring called!\n"); abort(); }
|
||||
|
|
|
@ -1028,6 +1028,7 @@ static struct migration dbmigrations[] = {
|
|||
" addrtype INTEGER)"), NULL},
|
||||
{NULL, insert_addrtype_to_addresses},
|
||||
{SQL("ALTER TABLE channel_funding_inflights ADD remote_funding BLOB DEFAULT NULL;"), NULL},
|
||||
{SQL("ALTER TABLE peers ADD last_known_address BLOB DEFAULT NULL;"), NULL},
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -239,6 +239,7 @@ struct logger *new_logger(const tal_t *ctx UNNEEDED, struct log_book *record UNN
|
|||
struct peer *new_peer(struct lightningd *ld UNNEEDED, u64 dbid UNNEEDED,
|
||||
const struct node_id *id UNNEEDED,
|
||||
const struct wireaddr_internal *addr UNNEEDED,
|
||||
const struct wireaddr *last_known_addr UNNEEDED,
|
||||
const u8 *their_features TAKES UNNEEDED,
|
||||
bool connected_incoming UNNEEDED)
|
||||
{ fprintf(stderr, "new_peer called!\n"); abort(); }
|
||||
|
|
|
@ -1441,7 +1441,7 @@ static bool test_wallet_outputs(struct lightningd *ld, const tal_t *ctx)
|
|||
|
||||
/* Add another utxo that's CSV-locked for 5 blocks */
|
||||
assert(parse_wireaddr_internal(tmpctx, "localhost:1234", 0, false, &addr) == NULL);
|
||||
channel.peer = new_peer(ld, 0, &id, &addr, NULL, false);
|
||||
channel.peer = new_peer(ld, 0, &id, &addr, NULL, NULL, false);
|
||||
channel.dbid = 1;
|
||||
channel.type = channel_type_anchors_zero_fee_htlc(tmpctx);
|
||||
memset(&u.outpoint, 3, sizeof(u.outpoint));
|
||||
|
@ -1767,7 +1767,7 @@ static bool test_channel_crud(struct lightningd *ld, const tal_t *ctx)
|
|||
c1.first_blocknum = 1;
|
||||
assert(parse_wireaddr_internal(tmpctx, "localhost:1234", 0, false, &addr) == NULL);
|
||||
c1.final_key_idx = 1337;
|
||||
p = new_peer(ld, 0, &id, &addr, NULL, false);
|
||||
p = new_peer(ld, 0, &id, &addr, NULL, NULL, false);
|
||||
c1.peer = p;
|
||||
c1.dbid = wallet_get_channel_dbid(w);
|
||||
c1.state = CHANNELD_NORMAL;
|
||||
|
@ -1935,7 +1935,7 @@ static bool test_channel_inflight_crud(struct lightningd *ld, const tal_t *ctx)
|
|||
assert(parse_wireaddr_internal(tmpctx, "localhost:1234", 0, false, &addr) == NULL);
|
||||
|
||||
/* new channel! */
|
||||
p = new_peer(ld, 0, &id, &addr, NULL, false);
|
||||
p = new_peer(ld, 0, &id, &addr, NULL, NULL, false);
|
||||
|
||||
funding_sats = AMOUNT_SAT(4444444);
|
||||
our_sats = AMOUNT_SAT(3333333);
|
||||
|
|
|
@ -1011,10 +1011,11 @@ static struct peer *wallet_peer_load(struct wallet *w, const u64 dbid)
|
|||
struct peer *peer = NULL;
|
||||
struct node_id id;
|
||||
struct wireaddr_internal addr;
|
||||
struct wireaddr *last_known_addr;
|
||||
struct db_stmt *stmt;
|
||||
|
||||
stmt = db_prepare_v2(
|
||||
w->db, SQL("SELECT id, node_id, address, feature_bits FROM peers WHERE id=?;"));
|
||||
w->db, SQL("SELECT id, node_id, address, feature_bits, last_known_address FROM peers WHERE id=?;"));
|
||||
db_bind_u64(stmt, dbid);
|
||||
db_query_prepared(stmt);
|
||||
|
||||
|
@ -1025,6 +1026,7 @@ static struct peer *wallet_peer_load(struct wallet *w, const u64 dbid)
|
|||
db_col_ignore(stmt, "address");
|
||||
db_col_ignore(stmt, "id");
|
||||
db_col_ignore(stmt, "feature_bits");
|
||||
db_col_ignore(stmt, "last_known_address");
|
||||
goto done;
|
||||
}
|
||||
|
||||
|
@ -1041,8 +1043,18 @@ static struct peer *wallet_peer_load(struct wallet *w, const u64 dbid)
|
|||
assert(!err);
|
||||
}
|
||||
|
||||
/* FIXME: save incoming in db! */
|
||||
peer = new_peer(w->ld, db_col_u64(stmt, "id"), &id, &addr, db_col_arr(stmt, stmt, "feature_bits", u8), false);
|
||||
if (db_col_is_null(stmt, "last_known_address")) {
|
||||
last_known_addr = NULL;
|
||||
} else {
|
||||
last_known_addr = db_col_wireaddr(tmpctx, stmt, "last_known_address");
|
||||
if (!last_known_addr) {
|
||||
log_broken(w->log, "Unparsable lastknown address %s: ignoring",
|
||||
tal_hex(tmpctx, db_col_arr(tmpctx, stmt, "last_known_address", u8)));
|
||||
}
|
||||
}
|
||||
|
||||
peer = new_peer(w->ld, db_col_u64(stmt, "id"), &id, &addr, last_known_addr,
|
||||
db_col_arr(stmt, stmt, "feature_bits", u8), false);
|
||||
|
||||
done:
|
||||
tal_free(stmt);
|
||||
|
@ -2583,6 +2595,16 @@ static void wallet_peer_save(struct wallet *w, struct peer *peer)
|
|||
db_exec_prepared_v2(stmt);
|
||||
peer_set_dbid(peer, db_last_insert_id_v2(take(stmt)));
|
||||
}
|
||||
|
||||
if (peer->last_known_addr) {
|
||||
u8 *wire = tal_arr(tmpctx, u8, 0);
|
||||
towire_wireaddr(&wire, peer->last_known_addr);
|
||||
stmt = db_prepare_v2(w->db,
|
||||
SQL("UPDATE peers SET last_known_address = ? WHERE id = ?;"));
|
||||
db_bind_talarr(stmt, wire);
|
||||
db_bind_u64(stmt, peer->dbid);
|
||||
db_exec_prepared_v2(take(stmt));
|
||||
}
|
||||
}
|
||||
|
||||
bool channel_exists_by_id(struct wallet *w, u64 dbid) {
|
||||
|
|
Loading…
Add table
Reference in a new issue