/* This allocates the block but doesn't sew it into data structures. */ static struct block *new_block(const tal_t *ctx, BIGNUM *prev_work, const struct protocol_block_id *sha, const struct block_info *bi) { struct block *block = tal(ctx, struct block); unsigned int i; total_work_done(le32_to_cpu(bi->tailer->difficulty), prev_work, &block->total_work); block->bi = *bi; block->all_known = false; list_head_init(&block->children); block->sha = *sha; block->shard = tal_arr(block, struct block_shard *, num_shards(bi->hdr)); for (i = 0; i < num_shards(bi->hdr); i++) block->shard[i] = new_block_shard(block->shard, i, bi->num_txs[i]); /* In case we destroy before block_add(), eg. testing. */ block->prev = NULL; tal_add_destructor(block, destroy_block); return block; }
tal_t *tal_newframe_(const char *label) { h = tal_alloc_(h, 0, false, false, label); assert(h != NULL); tal_add_destructor(h, _free_frame); return h; }
/* Simple LL(1) parser, inspired by Tridge's genstruct.pl. */ struct cdump_definitions *cdump_extract(const tal_t *ctx, const char *code, char **complaints) { struct parse_state ps; const struct token *toks; ps.defs = tal(ctx, struct cdump_definitions); ps.complaints = tal_strdup(ctx, ""); ps.code = code; strmap_init(&ps.defs->enums); strmap_init(&ps.defs->structs); strmap_init(&ps.defs->unions); tal_add_destructor(ps.defs, destroy_definitions); toks = ps.toks = tokenize(ps.defs, code); while (tok_peek(&ps.toks)) { if (tok_take_if(&ps.toks, "struct")) { if (!tok_take_conglom(&ps, CDUMP_STRUCT)) goto fail; } else if (tok_take_if(&ps.toks, "union")) { if (!tok_take_conglom(&ps, CDUMP_UNION)) goto fail; } else if (tok_take_if(&ps.toks, "enum")) { if (!tok_take_enum(&ps)) goto fail; } else tok_take_unknown_statement(&ps); } /* Now, remove any undefined types! */ remove_undefined(&ps.defs->enums); remove_undefined(&ps.defs->structs); remove_undefined(&ps.defs->unions); tal_free(toks); out: if (streq(ps.complaints, "")) ps.complaints = tal_free(ps.complaints); if (complaints) *complaints = ps.complaints; else tal_free(ps.complaints); return ps.defs; fail: ps.defs = tal_free(ps.defs); goto out; }
struct channel *new_full_channel(const tal_t *ctx, const struct bitcoin_blkid *chain_hash, const struct bitcoin_txid *funding_txid, unsigned int funding_txout, u32 minimum_depth, struct amount_sat funding, struct amount_msat local_msat, const u32 feerate_per_kw[NUM_SIDES], const struct channel_config *local, const struct channel_config *remote, const struct basepoints *local_basepoints, const struct basepoints *remote_basepoints, const struct pubkey *local_funding_pubkey, const struct pubkey *remote_funding_pubkey, enum side funder) { struct channel *channel = new_initial_channel(ctx, chain_hash, funding_txid, funding_txout, minimum_depth, funding, local_msat, feerate_per_kw[LOCAL], local, remote, local_basepoints, remote_basepoints, local_funding_pubkey, remote_funding_pubkey, funder); if (channel) { /* Feerates can be different. */ channel->view[REMOTE].feerate_per_kw = feerate_per_kw[REMOTE]; channel->htlcs = tal(channel, struct htlc_map); htlc_map_init(channel->htlcs); tal_add_destructor(channel->htlcs, htlc_map_clear); } return channel; }
EC_KEY *helper_gateway_key(const tal_t *ctx) { const unsigned char *p = gateway_key; EC_KEY *priv = EC_KEY_new_by_curve_name(NID_secp256k1); EC_KEY **ptr; if (!d2i_ECPrivateKey(&priv, &p, sizeof(gateway_key))) abort(); if (!EC_KEY_check_key(priv)) abort(); /* We *always* used compressed form keys. */ EC_KEY_set_conv_form(priv, POINT_CONVERSION_COMPRESSED); /* To get tal to clean it up... */ ptr = tal(ctx, EC_KEY *); *ptr = priv; tal_add_destructor(ptr, free_gateway_key); return priv; }
struct txwatch *watch_txid_(const tal_t *ctx, struct peer *peer, const struct sha256_double *txid, void (*cb)(struct peer *peer, unsigned int depth, const struct sha256_double *txid, void *arg), void *cb_arg) { struct txwatch *w; w = tal(ctx, struct txwatch); w->depth = 0; w->txid = *txid; w->dstate = peer->dstate; w->peer = peer; w->cb = cb; w->cbdata = cb_arg; txwatch_hash_add(&w->dstate->txwatches, w); tal_add_destructor(w, destroy_txwatch); return w; }
struct txowatch *watch_txo_(const tal_t *ctx, struct peer *peer, const struct sha256_double *txid, unsigned int output, void (*cb)(struct peer *peer, const struct bitcoin_tx *tx, size_t input_num, void *), void *cbdata) { struct txowatch *w = tal(ctx, struct txowatch); w->out.txid = *txid; w->out.index = output; w->peer = peer; w->cb = cb; w->cbdata = cbdata; txowatch_hash_add(&w->peer->dstate->txowatches, w); tal_add_destructor(w, destroy_txowatch); return w; }
int main(int argc, char *argv[]) { char *linkable, *p1, *p2, *p3; void **voidpp; plan_tests(23); linkable = tal(NULL, char); ok1(tal_linkable(linkable) == linkable); ok1(tal_add_destructor(linkable, destroy_obj)); /* First, free it immediately. */ tal_free(linkable); ok1(destroy_count == 1); /* Now create and remove a single link. */ linkable = tal_linkable(tal(NULL, char)); ok1(tal_add_destructor(linkable, destroy_obj)); ok1(p1 = tal_link(NULL, linkable)); ok1(p1 == linkable); tal_delink(NULL, linkable); ok1(destroy_count == 2); /* Two links.*/ linkable = tal_linkable(tal(NULL, char)); ok1(tal_add_destructor(linkable, destroy_obj)); ok1(p1 = tal_link(NULL, linkable)); ok1(p1 == linkable); ok1(p2 = tal_link(NULL, linkable)); ok1(p2 == linkable); tal_delink(NULL, linkable); tal_delink(NULL, linkable); ok1(destroy_count == 3); /* Three links.*/ linkable = tal_linkable(tal(NULL, char)); ok1(tal_add_destructor(linkable, destroy_obj)); ok1(p1 = tal_link(NULL, linkable)); ok1(p1 == linkable); ok1(p2 = tal_link(NULL, linkable)); ok1(p2 == linkable); ok1(p3 = tal_link(NULL, linkable)); ok1(p3 == linkable); tal_delink(NULL, linkable); tal_delink(NULL, linkable); tal_delink(NULL, linkable); ok1(destroy_count == 4); /* Now, indirectly. */ voidpp = tal(NULL, void *); linkable = tal_linkable(tal(NULL, char)); ok1(tal_add_destructor(linkable, destroy_obj)); /* Suppress gratuitous warning with tests_compile_without_features */ #if HAVE_STATEMENT_EXPR tal_link(voidpp, linkable); #else (void)tal_link(voidpp, linkable); #endif tal_free(voidpp); ok1(destroy_count == 5); return exit_status(); }