diff --git a/daemon/lightningd.c b/daemon/lightningd.c index e8b828d9f..419b6c264 100644 --- a/daemon/lightningd.c +++ b/daemon/lightningd.c @@ -554,6 +554,9 @@ int main(int argc, char *argv[]) /* If we loaded peers from database, reconnect now. */ reconnect_peers(dstate); + + /* And send out anchors again if we're waiting. */ + rebroadcast_anchors(dstate); for (;;) { struct timer *expired; diff --git a/daemon/peer.c b/daemon/peer.c index ebfdc537c..ea3eb36ea 100644 --- a/daemon/peer.c +++ b/daemon/peer.c @@ -512,7 +512,7 @@ out: } /* Creation the bitcoin anchor tx, spending output user provided. */ -static void bitcoin_create_anchor(struct peer *peer) +static bool bitcoin_create_anchor(struct peer *peer) { struct bitcoin_tx *tx = bitcoin_tx(peer, 1, 1); size_t i; @@ -530,8 +530,10 @@ static void bitcoin_create_anchor(struct peer *peer) tx->input[0].amount = tal_dup(tx->input, u64, &peer->anchor.input->in_amount); - wallet_add_signed_input(peer->dstate, &peer->anchor.input->walletkey, - tx, 0); + if (!wallet_add_signed_input(peer->dstate, + &peer->anchor.input->walletkey, + tx, 0)) + return false; bitcoin_txid(tx, &peer->anchor.txid); peer->anchor.tx = tx; @@ -542,6 +544,7 @@ static void bitcoin_create_anchor(struct peer *peer) /* To avoid malleation, all inputs must be segwit! */ for (i = 0; i < tx->input_count; i++) assert(tx->input[i].witness); + return true; } static bool open_pkt_in(struct peer *peer, const Pkt *pkt) @@ -577,7 +580,11 @@ static bool open_pkt_in(struct peer *peer, const Pkt *pkt) &peer->remote.commitkey); if (peer->local.offer_anchor) { - bitcoin_create_anchor(peer); + if (!bitcoin_create_anchor(peer)) { + db_abort_transaction(peer); + err = pkt_err(peer, "Own anchor unavailable"); + return peer_comms_err(peer, err); + } /* FIXME: Redundant with peer->local.offer_anchor? */ peer->anchor.ours = true; @@ -4419,6 +4426,23 @@ void reconnect_peers(struct lightningd_state *dstate) try_reconnect(peer); } +/* We may have gone down before broadcasting the anchor. Try again. */ +void rebroadcast_anchors(struct lightningd_state *dstate) +{ + struct peer *peer; + + list_for_each(&dstate->peers, peer, list) { + if (!state_is_waiting_for_anchor(peer->state)) + continue; + if (!peer->anchor.ours) + continue; + if (!bitcoin_create_anchor(peer)) + peer_fail(peer, __func__); + else + broadcast_tx(peer, peer->anchor.tx, NULL); + } +} + static void json_add_abstime(struct json_result *response, const char *id, const struct abs_locktime *t) diff --git a/daemon/peer.h b/daemon/peer.h index 4eec22630..a77bf5469 100644 --- a/daemon/peer.h +++ b/daemon/peer.h @@ -291,5 +291,6 @@ struct bitcoin_tx *peer_create_close_tx(const tal_t *ctx, void debug_dump_peers(struct lightningd_state *dstate); void reconnect_peers(struct lightningd_state *dstate); +void rebroadcast_anchors(struct lightningd_state *dstate); void cleanup_peers(struct lightningd_state *dstate); #endif /* LIGHTNING_DAEMON_PEER_H */ diff --git a/daemon/test/Makefile b/daemon/test/Makefile index cf0bd0e7f..ccaadce21 100644 --- a/daemon/test/Makefile +++ b/daemon/test/Makefile @@ -18,11 +18,9 @@ daemon-test.sh-0-mutual-close-with-htlcs: daemon-test.sh-0-manual-commit daemon-test.sh-0-manual-commit: daemon-test.sh-0-normal daemon-test.sh-0-normal: daemon-test-setup-0 -#FIXME: daemon-test.sh-1-timeout-anchor\ --restart -# This doesn't work because we don't retransmit anchor! - daemon-test.sh-1-steal\ --restart: daemon-test.sh-1-dump-onchain\ --restart -daemon-test.sh-1-dump-onchain\ --restart: daemon-test.sh-1-different-fee-rates\ --restart +daemon-test.sh-1-dump-onchain\ --restart: daemon-test.sh-1-timeout-anchor\ --restart +daemon-test.sh-1-timeout-anchor\ --restart: daemon-test.sh-1-different-fee-rates\ --restart daemon-test.sh-1-different-fee-rates\ --restart: daemon-test.sh-1-mutual-close-with-htlcs\ --restart daemon-test.sh-1-mutual-close-with-htlcs\ --restart: daemon-test.sh-1-manual-commit\ --restart daemon-test.sh-1-manual-commit\ --restart: daemon-test.sh-1-normal\ --restart