mirror of
https://github.com/aljazceru/lightning.git
synced 2026-01-22 15:24:21 +01:00
chaintopology: simply track txids, not watches.
This is less efficient, but simpler. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
@@ -14,12 +14,6 @@
|
||||
|
||||
static struct timeout topology_timeout;
|
||||
|
||||
struct tx_in_block {
|
||||
struct list_node list;
|
||||
struct txwatch *w;
|
||||
struct block *block;
|
||||
};
|
||||
|
||||
struct block {
|
||||
int height;
|
||||
|
||||
@@ -39,9 +33,9 @@ struct block {
|
||||
u32 mediantime;
|
||||
|
||||
/* Transactions in this block we care about */
|
||||
struct list_head txs;
|
||||
struct sha256_double *txids;
|
||||
|
||||
/* Full copy of txs (trimmed to txs list in connect_blocks) */
|
||||
/* Full copy of txs (trimmed to txs list in connect_block) */
|
||||
struct bitcoin_tx **full_txs;
|
||||
};
|
||||
|
||||
@@ -96,20 +90,13 @@ static u32 get_mediantime(const struct topology *topo, const struct block *b)
|
||||
return times[ARRAY_SIZE(times) / 2];
|
||||
}
|
||||
|
||||
static void remove_tx(struct tx_in_block *t)
|
||||
/* FIXME: Remove tx from block when peer done. */
|
||||
static void add_tx_to_block(struct block *b, const struct sha256_double *txid)
|
||||
{
|
||||
list_del_from(&t->block->txs, &t->list);
|
||||
}
|
||||
size_t n = tal_count(b->txids);
|
||||
|
||||
static void add_tx_to_block(struct block *b, struct txwatch *w)
|
||||
{
|
||||
/* We attach this to watch, so removed when that is */
|
||||
struct tx_in_block *t = tal(w, struct tx_in_block);
|
||||
|
||||
t->block = b;
|
||||
t->w = w;
|
||||
list_add_tail(&b->txs, &t->list);
|
||||
tal_add_destructor(t, remove_tx);
|
||||
tal_resize(&b->txids, n+1);
|
||||
b->txids[n] = *txid;
|
||||
}
|
||||
|
||||
/* Fills in prev, height, mediantime. */
|
||||
@@ -134,9 +121,7 @@ static void connect_block(struct lightningd_state *dstate,
|
||||
/* Now we see if any of those txs are interesting. */
|
||||
for (i = 0; i < tal_count(b->full_txs); i++) {
|
||||
struct bitcoin_tx *tx = b->full_txs[i];
|
||||
struct txwatch *w;
|
||||
struct sha256_double txid;
|
||||
struct txwatch_hash_iter iter;
|
||||
size_t j;
|
||||
|
||||
/* Tell them if it spends a txo we care about. */
|
||||
@@ -151,16 +136,10 @@ static void connect_block(struct lightningd_state *dstate,
|
||||
txowatch_fire(dstate, txo, tx, j);
|
||||
}
|
||||
|
||||
/* We do spends first, in case that tells us to watch tx. */
|
||||
/* We did spends first, in case that tells us to watch tx. */
|
||||
bitcoin_txid(tx, &txid);
|
||||
for (w = txwatch_hash_getfirst(&dstate->txwatches, &txid, &iter);
|
||||
w;
|
||||
w = txwatch_hash_getnext(&dstate->txwatches, &txid, &iter)){
|
||||
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);
|
||||
}
|
||||
if (watching_txid(dstate, &txid))
|
||||
add_tx_to_block(b, &txid);
|
||||
}
|
||||
b->full_txs = tal_free(b->full_txs);
|
||||
}
|
||||
@@ -168,19 +147,20 @@ static void connect_block(struct lightningd_state *dstate,
|
||||
static bool tx_in_block(const struct block *b,
|
||||
const struct sha256_double *txid)
|
||||
{
|
||||
struct tx_in_block *tx;
|
||||
size_t i, n = tal_count(b->txids);
|
||||
|
||||
list_for_each(&b->txs, tx, list) {
|
||||
if (structeq(&tx->w->txid, txid))
|
||||
for (i = 0; i < n; i++) {
|
||||
if (structeq(&b->txids[i], txid))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/* FIXME: put block pointer in txwatch. */
|
||||
static struct block *block_for_tx(struct topology *topo,
|
||||
/* FIXME: Use hash table. */
|
||||
static struct block *block_for_tx(struct lightningd_state *dstate,
|
||||
const struct sha256_double *txid)
|
||||
{
|
||||
struct topology *topo = dstate->topology;
|
||||
struct block *b;
|
||||
|
||||
for (b = topo->tip; b; b = b->prev) {
|
||||
@@ -190,12 +170,13 @@ static struct block *block_for_tx(struct topology *topo,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
size_t get_tx_depth(struct lightningd_state *dstate, const struct txwatch *w)
|
||||
size_t get_tx_depth(struct lightningd_state *dstate,
|
||||
const struct sha256_double *txid)
|
||||
{
|
||||
struct topology *topo = dstate->topology;
|
||||
const struct block *b;
|
||||
|
||||
b = block_for_tx(topo, &w->txid);
|
||||
b = block_for_tx(dstate, txid);
|
||||
if (!b)
|
||||
return 0;
|
||||
return topo->tip->height - b->height + 1;
|
||||
@@ -244,7 +225,7 @@ static void rebroadcast_txs(struct lightningd_state *dstate)
|
||||
list_for_each(&peer->outgoing_txs, otx, list) {
|
||||
u8 *rawtx;
|
||||
|
||||
if (block_for_tx(dstate->topology, &otx->txid))
|
||||
if (block_for_tx(dstate, &otx->txid))
|
||||
continue;
|
||||
|
||||
tal_resize(&txs, num_txs+1);
|
||||
@@ -291,11 +272,11 @@ static void free_blocks(struct lightningd_state *dstate, struct block *b)
|
||||
struct block *next;
|
||||
|
||||
while (b) {
|
||||
struct tx_in_block *tx, *n;
|
||||
size_t i, n = tal_count(b->txids);
|
||||
|
||||
/* Notify that txs are kicked out. */
|
||||
list_for_each_safe(&b->txs, tx, n, list)
|
||||
txwatch_fire(dstate, tx->w, 0);
|
||||
for (i = 0; i < n; i++)
|
||||
txwatch_fire(dstate, &b->txids[i], 0);
|
||||
|
||||
next = b->next;
|
||||
tal_free(b);
|
||||
@@ -349,7 +330,7 @@ static struct block *new_block(struct lightningd_state *dstate,
|
||||
|
||||
b->hdr = blk->hdr;
|
||||
|
||||
list_head_init(&b->txs);
|
||||
b->txids = tal_arr(b, struct sha256_double, 0);
|
||||
b->full_txs = tal_steal(b, blk->tx);
|
||||
|
||||
return b;
|
||||
@@ -441,7 +422,7 @@ u32 get_tx_mediantime(struct lightningd_state *dstate,
|
||||
{
|
||||
struct block *b;
|
||||
|
||||
b = block_for_tx(dstate->topology, txid);
|
||||
b = block_for_tx(dstate, txid);
|
||||
if (b)
|
||||
return b->mediantime;
|
||||
|
||||
|
||||
@@ -8,7 +8,8 @@ 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);
|
||||
size_t get_tx_depth(struct lightningd_state *dstate,
|
||||
const struct sha256_double *txid);
|
||||
|
||||
/* Get the mediantime of the block including this tx (must be one!) */
|
||||
u32 get_tx_mediantime(struct lightningd_state *dstate,
|
||||
|
||||
@@ -91,7 +91,7 @@ struct txwatch *watch_txid_(const tal_t *ctx,
|
||||
struct txwatch *w;
|
||||
|
||||
w = tal(ctx, struct txwatch);
|
||||
w->depth = -1;
|
||||
w->depth = 0;
|
||||
w->txid = *txid;
|
||||
w->dstate = peer->dstate;
|
||||
w->peer = peer;
|
||||
@@ -104,6 +104,12 @@ struct txwatch *watch_txid_(const tal_t *ctx,
|
||||
return w;
|
||||
}
|
||||
|
||||
bool watching_txid(struct lightningd_state *dstate,
|
||||
const struct sha256_double *txid)
|
||||
{
|
||||
return txwatch_hash_get(&dstate->txwatches, txid) != NULL;
|
||||
}
|
||||
|
||||
struct txwatch *watch_tx_(const tal_t *ctx,
|
||||
struct peer *peer,
|
||||
const struct bitcoin_tx *tx,
|
||||
@@ -142,12 +148,13 @@ struct txowatch *watch_txo_(const tal_t *ctx,
|
||||
return w;
|
||||
}
|
||||
|
||||
|
||||
void txwatch_fire(struct lightningd_state *dstate,
|
||||
struct txwatch *txw,
|
||||
const struct sha256_double *txid,
|
||||
unsigned int depth)
|
||||
{
|
||||
if (depth != txw->depth) {
|
||||
struct txwatch *txw = txwatch_hash_get(&dstate->txwatches, txid);
|
||||
|
||||
if (txw && depth != txw->depth) {
|
||||
log_debug(txw->peer->log,
|
||||
"Got depth change %u for %02x%02x%02x...\n",
|
||||
txw->depth,
|
||||
@@ -194,11 +201,7 @@ again:
|
||||
w = txwatch_hash_next(&dstate->txwatches, &i)) {
|
||||
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);
|
||||
depth = get_tx_depth(dstate, &w->txid);
|
||||
if (depth != w->depth) {
|
||||
w->depth = depth;
|
||||
w->cb(w->peer, w->depth, &w->txid, w->cbdata);
|
||||
|
||||
@@ -45,7 +45,7 @@ struct txwatch {
|
||||
|
||||
/* Peer who owns us. */
|
||||
struct peer *peer;
|
||||
|
||||
|
||||
/* Transaction to watch. */
|
||||
struct sha256_double txid;
|
||||
int depth;
|
||||
@@ -118,12 +118,15 @@ struct txowatch *watch_txo_(const tal_t *ctx,
|
||||
(cbdata))
|
||||
|
||||
void txwatch_fire(struct lightningd_state *dstate,
|
||||
struct txwatch *txw,
|
||||
const struct sha256_double *txid,
|
||||
unsigned int depth);
|
||||
|
||||
void txowatch_fire(struct lightningd_state *dstate,
|
||||
const struct txowatch *txow,
|
||||
const struct bitcoin_tx *tx, size_t input_num);
|
||||
|
||||
bool watching_txid(struct lightningd_state *dstate,
|
||||
const struct sha256_double *txid);
|
||||
|
||||
void watch_topology_changed(struct lightningd_state *dstate);
|
||||
#endif /* LIGHTNING_DAEMON_WATCH_H */
|
||||
|
||||
Reference in New Issue
Block a user