ld: Replace list of outgoing_txs with a hash table

We had a quadratic check when processing a block, and this just
reduces it to be linear. Combined with the previous fix of adding txs
multiple times, this should speed up block processing considerably.
This commit is contained in:
Christian Decker
2022-11-15 15:23:21 +01:00
parent 351b8999c9
commit d27591ff54
2 changed files with 17 additions and 17 deletions

View File

@@ -53,13 +53,7 @@ static void next_topology_timer(struct chain_topology *topo)
static bool we_broadcast(const struct chain_topology *topo,
const struct bitcoin_txid *txid)
{
const struct outgoing_tx *otx;
list_for_each(&topo->outgoing_txs, otx, list) {
if (bitcoin_txid_eq(&otx->txid, txid))
return true;
}
return false;
return outgoing_tx_map_get(&topo->outgoing_txs, txid) != NULL;
}
static void filter_block_txs(struct chain_topology *topo, struct block *b)
@@ -160,13 +154,16 @@ static void rebroadcast_txs(struct chain_topology *topo)
/* Copy txs now (peers may go away, and they own txs). */
struct txs_to_broadcast *txs;
struct outgoing_tx *otx;
struct outgoing_tx_map_iter it;
txs = tal(topo, struct txs_to_broadcast);
txs->cmd_id = tal_arr(txs, const char *, 0);
/* Put any txs we want to broadcast in ->txs. */
txs->txs = tal_arr(txs, const char *, 0);
list_for_each(&topo->outgoing_txs, otx, list) {
for (otx = outgoing_tx_map_first(&topo->outgoing_txs, &it); otx;
otx = outgoing_tx_map_next(&topo->outgoing_txs, &it)) {
if (wallet_transaction_height(topo->ld->wallet, &otx->txid))
continue;
@@ -180,9 +177,9 @@ static void rebroadcast_txs(struct chain_topology *topo)
broadcast_remainder(topo->bitcoind, true, "", txs);
}
static void destroy_outgoing_tx(struct outgoing_tx *otx)
static void destroy_outgoing_tx(struct outgoing_tx *otx, struct chain_topology *topo)
{
list_del(&otx->list);
outgoing_tx_map_del(&topo->outgoing_txs, otx);
}
static void clear_otx_channel(struct channel *channel, struct outgoing_tx *otx)
@@ -218,8 +215,8 @@ static void broadcast_done(struct bitcoind *bitcoind,
} else {
/* For continual rebroadcasting, until channel freed. */
tal_steal(otx->channel, otx);
list_add_tail(&bitcoind->ld->topology->outgoing_txs, &otx->list);
tal_add_destructor(otx, destroy_outgoing_tx);
outgoing_tx_map_add(&bitcoind->ld->topology->outgoing_txs, notleak(otx));
tal_add_destructor2(otx, destroy_outgoing_tx, bitcoind->ld->topology);
}
}
@@ -941,13 +938,17 @@ u32 feerate_max(struct lightningd *ld, bool *unknown)
static void destroy_chain_topology(struct chain_topology *topo)
{
struct outgoing_tx *otx;
while ((otx = list_pop(&topo->outgoing_txs, struct outgoing_tx, list)))
struct outgoing_tx_map_iter it;
for (otx = outgoing_tx_map_first(&topo->outgoing_txs, &it); otx;
otx = outgoing_tx_map_next(&topo->outgoing_txs, &it)) {
tal_del_destructor2(otx, destroy_outgoing_tx, topo);
tal_free(otx);
}
/* htable uses malloc, so it would leak here */
txwatch_hash_clear(&topo->txwatches);
txowatch_hash_clear(&topo->txowatches);
outgoing_tx_map_clear(&topo->outgoing_txs);
block_map_clear(&topo->block_map);
}
@@ -957,7 +958,7 @@ struct chain_topology *new_topology(struct lightningd *ld, struct log *log)
topo->ld = ld;
block_map_init(&topo->block_map);
list_head_init(&topo->outgoing_txs);
outgoing_tx_map_init(&topo->outgoing_txs);
txwatch_hash_init(&topo->txwatches);
txowatch_hash_init(&topo->txowatches);
topo->log = log;

View File

@@ -18,7 +18,6 @@ struct txwatch;
/* Off topology->outgoing_txs */
struct outgoing_tx {
struct list_node list;
struct channel *channel;
const char *hextx;
struct bitcoin_txid txid;
@@ -117,7 +116,7 @@ struct chain_topology {
struct oneshot *extend_timer, *updatefee_timer;
/* Bitcoin transactions we're broadcasting */
struct list_head outgoing_txs;
struct outgoing_tx_map outgoing_txs;
/* Transactions/txos we are watching. */
struct txwatch_hash txwatches;