broadcast_tx: add optional failed callback.

And if that's set, don't rebroadcast.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
Rusty Russell 2016-11-07 23:01:02 +10:30
parent 89131444b3
commit 7aa01b0e50
4 changed files with 29 additions and 15 deletions

View File

@ -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);

View File

@ -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);

View File

@ -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,

View File

@ -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 {