Exemple #1
0
struct channel_state *initial_funding(const tal_t *ctx,
				      const OpenChannel *a,
				      const OpenChannel *b,
				      const OpenAnchor *anchor,
				      uint64_t fee)
{
	struct channel_state *state = talz(ctx, struct channel_state);

	state->a.htlcs = tal_arr(state, UpdateAddHtlc *, 0);
	state->b.htlcs = tal_arr(state, UpdateAddHtlc *, 0);
	
	if (fee > anchor->amount)
		return tal_free(state);

	/* Initially, all goes back to funder. */
	state->a.pay = anchor->amount - fee;
	state->a.fee = fee;

	/* If B (not A) is funder, invert. */
	if (is_funder(b))
		invert_cstate(state);

	/* This checks we only have 1 anchor, and is nice code reuse. */
	if (!funding_delta(a, b, anchor, 0, 0, &state->a, &state->b))
		return tal_free(state);
	return state;
}
Exemple #2
0
/* Encoding is <blockhdr> <varint-num-txs> <tx>... */
struct bitcoin_block *bitcoin_block_from_hex(const tal_t *ctx,
					     const char *hex, size_t hexlen)
{
	struct bitcoin_block *b;
	u8 *linear_tx;
	const u8 *p;
	size_t len, i, num;

	if (hexlen && hex[hexlen-1] == '\n')
		hexlen--;

	/* Set up the block for success. */
	b = tal(ctx, struct bitcoin_block);

	/* De-hex the array. */
	len = hex_data_size(hexlen);
	p = linear_tx = tal_arr(ctx, u8, len);
	if (!hex_decode(hex, hexlen, linear_tx, len))
		return tal_free(b);

	pull(&p, &len, &b->hdr, sizeof(b->hdr));
	num = pull_varint(&p, &len);
	b->tx = tal_arr(b, struct bitcoin_tx *, num);
	for (i = 0; i < num; i++)
		b->tx[i] = pull_bitcoin_tx(b->tx, &p, &len);

	/* We should end up not overrunning, nor have extra */
	if (!p || len)
		return tal_free(b);

	tal_free(linear_tx);
	return b;
}
Exemple #3
0
struct bitcoin_tx *bitcoin_tx_from_hex(const tal_t *ctx, const char *hex,
				       size_t hexlen)
{
	const char *end;
	u8 *linear_tx;
	const u8 *p;
	struct bitcoin_tx *tx;
	size_t len;

	end = memchr(hex, '\n', hexlen);
	if (!end)
		end = hex + hexlen;

	len = hex_data_size(end - hex);
	p = linear_tx = tal_arr(ctx, u8, len);
	if (!hex_decode(hex, end - hex, linear_tx, len))
		goto fail;

	tx = pull_bitcoin_tx(ctx, &p, &len);
	if (!tx)
		goto fail;

	if (len)
		goto fail_free_tx;
	
	tal_free(linear_tx);
	return tx;

fail_free_tx:
	tal_free(tx);
fail:
	tal_free(linear_tx);
	return NULL;
}
Exemple #4
0
int main(void)
{
	int *p;
	char name[] = "test name";

	plan_tests(6);

	p = tal(NULL, int);
	ok1(strcmp(tal_name(p), "int") == 0);

	tal_set_name(p, "some literal");
	ok1(strcmp(tal_name(p), "some literal") == 0);

	tal_set_name(p, name);
	ok1(strcmp(tal_name(p), name) == 0);
	/* You can't reuse my pointer though! */
	ok1(tal_name(p) != name);

	tal_set_name(p, "some other literal");
	ok1(strcmp(tal_name(p), "some other literal") == 0);

	tal_free(p);

	p = tal_arr(NULL, int, 2);
	ok1(strcmp(tal_name(p), "int[]") == 0);
	tal_free(p);

	tal_cleanup();
	return exit_status();
}
Exemple #5
0
jsmntok_t *json_parse_input(const char *input, int len, bool *valid)
{
	jsmn_parser parser;
	jsmntok_t *toks;
	jsmnerr_t ret;

	toks = tal_arr(input, jsmntok_t, 10);

again:	
	jsmn_init(&parser);
	ret = jsmn_parse(&parser, input, len, toks, tal_count(toks) - 1);

	switch (ret) {
	case JSMN_ERROR_INVAL:
		*valid = false;
		return tal_free(toks);
	case JSMN_ERROR_PART:
		*valid = true;
		return tal_free(toks);
	case JSMN_ERROR_NOMEM:
		tal_resize(&toks, tal_count(toks) * 2);
		goto again;
	}

	/* Cut to length and return. */
	*valid = true;
	tal_resize(&toks, ret + 1);
	/* Make sure last one is always referencable. */
	toks[ret].type = -1;
	toks[ret].start = toks[ret].end = toks[ret].size = 0;
	
	return toks;
}
Exemple #6
0
void command_fail(struct command *cmd, const char *fmt, ...)
{
	char *quote, *error;
	struct json_connection *jcon = cmd->jcon;
	va_list ap;

	if (!jcon) {
		log_unusual(cmd->dstate->base_log,
			    "Command failed after jcon close");
		tal_free(cmd);
		return;
	}

	va_start(ap, fmt);
	error = tal_vfmt(cmd, fmt, ap);
	va_end(ap);

	log_debug(jcon->log, "Failing: %s", error);

	/* Remove " */
	while ((quote = strchr(error, '"')) != NULL)
		*quote = '\'';

	/* Now surround in quotes. */
	quote = tal_fmt(cmd, "\"%s\"", error);

	assert(jcon->current == cmd);
	json_result(jcon, cmd->id, "null", quote);
	jcon->current = tal_free(cmd);
}
Exemple #7
0
/* Returns leaks, and sets errs[] */
static char *analyze_output(const char *output, char **errs)
{
	char *leaks = tal_strdup(output, "");
	unsigned int i;
	char **lines = tal_strsplit(output, output, "\n", STR_EMPTY_OK);

	*errs = tal_strdup(output, "");
	for (i = 0; i < tal_count(lines) - 1; i++) {
		unsigned int preflen = strspn(lines[i], "=0123456789");
		char *prefix, **sublines;

		/* Ignore erased lines, or weird stuff. */
		if (preflen == 0)
			continue;

		prefix = tal_strndup(output, lines[i], preflen);
		sublines = extract_matching(prefix, lines);

		leaks = tal_strcat(output, take(leaks),
				   take(get_leaks(sublines, errs)));
	}

	if (!leaks[0]) {
		tal_free(leaks);
		leaks = NULL;
	}
	if (!(*errs)[0]) {
		tal_free(*errs);
		*errs = NULL;
	}
	return leaks;
}
Exemple #8
0
struct channel *new_initial_channel(const tal_t *ctx,
				    const struct bitcoin_blkid *chain_hash,
				    const struct bitcoin_txid *funding_txid,
				    unsigned int funding_txout,
				    u64 funding_satoshis,
				    u64 local_msatoshi,
				    u32 feerate_per_kw,
				    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 = tal(ctx, struct channel);

	channel->funding_txid = *funding_txid;
	channel->funding_txout = funding_txout;
	if (funding_satoshis > UINT64_MAX / 1000)
		return tal_free(channel);

	channel->funding_msat = funding_satoshis * 1000;
	if (local_msatoshi > channel->funding_msat)
		return tal_free(channel);

	channel->funder = funder;
	channel->config[LOCAL] = local;
	channel->config[REMOTE] = remote;
	channel->funding_pubkey[LOCAL] = *local_funding_pubkey;
	channel->funding_pubkey[REMOTE] = *remote_funding_pubkey;
	channel->htlcs = NULL;
	channel->changes_pending[LOCAL] = channel->changes_pending[REMOTE]
		= false;

	channel->view[LOCAL].feerate_per_kw
		= channel->view[REMOTE].feerate_per_kw
		= feerate_per_kw;

	channel->view[LOCAL].owed_msat[LOCAL]
		= channel->view[REMOTE].owed_msat[LOCAL]
		= local_msatoshi;
	channel->view[REMOTE].owed_msat[REMOTE]
		= channel->view[LOCAL].owed_msat[REMOTE]
		= channel->funding_msat - local_msatoshi;

	channel->basepoints[LOCAL] = *local_basepoints;
	channel->basepoints[REMOTE] = *remote_basepoints;

	channel->commitment_number_obscurer
		= commit_number_obscurer(&channel->basepoints[funder].payment,
					 &channel->basepoints[!funder].payment);
	channel->chainparams = chainparams_by_chainhash(chain_hash);
	if (channel->chainparams == NULL)
		return tal_free(channel);

	return channel;
}
Exemple #9
0
static struct io_plan *handshake_success(struct io_conn *conn,
					 const struct pubkey *them,
					 const struct wireaddr_internal *addr,
					 const struct crypto_state *orig_cs,
					 char **args)
{
	u8 *msg;
	struct crypto_state cs = *orig_cs;
	u8 *localfeatures;

	if (initial_sync) {
		localfeatures = tal(conn, u8);
		localfeatures[0] = (1 << 3);
	} else
		localfeatures = NULL;

	msg = towire_init(NULL, NULL, localfeatures);

	sync_crypto_write(&cs, conn->fd, take(msg));
	/* Ignore their init message. */
	tal_free(sync_crypto_read(NULL, &cs, conn->fd));

	/* Did they ask us to send any messages?  Do so now. */
	if (stream_stdin) {
		beint16_t be_inlen;

		while (read_all(STDIN_FILENO, &be_inlen, sizeof(be_inlen))) {
			u32 msglen = be16_to_cpu(be_inlen);
			u8 *msg = tal_arr(NULL, u8, msglen);

			if (!read_all(STDIN_FILENO, msg, msglen))
				err(1, "Only read partial message");
			sync_crypto_write(&cs, conn->fd, take(msg));
		}
	}

	while (*args) {
		u8 *m = tal_hexdata(NULL, *args, strlen(*args));
		if (!m)
			errx(1, "Invalid hexdata '%s'", *args);
		sync_crypto_write(&cs, conn->fd, take(m));
		args++;
	}

	/* Now write out whatever we get. */
	while ((msg = sync_crypto_read(NULL, &cs, conn->fd)) != NULL) {
		be16 len = cpu_to_be16(tal_bytelen(msg));

		if (!write_all(STDOUT_FILENO, &len, sizeof(len))
		    || !write_all(STDOUT_FILENO, msg, tal_bytelen(msg)))
			err(1, "Writing out msg");
		tal_free(msg);

		if (--max_messages == 0)
			exit(0);
	}
	err(1, "Reading msg");
}
Exemple #10
0
static struct io_plan *read_json(struct io_conn *conn,
				 struct json_connection *jcon)
{
	jsmntok_t *toks;
	bool valid;

