Beispiel #1
0
/* Creates and adds an example file. */
static char *add_example(struct manifest *m, struct ccan_file *source,
			 struct doc_section *example)
{
	char *name, *linemarker;
	unsigned int i;
	int fd;
	struct ccan_file *f;

	name = tal_fmt(m, "example-%s-%s",
		       source->name, example->function);
	/* example->function == 'struct foo' */
	while (strchr(name, ' '))
		*strchr(name, ' ') = '_';

	name = temp_file(m, ".c", take(name));
	f = new_ccan_file(m, take(path_dirname(m, name)),
			  take(path_basename(m, name)));
	tal_steal(f, name);
	list_add_tail(&m->examples, &f->list);

	fd = open(f->fullname, O_WRONLY | O_CREAT | O_EXCL, 0600);
	if (fd < 0)
		return tal_fmt(m, "Creating temporary file %s: %s",
			       f->fullname, strerror(errno));

	/* Add #line to demark where we are from, so errors are correct! */
	linemarker = tal_fmt(f, "#line %i \"%s\"\n",
			     example->srcline+2, source->fullname);
	if (write(fd, linemarker, strlen(linemarker)) != (int)strlen(linemarker)) {
		close(fd);
		return cast_const(char *, "Failure writing to temporary file");
	}
Beispiel #2
0
static struct io_plan *write_json(struct io_conn *conn,
				  struct json_connection *jcon)
{
	struct json_output *out;
	
	out = list_pop(&jcon->output, struct json_output, list);
	if (!out) {
		if (jcon->stop) {
			log_unusual(jcon->log, "JSON-RPC shutdown");
			/* Return us to toplevel lightningd.c */
			io_break(jcon->dstate);
			return io_close(conn);
		}

		/* Reader can go again now. */
		io_wake(jcon);
		return io_out_wait(conn, jcon, write_json, jcon);
	}

	jcon->outbuf = tal_steal(jcon, out->json);
	tal_free(out);

	log_io(jcon->log, false, jcon->outbuf, strlen(jcon->outbuf));
	return io_write(conn,
			jcon->outbuf, strlen(jcon->outbuf), write_json, jcon);
}
Beispiel #3
0
/* Wrap (and own!) member inside Pkt */
static Pkt *make_pkt(const tal_t *ctx, Pkt__PktCase type, const void *msg)
{
	Pkt *pkt = tal(ctx, Pkt);

	pkt__init(pkt);
	pkt->pkt_case = type;
	/* This is a union, so doesn't matter which we assign. */
	pkt->error = (Error *)tal_steal(pkt, msg);

	/* This makes sure all packets are valid. */
#ifndef NDEBUG
	{
		size_t len;
		u8 *packed;
		Pkt *cpy;
		
		len = pkt__get_packed_size(pkt);
		packed = tal_arr(pkt, u8, len);
		pkt__pack(pkt, packed);
		cpy = pkt__unpack(NULL, len, memcheck(packed, len));
		assert(cpy);
		pkt__free_unpacked(cpy, NULL);
		tal_free(packed);
	}
#endif
	return pkt;
}
Beispiel #4
0
static struct pending_tx *new_pending_tx(const tal_t *ctx,
					 const union protocol_tx *tx)
{
	struct pending_tx *pend;

	pend = tal(ctx, struct pending_tx);
	pend->tx = tal_steal(pend, tx);

	return pend;
}
Beispiel #5
0
static void add_to_unknown_pending(struct state *state,
				   const union protocol_tx *tx)
{
	struct pending_unknown_tx *unk;

	unk = tal(state->pending, struct pending_unknown_tx);
	unk->tx = tal_steal(unk, tx);

	list_add_tail(&state->pending->unknown_tx, &unk->list);
	state->pending->num_unknown++;
}
Beispiel #6
0
static struct io_plan *got_shard(struct io_conn *conn, struct generator *gen)
{
	gen->solution->shard[gen->solution->shards_read++]
		= tal_steal(gen->solution, gen->pkt_in);

	if (gen->solution->shards_read != tal_count(gen->solution->shard))
		return io_read_packet(conn, &gen->pkt_in, got_shard, gen);

	/* We've got all the shards! */
	recv_block_from_generator(gen->state, gen->log, gen->solution->block,
				  gen->solution->shard);

