Browse Source

lightningd: move channel/peer/htlc load into own function.

Also, wallet has no business wiring up HTLCs; move that code to
peer_htlcs.c.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
ppa-0.6.1
Rusty Russell 6 years ago
parent
commit
168bec0974
  1. 22
      lightningd/lightningd.c
  2. 27
      lightningd/peer_control.c
  3. 3
      lightningd/peer_control.h
  4. 42
      lightningd/peer_htlcs.c
  5. 4
      lightningd/peer_htlcs.h
  6. 17
      lightningd/test/run-find_my_path.c
  7. 83
      wallet/test/run-wallet.c
  8. 39
      wallet/wallet.c
  9. 12
      wallet/wallet.h

22
lightningd/lightningd.c

@ -366,26 +366,8 @@ int main(int argc, char *argv[])
ld->ini_autocleaninvoice_cycle,
ld->ini_autocleaninvoice_expiredby);
/* Load peers from database */
if (!wallet_channels_load_active(ld, ld->wallet))
fatal("Could not load channels from the database");
/* TODO(cdecker) Move this into common location for initialization */
struct peer *peer;
list_for_each(&ld->peers, peer, list) {
struct channel *channel;
list_for_each(&peer->channels, channel, list) {
if (!wallet_htlcs_load_for_channel(ld->wallet,
channel,
&ld->htlcs_in,
&ld->htlcs_out)) {
fatal("could not load htlcs for channel");
}
}
}
if (!wallet_htlcs_reconnect(ld->wallet, &ld->htlcs_in, &ld->htlcs_out))
fatal("could not reconnect htlcs loaded from wallet, wallet may be inconsistent.");
/* Pull peers, channels and HTLCs from db. */
load_channels_from_wallet(ld);
/* Get the blockheight we are currently at, UINT32_MAX is used to signal
* an unitialized wallet and that we should start off of bitcoind's

27
lightningd/peer_control.c

@ -945,6 +945,33 @@ void activate_peers(struct lightningd *ld)
activate_peer(p);
}
/* Pull peers, channels and HTLCs from db, and wire them up. */
void load_channels_from_wallet(struct lightningd *ld)
{
struct peer *peer;
/* Load peers from database */
if (!wallet_channels_load_active(ld, ld->wallet))
fatal("Could not load channels from the database");
/* This is a poor-man's db join :( */
list_for_each(&ld->peers, peer, list) {
struct channel *channel;
list_for_each(&peer->channels, channel, list) {
if (!wallet_htlcs_load_for_channel(ld->wallet,
channel,
&ld->htlcs_in,
&ld->htlcs_out)) {
fatal("could not load htlcs for channel");
}
}
}
/* Now connect HTLC pointers together */
htlcs_reconnect(ld, &ld->htlcs_in, &ld->htlcs_out);
}
static void json_disconnect(struct command *cmd,
const char *buffer, const jsmntok_t *params)
{

3
lightningd/peer_control.h

@ -89,4 +89,7 @@ void activate_peers(struct lightningd *ld);
void drop_to_chain(struct lightningd *ld, struct channel *channel, bool cooperative);
void channel_watch_funding(struct lightningd *ld, struct channel *channel);
/* Pull peers, channels and HTLCs from db, and wire them up. */
void load_channels_from_wallet(struct lightningd *ld);
#endif /* LIGHTNING_LIGHTNINGD_PEER_CONTROL_H */

42
lightningd/peer_htlcs.c

@ -1671,6 +1671,48 @@ void htlcs_notify_new_block(struct lightningd *ld, u32 height)
} while (removed);
}
/**
* htlcs_reconnect -- Link outgoing HTLCs to their origins after initial db load
*
* For each outgoing HTLC find the incoming HTLC that triggered it. If
* we are the origin of the transfer then we cannot resolve the
* incoming HTLC in which case we just leave it `NULL`.
*/
void htlcs_reconnect(struct lightningd *ld,
struct htlc_in_map *htlcs_in,
struct htlc_out_map *htlcs_out)
{
struct htlc_in_map_iter ini;
struct htlc_out_map_iter outi;
struct htlc_in *hin;
struct htlc_out *hout;
for (hout = htlc_out_map_first(htlcs_out, &outi); hout;
hout = htlc_out_map_next(htlcs_out, &outi)) {
if (hout->origin_htlc_id == 0) {
continue;
}
for (hin = htlc_in_map_first(htlcs_in, &ini); hin;
hin = htlc_in_map_next(htlcs_in, &ini)) {
if (hout->origin_htlc_id == hin->dbid) {
log_debug(ld->log,
"Found corresponding htlc_in %" PRIu64
" for htlc_out %" PRIu64,
hin->dbid, hout->dbid);
hout->in = hin;
break;
}
}
if (!hout->in)
fatal("Unable to find corresponding htlc_in %"PRIu64" for htlc_out %"PRIu64,
hout->origin_htlc_id, hout->dbid);
}
}
#if DEVELOPER
static void json_dev_ignore_htlcs(struct command *cmd, const char *buffer,
const jsmntok_t *params)