	log_io(jcon->log, true, jcon->buffer + jcon->used, jcon->len_read);

	/* Resize larger if we're full. */
	jcon->used += jcon->len_read;
	if (jcon->used == tal_count(jcon->buffer))
		tal_resize(&jcon->buffer, jcon->used * 2);

again:
	toks = json_parse_input(jcon->buffer, jcon->used, &valid);
	if (!toks) {
		if (!valid) {
			log_unusual(jcon->dstate->base_log,
				    "Invalid token in json input: '%.*s'",
				    (int)jcon->used, jcon->buffer);
			return io_close(conn);
		}
		/* We need more. */
		goto read_more;
	}

	/* Empty buffer? (eg. just whitespace). */
	if (tal_count(toks) == 1) {
		jcon->used = 0;
		goto read_more;
	}

	parse_request(jcon, toks);

	/* Remove first {}. */
	memmove(jcon->buffer, jcon->buffer + toks[0].end,
		tal_count(jcon->buffer) - toks[0].end);
	jcon->used -= toks[0].end;
	tal_free(toks);

	/* Need to wait for command to finish? */
	if (jcon->current) {
		jcon->len_read = 0;
		return io_wait(conn, jcon, read_json, jcon);
	}

	/* See if we can parse the rest. */
	goto again;

read_more:
	tal_free(toks);
	return io_read_partial(conn, jcon->buffer + jcon->used,
			       tal_count(jcon->buffer) - jcon->used,
			       &jcon->len_read, read_json, jcon);
}
Exemple #11
0
int main(void)
{
	char *path, *ctx = tal_strdup(NULL, "ctx");

	plan_tests(26);

	path = path_basename(ctx, "/usr/lib");
	ok1(streq(path, "lib"));
	ok1(tal_parent(path) == ctx);
	path = path_basename(ctx, "/usr/");
	ok1(streq(path, "usr"));
	ok1(tal_parent(path) == ctx);
	path = path_basename(ctx, "/usr//");
	ok1(streq(path, "usr"));
	ok1(tal_parent(path) == ctx);
	path = path_basename(ctx, "usr");
	ok1(streq(path, "usr"));
	ok1(tal_parent(path) == ctx);
	path = path_basename(ctx, "/");
	ok1(streq(path, "/"));
	ok1(tal_parent(path) == ctx);
	path = path_basename(ctx, "//");
	ok1(streq(path, "/"));
	ok1(tal_parent(path) == ctx);
	path = path_basename(ctx, ".");
	ok1(streq(path, "."));
	ok1(tal_parent(path) == ctx);
	path = path_basename(ctx, "./");
	ok1(streq(path, "."));
	ok1(tal_parent(path) == ctx);
	path = path_basename(ctx, "..");
	ok1(streq(path, ".."));
	ok1(tal_parent(path) == ctx);
	path = path_basename(ctx, "../");
	ok1(streq(path, ".."));
	ok1(tal_parent(path) == ctx);
	tal_free(ctx);

	ctx = tal_strdup(NULL, "ctx");
	ok1(!tal_first(ctx));

	/* Test take */
	path = path_basename(ctx, take(tal_strdup(ctx, "..")));
	ok1(streq(path, ".."));
	ok1(tal_parent(path) == ctx);
	ok1(tal_first(ctx) == path && !tal_next(ctx, path));
	tal_free(path);
	ok1(path_basename(ctx, take(NULL)) == NULL);
	ok1(!tal_first(ctx));

	tal_free(ctx);

	return exit_status();
}
Exemple #12
0
int main(void)
{
	char *parent, *c;

	plan_tests(21);

	/* We can take NULL. */
	ok1(take(NULL) == NULL);
	ok1(is_taken(NULL));
	ok1(taken(NULL)); /* Undoes take() */
	ok1(!is_taken(NULL));
	ok1(!taken(NULL));

	parent = tal(NULL, char);
	ok1(parent);

	ok1(take(parent) == parent);
	ok1(is_taken(parent));
	ok1(taken(parent)); /* Undoes take() */
	ok1(!is_taken(parent));
	ok1(!taken(parent));

	c = tal(parent, char);
	*c = 'h';
	c = tal_dup(parent, char, take(c), 1, 0);
	ok1(c[0] == 'h');
	ok1(tal_parent(c) == parent);

	c = tal_dup(parent, char, take(c), 1, 2);
	ok1(c[0] == 'h');
	strcpy(c, "hi");
	ok1(tal_parent(c) == parent);

	/* dup must reparent child. */
	c = tal_dup(NULL, char, take(c), 1, 0);
	ok1(c[0] == 'h');
	ok1(tal_parent(c) == NULL);

	/* No leftover allocations. */
	tal_free(c);
	ok1(talloc_total_blocks(parent) == 1);

	tal_free(parent);
	ok1(!taken_any());

	/* NULL pass-through. */
	c = NULL;
	ok1(tal_dup(NULL, char, take(c), 5, 5) == NULL);
	ok1(!taken_any());

	return exit_status();
}
void command_success(struct command *cmd, struct json_result *result)
{
    struct json_connection *jcon = cmd->jcon;

    if (!jcon) {
        log_unusual(cmd->dstate->base_log,
                    "Command returned result after jcon close");
        tal_free(cmd);
        return;
    }
    assert(jcon->current == cmd);
    json_result(jcon, cmd->id, json_result_string(result), "null");
    jcon->current = tal_free(cmd);
}
Exemple #14
0
/* 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;
}
Exemple #15
0
int main(void)
{
	char cwd[1024], *path, *path2, *ctx = tal_strdup(NULL, "ctx");

	plan_tests(15);

	if (!getcwd(cwd, sizeof(cwd)))
		abort();

	unlink("run-canon-link");
	rmdir("run-canon-foo");
	if (mkdir("run-canon-foo", 0700) != 0)
		abort();
	if (symlink("run-canon-foo", "run-canon-link") != 0)
		abort();

	path = path_canon(ctx, "run-canon-foo");
	ok1(tal_parent(path) == ctx);
	ok1(strends(path, "run-canon-foo"));
	ok1(strstarts(path, cwd));
	ok1(path[strlen(cwd)] == PATH_SEP);
	ok1(strlen(path) == strlen(cwd) + 1 + strlen("run-canon-foo"));
	tal_free(path);

	ok1(!path_canon(ctx, take(NULL)));
	ok1(tal_first(ctx) == NULL);

	/* Test take doesn't leak. */
	ok1(tal_first(ctx) == NULL);
	path = path_canon(ctx, take(tal_strdup(ctx, "run-canon-foo")));
	ok1(strends(path, "run-canon-foo"));
	ok1(strstarts(path, cwd));
	ok1(path[strlen(cwd)] == PATH_SEP);
	ok1(strlen(path) == strlen(cwd) + 1 + strlen("run-canon-foo"));
	ok1(tal_first(ctx) == path && tal_next(path) == NULL);
	path2 = path_canon(ctx, "run-canon-link");
	ok1(streq(path2, path));

	unlink("run-canon-link");
	if (symlink(".", "run-canon-link") != 0)
		abort();

	path = path_canon(ctx, "run-canon-link");
	ok1(streq(path, cwd));

	tal_free(ctx);

	return exit_status();
}
Exemple #16
0
tx *get_tx(const bitcoin_txid &txid, bool must_exist)
{
	char filename[sizeof("txcache/01234567890123456789012345678901234567890123456789012345678901234567")] = "txcache/";
	char *txstring;
	const u8 *txbytes;
	u8 *bytes;
	size_t len;
	u64 fee;
	tx *t;

	txstring = filename + strlen("txcache/");
	if (!hex_encode(txid.shad.sha.u.u8, sizeof(txid.shad.sha.u.u8),
					txstring,
					sizeof(filename) - strlen("txcache/")))
		throw std::logic_error("txid doesn't fit in filename");

	txbytes = bytes = (u8 *)grab_file(NULL, filename);
	if (!txbytes) {
		if (must_exist)
			errx(1, "Could not find tx %s", txstring);
		return NULL;
	}

	len = tal_count(txbytes)-1;
	if (len < 8)
		errx(1, "Truncated %s", filename);
	memcpy(&fee, txbytes, 8);
	txbytes += 8;
	len -= 8;
	t = new tx(fee, new bitcoin_tx(&txbytes, &len));
	assert(t->txid == txid);
	tal_free(bytes);
	return t;
}
Exemple #17
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;
}
Exemple #18
0
int main(void)
{
	int *a;
	const int arr[] = { 1, 2 };

	plan_tests(13);

	a = tal_arrz(NULL, int, 1);
	ok1(a);

	ok1(tal_expand(&a, arr, 2));
	ok1(tal_count(a) == 3);
	ok1(a[0] == 0);
	ok1(a[1] == 1);
	ok1(a[2] == 2);

	ok1(tal_expand(&a, take(tal_arrz(NULL, int, 1)), 1));
	ok1(tal_count(a) == 4);
	ok1(a[0] == 0);
	ok1(a[1] == 1);
	ok1(a[2] == 2);
	ok1(a[3] == 0);
	ok1(tal_first(NULL) == a && !tal_next(a) && !tal_first(a));

	tal_free(a);

	tal_cleanup();
	return exit_status();
}
Exemple #19
0
static void log_to_file(const char *prefix,
			enum log_level level,
			bool continued,
			const struct timeabs *time,
			const char *str,
			const u8 *io,
			size_t io_len,
			FILE *logf)
{
	char iso8601_msec_fmt[sizeof("YYYY-mm-ddTHH:MM:SS.%03dZ")];
	strftime(iso8601_msec_fmt, sizeof(iso8601_msec_fmt), "%FT%T.%%03dZ", gmtime(&time->ts.tv_sec));
	char iso8601_s[sizeof("YYYY-mm-ddTHH:MM:SS.nnnZ")];
	snprintf(iso8601_s, sizeof(iso8601_s), iso8601_msec_fmt, (int) time->ts.tv_nsec / 1000000);

	if (level == LOG_IO_IN || level == LOG_IO_OUT) {
		const char *dir = level == LOG_IO_IN ? "[IN]" : "[OUT]";
		char *hex = tal_hexstr(NULL, io, io_len);
		fprintf(logf, "%s %s%s%s %s\n",
			iso8601_s, prefix, str, dir, hex);
		tal_free(hex);
	} else 	if (!continued) {
		fprintf(logf, "%s %s %s\n", iso8601_s, prefix, str);
	} else {
		fprintf(logf, "%s %s \t%s\n", iso8601_s, prefix, str);
	}
	fflush(logf);
}
int main(int argc, char *argv[])
{
	const tal_t *ctx = tal_arr(NULL, char, 0);
	OpenAnchorScriptsigs *s;
	struct pkt *pkt;

	err_set_progname(argv[0]);

	opt_register_noarg("--help|-h", opt_usage_and_exit,
			   "<open-anchor-sig-file>\n"
			   "Create LeakAnchorSigsAndPretendWeDidnt to stdout",
			   "Print this message.");
	opt_register_version();

 	opt_parse(&argc, argv, opt_log_stderr_exit);

	if (argc != 2)
		opt_usage_exit_fail("Expected 1 argument");

	s = pkt_from_file(argv[1], PKT__PKT_OPEN_ANCHOR_SCRIPTSIGS)
		->open_anchor_scriptsigs;

	pkt = leak_anchor_sigs_and_pretend_we_didnt_pkt(ctx, s);
	if (!write_all(STDOUT_FILENO, pkt, pkt_totlen(pkt)))
		err(1, "Writing out packet");

	tal_free(ctx);
	return 0;
}
Exemple #21
0
int main(void)
{
	char cwd[1024], *path, *ctx = tal_strdup(NULL, "ctx");

	plan_tests(6);

	if (!getcwd(cwd, sizeof(cwd)))
		abort();

	unlink("run-is_dir-dir-link");
	unlink("run-is_dir-file-link");
	unlink("run-is_dir-dir/file");
	rmdir("run-is_dir-dir");
	if (mkdir("run-is_dir-dir", 0700) != 0)
		abort();
	if (symlink("run-is_dir-dir", "run-is_dir-dir-link") != 0)
		abort();
	if (symlink("run-is_dir-dir/file", "run-is_dir-file-link") != 0)
		abort();
	close(open("run-is_dir-dir/file", O_WRONLY|O_CREAT, 0600));

	ok1(path_is_dir("run-is_dir-dir-link"));
	ok1(!path_is_dir("run-is_dir-file-link"));
	ok1(!path_is_dir("run-is_dir-dir/file"));
	ok1(path_is_dir("run-is_dir-dir"));

	path = path_join(ctx, cwd, "run-is_dir-dir/file");
	ok1(!path_is_dir(path));
	ok1(path_is_dir(cwd));

	tal_free(ctx);

	return exit_status();
}
int main(int argc, char *argv[])
{
	const tal_t *ctx = tal_arr(NULL, char, 0);
	struct bitcoin_tx *tx;
	struct sha256_double txid;
	char str[hex_str_size(sizeof(txid))];

	err_set_progname(argv[0]);

	/* FIXME: Take update.pbs to adjust channel */
	opt_register_noarg("--help|-h", opt_usage_and_exit,
			   "<tx>\n"
			   "Print txid of the transaction in the file",
			   "Print this message.");
	opt_register_version();

 	opt_parse(&argc, argv, opt_log_stderr_exit);

	if (argc != 2)
		opt_usage_exit_fail("Expected 1 argument");

	tx = bitcoin_tx_from_file(ctx, argv[1]);
	bitcoin_txid(tx, &txid);

	if (!bitcoin_txid_to_hex(&txid, str, sizeof(str)))
		abort();

	/* Print it out. */
	if (!write_all(STDOUT_FILENO, str, strlen(str)))
		err(1, "Writing out txid");

	tal_free(ctx);
	return 0;
}
Exemple #23
0
static void test_full(void)
{
	struct full_graphr fgr;
	int i, j;

	full_graphr_init(&fgr, FULL_LEN);

	for (i = 1; i <= FULL_LEN; i++) {
		struct agar_state *sr;

		ok1(sr = agar_dijkstra_new(NULL, &fgr.gr, int2ptr(i)));

		for (j = 1; j <= FULL_LEN; j++) {
			aga_icost_t cost;
			const void *node, *edge;

			ok1(agar_dijkstra_path(sr, int2ptr(j),
					      &cost, &node, &edge));
			if (i == j) {
				ok1(cost == 0);
			} else {
				ok1(cost == 1);
				ok1(node == int2ptr(i));
				ok1(edge == int2ptr(j));
			}
		}

		tal_free(sr);
	}
}
Exemple #24
0
void publish_complaint(struct state *state,
		       struct block *block,
		       const void *complaint,
		       struct peer *origin)
{
	/* Don't complaint storm. */
	if (block->complaint) {
		tal_free(complaint);
		return;
	}

