From 6e39b0a642b0dfba7ca2a9f935b488e81b5dae16 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Sun, 24 Apr 2016 19:46:32 +0930 Subject: [PATCH] chaintopology: get_last_mediantime() This gets the median time of the block the tx is in. If there is more than one (different tips), it gets the last median time. Signed-off-by: Rusty Russell --- daemon/chaintopology.c | 38 +++++++++++++++++++++++++++++++++++--- daemon/chaintopology.h | 7 +++++++ 2 files changed, 42 insertions(+), 3 deletions(-) diff --git a/daemon/chaintopology.c b/daemon/chaintopology.c index 3a4973ad2..65932c233 100644 --- a/daemon/chaintopology.c +++ b/daemon/chaintopology.c @@ -62,6 +62,7 @@ static bool block_eq(const struct block *b, const struct sha256_double *key) HTABLE_DEFINE_TYPE(struct block, keyof_block_map, hash_sha, block_eq, block_map); struct topology { + struct block *root; struct block **tips; struct sha256_double *newtips; struct block_map block_map; @@ -429,10 +430,10 @@ static void init_topo(struct lightningd_state *dstate, struct bitcoin_block *blk, ptrint_t *p) { - struct block *b; + struct topology *topo = dstate->topology; - b = add_block(dstate, blk); - b->height = ptr2int(p); + topo->root = add_block(dstate, blk); + topo->root->height = ptr2int(p); /* Now grab chaintips immediately. */ bitcoind_get_chaintips(dstate, check_chaintips, NULL); @@ -459,6 +460,37 @@ static void get_init_blockhash(struct lightningd_state *dstate, u32 blockcount, bitcoind_getblockhash(dstate, start, get_init_block, int2ptr(start)); } +/* FIXME: Don't brute force this for the normal case! */ +static void last_mediantime(const struct block *b, + const struct txwatch *w, + u32 *mediantime) +{ + size_t i; + + if (tx_in_block(b, w)) { + if (b->mediantime > *mediantime) + *mediantime = b->mediantime; + /* Can't be in a later block */ + return; + } + + for (i = 0; i < tal_count(b->nexts); i++) + last_mediantime(b->nexts[i], w, mediantime); +} + +u32 get_last_mediantime(struct lightningd_state *dstate, + const struct sha256_double *txid) +{ + struct topology *topo = dstate->topology; + struct txwatch *w; + u32 mediantime = 0; + + w = txwatch_hash_get(&dstate->txwatches, txid); + + last_mediantime(topo->root, w, &mediantime); + return mediantime; +} + void setup_topology(struct lightningd_state *dstate) { dstate->topology = tal(dstate, struct topology); diff --git a/daemon/chaintopology.h b/daemon/chaintopology.h index d74b6cbfb..392e4248b 100644 --- a/daemon/chaintopology.h +++ b/daemon/chaintopology.h @@ -6,8 +6,15 @@ struct lightningd_state; 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); + +/* This is the worst-case (latest) mediantime of blocks including the txid. + * Assumes the depth is > 0! */ +u32 get_last_mediantime(struct lightningd_state *dstate, + const struct sha256_double *txid); void setup_topology(struct lightningd_state *dstate); #endif /* LIGHTNING_DAEMON_CRYPTOPKT_H */