	return io_close(conn);
}
Beispiel #7
0
/* May allocate a new type if not already found (steals @name) */
static struct cdump_type *get_type(struct cdump_definitions *defs,
				   enum cdump_type_kind kind,
				   const char *name)
{
	struct cdump_map *m;
	struct cdump_type *t;

	switch (kind) {
	case CDUMP_STRUCT:
		m = &defs->structs;
		break;
	case CDUMP_UNION:
		m = &defs->unions;
		break;
	case CDUMP_ENUM:
		m = &defs->enums;
		break;
	case CDUMP_UNKNOWN:
	case CDUMP_ARRAY:
	case CDUMP_POINTER:
		m = NULL;
	}

	/* Do we already have it? */
	if (m) {
		t = strmap_get(m, name);
		if (t)
			return t;
	}

	t = tal(defs, struct cdump_type);
	t->kind = kind;
	t->name = name ? tal_steal(t, name) : NULL;
	/* These are actually the same, but be thorough */
	t->u.members = NULL;
	t->u.enum_vals = NULL;
	if (m)
		strmap_add(m, t->name, t);

	return t;
}
Beispiel #8
0
		= tal_steal(gen->solution, gen->pkt_in);

	if (gen->solution->shards_read != tal_count(gen->solution->shard))
		return io_read_packet(conn, &gen->pkt_in, got_shard, gen);

	/* We've got all the shards! */
	recv_block_from_generator(gen->state, gen->log, gen->solution->block,
				  gen->solution->shard);

	return io_close(conn);
}

static struct io_plan *got_solution(struct io_conn *conn, struct generator *gen)
{
	gen->solution = tal(gen, struct solution);
	gen->solution->block = tal_steal(gen->solution, gen->pkt_in);

	gen->solution->shard = tal_arr(gen->solution,
				       struct protocol_pkt_shard *,
				       1 << gen->shard_order);
	gen->solution->shards_read = 0;
	return io_read_packet(conn, &gen->pkt_in, got_shard, gen);
}

/* FIXME: If transaction may go over horizon, time out generation */
static void add_update(struct state *state,
		       struct pending_tx *t,
		       size_t shard, size_t txoff)
{
	struct pending_update *update;
Beispiel #9
0
/* We've added a whole heap of transactions, recheck them and set input refs. */
void recheck_pending_txs(struct state *state)
{
	unsigned int unknown, known, total;
	unsigned int i, shard;
	const union protocol_tx **txs;
	struct pending_unknown_tx *utx;

	if (!state->pending->needs_recheck)
		return;

	state->pending->needs_recheck = false;

	/* Size up and allocate an array. */
	unknown = state->pending->num_unknown;
	known = num_pending_known(state);

	/* Avoid logging if nothing pending. */
	if (unknown == 0 && known == 0)
		return;
	
	txs = tal_arr(state, const union protocol_tx *, unknown + known);

	log_info(state->log, "Rechecking pending (%u known, %u unknown)",
		  known, unknown);

	/* Now move pending from shards. */
	total = 0;
	for (shard = 0; shard < ARRAY_SIZE(state->pending->pend); shard++) {
		struct pending_tx **pend = state->pending->pend[shard];
		unsigned int i;

		for (i = 0; i < tal_count(pend); i++) {
			remove_pending_tx_from_hashes(state, pend[i]->tx);
			txs[total++] = tal_steal(txs, pend[i]->tx);
		}
	}

	/* And last we move the unknown ones. */
	while ((utx = list_pop(&state->pending->unknown_tx,
			       struct pending_unknown_tx, list)) != NULL) {
		remove_pending_tx_from_hashes(state, utx->tx);
		txs[total++] = tal_steal(txs, utx->tx);
	}

	assert(total == unknown + known);

	/* Clean up pending (frees everything above as a side effect). */
	tal_free(state->pending);
	state->pending = new_pending_block(state);

	/* Now re-add them */
	for (i = 0; i < tal_count(txs); i++) {
		unsigned int bad_input_num;
		struct protocol_double_sha sha;

		hash_tx(txs[i], &sha);
		add_pending_tx(state, txs[i], &sha, &bad_input_num, NULL);
	}

	/* Just to print the debug! */		
	known = 0;
	for (shard = 0; shard < ARRAY_SIZE(state->pending->pend); shard++)
		known += tal_count(state->pending->pend[shard]);

	log_info(state->log, "Now have %u known, %u unknown",
		  known, state->pending->num_unknown);

	/* Restart generator on this block. */
	restart_generating(state);
}