	/* FIXME: Save complaint to blockfile! */

	/* If it's invalid, so are any descendents. */
	complaint_on_all(state, block, complaint);

	/* We have dumped all the txs from those blocks into pending. */
	recheck_pending_txs(state);

	/* Recalc everything.  Slow, but should be rare. */
	update_block_ptrs_invalidated(state, block);

	/* Tell everyone (except origin!) */
	broadcast_to_peers(state, complaint, origin);
}
Exemple #25
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);
}
Exemple #26
0
struct bitcoin_tx *create_close_tx(const tal_t *ctx,
				   const u8 *our_script,
				   const u8 *their_script,
				   const struct bitcoin_txid *anchor_txid,
				   unsigned int anchor_index,
				   struct amount_sat funding,
				   struct amount_sat to_us,
				   struct amount_sat to_them,
				   struct amount_sat dust_limit)
{
	struct bitcoin_tx *tx;
	size_t num_outputs = 0;
	struct amount_sat total_out;
	u8 *script;

	assert(amount_sat_add(&total_out, to_us, to_them));
	assert(amount_sat_less_eq(total_out, funding));

	/* BOLT #3:
	 *
	 * ## Closing Transaction
	 *
	 * Note that there are two possible variants for each node.
	 *
	 * * version: 2
	 * * locktime: 0
	 * * txin count: 1
	 */
	/* Now create close tx: one input, two outputs. */
	tx = bitcoin_tx(ctx, 1, 2);

