예제 #1
0
int main(int argc, char *argv[])
{
	int fd, i, off;
	const char *method;
	char *cmd, *resp, *idstr, *rpc_filename;
	char *result_end;
	struct sockaddr_un addr;
	jsmntok_t *toks;
	const jsmntok_t *result, *error, *id;
	char *lightning_dir;
	const tal_t *ctx = tal(NULL, char);
	size_t num_opens, num_closes;
	bool valid;

	err_set_progname(argv[0]);

	opt_set_alloc(opt_allocfn, tal_reallocfn, tal_freefn);
	configdir_register_opts(ctx, &lightning_dir, &rpc_filename);

	opt_register_noarg("--help|-h", opt_usage_and_exit,
			   "<command> [<params>...]", "Show this message");
	opt_register_version();

	opt_early_parse(argc, argv, opt_log_stderr_exit);
	opt_parse(&argc, argv, opt_log_stderr_exit);

	method = argv[1];
	if (!method)
		errx(ERROR_USAGE, "Need at least one argument\n%s",
		     opt_usage(argv[0], NULL));

	if (chdir(lightning_dir) != 0)
		err(ERROR_TALKING_TO_LIGHTNINGD, "Moving into '%s'",
		    lightning_dir);

	fd = socket(AF_UNIX, SOCK_STREAM, 0);
	if (strlen(rpc_filename) + 1 > sizeof(addr.sun_path))
		errx(ERROR_USAGE, "rpc filename '%s' too long", rpc_filename);
	strcpy(addr.sun_path, rpc_filename);
	addr.sun_family = AF_UNIX;

	if (connect(fd, (struct sockaddr *)&addr, sizeof(addr)) != 0)
		err(ERROR_TALKING_TO_LIGHTNINGD,
		    "Connecting to '%s'", rpc_filename);

	idstr = tal_fmt(ctx, "lightning-cli-%i", getpid());
	cmd = tal_fmt(ctx,
		      "{ \"method\" : \"%s\", \"id\" : \"%s\", \"params\" : [ ",
		      method, idstr);

	for (i = 2; i < argc; i++) {
		/* Numbers are left unquoted, and quoted things left alone. */
		if (strspn(argv[i], "0123456789") == strlen(argv[i])
		    || argv[i][0] == '"')
			tal_append_fmt(&cmd, "%s", argv[i]);
		else
			tal_append_fmt(&cmd, "\"%s\"", argv[i]);
		if (i != argc - 1)
			tal_append_fmt(&cmd, ", ");
	}
	tal_append_fmt(&cmd, "] }");

	if (!write_all(fd, cmd, strlen(cmd)))
		err(ERROR_TALKING_TO_LIGHTNINGD, "Writing command");

	resp = tal_arr(cmd, char, 100);
	off = 0;
	num_opens = num_closes = 0;
	while ((i = read(fd, resp + off, tal_count(resp) - 1 - off)) > 0) {
		resp[off + i] = '\0';
		num_opens += strcount(resp + off, "{");
		num_closes += strcount(resp + off, "}");

		off += i;
		if (off == tal_count(resp) - 1)
			tal_resize(&resp, tal_count(resp) * 2);

		/* parsing huge outputs is slow: do quick check first. */
		if (num_opens == num_closes && strstr(resp, "\"result\""))
			break;
	}
	if (i < 0)
		err(ERROR_TALKING_TO_LIGHTNINGD, "reading response");

	/* Parsing huge results is too slow, so hack fastpath common case */
	result_end = tal_fmt(ctx, ", \"error\" : null, \"id\" : \"%s\" }\n",
			     idstr);

	if (strstarts(resp, "{ \"result\" : ") && strends(resp, result_end)) {
		/* Result is OK, so dump it */
		resp += strlen("{ \"result\" : ");
		printf("%.*s\n", (int)(strlen(resp) - strlen(result_end)), resp);
		tal_free(ctx);
		return 0;
	}

	toks = json_parse_input(resp, off, &valid);
	if (!toks || !valid)
		errx(ERROR_TALKING_TO_LIGHTNINGD,
		     "Malformed response '%s'", resp);

	if (toks->type != JSMN_OBJECT)
		errx(ERROR_TALKING_TO_LIGHTNINGD,
		     "Non-object response '%s'", resp);

	result = json_get_member(resp, toks, "result");
	if (!result)
		errx(ERROR_TALKING_TO_LIGHTNINGD,
		     "Missing 'result' in response '%s'", resp);
	error = json_get_member(resp, toks, "error");
	if (!error)
		errx(ERROR_TALKING_TO_LIGHTNINGD,
		     "Missing 'error' in response '%s'", resp);
	id = json_get_member(resp, toks, "id");
	if (!id)
		errx(ERROR_TALKING_TO_LIGHTNINGD,
		     "Missing 'id' in response '%s'", resp);
	if (!json_tok_streq(resp, id, idstr))
		errx(ERROR_TALKING_TO_LIGHTNINGD,
		     "Incorrect 'id' in response: %.*s",
		     json_tok_len(id), json_tok_contents(resp, id));

	if (json_tok_is_null(resp, error)) {
		printf("%.*s\n",
		       json_tok_len(result),
		       json_tok_contents(resp, result));
		tal_free(ctx);
		return 0;
	}

	printf("%.*s\n",
	       json_tok_len(error), json_tok_contents(resp, error));
	tal_free(ctx);
	return 1;
}
예제 #2
0
static enum channel_add_err add_htlc(struct channel *channel,
				     enum htlc_state state,
				     u64 id,
				     struct amount_msat amount,
				     u32 cltv_expiry,
				     const struct sha256 *payment_hash,
				     const u8 routing[TOTAL_PACKET_SIZE],
				     struct htlc **htlcp,
				     bool enforce_aggregate_limits)
{
	struct htlc *htlc, *old;
	struct amount_msat msat_in_htlcs, committed_msat, adding_msat, removing_msat;
	struct amount_sat fee;
	enum side sender = htlc_state_owner(state), recipient = !sender;
	const struct htlc **committed, **adding, **removing;
	const struct channel_view *view;
	bool ok;
	size_t i;

	htlc = tal(tmpctx, struct htlc);

	htlc->id = id;
	htlc->amount = amount;
	htlc->state = state;
	htlc->shared_secret = NULL;

	/* FIXME: Change expiry to simple u32 */

	/* BOLT #2:
	 *
	 * A receiving node:
	 *...
	 *  - if sending node sets `cltv_expiry` to greater or equal to
	 *    500000000:
	 *    - SHOULD fail the channel.
	 */
	if (!blocks_to_abs_locktime(cltv_expiry, &htlc->expiry)) {
		return CHANNEL_ERR_INVALID_EXPIRY;
	}

	htlc->rhash = *payment_hash;
	htlc->fail = NULL;
	htlc->failcode = 0;
	htlc->failed_scid = NULL;
	htlc->r = NULL;
	htlc->routing = tal_dup_arr(htlc, u8, routing, TOTAL_PACKET_SIZE, 0);

	old = htlc_get(channel->htlcs, htlc->id, htlc_owner(htlc));
	if (old) {
		if (old->state != htlc->state
		    || !amount_msat_eq(old->amount, htlc->amount)
		    || old->expiry.locktime != htlc->expiry.locktime
		    || !sha256_eq(&old->rhash, &htlc->rhash))
			return CHANNEL_ERR_DUPLICATE_ID_DIFFERENT;
		else
			return CHANNEL_ERR_DUPLICATE;
	}

	/* We're always considering the recipient's view of the channel here */
	view = &channel->view[recipient];

	/* BOLT #2:
	 *
	 * A receiving node:
	 *  - receiving an `amount_msat` equal to 0, OR less than its own
	 *    `htlc_minimum_msat`:
	 *    - SHOULD fail the channel.
	 */
	if (amount_msat_eq(htlc->amount, AMOUNT_MSAT(0))) {
		return CHANNEL_ERR_HTLC_BELOW_MINIMUM;
	}
	if (amount_msat_less(htlc->amount, channel->config[recipient].htlc_minimum)) {
		return CHANNEL_ERR_HTLC_BELOW_MINIMUM;
	}

	/* BOLT #2:
	 *
	 * - for channels with `chain_hash` identifying the Bitcoin blockchain:
	 *    - MUST set the four most significant bytes of `amount_msat` to 0.
	 */
	if (amount_msat_greater(htlc->amount, channel->chainparams->max_payment)) {
		return CHANNEL_ERR_MAX_HTLC_VALUE_EXCEEDED;
	}

	/* Figure out what receiver will already be committed to. */
	gather_htlcs(tmpctx, channel, recipient, &committed, &removing, &adding);
	htlc_arr_append(&adding, htlc);

	/* BOLT #2:
	 *
	 *   - if a sending node adds more than receiver `max_accepted_htlcs`
	 *     HTLCs to its local commitment transaction...
	 *     - SHOULD fail the channel.
	 */
	if (tal_count(committed) - tal_count(removing) + tal_count(adding)
	    > channel->config[recipient].max_accepted_htlcs) {
		return CHANNEL_ERR_TOO_MANY_HTLCS;
	}

	/* These cannot overflow with HTLC amount limitations, but
	 * maybe adding could later if they try to add a maximal HTLC. */
	if (!sum_offered_msatoshis(&committed_msat,
				   committed, htlc_owner(htlc))
	    || !sum_offered_msatoshis(&removing_msat,
				      removing, htlc_owner(htlc))
	    || !sum_offered_msatoshis(&adding_msat,
				      adding, htlc_owner(htlc))) {
		return CHANNEL_ERR_MAX_HTLC_VALUE_EXCEEDED;
	}

	if (!amount_msat_add(&msat_in_htlcs, committed_msat, adding_msat)
	    || !amount_msat_sub(&msat_in_htlcs, msat_in_htlcs, removing_msat)) {
		return CHANNEL_ERR_MAX_HTLC_VALUE_EXCEEDED;
	}

	/* BOLT #2:
	 *
	 *   - if a sending node... adds more than receiver
	 *     `max_htlc_value_in_flight_msat` worth of offered HTLCs to its
	 *     local commitment transaction:
	 *     - SHOULD fail the channel.
	 */

	/* We don't enforce this for channel_force_htlcs: some might already
	 * be fulfilled/failed */
	if (enforce_aggregate_limits
	    && amount_msat_greater(msat_in_htlcs,
				   channel->config[recipient].max_htlc_value_in_flight)) {
		return CHANNEL_ERR_MAX_HTLC_VALUE_EXCEEDED;
	}

	/* BOLT #2:
	 *
	 * A receiving node:
	 *...
	 *  - receiving an `amount_msat` that the sending node cannot afford at
	 *    the current `feerate_per_kw` (while maintaining its channel
	 *    reserve):
	 *    - SHOULD fail the channel.
	 */
	if (channel->funder == htlc_owner(htlc)) {
		u32 feerate = view->feerate_per_kw;
		struct amount_sat dust_limit = channel->config[recipient].dust_limit;
		size_t untrimmed;

		untrimmed = commit_tx_num_untrimmed(committed, feerate, dust_limit,
						    recipient)
			+ commit_tx_num_untrimmed(adding, feerate, dust_limit,
						  recipient)
			- commit_tx_num_untrimmed(removing, feerate, dust_limit,
						  recipient);

		fee = commit_tx_base_fee(feerate, untrimmed);
	} else
		fee = AMOUNT_SAT(0);

	assert((s64)fee.satoshis >= 0); /* Raw: explicit signedness test */

	if (enforce_aggregate_limits) {
		/* Figure out what balance sender would have after applying all
		 * pending changes. */
		struct amount_msat balance = view->owed[sender];
		/* This is a little subtle:
		 *
		 * The change is being applied to the receiver but it will
		 * come back to the sender after revoke_and_ack.  So the check
		 * here is that the balance to the sender doesn't go below the
		 * sender's reserve. */
		const struct amount_sat reserve
			= channel->config[!sender].channel_reserve;

		assert(amount_msat_greater_eq(balance, AMOUNT_MSAT(0)));
		ok = true;
		for (i = 0; i < tal_count(removing); i++)
			ok &= balance_remove_htlc(&balance, removing[i], sender);
		assert(amount_msat_greater_eq(balance, AMOUNT_MSAT(0)));
		for (i = 0; i < tal_count(adding); i++)
			ok &= balance_add_htlc(&balance, adding[i], sender);

		/* Overflow shouldn't happen, but if it does, complain */
		if (!ok) {
			status_broken("Failed to add %zu remove %zu htlcs",
				      tal_count(adding), tal_count(removing));
			return CHANNEL_ERR_CHANNEL_CAPACITY_EXCEEDED;
		}

		if (!amount_msat_sub_sat(&balance, balance, fee)) {
			status_trace("Cannot afford fee %s with balance %s",
				     type_to_string(tmpctx, struct amount_sat,
						    &fee),
				     type_to_string(tmpctx, struct amount_msat,
						    &balance));
			return CHANNEL_ERR_CHANNEL_CAPACITY_EXCEEDED;
		}
		if (!amount_msat_greater_eq_sat(balance, reserve)) {
			status_trace("Cannot afford fee %s: would make balance %s"
				     " below reserve %s",
				     type_to_string(tmpctx, struct amount_sat,
						    &fee),
				     type_to_string(tmpctx, struct amount_msat,
						    &balance),
				     type_to_string(tmpctx, struct amount_sat,
						    &reserve));
			return CHANNEL_ERR_CHANNEL_CAPACITY_EXCEEDED;
		}
예제 #3
0
/*
 * We add changes to both our staging cstate (as they did when they sent
 * it) and theirs (as they will when we ack it).
 */
Pkt *accept_pkt_htlc_add(struct peer *peer, const Pkt *pkt)
{
	const UpdateAddHtlc *u = pkt->update_add_htlc;
	struct sha256 rhash;
	struct abs_locktime expiry;
	struct htlc *htlc;
	union htlc_staging stage;

	/* BOLT #2:
	 *
	 * `amount_msat` MUST BE greater than 0.
	 */
	if (u->amount_msat == 0)
		return pkt_err(peer, "Invalid amount_msat");

	proto_to_sha256(u->r_hash, &rhash);
	if (!proto_to_abs_locktime(u->expiry, &expiry))
		return pkt_err(peer, "Invalid HTLC expiry");

	if (abs_locktime_is_seconds(&expiry))
		return pkt_err(peer, "HTLC expiry in seconds not supported!");

	/* BOLT #2:
	 *
	 * A node MUST NOT add a HTLC if it would result in it
	 * offering more than 300 HTLCs in the remote commitment transaction.
	 */
	if (tal_count(peer->remote.staging_cstate->side[THEIRS].htlcs) == 300)
		return pkt_err(peer, "Too many HTLCs");

	/* BOLT #2:
	 *
	 * A node MUST set `id` to a unique identifier for this HTLC
	 * amongst all past or future `update_add_htlc` messages.
	 */
	/* Note that it's not *our* problem if they do this, it's
	 * theirs (future confusion).  Nonetheless, we detect and
	 * error for them. */
	if (htlc_map_get(&peer->remote.htlcs, u->id))
		return pkt_err(peer, "HTLC id %"PRIu64" clashes for you", u->id);

	/* BOLT #2:
	 *
	 * ...and the receiving node MUST add the HTLC addition to the
	 * unacked changeset for its local commitment. */
	htlc = peer_new_htlc(peer, u->id, u->amount_msat, &rhash,
			     abs_locktime_to_blocks(&expiry),
			     u->route->info.data, u->route->info.len,
			     NULL, THEIRS);

	/* BOLT #2:
	 *
	 * A node MUST NOT offer `amount_msat` it cannot pay for in
	 * the remote commitment transaction at the current `fee_rate` (see
	 * "Fee Calculation" ).  A node SHOULD fail the connection if
	 * this occurs.
	 */
	if (!cstate_add_htlc(peer->local.staging_cstate, htlc, THEIRS)) {
		tal_free(htlc);
		return pkt_err(peer, "Cannot afford %"PRIu64" milli-satoshis"
			       " in our commitment tx",
			       u->amount_msat);
	}

	stage.add.add = HTLC_ADD;
	stage.add.htlc = htlc;
	add_unacked(&peer->local, &stage);

	return NULL;
}
예제 #4
0
int main(int argc, char *argv[])
{
	u8 version;
	beint16_t be_inlen;
	struct amount_sat sat;
	bool verbose = false;
	char *infile = NULL, *outfile = NULL, *scidfile = NULL, *csat = NULL;
	int infd = 0, outfd;
       	FILE * scidfd;
	struct scidsat * scids = NULL;
	unsigned max = -1U;

	setup_locale();

	opt_register_noarg("--verbose|-v", opt_set_bool, &verbose,
			   "Print progress to stderr");
	opt_register_arg("--output|-o", opt_set_charp, NULL, &outfile,
			 "Send output to this file instead of stdout");
	opt_register_arg("--input|-i", opt_set_charp, NULL, &infile,
			 "Read input from this file instead of stdin");
	opt_register_arg("--scidfile", opt_set_charp, NULL, &scidfile,
			 "Input for 'scid, satshis' csv");
	opt_register_arg("--sat", opt_set_charp, NULL, &csat,
			 "default satoshi value if --scidfile flag not present");
	opt_register_arg("--max", opt_set_uintval, opt_show_uintval, &max,
			 "maximum number of messages to read");
	opt_register_noarg("--help|-h", opt_usage_and_exit,
			   "Create gossip store, from be16 / input messages",
			   "Print this message.");

	opt_parse(&argc, argv, opt_log_stderr_exit);


        if (scidfile) {
		scidfd = fopen(scidfile, "r");
		if (scidfd < 0)
			err(1, "opening %s", scidfile);
                scids = load_scid_file(scidfd);
	        fclose(scidfd);
	}
	else if (csat) {
		if (!parse_amount_sat(&sat, csat, strlen(csat))) {
		        errx(1, "Invalid satoshi amount %s", csat);
		}
	}
	else {
		err(1, "must contain either --sat xor --scidfile");
	}

	if (infile) {
		infd = open(infile, O_RDONLY);
		if (infd < 0)
			err(1, "opening %s", infile);
	}

	if (outfile) {
		outfd = open(outfile, O_WRONLY|O_TRUNC|O_CREAT, 0666);
		if (outfd < 0)
			err(1, "opening %s", outfile);
	} else
		outfd = STDOUT_FILENO;

	version = GOSSIP_STORE_VERSION;
	if (!write_all(outfd, &version, sizeof(version)))
		err(1, "Writing version");

	int scidi = 0;
	int channels = 0;
	int nodes = 0;
	int updates = 0;
	while (read_all(infd, &be_inlen, sizeof(be_inlen))) {
		u32 msglen = be16_to_cpu(be_inlen);
		u8 *inmsg = tal_arr(NULL, u8, msglen), *outmsg;
		beint32_t be_outlen;
		beint32_t becsum;

		if (!read_all(infd, inmsg, msglen))
			err(1, "Only read partial message");

		switch (fromwire_peektype(inmsg)) {
		case WIRE_CHANNEL_ANNOUNCEMENT:
			if (scids) {
				sat = scids[scidi].sat;
				scidi += 1;
			}
			channels += 1;
			outmsg = towire_gossip_store_channel_announcement(inmsg, inmsg, sat);
			break;
		case WIRE_CHANNEL_UPDATE:
			outmsg = towire_gossip_store_channel_update(inmsg, inmsg);
			updates += 1;
			break;
		case WIRE_NODE_ANNOUNCEMENT:
			outmsg = towire_gossip_store_node_announcement(inmsg, inmsg);
			nodes += 1;
			break;
		default:
			warnx("Unknown message %u (%s)", fromwire_peektype(inmsg),
			      wire_type_name(fromwire_peektype(inmsg)));
			tal_free(inmsg);
			continue;
		}
		if (verbose)
			fprintf(stderr, "%s->%s\n",
				wire_type_name(fromwire_peektype(inmsg)),
				gossip_store_type_name(fromwire_peektype(outmsg)));

		becsum = cpu_to_be32(crc32c(0, outmsg, tal_count(outmsg)));
		be_outlen = cpu_to_be32(tal_count(outmsg));
		if (!write_all(outfd, &be_outlen, sizeof(be_outlen))
		    || !write_all(outfd, &becsum, sizeof(becsum))
		    || !write_all(outfd, outmsg, tal_count(outmsg))) {
			exit(1);
		}
		tal_free(inmsg);
		if (--max == 0)
			break;
	}
	fprintf(stderr, "channels %d, updates %d, nodes %d\n", channels, updates, nodes);
	free(scids);
	return 0;
}
예제 #5
0
int main(int argc, char *argv[])
{
	const tal_t *ctx = tal_arr(NULL, char, 0);
	OpenChannel *o1, *o2;
	struct bitcoin_tx *anchor, *close_tx;
	struct sha256_double anchor_txid;
	struct bitcoin_signature sig1, sig2;
	struct pubkey pubkey1, pubkey2;
	u8 *redeemscript, *tx_arr;
	char *tx_hex;
	CloseChannel *close;
	CloseChannelComplete *closecomplete;
	size_t i;
	int64_t delta;

	err_set_progname(argv[0]);

	/* FIXME: Take update.pbs to adjust channel */
	opt_register_noarg("--help|-h", opt_usage_and_exit,
			   "<anchor-tx> <open-channel-file1> <open-channel-file2> <close-protobuf> <close-complete-protobuf> [update-protobuf]...\n"
			   "Create the close transaction from the signatures",
			   "Print this message.");

 	opt_parse(&argc, argv, opt_log_stderr_exit);

	if (argc < 6)
		opt_usage_exit_fail("Expected 5+ arguments");

	anchor = bitcoin_tx_from_file(ctx, argv[1]);
	o1 = pkt_from_file(argv[2], PKT__PKT_OPEN)->open;
	o2 = pkt_from_file(argv[3], PKT__PKT_OPEN)->open;
	close = pkt_from_file(argv[4], PKT__PKT_CLOSE)->close;
	closecomplete = pkt_from_file(argv[5], PKT__PKT_CLOSE_COMPLETE)->close_complete;

	bitcoin_txid(anchor, &anchor_txid);

	/* Pubkeys well-formed? */
	if (!proto_to_pubkey(o1->anchor->pubkey, &pubkey1))
		errx(1, "Invalid anchor-1 key");
	if (!proto_to_pubkey(o2->anchor->pubkey, &pubkey2))
		errx(1, "Invalid anchor-2 key");
	
	/* Get delta by accumulting all the updates. */
	delta = 0;
	for (i = 6; i < argc; i++) {
		Update *u = pkt_from_file(argv[i], PKT__PKT_UPDATE)->update;
		delta += u->delta;
	}	

	/* This is what the anchor pays to; figure out which output. */
	redeemscript = bitcoin_redeem_2of2(ctx, &pubkey1, &pubkey2);

	/* Now create the close tx to spend 2/2 output of anchor. */
	close_tx = create_close_tx(ctx, o1, o2, delta, &anchor_txid,
				   find_p2sh_out(anchor, redeemscript));

	/* Signatures well-formed? */
	sig1.stype = sig2.stype = SIGHASH_ALL;
	if (!proto_to_signature(close->sig, &sig1.sig))
		errx(1, "Invalid close-packet");
	if (!proto_to_signature(closecomplete->sig, &sig2.sig))
		errx(1, "Invalid closecomplete-packet");

	/* Combined signatures must validate correctly. */
	if (!check_2of2_sig(close_tx, 0, redeemscript, tal_count(redeemscript),
			    &pubkey1, &pubkey2, &sig1, &sig2))
		errx(1, "Signature failed");

	/* Create p2sh input for close_tx */
	close_tx->input[0].script = scriptsig_p2sh_2of2(close_tx, &sig1, &sig2,
						      &pubkey1, &pubkey2);
	close_tx->input[0].script_length = tal_count(close_tx->input[0].script);

	/* Print it out in hex. */
	tx_arr = linearize_tx(ctx, close_tx);
	tx_hex = tal_arr(tx_arr, char, hex_str_size(tal_count(tx_arr)));
	hex_encode(tx_arr, tal_count(tx_arr), tx_hex, tal_count(tx_hex));

	if (!write_all(STDOUT_FILENO, tx_hex, strlen(tx_hex)))
		err(1, "Writing out transaction");

	tal_free(ctx);
	return 0;
}
예제 #6
0
int main(int argc, char *argv[])
{
	const tal_t *ctx = tal_arr(NULL, char, 0);
	struct sha256 seed, revocation_hash, their_rhash;
	OpenChannel *o1, *o2;
	OpenAnchor *a;
	struct bitcoin_tx *commit;
	struct pkt *pkt;
	struct bitcoin_signature sig;
	struct privkey privkey;
	bool testnet;
	size_t num_updates;
	struct pubkey pubkey1, pubkey2;
	u8 *redeemscript;
	struct channel_state *cstate;

	err_set_progname(argv[0]);

	opt_register_noarg("--help|-h", opt_usage_and_exit,
			   "<seed> <open-channel-file1> <open-channel-file2> <open-anchor-file> <commit-privkey> <all-updates...>\n"
			   "Accept a new update message",
			   "Print this message.");
	opt_register_version();

 	opt_parse(&argc, argv, opt_log_stderr_exit);

	if (argc < 7)
		opt_usage_exit_fail("Expected 6+ arguments");

	if (!hex_decode(argv[1], strlen(argv[1]), &seed, sizeof(seed)))
		errx(1, "Invalid seed '%s' - need 256 hex bits", argv[1]);
	
	o1 = pkt_from_file(argv[2], PKT__PKT_OPEN)->open;
	o2 = pkt_from_file(argv[3], PKT__PKT_OPEN)->open;
	a = pkt_from_file(argv[4], PKT__PKT_OPEN_ANCHOR)->open_anchor;

	if (!key_from_base58(argv[5], strlen(argv[5]), &testnet, &privkey, &pubkey1))
		errx(1, "Invalid private key '%s'", argv[5]);
	if (!testnet)
		errx(1, "Private key '%s' not on testnet!", argv[5]);

	/* Figure out cumulative delta since anchor. */
	cstate = gather_updates(ctx, o1, o2, a, commit_fee(o1, o2), argv + 6,
				&num_updates, NULL, &their_rhash, NULL);

	/* Get next revocation hash. */
	shachain_from_seed(&seed, num_updates, &revocation_hash);
	sha256(&revocation_hash,
	       revocation_hash.u.u8, sizeof(revocation_hash.u.u8));
	
	/* Get pubkeys */
	if (!proto_to_pubkey(o1->commit_key, &pubkey2))
		errx(1, "Invalid o1 commit pubkey");
	if (!pubkey_eq(&pubkey1, &pubkey2))
		errx(1, "o1 pubkey != this privkey");
	if (!proto_to_pubkey(o2->commit_key, &pubkey2))
		errx(1, "Invalid o2 commit pubkey");

	/* This is what the anchor pays to; figure out whick output. */
	redeemscript = bitcoin_redeem_2of2(ctx, &pubkey1, &pubkey2);

	/* Now create THEIR new commitment tx to spend 2/2 output of anchor. */
	invert_cstate(cstate);
	commit = create_commit_tx(ctx, o2, o1, a, &their_rhash, cstate);

	/* If contributions don't exceed fees, this fails. */
	if (!commit)
		errx(1, "Delta too large");

	/* Sign it for them. */
	sign_tx_input(ctx, commit, 0, redeemscript, tal_count(redeemscript),
		      &privkey, &pubkey1, &sig.sig);

	pkt = update_accept_pkt(ctx, &sig.sig, &revocation_hash);
	if (!write_all(STDOUT_FILENO, pkt, pkt_totlen(pkt)))
		err(1, "Writing out packet");

	tal_free(ctx);
	return 0;
}
예제 #7
0
static void tal_hexeq(const u8 *p, const char *hex)
{
	hexeq(p, tal_count(p),hex);
}
예제 #8
0
파일: packets.c 프로젝트: dooglus/lightning
/*
 * We add changes to both our staging cstate (as they did when they sent
 * it) and theirs (as they will when we ack it).
 */
Pkt *accept_pkt_htlc_add(struct peer *peer, const Pkt *pkt)
{
	const UpdateAddHtlc *u = pkt->update_add_htlc;
	struct sha256 rhash;
	struct abs_locktime expiry;

	/* BOLT #2:
	 *
	 * `amount_msat` MUST BE greater than 0.
	 */
	if (u->amount_msat == 0)
		return pkt_err(peer, "Invalid amount_msat");

	proto_to_sha256(u->r_hash, &rhash);
	if (!proto_to_abs_locktime(u->expiry, &expiry))
		return pkt_err(peer, "Invalid HTLC expiry");

	/* FIXME: Handle block-based expiry! */
	if (!abs_locktime_is_seconds(&expiry))
		return pkt_err(peer, "HTLC expiry in blocks not supported!");

	/* BOLT #2:
	 *
	 * A node MUST NOT add a HTLC if it would result in it
	 * offering more than 1500 HTLCs in either commitment transaction.
	 */
	if (tal_count(peer->them.staging_cstate->a.htlcs) == 1500
	    || tal_count(peer->us.staging_cstate->b.htlcs) == 1500)
		return pkt_err(peer, "Too many HTLCs");

	/* BOLT #2:
	 *
	 * A node MUST NOT set `id` equal to another HTLC which is in
	 * the current staged commitment transaction.
	 */
	if (funding_htlc_by_id(&peer->them.staging_cstate->a, u->id)
	    < tal_count(peer->them.staging_cstate->a.htlcs))
		return pkt_err(peer, "HTLC id %"PRIu64" clashes for you", u->id);

	/* FIXME: Assert this... */
	/* Note: these should be in sync, so this should be redundant! */
	if (funding_htlc_by_id(&peer->us.staging_cstate->b, u->id)
	    < tal_count(peer->us.staging_cstate->b.htlcs))
		return pkt_err(peer, "HTLC id %"PRIu64" clashes for us", u->id);

	/* BOLT #2:
	 *
	 * A node MUST NOT offer `amount_msat` it cannot pay for in
	 * both commitment transactions at the current `fee_rate` (see
	 * "Fee Calculation" ).  A node SHOULD fail the connection if
	 * this occurs.
	 */

	/* FIXME: This is wrong!  We may have already added more txs to
	 * them.staging_cstate, driving that fee up.
	 * We should check against the last version they acknowledged. */
	if (!funding_a_add_htlc(peer->them.staging_cstate,
				u->amount_msat, &expiry, &rhash, u->id))
		return pkt_err(peer, "Cannot afford %"PRIu64" milli-satoshis"
			       " in your commitment tx",
			       u->amount_msat);

	/* If we fail here, we've already changed them.staging_cstate, so
	 * MUST terminate. */
	if (!funding_b_add_htlc(peer->us.staging_cstate,
				u->amount_msat, &expiry, &rhash, u->id))
		return pkt_err(peer, "Cannot afford %"PRIu64" milli-satoshis"
			       " in our commitment tx",
			       u->amount_msat);

	peer_add_htlc_expiry(peer, &expiry);

	/* FIXME: Fees must be sufficient. */
	return NULL;
}
예제 #9
0
int main(void)
{
	struct protocol_double_sha dsha;
	struct protocol_net_address netaddr;
	int fds[2];
	char *p, *mem1, *mem2, *mem3;
	int status;
	size_t maxmem = sizeof(struct log_entry) * 4 + 25 + 25 + 28 + 161;
	void *ctx = tal(NULL, char);
	struct log *log = new_log(ctx, NULL, "PREFIX", LOG_BROKEN+1, maxmem);

	assert(tal_parent(log) == ctx);
	my_time.ts.tv_sec = 1384064855;
	my_time.ts.tv_nsec = 500;

	log_debug(log, "This is a debug %s!", "message");
	my_time.ts.tv_nsec++;
	log_info(log, "This is an info %s!", "message");
	my_time.ts.tv_nsec++;
	log_unusual(log, "This is an unusual %s!", "message");
	my_time.ts.tv_nsec++;
	log_broken(log, "This is a broken %s!", "message");
	my_time.ts.tv_nsec++;

	log_add(log, "the sha is ");
	memset(&dsha, 0xFF, sizeof(dsha));
	log_add_struct(log, struct protocol_double_sha, &dsha);

	log_add(log, " and the address is: ");
	memset(netaddr.addr, 0, 10);
	memset(netaddr.addr + 10, 0xFF, 2);
	netaddr.addr[12] = 127;
	netaddr.addr[13] = 0;
	netaddr.addr[14] = 0;
	netaddr.addr[15] = 1;
	netaddr.port = cpu_to_le16(65000);
	netaddr.time = time_now().ts.tv_sec - 10;
	log_add_struct(log, struct protocol_net_address, &netaddr);

	/* Make child write log, be sure it's correct. */
	pipe(fds);
	switch (fork()) {
	case -1:
		err(1, "forking");
	case 0:
		close(fds[0]);
		setenv("TZ", "UTC", 1);
		log_to_file(fds[1], log);
		tal_free(ctx);
		exit(0);
	}

	close(fds[1]);
	p = read_from(ctx, fds[0]);
	/* Shouldn't contain any NUL chars */
	assert(strlen(p) + 1 == tal_count(p));

	assert(tal_strreg(p, p,
			  "PREFIX ([0-9])* bytes, Sun Nov 10 06:27:35 2013\n"
			  "\\+0\\.000000500 DEBUG: This is a debug message!\n"
			  "\\+0\\.000000501 INFO: This is an info message!\n"
			  "\\+0\\.000000502 UNUSUAL: This is an unusual message!\n"
			  "\\+0\\.000000503 BROKEN: This is a broken message!the sha is ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff and the address is: ::ffff:127\\.0\\.0\\.1:65000 \\(10 seconds old\\)\n\n", &mem1));
	assert(atoi(mem1) < maxmem);
	tal_free(p);

	wait(&status);
	assert(WIFEXITED(status) && WEXITSTATUS(status) == 0);

	/* This cleans us out! */
	log_debug(log, "Overflow!");
	
	/* Make child write log, be sure it's correct. */
	pipe(fds);
	switch (fork()) {
	case -1:
		err(1, "forking");
	case 0:
		close(fds[0]);
		setenv("TZ", "UTC", 1);
		log_to_file(fds[1], log);
		tal_free(ctx);
		exit(0);
	}

	close(fds[1]);

	p = read_from(ctx, fds[0]);
	/* Shouldn't contain any NUL chars */
	assert(strlen(p) + 1 == tal_count(p));

	assert(tal_strreg(p, p,
			  "PREFIX ([0-9]*) bytes, Sun Nov 10 06:27:35 2013\n"
			  "\\.\\.\\. 4 skipped\\.\\.\\.\n"
			  "\\+0.000000504 DEBUG: Overflow!\n"
			  "\\+0.000000504 DEBUG: Log pruned 4 entries \\(mem ([0-9]*) -> ([0-9]*)\\)\n\n", &mem1, &mem2, &mem3));
	assert(atoi(mem1) < maxmem);
	assert(atoi(mem2) >= maxmem);
	assert(atoi(mem3) < maxmem);
	tal_free(ctx);
	wait(&status);
	assert(WIFEXITED(status) && WEXITSTATUS(status) == 0);
	return 0;
}
예제 #10
0
/* BIP 141:
 * It is followed by stack items, with each item starts with a var_int
 * to indicate the length. */
static void add_witness(const u8 *witness, 
			void (*add)(const void *, size_t, void *), void *addp)
{
	add_varint_blob(witness, tal_count(witness), add, addp);
}
예제 #11
0
파일: packets.c 프로젝트: dooglus/lightning
static void dump_tx(const char *str, const struct bitcoin_tx *tx)
{
	u8 *linear = linearize_tx(NULL, tx);
	printf("%s:%s\n", str, hex_of(linear, linear, tal_count(linear)));
	tal_free(linear);
}
예제 #12
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);
}
예제 #13
0
int main(int argc, char *argv[])
{
	const tal_t *ctx = tal_arr(NULL, char, 0);
	OpenChannel *o1, *o2;
	OpenAnchor *a;
	struct bitcoin_tx *close_tx;
	struct pkt *pkt;
	struct signature sig;
	struct privkey privkey;
	bool testnet;
	struct pubkey pubkey1, pubkey2;
	u8 *redeemscript;
	char *close_file = NULL;
	u64 close_fee = 10000;
	struct channel_state *cstate;

	err_set_progname(argv[0]);

	opt_register_arg("--complete=<close-msg-file>",
			 opt_set_charp, NULL, &close_file,
			 "Create a close_transaction_complete msg instead");
	opt_register_noarg("--help|-h", opt_usage_and_exit,
			   "<open-channel-file1> <open-channel-file2> <anchor-file> <commit-privkey> [{+/-}update-protobuf]...\n"
			   "Create the signature needed for the close transaction",
			   "Print this message.");
	opt_register_arg("--close-fee=<bits>",
			 opt_set_bits, opt_show_bits, &close_fee,
			 "100's of satoshi to pay for close tx");
	opt_register_version();

 	opt_parse(&argc, argv, opt_log_stderr_exit);

	if (argc < 5)
		opt_usage_exit_fail("Expected 4+ arguments");

	o1 = pkt_from_file(argv[1], PKT__PKT_OPEN)->open;
	o2 = pkt_from_file(argv[2], PKT__PKT_OPEN)->open;
	a = pkt_from_file(argv[3], PKT__PKT_OPEN_ANCHOR)->open_anchor;

	if (!key_from_base58(argv[4], strlen(argv[4]), &testnet, &privkey, &pubkey1))
		errx(1, "Invalid private key '%s'", argv[4]);
	if (!testnet)
		errx(1, "Private key '%s' not on testnet!", argv[4]);

	if (close_file) {
		CloseChannel *c;
		c = pkt_from_file(close_file, PKT__PKT_CLOSE)->close;
		close_fee = c->close_fee;
	}
	
	cstate = gather_updates(ctx, o1, o2, a, close_fee, argv + 5, NULL,
		       NULL, NULL, NULL);

	/* Get pubkeys */
	if (!proto_to_pubkey(o1->commit_key, &pubkey2))
		errx(1, "Invalid o1 commit pubkey");
	if (pubkey_len(&pubkey1) != pubkey_len(&pubkey2)
	    || memcmp(pubkey1.key, pubkey2.key, pubkey_len(&pubkey2)) != 0)
		errx(1, "o1 pubkey != this privkey");
	if (!proto_to_pubkey(o2->commit_key, &pubkey2))
		errx(1, "Invalid o2 commit pubkey");

	/* This is what the anchor pays to. */
	redeemscript = bitcoin_redeem_2of2(ctx, &pubkey1, &pubkey2);

	close_tx = create_close_tx(ctx, o1, o2, a, cstate->a.pay, cstate->b.pay);

	/* Sign it for them. */
	sign_tx_input(ctx, close_tx, 0, redeemscript, tal_count(redeemscript),
		      &privkey, &pubkey1, &sig);

	if (close_file)
		pkt = close_channel_complete_pkt(ctx, &sig);
	else
		pkt = close_channel_pkt(ctx, close_fee, &sig);
	if (!write_all(STDOUT_FILENO, pkt, pkt_totlen(pkt)))
		err(1, "Writing out packet");

	tal_free(ctx);
	return 0;
}
예제 #14
0
		      tal_count(peer->anchor.redeemscript),
		      &peer->secrets->commit,
		      &peer->us.commitkey,
		      sig);
}

