Browse Source

init: rebroadcast anchors on restart if we haven't seen them.

It's possible that we won't have sent the anchor, but state is
committed in db.  And our current philosophy is that we retransmit all
the txs dumbly, all the time.

Our --restart --timeout-anchor test trigger this case, too, so
re-enable that now.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
ppa-0.6.1
Rusty Russell 8 years ago
parent
commit
3aca5c87e3
  1. 3
      daemon/lightningd.c
  2. 32
      daemon/peer.c
  3. 1
      daemon/peer.h
  4. 6
      daemon/test/Makefile

3
daemon/lightningd.c

@ -555,6 +555,9 @@ int main(int argc, char *argv[])
/* If we loaded peers from database, reconnect now. */ /* If we loaded peers from database, reconnect now. */
reconnect_peers(dstate); reconnect_peers(dstate);
/* And send out anchors again if we're waiting. */
rebroadcast_anchors(dstate);
for (;;) { for (;;) {
struct timer *expired; struct timer *expired;
void *v = io_loop(&dstate->timers, &expired); void *v = io_loop(&dstate->timers, &expired);

32
daemon/peer.c

@ -512,7 +512,7 @@ out:
} }
/* Creation the bitcoin anchor tx, spending output user provided. */ /* 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); struct bitcoin_tx *tx = bitcoin_tx(peer, 1, 1);
size_t i; size_t i;
@ -530,8 +530,10 @@ static void bitcoin_create_anchor(struct peer *peer)
tx->input[0].amount = tal_dup(tx->input, u64, tx->input[0].amount = tal_dup(tx->input, u64,
&peer->anchor.input->in_amount); &peer->anchor.input->in_amount);
wallet_add_signed_input(peer->dstate, &peer->anchor.input->walletkey, if (!wallet_add_signed_input(peer->dstate,
tx, 0); &peer->anchor.input->walletkey,
tx, 0))
return false;
bitcoin_txid(tx, &peer->anchor.txid); bitcoin_txid(tx, &peer->anchor.txid);
peer->anchor.tx = tx; peer->anchor.tx = tx;
@ -542,6 +544,7 @@ static void bitcoin_create_anchor(struct peer *peer)
/* To avoid malleation, all inputs must be segwit! */ /* To avoid malleation, all inputs must be segwit! */
for (i = 0; i < tx->input_count; i++) for (i = 0; i < tx->input_count; i++)
assert(tx->input[i].witness); assert(tx->input[i].witness);
return true;
} }
static bool open_pkt_in(struct peer *peer, const Pkt *pkt) 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); &peer->remote.commitkey);
if (peer->local.offer_anchor) { 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? */ /* FIXME: Redundant with peer->local.offer_anchor? */
peer->anchor.ours = true; peer->anchor.ours = true;
@ -4419,6 +4426,23 @@ void reconnect_peers(struct lightningd_state *dstate)
try_reconnect(peer); 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, static void json_add_abstime(struct json_result *response,
const char *id, const char *id,
const struct abs_locktime *t) const struct abs_locktime *t)

1
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 debug_dump_peers(struct lightningd_state *dstate);
void reconnect_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); void cleanup_peers(struct lightningd_state *dstate);
#endif /* LIGHTNING_DAEMON_PEER_H */ #endif /* LIGHTNING_DAEMON_PEER_H */

6
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-manual-commit: daemon-test.sh-0-normal
daemon-test.sh-0-normal: daemon-test-setup-0 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-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-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-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 daemon-test.sh-1-manual-commit\ --restart: daemon-test.sh-1-normal\ --restart

Loading…
Cancel
Save