	/* Our input spends the anchor tx output. */
	bitcoin_tx_add_input(tx, anchor_txid, anchor_index,
			     BITCOIN_TX_DEFAULT_SEQUENCE, &funding, NULL);

	if (amount_sat_greater_eq(to_us, dust_limit)) {
		script =
		    tal_dup_arr(tx, u8, our_script, tal_count(our_script), 0);
		/* One output is to us. */
		bitcoin_tx_add_output(tx, script, &to_us);
		num_outputs++;
	}

	if (amount_sat_greater_eq(to_them, dust_limit)) {
		script = tal_dup_arr(tx, u8, their_script,
				     tal_count(their_script), 0);
		/* Other output is to them. */
		bitcoin_tx_add_output(tx, script, &to_them);
		num_outputs++;
	}

	/* Can't have no outputs at all! */
	if (num_outputs == 0)
		return tal_free(tx);

	permute_outputs(tx, NULL, NULL);
	assert(bitcoin_tx_check(tx));
	return tx;
}
Exemple #27
0
char *short_channel_id_dir_to_str(const tal_t *ctx,
				  const struct short_channel_id_dir *scidd)
{
	char *str, *scidstr = short_channel_id_to_str(NULL, &scidd->scid);
	str = tal_fmt(ctx, "%s/%u", scidstr, scidd->dir);
	tal_free(scidstr);
	return str;
}
Exemple #28
0
struct secret *hsm_do_ecdh(const tal_t *ctx, const struct pubkey *point)
{
	struct secret *ss = tal(ctx, struct secret);
	if (secp256k1_ecdh(secp256k1_ctx, ss->data, &point->pubkey,
			   notsosecret.data, NULL, NULL) != 1)
		return tal_free(ss);
	return ss;
}
Exemple #29
0
void json_add_hex(char **result, const char *fieldname, const void *data,
		  size_t len)
{
	char *hex = to_hex(*result, data, len);

	json_add_string(result, fieldname, hex);
	tal_free(hex);
}
Exemple #30
0
void json_add_address(char **result, const char *fieldname, bool test_net,
		      const struct protocol_address *addr)
{
	char *str = pettycoin_to_base58(*result, test_net, addr, false);

	json_add_string(result, fieldname, str);
	tal_free(str);
}