void peer_sign_spend(const struct peer *peer,
		     struct bitcoin_tx *spend,
		     const u8 *commit_redeemscript,
		     struct signature *sig)
{
	/* Spend tx only has one input: that of the commit tx. */
	sign_tx_input(peer->dstate->secpctx,
		      spend, 0,
		      commit_redeemscript,
		      tal_count(commit_redeemscript),
		      &peer->secrets->final,
		      &peer->us.finalkey,
		      sig);
}

void peer_sign_mutual_close(const struct peer *peer,
			    struct bitcoin_tx *close,
			    struct signature *sig)
{
	sign_tx_input(peer->dstate->secpctx,
		      close, 0,
		      peer->anchor.redeemscript,
		      tal_count(peer->anchor.redeemscript),
		      &peer->secrets->commit,
		      &peer->us.commitkey,
int main(int argc, char *argv[])
{
	const tal_t *ctx = tal_arr(NULL, char, 0);
	struct sha256 seed, our_rhash, their_rhash, preimage;
	OpenChannel *o1, *o2;
	OpenAnchor *a;
	struct pkt *pkt;
	struct bitcoin_tx *commit;
	struct pubkey pubkey1, pubkey2;
	size_t num_updates;
	struct bitcoin_signature sig;
	u8 *redeemscript;
	struct channel_state *cstate;

	err_set_progname(argv[0]);

	opt_register_noarg("--help|-h", opt_usage_and_exit,
			   "<seed> <open-channel-file1> <open-channel-file2> <open-anchor-file> <all-previous-updates>\n"
			   "Create a new update-complete message",
			   "Print this message.");
	opt_register_version();

 	opt_parse(&argc, argv, opt_log_stderr_exit);

	if (argc < 7)
		opt_usage_exit_fail("Expected 6+ arguments");

	if (!hex_decode(argv[1], strlen(argv[1]), &seed, sizeof(seed)))
		errx(1, "Invalid seed '%s' - need 256 hex bits", argv[1]);

	o1 = pkt_from_file(argv[2], PKT__PKT_OPEN)->open;
	o2 = pkt_from_file(argv[3], PKT__PKT_OPEN)->open;
	a = pkt_from_file(argv[4], PKT__PKT_OPEN_ANCHOR)->open_anchor;

	sig.stype = SIGHASH_ALL;

	/* This also checks that preimage is correct! */
	cstate = gather_updates(ctx, o1, o2, a, commit_fee(o1, o2), argv + 5,
				&num_updates,
				&our_rhash, &their_rhash, &sig.sig);
	if (num_updates < 1)
		errx(1, "Expected at least one update!");

	/* Get pubkeys */
	if (!proto_to_pubkey(o1->commit_key, &pubkey1))
		errx(1, "Invalid o1 commit pubkey");
	if (!proto_to_pubkey(o2->commit_key, &pubkey2))
		errx(1, "Invalid o2 commit pubkey");

	/* This is what the anchor pays to. */
	redeemscript = bitcoin_redeem_2of2(ctx, &pubkey1, &pubkey2);

	/* Check their signature signs our new commit tx correctly. */
	commit = create_commit_tx(ctx, o1, o2, a, &our_rhash, cstate);
	if (!commit)
		errx(1, "Delta too large");

	if (!check_tx_sig(commit, 0, redeemscript, tal_count(redeemscript),
			  &pubkey2, &sig))
		errx(1, "Invalid signature.");
	
	/* Hand over our preimage for previous tx. */
	shachain_from_seed(&seed, num_updates - 1, &preimage);
	pkt = update_complete_pkt(ctx, &preimage);
	if (!write_all(STDOUT_FILENO, pkt, pkt_totlen(pkt)))
		err(1, "Writing out packet");

	tal_free(ctx);
	return 0;
}
예제 #16
0
int main(int argc, char *argv[])
{
	size_t i, j, num;
	struct timeabs start, stop;
	char **w;
	ENTRY *words, *misswords;

	w = tal_strsplit(NULL, grab_file(NULL,
					 argv[1] ? argv[1] : "/usr/share/dict/words"), "\n", STR_NO_EMPTY);
	num = tal_count(w) - 1;
	printf("%zu words\n", num);

	hcreate(num+num/3);

	words = tal_arr(w, ENTRY, num);
	for (i = 0; i < num; i++) {
		words[i].key = w[i];
		words[i].data = words[i].key;
	}

	/* Append and prepend last char for miss testing. */
	misswords = tal_arr(w, ENTRY, num);
	for (i = 0; i < num; i++) {
		char lastc;
		if (strlen(w[i]))
			lastc = w[i][strlen(w[i])-1];
		else
			lastc = 'z';
		misswords[i].key = tal_fmt(misswords, "%c%s%c%c",
					   lastc, w[i], lastc, lastc);
	}

	printf("#01: Initial insert: ");
	fflush(stdout);
	start = time_now();
	for (i = 0; i < num; i++)
		hsearch(words[i], ENTER);
	stop = time_now();
	printf(" %zu ns\n", normalize(&start, &stop, num));

	printf("#02: Initial lookup (match): ");
	fflush(stdout);
	start = time_now();
	for (i = 0; i < num; i++)
		if (hsearch(words[i], FIND)->data != words[i].data)
			abort();
	stop = time_now();
	printf(" %zu ns\n", normalize(&start, &stop, num));

	printf("#03: Initial lookup (miss): ");
	fflush(stdout);
	start = time_now();
	for (i = 0; i < num; i++) {
		if (hsearch(misswords[i], FIND))
			abort();
	}
	stop = time_now();
	printf(" %zu ns\n", normalize(&start, &stop, num));

	/* Lookups in order are very cache-friendly for judy; try random */
	printf("#04: Initial lookup (random): ");
	fflush(stdout);
	start = time_now();
	for (i = 0, j = 0; i < num; i++, j = (j + 10007) % num)
		if (hsearch(words[i], FIND)->data != words[i].data)
			abort();
	stop = time_now();
	printf(" %zu ns\n", normalize(&start, &stop, num));

	return 0;
}
예제 #17
0
int main(int argc, char *argv[])
{
	struct state *s;
	struct working_block *w;
	unsigned int i;
	union protocol_tx *t;
	struct protocol_gateway_payment payment;
	struct block *prev, *b;
	struct block_shard *shard;
	u8 *prev_txhashes;
	enum protocol_ecode e;
	struct gen_update update;
	struct protocol_input_ref *refs;
	struct protocol_block_id sha;
	struct protocol_block_id prevs[PROTOCOL_NUM_PREV_IDS];

	/* We need enough of state to use the real init function here. */
	pseudorand_init();
	s = new_state(true);
	check_chains(s, true);

	fake_time = le32_to_cpu(genesis_tlr.timestamp) + 1;

	/* Create a block after that, with a gateway tx in it. */
	prev_txhashes = make_prev_txhashes(s, &genesis, helper_addr(1));

	/* We should need 1 prev_merkle per shard per block. */
	assert(num_prev_txhashes(&genesis) == (1 << genesis.bi.hdr->shard_order));
	assert(tal_count(prev_txhashes) == num_prev_txhashes(&genesis));

	memset(prevs, 0, sizeof(prevs));
	prevs[0] = genesis.sha;
	w = new_working_block(s, 0x1ffffff0,
			      prev_txhashes, tal_count(prev_txhashes),
			      block_height(&genesis.bi) + 1,
			      next_shard_order(&genesis),
			      prevs, helper_addr(1));

	payment.send_amount = cpu_to_le32(1000);
	payment.output_addr = *helper_addr(0);
	t = create_from_gateway_tx(s, helper_gateway_public_key(),
				   1, &payment, false, helper_gateway_key(s));
	/* Gateway txs have empty refs, so this gives 0-len array. */
	refs = create_refs(s, &genesis, t, 1);

	update.shard = shard_of_tx(t, next_shard_order(&genesis));
	update.txoff = 0;
	update.features = 0;
	update.unused = 0;
	hash_tx_and_refs(t, refs, &update.hashes);
	assert(add_tx(w, &update));
	for (i = 0; !solve_block(w); i++);

	e = check_block_header(s, &w->bi, &prev, &sha.sha);
	assert(e == PROTOCOL_ECODE_NONE);
	assert(prev == &genesis);

	b = block_add(s, prev, &sha, &w->bi);

	/* This is a NOOP, so should succeed. */
	assert(check_prev_txhashes(s, b, NULL, NULL));

	/* Put the single tx into the shard. */
	shard = new_block_shard(s, update.shard, 1);
	shard->txcount = 1;
	shard->u[0].txp = txptr_with_ref(shard, t, refs);

	/* This should all be correct. */
	check_block_shard(s, b, shard);
	b->shard[shard->shardnum] = shard;

	/* Should require a prev_merkle per shard for each of 2 prev blocks. */
	assert(num_prev_txhashes(b) == (2 << genesis.bi.hdr->shard_order));
	prev_txhashes = make_prev_txhashes(s, b, helper_addr(1));
	assert(tal_count(prev_txhashes) == num_prev_txhashes(b));

	/* Solve third block. */
	fake_time++;
	prevs[0] = b->sha;
	prevs[1] = genesis.sha;
	w = new_working_block(s, 0x1ffffff0, prev_txhashes, num_prev_txhashes(b),
			      block_height(&b->bi) + 1,
			      next_shard_order(b),
			      prevs, helper_addr(1));
	for (i = 0; !solve_block(w); i++);

	e = check_block_header(s, &w->bi, &prev, &sha.sha);
	assert(e == PROTOCOL_ECODE_NONE);
	assert(prev == b);

	b = block_add(s, prev, &sha, &w->bi);

	/* This should be correct. */
	assert(check_prev_txhashes(s, b, NULL, NULL));

	tal_free(s);
	return 0;
}
예제 #18
0
파일: script.c 프로젝트: rvaughan/lightning
static void add(u8 **scriptp, const void *mem, size_t len)
{
	size_t oldlen = tal_count(*scriptp);
	tal_resize(scriptp, oldlen + len);
	memcpy(*scriptp + oldlen, mem, len);
}
예제 #19
0
int main(int argc, char *argv[])
{
	const tal_t *ctx = tal_arr(NULL, char, 0);
	OpenChannel *o1, *o2;
	OpenAnchor *a;
	struct bitcoin_tx *close_tx;
	struct bitcoin_signature sig1, sig2;
	struct pubkey pubkey1, pubkey2;
	u8 *redeemscript;
	CloseChannel *close;
	CloseChannelComplete *closecomplete;
	struct channel_state *cstate;

	err_set_progname(argv[0]);

	/* FIXME: Take update.pbs to adjust channel */
	opt_register_noarg("--help|-h", opt_usage_and_exit,
			   "<open-channel-file1> <open-channel-file2> <open-anchor-file> <close-protobuf> <close-complete-protobuf> [update-protobuf]...\n"
			   "Create the close transaction from the signatures",
			   "Print this message.");
	opt_register_version();

 	opt_parse(&argc, argv, opt_log_stderr_exit);

	if (argc < 6)
		opt_usage_exit_fail("Expected 5+ arguments");

	o1 = pkt_from_file(argv[1], PKT__PKT_OPEN)->open;
	o2 = pkt_from_file(argv[2], PKT__PKT_OPEN)->open;
	a = pkt_from_file(argv[3], PKT__PKT_OPEN_ANCHOR)->open_anchor;
	close = pkt_from_file(argv[4], PKT__PKT_CLOSE)->close;
	closecomplete = pkt_from_file(argv[5], PKT__PKT_CLOSE_COMPLETE)->close_complete;

	/* Pubkeys well-formed? */
	if (!proto_to_pubkey(o1->commit_key, &pubkey1))
		errx(1, "Invalid o1 commit_key");
	if (!proto_to_pubkey(o2->commit_key, &pubkey2))
		errx(1, "Invalid o2 commit_key");
	
	/* Get delta by accumulting all the updates. */
	cstate = gather_updates(ctx, o1, o2, a, close->close_fee, argv + 6,
				NULL, NULL, NULL, NULL);

	/* This is what the anchor pays to; figure out which output. */
	redeemscript = bitcoin_redeem_2of2(ctx, &pubkey1, &pubkey2);

	/* Now create the close tx to spend 2/2 output of anchor. */
	close_tx = create_close_tx(ctx, o1, o2, a,
				   cstate->a.pay_msat / 1000,
				   cstate->b.pay_msat / 1000);

	/* Signatures well-formed? */
	sig1.stype = sig2.stype = SIGHASH_ALL;
	if (!proto_to_signature(close->sig, &sig1.sig))
		errx(1, "Invalid close-packet");
	if (!proto_to_signature(closecomplete->sig, &sig2.sig))
		errx(1, "Invalid closecomplete-packet");

	/* Combined signatures must validate correctly. */
	if (!check_2of2_sig(close_tx, 0, redeemscript, tal_count(redeemscript),
			    &pubkey1, &pubkey2, &sig1, &sig2))
		errx(1, "Signature failed");

	/* Create p2sh input for close_tx */
	close_tx->input[0].script = scriptsig_p2sh_2of2(close_tx, &sig1, &sig2,
						      &pubkey1, &pubkey2);
	close_tx->input[0].script_length = tal_count(close_tx->input[0].script);

	/* Print it out in hex. */
	if (!bitcoin_tx_write(STDOUT_FILENO, close_tx))
		err(1, "Writing out transaction");

	tal_free(ctx);
	return 0;
}
예제 #20
0
/* Simple test code to create a gateway transaction */
int main(int argc, char *argv[])
{
	int fd, i, off;
	const char *method;
	char *cmd, *resp, *idstr, *rpc_filename;
	struct sockaddr_un addr;
	jsmntok_t *toks;
	const jsmntok_t *result, *error, *id;
	char *pettycoin_dir;
	const tal_t *ctx = tal(NULL, char);

	err_set_progname(argv[0]);

	opt_set_alloc(opt_allocfn, tal_reallocfn, tal_freefn);
	pettycoin_dir_register_opts(ctx, &pettycoin_dir, &rpc_filename);

	opt_register_noarg("--help|-h", opt_usage_and_exit,
			   "<command> [<params>...]", "Show this message");
	opt_register_noarg("--version|-V", opt_version_and_exit, VERSION,
			   "Display version and exit");

	opt_early_parse(argc, argv, opt_log_stderr_exit);
	opt_parse(&argc, argv, opt_log_stderr_exit);

	method = argv[1];
	if (!method)
		errx(ERROR_USAGE, "Need at least one argument\n%s",
		     opt_usage(argv[0], NULL));

	if (chdir(pettycoin_dir) != 0)
		err(ERROR_TALKING_TO_PETTYCOIN, "Moving into '%s'",
		    pettycoin_dir);

	fd = socket(AF_UNIX, SOCK_STREAM, 0);
	if (strlen(rpc_filename) + 1 > sizeof(addr.sun_path))
		errx(ERROR_USAGE, "rpc filename '%s' too long", rpc_filename);
	strcpy(addr.sun_path, rpc_filename);
	addr.sun_family = AF_UNIX;

	if (connect(fd, (struct sockaddr *)&addr, sizeof(addr)) != 0)
		err(ERROR_TALKING_TO_PETTYCOIN,
		    "Connecting to '%s'", rpc_filename);

	idstr = tal_fmt(ctx, "pettycoin_query-%i", getpid());
	cmd = tal_fmt(ctx,
		      "{ \"method\" : \"%s\", \"id\" : \"%s\", \"params\" : [ ",
		      method, idstr);

	for (i = 2; i < argc; i++) {
		/* Numbers are left unquoted, and quoted things left alone. */
		if (strspn(argv[i], "0123456789") == strlen(argv[i])
		    || argv[i][0] == '"')
			tal_append_fmt(&cmd, "%s", argv[i]);
		else
			tal_append_fmt(&cmd, "\"%s\"", argv[i]);
		if (i != argc - 1)
			tal_append_fmt(&cmd, ", ");
	}
	tal_append_fmt(&cmd, "] }");

	if (!write_all(fd, cmd, strlen(cmd)))
		err(ERROR_TALKING_TO_PETTYCOIN, "Writing command");

	resp = tal_arr(cmd, char, 100);
	off = 0;
	while ((i = read(fd, resp + off, tal_count(resp) - 1 - off)) > 0) {
		bool valid;
		off += i;
		if (off == tal_count(resp) - 1)
			tal_resize(&resp, tal_count(resp) * 2);

		toks = json_parse_input(resp, off, &valid);
		if (toks)
			break;
		if (!valid)
			errx(ERROR_TALKING_TO_PETTYCOIN,
			     "Malformed response '%.*s'", off, resp);
	}
	resp[off] = '\0';
	if (i < 0)
		err(ERROR_TALKING_TO_PETTYCOIN, "reading response");

	result = json_get_member(resp, toks, "result");
	if (!result)
		errx(ERROR_TALKING_TO_PETTYCOIN,
		     "Missing 'result' in response '%s'", resp);
	error = json_get_member(resp, toks, "error");
	if (!error)
		errx(ERROR_TALKING_TO_PETTYCOIN,
		     "Missing 'error' in response '%s'", resp);
	id = json_get_member(resp, toks, "id");
	if (!id)
		errx(ERROR_TALKING_TO_PETTYCOIN,
		     "Missing 'id' in response '%s'", resp);
	if (!json_tok_streq(resp, id, idstr))
		errx(ERROR_TALKING_TO_PETTYCOIN,
		     "Incorrect 'id' in response: %.*s",
		     json_tok_len(id), json_tok_contents(resp, id));

	if (json_tok_is_null(resp, error)) {
		printf("%.*s\n",
		       json_tok_len(result),
		       json_tok_contents(resp, result));
		tal_free(ctx);
		return 0;
	}

	printf("%.*s\n",
	       json_tok_len(error), json_tok_contents(resp, error));
	tal_free(ctx);
	return 1;
}
예제 #21
0
int main(int argc, char *argv[])
{
	const tal_t *ctx = tal_arr(NULL, char, 0);
	struct sha256 seed, preimage, our_rhash, their_rhash;
	OpenChannel *o1, *o2;
	OpenAnchor *a;
	struct bitcoin_tx *commit;
	struct pkt *pkt;
	struct bitcoin_signature sig;
	struct privkey privkey;
	bool testnet;
	struct pubkey pubkey1, pubkey2;
	u8 *redeemscript;
	size_t num_updates;
	struct channel_state *cstate;

	err_set_progname(argv[0]);

	opt_register_noarg("--help|-h", opt_usage_and_exit,
			   "<seed> <open-channel-file1> <open-channel-file2> <open-anchor-file> <commit-privkey> <all-previous-updates>...\n"
			   "Create a new update-channel-signature message",
			   "Print this message.");
	opt_register_version();

 	opt_parse(&argc, argv, opt_log_stderr_exit);

	if (argc < 8)
		opt_usage_exit_fail("Expected 7+ arguments");

	if (!hex_decode(argv[1], strlen(argv[1]), &seed, sizeof(seed)))
		errx(1, "Invalid seed '%s' - need 256 hex bits", argv[1]);

	o1 = pkt_from_file(argv[2], PKT__PKT_OPEN)->open;
	o2 = pkt_from_file(argv[3], PKT__PKT_OPEN)->open;
	a = pkt_from_file(argv[4], PKT__PKT_OPEN_ANCHOR)->open_anchor;

	if (!key_from_base58(argv[5], strlen(argv[5]), &testnet, &privkey, &pubkey1))
		errx(1, "Invalid private key '%s'", argv[5]);
	if (!testnet)
		errx(1, "Private key '%s' not on testnet!", argv[5]);

	sig.stype = SIGHASH_ALL;

	/* Figure out cumulative delta since anchor. */
	cstate = gather_updates(ctx, o1, o2, a, commit_fee(o1, o2), argv + 6,
				&num_updates,
				&our_rhash, &their_rhash, &sig.sig);
	if (num_updates < 1)
		errx(1, "Expected at least one update!");

	/* Give up revocation preimage for old tx. */
	shachain_from_seed(&seed, num_updates - 1, &preimage);
	
	/* Get pubkeys */
	if (!proto_to_pubkey(o1->commit_key, &pubkey2))
		errx(1, "Invalid o1 commit pubkey");
	if (!pubkey_eq(&pubkey1, &pubkey2))
		errx(1, "o1 pubkey != this privkey");
	if (!proto_to_pubkey(o2->commit_key, &pubkey2))
		errx(1, "Invalid o2 commit pubkey");

	/* This is what the anchor pays to. */
	redeemscript = bitcoin_redeem_2of2(ctx, &pubkey1, &pubkey2);

	/* Check our new commit is signed correctly by them. */
	commit = create_commit_tx(ctx, o1, o2, a, &our_rhash, cstate);
	if (!commit)
		errx(1, "Invalid packets");

	/* Check their signature signs this input correctly. */
	if (!check_tx_sig(commit, 0, redeemscript, tal_count(redeemscript),
			  &pubkey2, &sig))
		errx(1, "Invalid signature.");

	/* Now create THEIR new commitment tx to spend 2/2 output of anchor. */
	invert_cstate(cstate);
	commit = create_commit_tx(ctx, o2, o1, a, &their_rhash, cstate);
	if (!commit)
		errx(1, "Invalid packets");

	/* Their pubkey must be valid */
	if (!proto_to_pubkey(o2->commit_key, &pubkey2))
		errx(1, "Invalid public open-channel-file2");

	/* Sign it for them. */
	sign_tx_input(ctx, commit, 0, redeemscript, tal_count(redeemscript),
		      &privkey, &pubkey1, &sig.sig);

	pkt = update_signature_pkt(ctx, &sig.sig, &preimage);
	if (!write_all(STDOUT_FILENO, pkt, pkt_totlen(pkt)))
		err(1, "Writing out packet");

	tal_free(ctx);
	return 0;
}
예제 #22
0
int main(void)
{
	char *parent, *c;

	plan_tests(43);

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

	c = tal_strdup(parent, "hello");
	ok1(strcmp(c, "hello") == 0);
	ok1(tal_parent(c) == parent);
	ok1(tal_count(c) == strlen(c) + 1);
	tal_free(c);

	c = tal_strndup(parent, "hello", 3);
	ok1(strcmp(c, "hel") == 0);
	ok1(tal_parent(c) == parent);
	ok1(tal_count(c) == strlen(c) + 1);
	tal_free(c);

#ifdef TAL_USE_TALLOC
	c = tal_talloc_typechk_(parent, char *);
#else
	c = tal_typechk_(parent, char *);
#endif
	c = tal_dup_arr(parent, char, "hello", 6, 0);
	ok1(strcmp(c, "hello") == 0);
	ok1(strcmp(tal_name(c), "char[]") == 0);
	ok1(tal_count(c) == 6);
	ok1(tal_parent(c) == parent);
	tal_free(c);

	/* Now with an extra byte. */
	c = tal_dup_arr(parent, char, "hello", 6, 1);
	ok1(strcmp(c, "hello") == 0);
	ok1(strcmp(tal_name(c), "char[]") == 0);
	ok1(tal_count(c) == 7);
	ok1(tal_parent(c) == parent);
	strcat(c, "x");
	tal_free(c);

	c = tal_fmt(parent, "hello %s", "there");
	ok1(strcmp(c, "hello there") == 0);
	ok1(tal_count(c) == strlen(c) + 1);
	ok1(tal_parent(c) == parent);
	tal_free(c);

	c = tal_strcat(parent, "hello ", "there");
	ok1(strcmp(c, "hello there") == 0);
	ok1(tal_count(c) == strlen(c) + 1);
	ok1(tal_parent(c) == parent);

	/* Make sure take works correctly. */
	c = tal_strcat(parent, take(c), " again");
	ok1(strcmp(c, "hello there again") == 0);
	ok1(tal_count(c) == strlen(c) + 1);
	ok1(tal_parent(c) == parent);
	ok1(single_child(parent, c));

	c = tal_strcat(parent, "And ", take(c));
	ok1(tal_count(c) == strlen(c) + 1);
	ok1(strcmp(c, "And hello there again") == 0);
	ok1(tal_parent(c) == parent);
	ok1(single_child(parent, c));

	/* NULL pass through works... */
	c = tal_strcat(parent, take(NULL), take(c));
	ok1(!c);
	ok1(no_children(parent));

	c = tal_strcat(parent, take(tal_strdup(parent, "hi")),
		       take(NULL));
	ok1(!c);
	ok1(no_children(parent));

	c = tal_strcat(parent, take(NULL), take(NULL));
	ok1(!c);
	ok1(no_children(parent));

	/* Appending formatted strings. */
	c = tal_strdup(parent, "hi");
	ok1(tal_count(c) == strlen(c) + 1);
	ok1(tal_append_fmt(&c, "%s %s", "there", "world"));
	ok1(strcmp(c, "hithere world") == 0);
	ok1(tal_count(c) == strlen(c) + 1);
	ok1(tal_parent(c) == parent);

	ok1(!tal_append_fmt(&c, take(NULL), "there", "world"));
	ok1(strcmp(c, "hithere world") == 0);
	ok1(tal_count(c) == strlen(c) + 1);

	tal_free(parent);

	return exit_status();
}
예제 #23
0
int main(int argc, char *argv[])
{
	const tal_t *ctx = tal_arr(NULL, char, 0);
	OpenChannel *o1, *o2;
	OpenAnchor *a;
	struct bitcoin_tx *commit, *tx;
	struct bitcoin_signature sig;
	struct privkey privkey;
	bool testnet;
	struct pubkey pubkey1, pubkey2, outpubkey;
	u8 *redeemscript;
	struct sha256 rhash;
	size_t p2sh_out;
	u64 fee = 10000;
	u32 locktime;

	err_set_progname(argv[0]);

	/* FIXME: If we've updated channel since, we need the final
	 * revocation hash we sent (either update_accept or update_complete) */
	opt_register_noarg("--help|-h", opt_usage_and_exit,
			   "<commitment-tx> <open-channel-file1> <open-channel-file2> <open-anchor-file> <my-privoutkey> <someaddress> [previous-updates]\n"
			   "Create the transaction to spend our commit transaction",
			   "Print this message.");
	opt_register_arg("--fee=<bits>",
			 opt_set_bits, opt_show_bits, &fee,
			 "100's of satoshi to pay in transaction fee");
	opt_register_version();

 	opt_parse(&argc, argv, opt_log_stderr_exit);

	if (argc < 6)
		opt_usage_exit_fail("Expected 5+ arguments");

	commit = bitcoin_tx_from_file(ctx, argv[1]);

	o1 = pkt_from_file(argv[2], PKT__PKT_OPEN)->open;
	o2 = pkt_from_file(argv[3], PKT__PKT_OPEN)->open;
	a = pkt_from_file(argv[4], PKT__PKT_OPEN_ANCHOR)->open_anchor;
	if (!proto_to_rel_locktime(o2->delay, &locktime))
		errx(1, "Invalid locktime in o2");

 	/* We need our private key to spend commit output. */
	if (!key_from_base58(argv[5], strlen(argv[5]), &testnet, &privkey, &pubkey1))
		errx(1, "Invalid private key '%s'", argv[5]);
	if (!testnet)
		errx(1, "Private key '%s' not on testnet!", argv[5]);

	if (!pubkey_from_hexstr(argv[6], &outpubkey))
		errx(1, "Invalid bitcoin pubkey '%s'", argv[6]);

	/* Get pubkeys */
	if (!proto_to_pubkey(o1->final_key, &pubkey2))
		errx(1, "Invalid o1 final pubkey");
	if (!pubkey_eq(&pubkey1, &pubkey2))
		errx(1, "o1 pubkey != this privkey");
	if (!proto_to_pubkey(o2->final_key, &pubkey2))
		errx(1, "Invalid o2 final pubkey");

	/* We use this simply to get final revocation hash. */
	gather_updates(ctx, o1, o2, a, commit_fee(o1, o2), argv + 7,
		       NULL, &rhash, NULL, NULL);

	/* Create redeem script */
	redeemscript = bitcoin_redeem_secret_or_delay(ctx, &pubkey1, locktime,
						      &pubkey2, &rhash);

	/* Now, create transaction to spend it. */
	tx = bitcoin_tx(ctx, 1, 1);
	bitcoin_txid(commit, &tx->input[0].txid);
	p2sh_out = find_p2sh_out(commit, redeemscript);
	tx->input[0].index = p2sh_out;
	tx->input[0].input_amount = commit->output[p2sh_out].amount;
	tx->fee = fee;

	tx->input[0].sequence_number = bitcoin_nsequence(locktime);

	if (commit->output[p2sh_out].amount <= fee)
		errx(1, "Amount of %llu won't exceed fee",
		     (unsigned long long)commit->output[p2sh_out].amount);

	tx->output[0].amount = commit->output[p2sh_out].amount - fee;
	tx->output[0].script = scriptpubkey_p2sh(tx,
						 bitcoin_redeem_single(tx, &outpubkey));
	tx->output[0].script_length = tal_count(tx->output[0].script);

	/* Now get signature, to set up input script. */
	if (!sign_tx_input(tx, tx, 0, redeemscript, tal_count(redeemscript),
			   &privkey, &pubkey1, &sig.sig))
		errx(1, "Could not sign tx");
	sig.stype = SIGHASH_ALL;
	tx->input[0].script = scriptsig_p2sh_secret(tx, NULL, 0, &sig,
						    redeemscript,
						    tal_count(redeemscript));
	tx->input[0].script_length = tal_count(tx->input[0].script);

	/* Print it out in hex. */
	if (!bitcoin_tx_write(STDOUT_FILENO, tx))
		err(1, "Writing out transaction");

	tal_free(ctx);
	return 0;
}
예제 #24
0
/* Takes complete update history, gets summary of last state. */
struct channel_state *gather_updates(const tal_t *ctx,
                                     const OpenChannel *o1, const OpenChannel *o2,
                                     const OpenAnchor *oa, uint64_t fee,
                                     char **argv,
                                     size_t *num_updates,
                                     struct sha256 *our_rhash,
                                     struct sha256 *their_rhash,
                                     struct signature *their_commit_sig)
{
    Signature *sig = NULL;
    struct sha256 old_our_rhash, old_their_rhash, rhash1, rhash2;
    struct channel_state *cstate;

    /* Start sanity check. */
    cstate = initial_funding(NULL, o1, o2, oa, fee);
    if (!cstate)
        errx(1, "Invalid open combination (need 1 anchor offer)");

    /* If they don't want these, use dummy ones. */
    if (!our_rhash)
        our_rhash = &rhash1;

    if (!their_rhash)
        their_rhash = &rhash2;

    proto_to_sha256(o1->revocation_hash, our_rhash);
    proto_to_sha256(o2->revocation_hash, their_rhash);

    assert(tal_count(cstate->a.htlcs) == 0);
    assert(tal_count(cstate->b.htlcs) == 0);

    /* If o2 sent anchor, it contains their commit sig. */
    if (o2->anch == OPEN_CHANNEL__ANCHOR_OFFER__WILL_CREATE_ANCHOR)
        sig = oa->commit_sig;

    if (num_updates)
        *num_updates = 0;
    while (*argv) {
        int64_t delta, amount;
        size_t n;
        bool received;
        Pkt *pkt;

        /* + marks messages sent by us, - for messages from them */
        if (strstarts(*argv, "+")) {
            received = false;
        } else if (strstarts(*argv, "-")) {
            received = true;
        } else
            errx(1, "%s does not start with +/-", *argv);

        pkt = any_pkt_from_file(*argv + 1);
        switch (pkt->pkt_case) {
        case PKT__PKT_OPEN_COMMIT_SIG:
            if (received)
                sig = pkt->open_commit_sig->sig;
            break;
        case PKT__PKT_UPDATE_ADD_HTLC:
            amount = pkt->update_add_htlc->amount_msat;
            if (received) {
                if (!funding_delta(o2, o1, oa, 0, amount,
                                   &cstate->b, &cstate->a))
                    errx(1, "Impossible htlc %llu %s",
                         (long long)amount, *argv);
                add_htlc(&cstate->b, pkt->update_add_htlc,
                         *argv);
            } else {
                if (!funding_delta(o1, o2, oa, 0, amount,
                                   &cstate->a, &cstate->b))
                    errx(1, "Impossible htlc %llu %s",
                         (long long)amount, *argv);
                add_htlc(&cstate->a, pkt->update_add_htlc,
                         *argv);
            }

            update_rhash(pkt->update_add_htlc->revocation_hash,
                         received, num_updates,
                         &old_our_rhash, &old_their_rhash,
                         our_rhash, their_rhash);
            break;

        case PKT__PKT_UPDATE_TIMEDOUT_HTLC:
            if (received) {
                n = find_htlc(&cstate->b,
                              pkt->update_timedout_htlc->r_hash);
                if (n == tal_count(cstate->b.htlcs))
                    errx(1, "Unknown R hash in %s", *argv);
                amount = cstate->b.htlcs[n]->amount_msat;
                if (!funding_delta(o2, o1, oa, 0, -amount,
                                   &cstate->b, &cstate->a))
                    errx(1, "Impossible htlc %llu %s",
                         (long long)amount, *argv);
                remove_htlc(&cstate->b, n);
            } else {
                n = find_htlc(&cstate->a,
                              pkt->update_timedout_htlc->r_hash);
                if (n == tal_count(cstate->a.htlcs))
                    errx(1, "Unknown R hash in %s", *argv);
                amount = cstate->a.htlcs[n]->amount_msat;
                if (!funding_delta(o1, o2, oa, 0, -amount,
                                   &cstate->a, &cstate->b))
                    errx(1, "Impossible htlc %llu %s",
                         (long long)amount, *argv);
                remove_htlc(&cstate->a, n);
            }
            update_rhash(pkt->update_timedout_htlc->revocation_hash,
                         received, num_updates,
                         &old_our_rhash, &old_their_rhash,
                         our_rhash, their_rhash);
            break;

        /* HTLC acceptor sends this to initiator. */
        case PKT__PKT_UPDATE_ROUTEFAIL_HTLC:
            if (received) {
                n = find_htlc(&cstate->a,
                              pkt->update_routefail_htlc->r_hash);
                if (n == tal_count(cstate->a.htlcs))
                    errx(1, "Unknown R hash in %s", *argv);
                amount = cstate->a.htlcs[n]->amount_msat;
                if (!funding_delta(o1, o2, oa, 0, -amount,
                                   &cstate->a, &cstate->b))
                    errx(1, "Impossible htlc %llu %s",
                         (long long)amount, *argv);
                remove_htlc(&cstate->a, n);
            } else {
                n = find_htlc(&cstate->b,
                              pkt->update_routefail_htlc->r_hash);
                if (n == tal_count(cstate->b.htlcs))
                    errx(1, "Unknown R hash in %s", *argv);
                amount = cstate->b.htlcs[n]->amount_msat;
                if (!funding_delta(o2, o1, oa, 0, -amount,
                                   &cstate->b, &cstate->a))
                    errx(1, "Impossible htlc %llu %s",
                         (long long)amount, *argv);
                remove_htlc(&cstate->b, n);
            }
            update_rhash(pkt->update_routefail_htlc->revocation_hash,
                         received, num_updates,
                         &old_our_rhash, &old_their_rhash,
                         our_rhash, their_rhash);
            break;

        case PKT__PKT_UPDATE_FULFILL_HTLC: {
            struct sha256 r_hash, r_val;
            Sha256Hash *rh;

            /* Get hash, to find the HTLC. */
            proto_to_sha256(pkt->update_fulfill_htlc->r, &r_val);
            sha256(&r_hash, &r_val, sizeof(r_val));
            rh = sha256_to_proto(ctx, &r_hash);

            if (received) {
                /* HTLC was us->them, funds go to them. */
                n = find_htlc(&cstate->a, rh);
                if (n == tal_count(cstate->a.htlcs))
                    errx(1, "Unknown R hash in %s", *argv);
                amount = cstate->a.htlcs[n]->amount_msat;
                if (!funding_delta(o1, o2, oa, amount, -amount,
                                   &cstate->a, &cstate->b))
                    errx(1, "Impossible htlc %llu %s",
                         (long long)amount, *argv);
                remove_htlc(&cstate->a, n);
            } else {
                /* HTLC was them->us, funds go to us. */
                n = find_htlc(&cstate->b, rh);
                if (n == tal_count(cstate->b.htlcs))
                    errx(1, "Unknown R hash in %s", *argv);
                amount = cstate->b.htlcs[n]->amount_msat;
                if (!funding_delta(o2, o1, oa, amount, -amount,
                                   &cstate->b, &cstate->a))
                    errx(1, "Impossible htlc %llu %s",
                         (long long)amount, *argv);
                remove_htlc(&cstate->b, n);
            }
            update_rhash(pkt->update_fulfill_htlc->revocation_hash,
                         received, num_updates,
                         &old_our_rhash, &old_their_rhash,
                         our_rhash, their_rhash);
            break;
        }

        case PKT__PKT_UPDATE:
            if (received)
                delta = -pkt->update->delta_msat;
            else
                delta = pkt->update->delta_msat;
            if (!funding_delta(o1, o2, oa, delta, 0,
                               &cstate->a, &cstate->b))
                errx(1, "Impossible funding update %lli %s",
                     (long long)delta, *argv);

            update_rhash(pkt->update->revocation_hash,
                         received, num_updates,
                         &old_our_rhash, &old_their_rhash,
                         our_rhash, their_rhash);
            break;
        case PKT__PKT_UPDATE_ACCEPT:
            if (received)
                sig = pkt->update_accept->sig;

            /* Does not increase num_updates */
            update_rhash(pkt->update_accept->revocation_hash,
                         received, NULL,
                         &old_our_rhash, &old_their_rhash,
                         our_rhash, their_rhash);
            break;
        case PKT__PKT_UPDATE_SIGNATURE:
            if (received) {
                sig = pkt->update_signature->sig;
                check_preimage(pkt->update_signature
                               ->revocation_preimage,
                               &old_their_rhash, their_rhash,
                               *argv);
            } else {
                check_preimage(pkt->update_signature
                               ->revocation_preimage,
                               &old_our_rhash, our_rhash,
                               *argv);
            }
            break;
        case PKT__PKT_UPDATE_COMPLETE:
            if (received) {
                check_preimage(pkt->update_complete
                               ->revocation_preimage,
                               &old_their_rhash, their_rhash,
                               *argv);
            } else {
                check_preimage(pkt->update_complete
                               ->revocation_preimage,
                               &old_our_rhash, our_rhash,
                               *argv);
            }
            break;
        default:
            errx(1, "Unexpected packet type %u", pkt->pkt_case);
        }
        argv++;
    }

    if (their_commit_sig) {
        if (!sig)
            errx(1, "No commit signature message found");
        if (!proto_to_signature(sig, their_commit_sig))
            errx(1, "Invalid signature");
    }

    return cstate;
}
예제 #25
0
static struct io_plan *write_done(struct io_conn *conn, struct data *d)
{
	tal_resize(&d->pattern, tal_count(d->pattern) + 1);
	strcat(d->pattern, ">");
	return write_more(conn, d);
}
예제 #26
0
#include <assert.h>
#include <ccan/endian/endian.h>
#include <ccan/read_write_all/read_write_all.h>
#include <errno.h>
#include <wire/wire_io.h>
#include <wire/wire_sync.h>

bool wire_sync_write(int fd, const void *msg TAKES)
{
	wire_len_t hdr = cpu_to_wirelen(tal_bytelen(msg));
	bool ret;

	assert(tal_bytelen(msg) < WIRE_LEN_LIMIT);
	ret = write_all(fd, &hdr, sizeof(hdr))
		&& write_all(fd, msg, tal_count(msg));

	if (taken(msg))
		tal_free(msg);
	return ret;
}

u8 *wire_sync_read(const tal_t *ctx, int fd)
{
	wire_len_t len;
	u8 *msg;

	if (!read_all(fd, &len, sizeof(len)))
		return NULL;
	if (wirelen_to_cpu(len) >= WIRE_LEN_LIMIT) {
		errno = E2BIG;
		return NULL;