From 7aa01b0e50108f902b9e7036b762de91cf681e60 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Mon, 7 Nov 2016 23:01:02 +1030 Subject: [PATCH] broadcast_tx: add optional failed callback. And if that's set, don't rebroadcast. Signed-off-by: Rusty Russell --- daemon/chaintopology.c | 16 ++++++++++++---- daemon/chaintopology.h | 8 ++++++-- daemon/peer.c | 19 ++++++++++--------- daemon/peer.h | 1 + 4 files changed, 29 insertions(+), 15 deletions(-) diff --git a/daemon/chaintopology.c b/daemon/chaintopology.c index dbb7b219e..b05843a24 100644 --- a/daemon/chaintopology.c +++ b/daemon/chaintopology.c @@ -279,12 +279,19 @@ static void broadcast_done(struct lightningd_state *dstate, int exitstatus, const char *msg, struct outgoing_tx *otx) { - /* For continual rebroadcasting */ - list_add_tail(&otx->peer->outgoing_txs, &otx->list); - tal_add_destructor(otx, destroy_outgoing_tx); + if (otx->failed && exitstatus != 0) { + otx->failed(otx->peer, exitstatus, msg); + tal_free(otx); + } else { + /* For continual rebroadcasting */ + list_add_tail(&otx->peer->outgoing_txs, &otx->list); + tal_add_destructor(otx, destroy_outgoing_tx); + } } -void broadcast_tx(struct peer *peer, const struct bitcoin_tx *tx) +void broadcast_tx(struct peer *peer, const struct bitcoin_tx *tx, + void (*failed)(struct peer *peer, + int exitstatus, const char *err)) { struct outgoing_tx *otx = tal(peer, struct outgoing_tx); const u8 *rawtx = linearize_tx(otx, tx); @@ -292,6 +299,7 @@ void broadcast_tx(struct peer *peer, const struct bitcoin_tx *tx) otx->peer = peer; bitcoin_txid(tx, &otx->txid); otx->hextx = tal_hexstr(otx, rawtx, tal_count(rawtx)); + otx->failed = failed; tal_free(rawtx); log_add_struct(peer->log, " (tx %s)", struct sha256_double, &otx->txid); diff --git a/daemon/chaintopology.h b/daemon/chaintopology.h index 613ae9fc5..4f810a44e 100644 --- a/daemon/chaintopology.h +++ b/daemon/chaintopology.h @@ -38,8 +38,12 @@ u32 get_block_height(struct lightningd_state *dstate); /* Get fee rate. */ u64 get_feerate(struct lightningd_state *dstate); -/* Broadcast a single tx, and rebroadcast as reqd (copies tx). */ -void broadcast_tx(struct peer *peer, const struct bitcoin_tx *tx); +/* Broadcast a single tx, and rebroadcast as reqd (copies tx). + * If failed is non-NULL, call that and don't rebroadcast. */ +void broadcast_tx(struct peer *peer, const struct bitcoin_tx *tx, + void (*failed)(struct peer *peer, + int exitstatus, + const char *err)); void setup_topology(struct lightningd_state *dstate); diff --git a/daemon/peer.c b/daemon/peer.c index ee78c779e..140fe9144 100644 --- a/daemon/peer.c +++ b/daemon/peer.c @@ -342,12 +342,12 @@ static void peer_breakdown(struct peer *peer) /* If we have a closing tx, use it. */ if (peer->closing.their_sig) { log_unusual(peer->log, "Peer breakdown: sending close tx"); - broadcast_tx(peer, bitcoin_close(peer)); + broadcast_tx(peer, bitcoin_close(peer), NULL); /* If we have a signed commit tx (maybe not if we just offered * anchor, or they supplied anchor, or no outputs to us). */ } else if (peer->local.commit && peer->local.commit->sig) { log_unusual(peer->log, "Peer breakdown: sending commit tx"); - broadcast_tx(peer, bitcoin_commit(peer)); + broadcast_tx(peer, bitcoin_commit(peer), NULL); } else { log_info(peer->log, "Peer breakdown: nothing to do"); /* We close immediately. */ @@ -963,7 +963,7 @@ static bool closing_pkt_in(struct peer *peer, const Pkt *pkt) * matching `close_fee` it SHOULD close the connection and * SHOULD sign and broadcast the final closing transaction. */ - broadcast_tx(peer, bitcoin_close(peer)); + broadcast_tx(peer, bitcoin_close(peer), NULL); return false; } @@ -1553,7 +1553,7 @@ static void state_single(struct peer *peer, log_add(peer->log, " (out %s)", pkt_name(outpkt->pkt_case)); } if (broadcast) - broadcast_tx(peer, broadcast); + broadcast_tx(peer, broadcast, NULL); if (state_is_error(peer->state)) { /* Breakdown is common, others less so. */ @@ -1694,7 +1694,7 @@ static bool fulfill_onchain(struct peer *peer, struct htlc *htlc) return false; peer->onchain.resolved[i] = htlc_fulfill_tx(peer, i); - broadcast_tx(peer, peer->onchain.resolved[i]); + broadcast_tx(peer, peer->onchain.resolved[i], NULL); return true; } } @@ -3301,7 +3301,7 @@ static enum watch_result our_htlc_depth(struct peer *peer, peer, peer->onchain.resolved[out_num], our_htlc_timeout_depth, h); - broadcast_tx(peer, peer->onchain.resolved[out_num]); + broadcast_tx(peer, peer->onchain.resolved[out_num], NULL); } return DELETE_WATCH; } @@ -3370,7 +3370,8 @@ static enum watch_result our_main_output_depth(struct peer *peer, */ peer->onchain.resolved[peer->onchain.to_us_idx] = bitcoin_spend_ours(peer); - broadcast_tx(peer, peer->onchain.resolved[peer->onchain.to_us_idx]); + broadcast_tx(peer, peer->onchain.resolved[peer->onchain.to_us_idx], + NULL); return DELETE_WATCH; } @@ -3486,7 +3487,7 @@ static void resolve_their_htlc(struct peer *peer, unsigned int out_num) */ if (peer->onchain.htlcs[out_num]->r) { peer->onchain.resolved[out_num] = htlc_fulfill_tx(peer, out_num); - broadcast_tx(peer, peer->onchain.resolved[out_num]); + broadcast_tx(peer, peer->onchain.resolved[out_num], NULL); } else { /* BOLT #onchain: * @@ -3773,7 +3774,7 @@ static void resolve_their_steal(struct peer *peer, peer->onchain.wscripts[i]); } - broadcast_tx(peer, steal_tx); + broadcast_tx(peer, steal_tx, NULL); } static struct sha256 *get_rhash(struct peer *peer, u64 commit_num, diff --git a/daemon/peer.h b/daemon/peer.h index 1e612173b..aca7d0e06 100644 --- a/daemon/peer.h +++ b/daemon/peer.h @@ -82,6 +82,7 @@ struct outgoing_tx { struct peer *peer; const char *hextx; struct sha256_double txid; + void (*failed)(struct peer *peer, int exitstatus, const char *err); }; struct peer {