Browse Source

watch: don't hand blockhash, have commit_tx_depth() use get_last_mediantime()

There isn't a single blockhash; we may be on multiple forks.  But the one
caller which cares is commit_tx_depth(), which wants to know if the tx is
spendable yet.  So that uses get_last_mediantime().

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
ppa-0.6.1
Rusty Russell 9 years ago
parent
commit
b5a6ac26c7
  1. 14
      daemon/chaintopology.c
  2. 3
      daemon/chaintopology.h
  3. 45
      daemon/peer.c
  4. 4
      daemon/peer.h
  5. 14
      daemon/watch.c
  6. 14
      daemon/watch.h

14
daemon/chaintopology.c

@ -162,7 +162,7 @@ static void connect_blocks(struct lightningd_state *dstate, struct block *b)
add_tx_to_block(b, w);
/* Fire if it's the first we've seen it: this might
* set up txo watches, which could fire in this block */
txwatch_fire(dstate, w, 0, &b->blkid);
txwatch_fire(dstate, w, 0);
}
}
b->full_txs = tal_free(b->full_txs);
@ -219,16 +219,14 @@ static bool tx_in_block(const struct block *b, const struct txwatch *w)
static size_t get_tx_branch_height(const struct topology *topo,
const struct block *tip,
const struct txwatch *w,
struct sha256_double *blkid,
size_t max)
{
const struct block *b;
for (b = tip; b; b = b->prev) {
if (tx_in_block(b, w)) {
*blkid = b->blkid;
if (tx_in_block(b, w))
return b->height;
}
/* Don't bother returning less than max */
if (b->height < max)
return max;
@ -237,16 +235,14 @@ static size_t get_tx_branch_height(const struct topology *topo,
return tip->height + 1;
}
size_t get_tx_depth(struct lightningd_state *dstate, const struct txwatch *w,
struct sha256_double *blkid)
size_t get_tx_depth(struct lightningd_state *dstate, const struct txwatch *w)
{
const struct topology *topo = dstate->topology;
size_t i, max = 0, longest = 0;
/* Calculate tx height. */
for (i = 0; i < tal_count(topo->tips); i++) {
size_t h = get_tx_branch_height(topo, topo->tips[i], w, blkid,
max);
size_t h = get_tx_branch_height(topo, topo->tips[i], w, max);
if (h > max)
max = h;

3
daemon/chaintopology.h

@ -8,8 +8,7 @@ struct txwatch;
/* This is the number of blocks which would have to be mined to invalidate
* the tx. */
size_t get_tx_depth(struct lightningd_state *dstate, const struct txwatch *w,
struct sha256_double *blkid);
size_t get_tx_depth(struct lightningd_state *dstate, const struct txwatch *w);
/* This is the worst-case (latest) mediantime of blocks including the txid.
* Assumes the depth is > 0! */

45
daemon/peer.c

@ -1,4 +1,5 @@
#include "bitcoind.h"
#include "chaintopology.h"
#include "close_tx.h"
#include "commit_tx.h"
#include "controlled_time.h"
@ -643,7 +644,6 @@ struct anchor_watch {
};
static void anchor_depthchange(struct peer *peer, int depth,
const struct sha256_double *blkhash,
const struct sha256_double *txid,
void *unused)
{
@ -741,7 +741,6 @@ static bool is_mutual_close(const struct peer *peer,
static void close_depth_cb(struct peer *peer, int depth,
const struct sha256_double *txid,
const struct sha256_double *blkhash,
void *unused)
{
if (depth >= peer->dstate->config.forever_confirms) {
@ -836,39 +835,24 @@ void peer_unwatch_anchor_depth(struct peer *peer,
}
static void commit_tx_depth(struct peer *peer, int depth,
const struct sha256_double *blkhash,
const struct sha256_double *txid,
ptrint_t *canspend)
{
u32 mediantime;
log_debug(peer->log, "Commit tx reached depth %i", depth);
/* FIXME: Handle locktime in blocks, as well as seconds! */
/* Fell out of a block? */
if (depth < 0) {
/* Forget any old block. */
peer->cur_commit.start_time = 0;
memset(&peer->cur_commit.blockid, 0xFF,
sizeof(peer->cur_commit.blockid));
return;
}
/* In a new block? */
if (!structeq(blkhash, &peer->cur_commit.blockid)) {
peer->cur_commit.start_time = 0;
peer->cur_commit.blockid = *blkhash;
bitcoind_get_mediantime(peer->dstate, blkhash,
&peer->cur_commit.start_time);
if (depth <= 0)
return;
}
/* Don't yet know the median start time? */
if (!peer->cur_commit.start_time) {
log_debug(peer->log, "... but we don't know start_time");
return;
}
mediantime = get_last_mediantime(peer->dstate, txid);
assert(mediantime);
/* FIXME: We should really use bitcoin time here. */
if (controlled_time().ts.tv_sec > peer->cur_commit.start_time
if (controlled_time().ts.tv_sec > mediantime
+ rel_locktime_to_seconds(&peer->them.locktime)) {
/* Free this watch; we're done */
peer->cur_commit.watch = tal_free(peer->cur_commit.watch);
@ -889,9 +873,12 @@ static void our_commit_spent(struct peer *peer,
static void watch_commit_outputs(struct peer *peer, const struct bitcoin_tx *tx)
{
varint_t i;
struct sha256_double txid;
normalized_txid(tx, &txid);
for (i = 0; i < tx->output_count; i++) {
watch_txo(peer, peer, tx, i, our_commit_spent, peer->us.commit);
watch_txo(peer, peer, &txid, i, our_commit_spent,
peer->us.commit);
}
}
@ -902,17 +889,13 @@ void peer_watch_delayed(struct peer *peer,
{
/* We only ever spend the last one. */
assert(tx == peer->us.commit->tx);
memset(&peer->cur_commit.blockid, 0xFF,
sizeof(peer->cur_commit.blockid));
peer->cur_commit.watch
= watch_tx(tx, peer, tx, commit_tx_depth,
int2ptr(canspend));
peer->cur_commit.watch = watch_tx(tx, peer, tx, commit_tx_depth,
int2ptr(canspend));
watch_commit_outputs(peer, tx);
}
static void spend_tx_done(struct peer *peer, int depth,
const struct sha256_double *blkhash,
const struct sha256_double *txid,
ptrint_t *done)
{

4
daemon/peer.h

@ -153,10 +153,6 @@ struct peer {
struct {
/* Their signature for our current commit sig. */
struct bitcoin_signature theirsig;
/* When it entered a block (mediantime). */
u32 start_time;
/* Which block it entered. */
struct sha256_double blockid;
/* The watch we have on a live commit tx. */
struct txwatch *watch;
} cur_commit;

14
daemon/watch.c

@ -36,6 +36,7 @@
#include "timeout.h"
#include "watch.h"
#include <ccan/hash/hash.h>
#include <ccan/ptrint/ptrint.h>
#include <ccan/structeq/structeq.h>
const struct txwatch_output *txowatch_keyof(const struct txowatch *w)
@ -83,7 +84,6 @@ struct txwatch *watch_txid_(const tal_t *ctx,
struct peer *peer,
const struct sha256_double *txid,
void (*cb)(struct peer *peer, int depth,
const struct sha256_double *blkhash,
const struct sha256_double *txid,
void *arg),
void *cb_arg)
@ -110,7 +110,6 @@ struct txwatch *watch_tx_(const tal_t *ctx,
struct peer *peer,
const struct bitcoin_tx *tx,
void (*cb)(struct peer *peer, int depth,
const struct sha256_double *blkhash,
const struct sha256_double *txid,
void *arg),
void *cb_arg)
@ -147,8 +146,7 @@ struct txowatch *watch_txo_(const tal_t *ctx,
void txwatch_fire(struct lightningd_state *dstate,
struct txwatch *txw,
unsigned int depth,
const struct sha256_double *blkhash)
unsigned int depth)
{
if (depth != txw->depth) {
log_debug(txw->peer->log,
@ -158,8 +156,7 @@ 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, blkhash, &txw->txid,
txw->cbdata);
txw->cb(txw->peer, txw->depth, &txw->txid, txw->cbdata);
}
}
@ -195,17 +192,16 @@ again:
for (w = txwatch_hash_first(&dstate->txwatches, &i);
w;
w = txwatch_hash_next(&dstate->txwatches, &i)) {
struct sha256_double blkid;
size_t depth;
/* Don't fire if we haven't seen it at all. */
if (w->depth == -1)
continue;
depth = get_tx_depth(dstate, w, &blkid);
depth = get_tx_depth(dstate, w);
if (depth != w->depth) {
w->depth = depth;
w->cb(w->peer, w->depth, &blkid, &w->txid, w->cbdata);
w->cb(w->peer, w->depth, &w->txid, w->cbdata);
needs_rerun = true;
}
}

14
daemon/watch.h

@ -51,7 +51,6 @@ struct txwatch {
/* A new depth (-1 if conflicted), blkhash valid if > 0 */
void (*cb)(struct peer *peer, int depth,
const struct sha256_double *blkhash,
const struct sha256_double *txid,
void *cbdata);
void *cbdata;
@ -68,8 +67,7 @@ struct txwatch *watch_txid_(const tal_t *ctx,
struct peer *peer,
const struct sha256_double *txid,
void (*cb)(struct peer *peer, int depth,
const struct sha256_double *blkhash,
const struct sha256_double *txidx,
const struct sha256_double *txid,
void *),
void *cbdata);
@ -79,16 +77,14 @@ struct txwatch *watch_txid_(const tal_t *ctx,
(cb), (cbdata), \
struct peer *, \
int depth, \
const struct sha256_double *, \
const struct sha256_double *txidx), \
const struct sha256_double *), \
(cbdata))
struct txwatch *watch_tx_(const tal_t *ctx,
struct peer *peer,
const struct bitcoin_tx *tx,
void (*cb)(struct peer *peer, int depth,
const struct sha256_double *blkhash,
const struct sha256_double *txidx,
const struct sha256_double *txid,
void *),
void *cbdata);
@ -98,7 +94,6 @@ struct txwatch *watch_tx_(const tal_t *ctx,
(cb), (cbdata), \
struct peer *, \
int depth, \
const struct sha256_double *, \
const struct sha256_double *), \
(cbdata))
@ -124,8 +119,7 @@ void normalized_txid(const struct bitcoin_tx *tx, struct sha256_double *txid);
void txwatch_fire(struct lightningd_state *dstate,
struct txwatch *txw,
unsigned int depth,
const struct sha256_double *blkhash);
unsigned int depth);
void txowatch_fire(struct lightningd_state *dstate,
const struct txowatch *txow,

Loading…
Cancel
Save