#include "commit_tx.h" #include "output_to_htlc.h" #include "peer.h" /* FIXME: Array makes this O(n^2). Use a hash table. */ struct wscript_by_wpkh { struct htlc *h; const u8 *wscript; struct sha256 hash; }; struct htlc_output_map { struct wscript_by_wpkh *wpkh; }; struct htlc_output_map *get_htlc_output_map(const tal_t *ctx, const struct peer *peer, const struct sha256 *rhash, enum side side, unsigned int commit_num) { struct htlc_map_iter it; struct htlc *h; size_t i; struct htlc_output_map *omap = tal(ctx, struct htlc_output_map); /* FIXME: use commit_num to filter htlcs. */ if (side == LOCAL) assert(commit_num <= peer->local.commit->commit_num); else assert(commit_num <= peer->remote.commit->commit_num); omap->wpkh = tal_arr(omap, struct wscript_by_wpkh, htlc_map_count(&peer->htlcs)); for (i = 0, h = htlc_map_first(&peer->htlcs, &it); h; h = htlc_map_next(&peer->htlcs, &it)) { omap->wpkh[i].h = h; omap->wpkh[i].wscript = wscript_for_htlc(omap, peer, h, rhash, side); sha256(&omap->wpkh[i].hash, omap->wpkh[i].wscript, tal_count(omap->wpkh[i].wscript)); i++; } tal_resize(&omap->wpkh, i); return omap; } static struct wscript_by_wpkh *get_wpkh(struct htlc_output_map *omap, const u8 *script) { size_t i; if (!is_p2wsh(script)) return NULL; for (i = 0; i < tal_count(omap->wpkh); i++) { if (!memcmp(script + 2, omap->wpkh[i].hash.u.u8, sizeof(omap->wpkh[i].hash))) return &omap->wpkh[i]; } return NULL; } /* Which wscript does this pay to? */ struct htlc *txout_get_htlc(struct htlc_output_map *omap, const u8 *script, const u8 **wscript) { struct wscript_by_wpkh *wpkh = get_wpkh(omap, script); if (wpkh) { *wscript = wpkh->wscript; return wpkh->h; } return NULL; }