diff --git a/lightningd/channel/channel.c b/lightningd/channel/channel.c index 3f0fe88ab..3219e8928 100644 --- a/lightningd/channel/channel.c +++ b/lightningd/channel/channel.c @@ -1222,6 +1222,10 @@ static void init_channel(struct peer *peer) struct sha256_double funding_txid; bool am_funder, last_was_revoke; enum htlc_state *hstates; + struct fulfilled_htlc *fulfilled; + enum side *fulfilled_sides; + struct failed_htlc *failed; + enum side *failed_sides; struct changed_htlc *last_sent_commit; struct added_htlc *htlcs; u8 *funding_signed; @@ -1256,6 +1260,10 @@ static void init_channel(struct peer *peer) &peer->htlc_id, &htlcs, &hstates, + &fulfilled, + &fulfilled_sides, + &failed, + &failed_sides, &funding_signed)) status_failed(WIRE_CHANNEL_BAD_COMMAND, "Init: %s", tal_hex(msg, msg)); @@ -1290,6 +1298,12 @@ static void init_channel(struct peer *peer) &funding_pubkey[REMOTE], am_funder ? LOCAL : REMOTE); + if (!channel_force_htlcs(peer->channel, htlcs, hstates, + fulfilled, fulfilled_sides, + failed, failed_sides)) + status_failed(WIRE_CHANNEL_BAD_COMMAND, + "Could not restore HTLCs"); + peer->channel_direction = get_channel_direction( &peer->node_ids[LOCAL], &peer->node_ids[REMOTE]); diff --git a/lightningd/channel/channel_wire.csv b/lightningd/channel/channel_wire.csv index 60a4a5259..db9eab1e7 100644 --- a/lightningd/channel/channel_wire.csv +++ b/lightningd/channel/channel_wire.csv @@ -50,6 +50,12 @@ channel_init,,next_htlc_id,u64 channel_init,,num_htlcs,u16 channel_init,,htlcs,num_htlcs*struct added_htlc channel_init,,htlc_states,num_htlcs*enum htlc_state +channel_init,,num_fulfilled,u16 +channel_init,,fulfilled,num_fulfilled*struct fulfilled_htlc +channel_init,,fulfilled_sides,num_fulfilled*enum side +channel_init,,num_failed,u16 +channel_init,,failed,num_failed*struct failed_htlc +channel_init,,failed_sides,num_failed*enum side channel_init,,init_peer_pkt_len,u16 channel_init,,init_peer_pkt,init_peer_pkt_len*u8 diff --git a/lightningd/peer_control.c b/lightningd/peer_control.c index 352e745c7..de0830195 100644 --- a/lightningd/peer_control.c +++ b/lightningd/peer_control.c @@ -924,6 +924,10 @@ static bool peer_start_channeld_hsmfd(struct subd *hsm, const u8 *resp, const struct config *cfg = &peer->ld->dstate.config; struct added_htlc *htlcs; enum htlc_state *htlc_states; + struct fulfilled_htlc *fulfilled_htlcs; + enum side *fulfilled_sides; + struct failed_htlc *failed_htlcs; + enum side *failed_sides; peer->owner = new_subd(peer->ld, peer->ld, "lightningd_channel", peer, @@ -943,7 +947,8 @@ static bool peer_start_channeld_hsmfd(struct subd *hsm, const u8 *resp, log_debug(peer->log, "Waiting for funding confirmations"); peer_set_condition(peer, GETTING_HSMFD, CHANNELD_AWAITING_LOCKIN); - peer_htlcs(resp, peer, &htlcs, &htlc_states); + peer_htlcs(resp, peer, &htlcs, &htlc_states, &fulfilled_htlcs, + &fulfilled_sides, &failed_htlcs, &failed_sides); initmsg = towire_channel_init(peer, peer->funding_txid, @@ -974,6 +979,8 @@ static bool peer_start_channeld_hsmfd(struct subd *hsm, const u8 *resp, peer->num_revocations_received, peer->next_htlc_id, htlcs, htlc_states, + fulfilled_htlcs, fulfilled_sides, + failed_htlcs, failed_sides, peer->funding_signed); /* Don't need this any more (we never re-transmit it) */ diff --git a/lightningd/peer_htlcs.c b/lightningd/peer_htlcs.c index fdf2b59d2..f626eb73b 100644 --- a/lightningd/peer_htlcs.c +++ b/lightningd/peer_htlcs.c @@ -1118,11 +1118,46 @@ static void add_htlc(struct added_htlc **htlcs, *h = state; } +static void add_fulfill(u64 id, enum side side, + const struct preimage *payment_preimage, + struct fulfilled_htlc **fulfilled_htlcs, + enum side **fulfilled_sides) +{ + struct fulfilled_htlc *f; + enum side *s; + + f = tal_arr_append(fulfilled_htlcs); + s = tal_arr_append(fulfilled_sides); + f->id = id; + f->payment_preimage = *payment_preimage; + *s = side; +} + +static void add_fail(u64 id, enum side side, + const u8 *failuremsg, + struct failed_htlc **failed_htlcs, + enum side **failed_sides) +{ + struct failed_htlc *f; + enum side *s; + + f = tal_arr_append(failed_htlcs); + s = tal_arr_append(failed_sides); + f->id = id; + f->failreason = tal_dup_arr(*failed_htlcs, u8, + failuremsg, tal_len(failuremsg), 0); + *s = side; +} + /* FIXME: Load direct from db. */ void peer_htlcs(const tal_t *ctx, const struct peer *peer, struct added_htlc **htlcs, - enum htlc_state **htlc_states) + enum htlc_state **htlc_states, + struct fulfilled_htlc **fulfilled_htlcs, + enum side **fulfilled_sides, + struct failed_htlc **failed_htlcs, + enum side **failed_sides) { struct htlc_in_map_iter ini; struct htlc_out_map_iter outi; @@ -1131,6 +1166,10 @@ void peer_htlcs(const tal_t *ctx, *htlcs = tal_arr(ctx, struct added_htlc, 0); *htlc_states = tal_arr(ctx, enum htlc_state, 0); + *fulfilled_htlcs = tal_arr(ctx, struct fulfilled_htlc, 0); + *fulfilled_sides = tal_arr(ctx, enum side, 0); + *failed_htlcs = tal_arr(ctx, struct failed_htlc, 0); + *failed_sides = tal_arr(ctx, enum side, 0); for (hin = htlc_in_map_first(&peer->ld->htlcs_in, &ini); hin; @@ -1142,6 +1181,13 @@ void peer_htlcs(const tal_t *ctx, hin->key.id, hin->msatoshi, &hin->payment_hash, hin->cltv_expiry, hin->onion_routing_packet, hin->hstate); + + if (hin->failuremsg) + add_fail(hin->key.id, REMOTE, hin->failuremsg, + failed_htlcs, failed_sides); + if (hin->preimage) + add_fulfill(hin->key.id, REMOTE, hin->preimage, + fulfilled_htlcs, fulfilled_sides); } for (hout = htlc_out_map_first(&peer->ld->htlcs_out, &outi); @@ -1154,5 +1200,12 @@ void peer_htlcs(const tal_t *ctx, hout->key.id, hout->msatoshi, &hout->payment_hash, hout->cltv_expiry, hout->onion_routing_packet, hout->hstate); + + if (hout->failuremsg) + add_fail(hout->key.id, LOCAL, hout->failuremsg, + failed_htlcs, failed_sides); + if (hout->preimage) + add_fulfill(hout->key.id, LOCAL, hout->preimage, + fulfilled_htlcs, fulfilled_sides); } } diff --git a/lightningd/peer_htlcs.h b/lightningd/peer_htlcs.h index f7200d94d..184eeabd2 100644 --- a/lightningd/peer_htlcs.h +++ b/lightningd/peer_htlcs.h @@ -17,7 +17,11 @@ struct channel_info { void peer_htlcs(const tal_t *ctx, const struct peer *peer, struct added_htlc **htlcs, - enum htlc_state **htlc_states); + enum htlc_state **htlc_states, + struct fulfilled_htlc **fulfilled_htlcs, + enum side **fulfilled_sides, + struct failed_htlc **failed_htlcs, + enum side **failed_sides); bool peer_save_commitsig_received(struct peer *peer, u64 commitnum); bool peer_save_commitsig_sent(struct peer *peer, u64 commitnum);