4
lightningd/peer_htlcs.h

@ -60,4 +60,8 @@ void onchain_fulfilled_htlc(struct channel *channel,
void htlcs_notify_new_block(struct lightningd *ld, u32 height);
void htlcs_reconnect(struct lightningd *ld,
struct htlc_in_map *htlcs_in,
struct htlc_out_map *htlcs_out);
#endif /* LIGHTNING_LIGHTNINGD_PEER_HTLCS_H */

17
lightningd/test/run-find_my_path.c

@ -71,6 +71,9 @@ void htlcs_notify_new_block(struct lightningd *ld UNNEEDED, u32 height UNNEEDED)
/* Generated stub for json_escape */
struct json_escaped *json_escape(const tal_t *ctx UNNEEDED, const char *str TAKES UNNEEDED)
{ fprintf(stderr, "json_escape called!\n"); abort(); }
/* Generated stub for load_channels_from_wallet */
void load_channels_from_wallet(struct lightningd *ld UNNEEDED)
{ fprintf(stderr, "load_channels_from_wallet called!\n"); abort(); }
/* Generated stub for log_ */
void log_(struct log *log UNNEEDED, enum log_level level UNNEEDED, const char *fmt UNNEEDED, ...)
@ -126,20 +129,6 @@ const char *version(void)
/* Generated stub for wallet_blocks_heights */
void wallet_blocks_heights(struct wallet *w UNNEEDED, u32 def UNNEEDED, u32 *min UNNEEDED, u32 *max UNNEEDED)
{ fprintf(stderr, "wallet_blocks_heights called!\n"); abort(); }
/* Generated stub for wallet_channels_load_active */
bool wallet_channels_load_active(const tal_t *ctx UNNEEDED, struct wallet *w UNNEEDED)
{ fprintf(stderr, "wallet_channels_load_active called!\n"); abort(); }
/* Generated stub for wallet_htlcs_load_for_channel */
bool wallet_htlcs_load_for_channel(struct wallet *wallet UNNEEDED,
struct channel *chan UNNEEDED,
struct htlc_in_map *htlcs_in UNNEEDED,
struct htlc_out_map *htlcs_out UNNEEDED)
{ fprintf(stderr, "wallet_htlcs_load_for_channel called!\n"); abort(); }
/* Generated stub for wallet_htlcs_reconnect */
bool wallet_htlcs_reconnect(struct wallet *wallet UNNEEDED,
struct htlc_in_map *htlcs_in UNNEEDED,
struct htlc_out_map *htlcs_out UNNEEDED)
{ fprintf(stderr, "wallet_htlcs_reconnect called!\n"); abort(); }
/* Generated stub for wallet_invoice_autoclean */
void wallet_invoice_autoclean(struct wallet * wallet UNNEEDED,
u64 cycle_seconds UNNEEDED,

83
wallet/test/run-wallet.c

@ -12,6 +12,7 @@ static void db_log_(struct log *log UNUSED, enum log_level level UNUSED, const c
#include "wallet/wallet.c"
#include "lightningd/htlc_end.c"
#include "lightningd/peer_control.c"
#include "lightningd/peer_htlcs.c"
#include "lightningd/channel.c"
#include "wallet/db.c"
@ -69,12 +70,30 @@ void delay_then_reconnect(struct channel *channel UNNEEDED, u32 seconds_delay UN
/* Generated stub for fatal */
void fatal(const char *fmt UNNEEDED, ...)
{ fprintf(stderr, "fatal called!\n"); abort(); }
/* Generated stub for fromwire_channel_got_commitsig */
bool fromwire_channel_got_commitsig(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, u64 *commitnum UNNEEDED, u32 *feerate UNNEEDED, secp256k1_ecdsa_signature *signature UNNEEDED, secp256k1_ecdsa_signature **htlc_signature UNNEEDED, struct added_htlc **added UNNEEDED, struct secret **shared_secret UNNEEDED, struct fulfilled_htlc **fulfilled UNNEEDED, struct failed_htlc ***failed UNNEEDED, struct changed_htlc **changed UNNEEDED, struct bitcoin_tx **tx UNNEEDED)
{ fprintf(stderr, "fromwire_channel_got_commitsig called!\n"); abort(); }
/* Generated stub for fromwire_channel_got_revoke */
bool fromwire_channel_got_revoke(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, u64 *revokenum UNNEEDED, struct secret *per_commitment_secret UNNEEDED, struct pubkey *next_per_commit_point UNNEEDED, u32 *feerate UNNEEDED, struct changed_htlc **changed UNNEEDED)
{ fprintf(stderr, "fromwire_channel_got_revoke called!\n"); abort(); }
/* Generated stub for fromwire_channel_offer_htlc_reply */
bool fromwire_channel_offer_htlc_reply(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, u64 *id UNNEEDED, u16 *failure_code UNNEEDED, u8 **failurestr UNNEEDED)
{ fprintf(stderr, "fromwire_channel_offer_htlc_reply called!\n"); abort(); }
/* Generated stub for fromwire_channel_sending_commitsig */
bool fromwire_channel_sending_commitsig(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, u64 *commitnum UNNEEDED, u32 *feerate UNNEEDED, struct changed_htlc **changed UNNEEDED, secp256k1_ecdsa_signature *commit_sig UNNEEDED, secp256k1_ecdsa_signature **htlc_sigs UNNEEDED)
{ fprintf(stderr, "fromwire_channel_sending_commitsig called!\n"); abort(); }
/* Generated stub for fromwire_connect_peer_connected */
bool fromwire_connect_peer_connected(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, struct pubkey *id UNNEEDED, struct wireaddr_internal *addr UNNEEDED, struct crypto_state *crypto_state UNNEEDED, u8 **gfeatures UNNEEDED, u8 **lfeatures UNNEEDED)
{ fprintf(stderr, "fromwire_connect_peer_connected called!\n"); abort(); }
/* Generated stub for fromwire_gossip_resolve_channel_reply */
bool fromwire_gossip_resolve_channel_reply(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, struct pubkey **keys UNNEEDED)
{ fprintf(stderr, "fromwire_gossip_resolve_channel_reply called!\n"); abort(); }
/* Generated stub for fromwire_hsm_sign_commitment_tx_reply */
bool fromwire_hsm_sign_commitment_tx_reply(const void *p UNNEEDED, secp256k1_ecdsa_signature *sig UNNEEDED)
{ fprintf(stderr, "fromwire_hsm_sign_commitment_tx_reply called!\n"); abort(); }
/* Generated stub for get_block_height */
u32 get_block_height(const struct chain_topology *topo UNNEEDED)
{ fprintf(stderr, "get_block_height called!\n"); abort(); }
/* Generated stub for invoices_autoclean_set */
void invoices_autoclean_set(struct invoices *invoices UNNEEDED,
u64 cycle_seconds UNNEEDED,
@ -275,6 +294,9 @@ enum watch_result onchaind_funding_spent(struct channel *channel UNNEEDED,
const struct bitcoin_tx *tx UNNEEDED,
u32 blockheight UNNEEDED)
{ fprintf(stderr, "onchaind_funding_spent called!\n"); abort(); }
/* Generated stub for onion_type_name */
const char *onion_type_name(int e UNNEEDED)
{ fprintf(stderr, "onion_type_name called!\n"); abort(); }
/* Generated stub for opening_peer_no_active_channels */
void opening_peer_no_active_channels(struct peer *peer UNNEEDED)
{ fprintf(stderr, "opening_peer_no_active_channels called!\n"); abort(); }
@ -297,6 +319,24 @@ void outpointfilter_remove(struct outpointfilter *of UNNEEDED,
bool param(struct command *cmd UNNEEDED, const char *buffer UNNEEDED,
const jsmntok_t params[] UNNEEDED, ...)
{ fprintf(stderr, "param called!\n"); abort(); }
/* Generated stub for parse_onionpacket */
struct onionpacket *parse_onionpacket(
const tal_t *ctx UNNEEDED,
const void *src UNNEEDED,
const size_t srclen
)
{ fprintf(stderr, "parse_onionpacket called!\n"); abort(); }
/* Generated stub for payment_failed */
void payment_failed(struct lightningd *ld UNNEEDED, const struct htlc_out *hout UNNEEDED,
const char *localfail UNNEEDED)
{ fprintf(stderr, "payment_failed called!\n"); abort(); }
/* Generated stub for payment_store */
void payment_store(struct lightningd *ld UNNEEDED, const struct sha256 *payment_hash UNNEEDED)
{ fprintf(stderr, "payment_store called!\n"); abort(); }
/* Generated stub for payment_succeeded */
void payment_succeeded(struct lightningd *ld UNNEEDED, struct htlc_out *hout UNNEEDED,
const struct preimage *rval UNNEEDED)
{ fprintf(stderr, "payment_succeeded called!\n"); abort(); }
/* Generated stub for peer_start_channeld */
void peer_start_channeld(struct channel *channel UNNEEDED,
const struct crypto_state *cs UNNEEDED,
@ -317,6 +357,20 @@ void peer_start_openingd(struct peer *peer UNNEEDED,
int peer_fd UNNEEDED, int gossip_fd UNNEEDED,
const u8 *msg UNNEEDED)
{ fprintf(stderr, "peer_start_openingd called!\n"); abort(); }
/* Generated stub for process_onionpacket */
struct route_step *process_onionpacket(
const tal_t * ctx UNNEEDED,
const struct onionpacket *packet UNNEEDED,
const u8 *shared_secret UNNEEDED,
const u8 *assocdata UNNEEDED,
const size_t assocdatalen
)
{ fprintf(stderr, "process_onionpacket called!\n"); abort(); }
/* Generated stub for serialize_onionpacket */
u8 *serialize_onionpacket(
const tal_t *ctx UNNEEDED,
const struct onionpacket *packet UNNEEDED)
{ fprintf(stderr, "serialize_onionpacket called!\n"); abort(); }
/* Generated stub for subd_release_channel */
void subd_release_channel(struct subd *owner UNNEEDED, void *channel UNNEEDED)
{ fprintf(stderr, "subd_release_channel called!\n"); abort(); }
@ -334,6 +388,24 @@ void subd_send_msg(struct subd *sd UNNEEDED, const u8 *msg_out UNNEEDED)
/* Generated stub for towire_channel_dev_reenable_commit */
u8 *towire_channel_dev_reenable_commit(const tal_t *ctx UNNEEDED)
{ fprintf(stderr, "towire_channel_dev_reenable_commit called!\n"); abort(); }
/* Generated stub for towire_channel_fail_htlc */
u8 *towire_channel_fail_htlc(const tal_t *ctx UNNEEDED, const struct failed_htlc *failed_htlc UNNEEDED)
{ fprintf(stderr, "towire_channel_fail_htlc called!\n"); abort(); }
/* Generated stub for towire_channel_fulfill_htlc */
u8 *towire_channel_fulfill_htlc(const tal_t *ctx UNNEEDED, const struct fulfilled_htlc *fulfilled_htlc UNNEEDED)
{ fprintf(stderr, "towire_channel_fulfill_htlc called!\n"); abort(); }
/* Generated stub for towire_channel_got_commitsig_reply */
u8 *towire_channel_got_commitsig_reply(const tal_t *ctx UNNEEDED)
{ fprintf(stderr, "towire_channel_got_commitsig_reply called!\n"); abort(); }
/* Generated stub for towire_channel_got_revoke_reply */
u8 *towire_channel_got_revoke_reply(const tal_t *ctx UNNEEDED)
{ fprintf(stderr, "towire_channel_got_revoke_reply called!\n"); abort(); }
/* Generated stub for towire_channel_offer_htlc */
u8 *towire_channel_offer_htlc(const tal_t *ctx UNNEEDED, u64 amount_msat UNNEEDED, u32 cltv_expiry UNNEEDED, const struct sha256 *payment_hash UNNEEDED, const u8 onion_routing_packet[1366])
{ fprintf(stderr, "towire_channel_offer_htlc called!\n"); abort(); }
/* Generated stub for towire_channel_sending_commitsig_reply */
u8 *towire_channel_sending_commitsig_reply(const tal_t *ctx UNNEEDED)
{ fprintf(stderr, "towire_channel_sending_commitsig_reply called!\n"); abort(); }
/* Generated stub for towire_channel_send_shutdown */
u8 *towire_channel_send_shutdown(const tal_t *ctx UNNEEDED)
{ fprintf(stderr, "towire_channel_send_shutdown called!\n"); abort(); }
@ -348,9 +420,15 @@ u8 *towire_errorfmt(const tal_t *ctx UNNEEDED,
const struct channel_id *channel UNNEEDED,
const char *fmt UNNEEDED, ...)
{ fprintf(stderr, "towire_errorfmt called!\n"); abort(); }
/* Generated stub for towire_gossip_resolve_channel_request */
u8 *towire_gossip_resolve_channel_request(const tal_t *ctx UNNEEDED, const struct short_channel_id *channel_id UNNEEDED)
{ fprintf(stderr, "towire_gossip_resolve_channel_request called!\n"); abort(); }
/* Generated stub for towire_hsm_sign_commitment_tx */
u8 *towire_hsm_sign_commitment_tx(const tal_t *ctx UNNEEDED, const struct pubkey *peer_id UNNEEDED, u64 channel_dbid UNNEEDED, const struct bitcoin_tx *tx UNNEEDED, const struct pubkey *remote_funding_key UNNEEDED, u64 funding_amount UNNEEDED)
{ fprintf(stderr, "towire_hsm_sign_commitment_tx called!\n"); abort(); }
/* Generated stub for towire_onchain_known_preimage */
u8 *towire_onchain_known_preimage(const tal_t *ctx UNNEEDED, const struct preimage *preimage UNNEEDED)
{ fprintf(stderr, "towire_onchain_known_preimage called!\n"); abort(); }
/* Generated stub for watch_txid */
struct txwatch *watch_txid(const tal_t *ctx UNNEEDED,
struct chain_topology *topo UNNEEDED,
@ -903,10 +981,9 @@ static bool test_htlc_crud(struct lightningd *ld, const tal_t *ctx)
CHECK_MSG(wallet_htlcs_load_for_channel(w, chan, htlcs_in, htlcs_out),
"Failed loading HTLCs");
CHECK_MSG(wallet_htlcs_reconnect(w, htlcs_in, htlcs_out),
"Unable to reconnect htlcs.");
db_commit_transaction(w->db);
htlcs_reconnect(w->ld, htlcs_in, htlcs_out);
CHECK(!wallet_err);
hin = htlc_in_map_get(htlcs_in, &in.key);

39
wallet/wallet.c

@ -1383,45 +1383,6 @@ bool wallet_htlcs_load_for_channel(struct wallet *wallet,
return ok;
}
bool wallet_htlcs_reconnect(struct wallet *wallet,
struct htlc_in_map *htlcs_in,
struct htlc_out_map *htlcs_out)
{
struct htlc_in_map_iter ini;
struct htlc_out_map_iter outi;
struct htlc_in *hin;
struct htlc_out *hout;
for (hout = htlc_out_map_first(htlcs_out, &outi); hout;
hout = htlc_out_map_next(htlcs_out, &outi)) {
if (hout->origin_htlc_id == 0) {
continue;
}
for (hin = htlc_in_map_first(htlcs_in, &ini); hin;
hin = htlc_in_map_next(htlcs_in, &ini)) {
if (hout->origin_htlc_id == hin->dbid) {
log_debug(wallet->log,
"Found corresponding htlc_in %" PRIu64
" for htlc_out %" PRIu64,
hin->dbid, hout->dbid);
hout->in = hin;
break;
}
}
if (!hout->in) {
log_broken(
wallet->log,
"Unable to find corresponding htlc_in %"PRIu64" for htlc_out %"PRIu64,
hout->origin_htlc_id, hout->dbid);
}
}
return true;
}
bool wallet_invoice_create(struct wallet *wallet,
struct invoice *pinvoice,
u64 *msatoshi TAKES,

12
wallet/wallet.h

@ -480,7 +480,7 @@ void wallet_htlc_update(struct wallet *wallet, const u64 htlc_dbid,
* may not have been loaded yet. In the latter case the pay_command
* does not exist anymore since we restarted.
*
* Use `wallet_htlcs_reconnect` to wire htlc_out instances to the
* Use `htlcs_reconnect` to wire htlc_out instances to the
* corresponding htlc_in after loading all channels.
*/
bool wallet_htlcs_load_for_channel(struct wallet *wallet,
@ -488,16 +488,6 @@ bool wallet_htlcs_load_for_channel(struct wallet *wallet,
struct htlc_in_map *htlcs_in,
struct htlc_out_map *htlcs_out);
/**
* wallet_htlcs_reconnect -- Link outgoing HTLCs to their origins
*
* For each outgoing HTLC find the incoming HTLC that triggered it. If
* we are the origin of the transfer then we cannot resolve the
* incoming HTLC in which case we just leave it `NULL`.
*/
bool wallet_htlcs_reconnect(struct wallet *wallet,
struct htlc_in_map *htlcs_in,
struct htlc_out_map *htlcs_out);
/* /!\ This is a DB ENUM, please do not change the numbering of any
* already defined elements (adding is ok) /!\ */

Loading…
Cancel
Save