mirror of
https://github.com/ElementsProject/lightning.git
synced 2024-11-19 09:54:16 +01:00
watch: make it easier for them to self-delete.
Rather than keeping a pointer so they can free themselves, make it explicit. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
parent
3ba25dd994
commit
b8571c1ac8
113
daemon/peer.c
113
daemon/peer.c
@ -1154,9 +1154,10 @@ struct anchor_watch {
|
||||
struct oneshot *timer;
|
||||
};
|
||||
|
||||
static void anchor_depthchange(struct peer *peer, unsigned int depth,
|
||||
const struct sha256_double *txid,
|
||||
void *unused)
|
||||
static enum watch_result anchor_depthchange(struct peer *peer,
|
||||
unsigned int depth,
|
||||
const struct sha256_double *txid,
|
||||
void *unused)
|
||||
{
|
||||
struct anchor_watch *w = peer->anchor.watches;
|
||||
|
||||
@ -1175,6 +1176,7 @@ static void anchor_depthchange(struct peer *peer, unsigned int depth,
|
||||
|
||||
/* Since this gets called on every new block, check HTLCs here. */
|
||||
check_htlc_expiry(peer);
|
||||
return KEEP_WATCHING;
|
||||
}
|
||||
|
||||
/* Yay, segwit! We can just compare txids, even though we don't have both
|
||||
@ -1474,10 +1476,10 @@ static void resolve_cheating(struct peer *peer)
|
||||
broadcast_tx(peer, steal_tx);
|
||||
}
|
||||
|
||||
static void our_htlc_spent(struct peer *peer,
|
||||
const struct bitcoin_tx *tx,
|
||||
size_t input_num,
|
||||
ptrint_t *pi)
|
||||
static enum watch_result our_htlc_spent(struct peer *peer,
|
||||
const struct bitcoin_tx *tx,
|
||||
size_t input_num,
|
||||
ptrint_t *pi)
|
||||
{
|
||||
struct htlc *h;
|
||||
struct sha256 sha;
|
||||
@ -1503,7 +1505,8 @@ static void our_htlc_spent(struct peer *peer,
|
||||
|
||||
/* Our timeout tx has all-zeroes, so we can distinguish it. */
|
||||
if (memeqzero(tx->input[input_num].witness[1], sizeof(preimage)))
|
||||
return;
|
||||
/* They might try to race us. */
|
||||
return KEEP_WATCHING;
|
||||
|
||||
memcpy(&preimage, tx->input[input_num].witness[1], sizeof(preimage));
|
||||
sha256(&sha, &preimage, sizeof(preimage));
|
||||
@ -1526,20 +1529,21 @@ static void our_htlc_spent(struct peer *peer,
|
||||
* preimage; the knowledge is not revocable.
|
||||
*/
|
||||
peer->closing_onchain.resolved[i] = irrevocably_resolved(peer);
|
||||
return DELETE_WATCH;
|
||||
}
|
||||
|
||||
static void our_htlc_depth(struct peer *peer,
|
||||
unsigned int depth,
|
||||
const struct sha256_double *txid,
|
||||
bool our_commit,
|
||||
size_t i)
|
||||
static enum watch_result our_htlc_depth(struct peer *peer,
|
||||
unsigned int depth,
|
||||
const struct sha256_double *txid,
|
||||
bool our_commit,
|
||||
size_t i)
|
||||
{
|
||||
struct htlc *h;
|
||||
u32 height;
|
||||
|
||||
/* Must be in a block. */
|
||||
if (depth == 0)
|
||||
return;
|
||||
return KEEP_WATCHING;
|
||||
|
||||
height = get_block_height(peer->dstate);
|
||||
h = htlc_by_index(peer->closing_onchain.ci, i);
|
||||
@ -1554,11 +1558,11 @@ static void our_htlc_depth(struct peer *peer,
|
||||
*/
|
||||
|
||||
if (height < abs_locktime_to_blocks(&h->expiry))
|
||||
return;
|
||||
return KEEP_WATCHING;
|
||||
|
||||
if (our_commit) {
|
||||
if (depth < rel_locktime_to_blocks(&peer->remote.locktime))
|
||||
return;
|
||||
return KEEP_WATCHING;
|
||||
}
|
||||
|
||||
/* BOLT #onchain:
|
||||
@ -1566,27 +1570,29 @@ static void our_htlc_depth(struct peer *peer,
|
||||
* If the output has *timed out* and not been *resolved*, the node
|
||||
* MUST *resolve* the output by spending it.
|
||||
*/
|
||||
/* FIXME: we should simply delete this watch if HTLC is fulfilled. */
|
||||
if (!peer->closing_onchain.resolved[i]) {
|
||||
peer->closing_onchain.resolved[i]
|
||||
= htlc_timeout_tx(peer, peer->closing_onchain.ci, i);
|
||||
broadcast_tx(peer, peer->closing_onchain.resolved[i]);
|
||||
}
|
||||
return DELETE_WATCH;
|
||||
}
|
||||
|
||||
static void our_htlc_depth_ourcommit(struct peer *peer,
|
||||
unsigned int depth,
|
||||
const struct sha256_double *txid,
|
||||
ptrint_t *i)
|
||||
static enum watch_result our_htlc_depth_ourcommit(struct peer *peer,
|
||||
unsigned int depth,
|
||||
const struct sha256_double *txid,
|
||||
ptrint_t *i)
|
||||
{
|
||||
our_htlc_depth(peer, depth, txid, true, ptr2int(i));
|
||||
return our_htlc_depth(peer, depth, txid, true, ptr2int(i));
|
||||
}
|
||||
|
||||
static void our_htlc_depth_theircommit(struct peer *peer,
|
||||
unsigned int depth,
|
||||
const struct sha256_double *txid,
|
||||
ptrint_t *i)
|
||||
static enum watch_result our_htlc_depth_theircommit(struct peer *peer,
|
||||
unsigned int depth,
|
||||
const struct sha256_double *txid,
|
||||
ptrint_t *i)
|
||||
{
|
||||
our_htlc_depth(peer, depth, txid, false, ptr2int(i));
|
||||
return our_htlc_depth(peer, depth, txid, false, ptr2int(i));
|
||||
}
|
||||
|
||||
static void resolve_our_htlcs(struct peer *peer,
|
||||
@ -1644,10 +1650,10 @@ void our_htlc_fulfilled(struct peer *peer, struct htlc *htlc,
|
||||
}
|
||||
}
|
||||
|
||||
static void their_htlc_depth(struct peer *peer,
|
||||
unsigned int depth,
|
||||
const struct sha256_double *txid,
|
||||
ptrint_t *pi)
|
||||
static enum watch_result their_htlc_depth(struct peer *peer,
|
||||
unsigned int depth,
|
||||
const struct sha256_double *txid,
|
||||
ptrint_t *pi)
|
||||
{
|
||||
u32 height;
|
||||
struct htlc *h;
|
||||
@ -1655,7 +1661,7 @@ static void their_htlc_depth(struct peer *peer,
|
||||
|
||||
/* Must be in a block. */
|
||||
if (depth == 0)
|
||||
return;
|
||||
return KEEP_WATCHING;
|
||||
|
||||
height = get_block_height(peer->dstate);
|
||||
h = htlc_by_index(peer->closing_onchain.ci, i);
|
||||
@ -1667,9 +1673,10 @@ static void their_htlc_depth(struct peer *peer,
|
||||
*/
|
||||
|
||||
if (height < abs_locktime_to_blocks(&h->expiry))
|
||||
return;
|
||||
return KEEP_WATCHING;
|
||||
|
||||
peer->closing_onchain.resolved[i] = irrevocably_resolved(peer);
|
||||
return DELETE_WATCH;
|
||||
}
|
||||
|
||||
static void resolve_their_htlcs(struct peer *peer,
|
||||
@ -1691,18 +1698,16 @@ static void resolve_their_htlcs(struct peer *peer,
|
||||
}
|
||||
}
|
||||
|
||||
static void our_main_output_depth(struct peer *peer,
|
||||
unsigned int depth,
|
||||
const struct sha256_double *txid,
|
||||
void *unused)
|
||||
static enum watch_result our_main_output_depth(struct peer *peer,
|
||||
unsigned int depth,
|
||||
const struct sha256_double *txid,
|
||||
void *unused)
|
||||
{
|
||||
/* Not past CSV timeout? */
|
||||
if (depth < rel_locktime_to_blocks(&peer->remote.locktime))
|
||||
return;
|
||||
return KEEP_WATCHING;
|
||||
|
||||
/* Already done? (FIXME: Delete after first time) */
|
||||
if (peer->closing_onchain.resolved[0])
|
||||
return;
|
||||
assert(!peer->closing_onchain.resolved[0]);
|
||||
|
||||
/* BOLT #onchain:
|
||||
*
|
||||
@ -1715,6 +1720,7 @@ static void our_main_output_depth(struct peer *peer,
|
||||
*/
|
||||
peer->closing_onchain.resolved[0] = bitcoin_spend_ours(peer);
|
||||
broadcast_tx(peer, peer->closing_onchain.resolved[0]);
|
||||
return DELETE_WATCH;
|
||||
}
|
||||
|
||||
/* BOLT #onchain:
|
||||
@ -1832,10 +1838,10 @@ static void resolve_mutual_close(struct peer *peer)
|
||||
}
|
||||
|
||||
/* Called every time the tx spending the funding tx changes depth. */
|
||||
static void check_for_resolution(struct peer *peer,
|
||||
unsigned int depth,
|
||||
const struct sha256_double *txid,
|
||||
void *unused)
|
||||
static enum watch_result check_for_resolution(struct peer *peer,
|
||||
unsigned int depth,
|
||||
const struct sha256_double *txid,
|
||||
void *unused)
|
||||
{
|
||||
size_t i, n = tal_count(peer->closing_onchain.resolved);
|
||||
size_t forever = peer->dstate->config.forever_confirms;
|
||||
@ -1848,7 +1854,7 @@ static void check_for_resolution(struct peer *peer,
|
||||
*/
|
||||
for (i = 0; i < n; i++)
|
||||
if (!peer->closing_onchain.resolved[i])
|
||||
return;
|
||||
return KEEP_WATCHING;
|
||||
|
||||
/* BOLT #onchain:
|
||||
*
|
||||
@ -1857,14 +1863,14 @@ static void check_for_resolution(struct peer *peer,
|
||||
* 100 deep on the most-work blockchain.
|
||||
*/
|
||||
if (depth < forever)
|
||||
return;
|
||||
return KEEP_WATCHING;
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
struct sha256_double txid;
|
||||
|
||||
bitcoin_txid(peer->closing_onchain.resolved[i], &txid);
|
||||
if (get_tx_depth(peer->dstate, &txid) < forever)
|
||||
return;
|
||||
return KEEP_WATCHING;
|
||||
}
|
||||
|
||||
/* BOLT #onchain:
|
||||
@ -1880,14 +1886,16 @@ static void check_for_resolution(struct peer *peer,
|
||||
io_break(peer);
|
||||
else
|
||||
io_wake(peer);
|
||||
|
||||
return DELETE_WATCH;
|
||||
}
|
||||
|
||||
/* We assume the tx is valid! Don't do a blockchain.info and feed this
|
||||
* invalid transactions! */
|
||||
static void anchor_spent(struct peer *peer,
|
||||
const struct bitcoin_tx *tx,
|
||||
size_t input_num,
|
||||
void *unused)
|
||||
static enum watch_result anchor_spent(struct peer *peer,
|
||||
const struct bitcoin_tx *tx,
|
||||
size_t input_num,
|
||||
void *unused)
|
||||
{
|
||||
struct sha256_double txid;
|
||||
Pkt *err;
|
||||
@ -1943,7 +1951,7 @@ static void anchor_spent(struct peer *peer,
|
||||
"anchor_spent");
|
||||
/* No longer call into the state machine. */
|
||||
peer->anchor.watches->depthok = INPUT_NONE;
|
||||
return;
|
||||
return DELETE_WATCH;
|
||||
}
|
||||
|
||||
/* BOLT #onchain:
|
||||
@ -1970,6 +1978,7 @@ static void anchor_spent(struct peer *peer,
|
||||
|
||||
/* No longer call into the state machine. */
|
||||
peer->anchor.watches->depthok = INPUT_NONE;
|
||||
return KEEP_WATCHING;
|
||||
}
|
||||
|
||||
static void anchor_timeout(struct anchor_watch *w)
|
||||
|
@ -88,9 +88,10 @@ static void destroy_txwatch(struct txwatch *w)
|
||||
struct txwatch *watch_txid_(const tal_t *ctx,
|
||||
struct peer *peer,
|
||||
const struct sha256_double *txid,
|
||||
void (*cb)(struct peer *peer, unsigned int depth,
|
||||
const struct sha256_double *txid,
|
||||
void *arg),
|
||||
enum watch_result (*cb)(struct peer *peer,
|
||||
unsigned int depth,
|
||||
const struct sha256_double *,
|
||||
void *arg),
|
||||
void *cb_arg)
|
||||
{
|
||||
struct txwatch *w;
|
||||
@ -118,9 +119,10 @@ bool watching_txid(struct lightningd_state *dstate,
|
||||
struct txwatch *watch_tx_(const tal_t *ctx,
|
||||
struct peer *peer,
|
||||
const struct bitcoin_tx *tx,
|
||||
void (*cb)(struct peer *peer, unsigned int depth,
|
||||
const struct sha256_double *txid,
|
||||
void *arg),
|
||||
enum watch_result (*cb)(struct peer *peer,
|
||||
unsigned int depth,
|
||||
const struct sha256_double *,
|
||||
void *arg),
|
||||
void *cb_arg)
|
||||
{
|
||||
struct sha256_double txid;
|
||||
@ -133,10 +135,10 @@ struct txowatch *watch_txo_(const tal_t *ctx,
|
||||
struct peer *peer,
|
||||
const struct sha256_double *txid,
|
||||
unsigned int output,
|
||||
void (*cb)(struct peer *peer,
|
||||
const struct bitcoin_tx *tx,
|
||||
size_t input_num,
|
||||
void *),
|
||||
enum watch_result (*cb)(struct peer *peer,
|
||||
const struct bitcoin_tx *tx,
|
||||
size_t input_num,
|
||||
void *),
|
||||
void *cbdata)
|
||||
{
|
||||
struct txowatch *w = tal(ctx, struct txowatch);
|
||||
@ -160,6 +162,7 @@ void txwatch_fire(struct lightningd_state *dstate,
|
||||
struct txwatch *txw = txwatch_hash_get(&dstate->txwatches, txid);
|
||||
|
||||
if (txw && depth != txw->depth) {
|
||||
enum watch_result r;
|
||||
log_debug(txw->peer->log,
|
||||
"Got depth change %u for %02x%02x%02x...\n",
|
||||
txw->depth,
|
||||
@ -167,7 +170,15 @@ void txwatch_fire(struct lightningd_state *dstate,
|
||||
txw->txid.sha.u.u8[1],
|
||||
txw->txid.sha.u.u8[2]);
|
||||
txw->depth = depth;
|
||||
txw->cb(txw->peer, txw->depth, &txw->txid, txw->cbdata);
|
||||
r = txw->cb(txw->peer, txw->depth, &txw->txid, txw->cbdata);
|
||||
switch (r) {
|
||||
case DELETE_WATCH:
|
||||
tal_free(txw);
|
||||
return;
|
||||
case KEEP_WATCHING:
|
||||
return;
|
||||
}
|
||||
fatal("txwatch callback %p returned %i\n", txw->cb, r);
|
||||
}
|
||||
}
|
||||
|
||||
@ -177,6 +188,7 @@ void txowatch_fire(struct lightningd_state *dstate,
|
||||
size_t input_num)
|
||||
{
|
||||
struct sha256_double txid;
|
||||
enum watch_result r;
|
||||
|
||||
bitcoin_txid(tx, &txid);
|
||||
log_debug(txow->peer->log,
|
||||
@ -189,7 +201,15 @@ void txowatch_fire(struct lightningd_state *dstate,
|
||||
txid.sha.u.u8[1],
|
||||
txid.sha.u.u8[2],
|
||||
txid.sha.u.u8[3]);
|
||||
txow->cb(txow->peer, tx, input_num, txow->cbdata);
|
||||
r = txow->cb(txow->peer, tx, input_num, txow->cbdata);
|
||||
switch (r) {
|
||||
case DELETE_WATCH:
|
||||
tal_free(txow);
|
||||
return;
|
||||
case KEEP_WATCHING:
|
||||
return;
|
||||
}
|
||||
fatal("txowatch callback %p returned %i\n", txow->cb, r);
|
||||
}
|
||||
|
||||
void watch_topology_changed(struct lightningd_state *dstate)
|
||||
@ -208,9 +228,18 @@ again:
|
||||
|
||||
depth = get_tx_depth(dstate, &w->txid);
|
||||
if (depth != w->depth) {
|
||||
enum watch_result r;
|
||||
w->depth = depth;
|
||||
w->cb(w->peer, w->depth, &w->txid, w->cbdata);
|
||||
needs_rerun = true;
|
||||
r = w->cb(w->peer, w->depth, &w->txid, w->cbdata);
|
||||
switch (r) {
|
||||
case DELETE_WATCH:
|
||||
tal_free(w);
|
||||
continue;
|
||||
case KEEP_WATCHING:
|
||||
continue;
|
||||
}
|
||||
fatal("txwatch callback %p returned %i\n", w->cb, r);
|
||||
}
|
||||
}
|
||||
if (needs_rerun)
|
||||
|
@ -11,6 +11,11 @@
|
||||
struct bitcoin_tx;
|
||||
struct lightningd_state;
|
||||
|
||||
enum watch_result {
|
||||
DELETE_WATCH = -1,
|
||||
KEEP_WATCHING = -2
|
||||
};
|
||||
|
||||
struct txwatch_output {
|
||||
struct sha256_double txid;
|
||||
unsigned int index;
|
||||
@ -25,10 +30,10 @@ struct txowatch {
|
||||
struct txwatch_output out;
|
||||
|
||||
/* A new tx. */
|
||||
void (*cb)(struct peer *peer,
|
||||
const struct bitcoin_tx *tx,
|
||||
size_t input_num,
|
||||
void *cbdata);
|
||||
enum watch_result (*cb)(struct peer *peer,
|
||||
const struct bitcoin_tx *tx,
|
||||
size_t input_num,
|
||||
void *cbdata);
|
||||
|
||||
void *cbdata;
|
||||
};
|
||||
@ -51,9 +56,9 @@ struct txwatch {
|
||||
unsigned int depth;
|
||||
|
||||
/* A new depth (0 if kicked out, otherwise 1 = tip, etc.) */
|
||||
void (*cb)(struct peer *peer, unsigned int depth,
|
||||
const struct sha256_double *txid,
|
||||
void *cbdata);
|
||||
enum watch_result (*cb)(struct peer *peer, unsigned int depth,
|
||||
const struct sha256_double *txid,
|
||||
void *cbdata);
|
||||
void *cbdata;
|
||||
};
|
||||
|
||||
@ -67,14 +72,15 @@ HTABLE_DEFINE_TYPE(struct txwatch, txwatch_keyof, txid_hash, txwatch_eq,
|
||||
struct txwatch *watch_txid_(const tal_t *ctx,
|
||||
struct peer *peer,
|
||||
const struct sha256_double *txid,
|
||||
void (*cb)(struct peer *peer, unsigned int depth,
|
||||
const struct sha256_double *txid,
|
||||
void *),
|
||||
enum watch_result (*cb)(struct peer *peer,
|
||||
unsigned int depth,
|
||||
const struct sha256_double*,
|
||||
void *),
|
||||
void *cbdata);
|
||||
|
||||
#define watch_txid(ctx, peer, txid, cb, cbdata) \
|
||||
watch_txid_((ctx), (peer), (txid), \
|
||||
typesafe_cb_preargs(void, void *, \
|
||||
typesafe_cb_preargs(enum watch_result, void *, \
|
||||
(cb), (cbdata), \
|
||||
struct peer *, \
|
||||
unsigned int depth, \
|
||||
@ -84,14 +90,15 @@ struct txwatch *watch_txid_(const tal_t *ctx,
|
||||
struct txwatch *watch_tx_(const tal_t *ctx,
|
||||
struct peer *peer,
|
||||
const struct bitcoin_tx *tx,
|
||||
void (*cb)(struct peer *peer, unsigned int depth,
|
||||
const struct sha256_double *txid,
|
||||
void *),
|
||||
enum watch_result (*cb)(struct peer *peer,
|
||||
unsigned int depth,
|
||||
const struct sha256_double *,
|
||||
void *),
|
||||
void *cbdata);
|
||||
|
||||
#define watch_tx(ctx, peer, tx, cb, cbdata) \
|
||||
watch_tx_((ctx), (peer), (tx), \
|
||||
typesafe_cb_preargs(void, void *, \
|
||||
typesafe_cb_preargs(enum watch_result, void *, \
|
||||
(cb), (cbdata), \
|
||||
struct peer *, \
|
||||
unsigned int depth, \
|
||||
@ -102,15 +109,15 @@ struct txowatch *watch_txo_(const tal_t *ctx,
|
||||
struct peer *peer,
|
||||
const struct sha256_double *txid,
|
||||
unsigned int output,
|
||||
void (*cb)(struct peer *peer,
|
||||
const struct bitcoin_tx *tx,
|
||||
size_t input_num,
|
||||
void *),
|
||||
enum watch_result (*cb)(struct peer *peer,
|
||||
const struct bitcoin_tx *tx,
|
||||
size_t input_num,
|
||||
void *),
|
||||
void *cbdata);
|
||||
|
||||
#define watch_txo(ctx, peer, txid, outnum, cb, cbdata) \
|
||||
watch_txo_((ctx), (peer), (txid), (outnum), \
|
||||
typesafe_cb_preargs(void, void *, \
|
||||
typesafe_cb_preargs(enum watch_result, void *, \
|
||||
(cb), (cbdata), \
|
||||
struct peer *, \
|
||||
const struct bitcoin_tx *, \
|
||||
|
Loading…
Reference in New Issue
Block a user