예제 #1
0
static void parse_request(struct json_connection *jcon, const jsmntok_t tok[])
{
	const jsmntok_t *method, *id, *params;
	const struct json_command *cmd;

	assert(!jcon->current);
	if (tok[0].type != JSMN_OBJECT) {
		json_command_malformed(jcon, "null",
				       "Expected {} for json command");
		return;
	}

	method = json_get_member(jcon->buffer, tok, "method");
	params = json_get_member(jcon->buffer, tok, "params");
	id = json_get_member(jcon->buffer, tok, "id");

	if (!id) {
		json_command_malformed(jcon, "null", "No id");
		return;
	}
	if (id->type != JSMN_STRING && id->type != JSMN_PRIMITIVE) {
		json_command_malformed(jcon, "null",
				       "Expected string/primitive for id");
		return;
	}

	/* This is a convenient tal parent for durarion of command
	 * (which may outlive the conn!). */
	jcon->current = tal(jcon->dstate, struct command);
	jcon->current->jcon = jcon;
	jcon->current->dstate = jcon->dstate;
	jcon->current->id = tal_strndup(jcon->current,
					json_tok_contents(jcon->buffer, id),
					json_tok_len(id));

	if (!method || !params) {
		command_fail(jcon->current, method ? "No params" : "No method");
		return;
	}

	if (method->type != JSMN_STRING) {
		command_fail(jcon->current, "Expected string for method");
		return;
	}

	cmd = find_cmd(jcon->buffer, method);
	if (!cmd) {
		command_fail(jcon->current,
			     "Unknown command '%.*s'",
			     (int)(method->end - method->start),
			     jcon->buffer + method->start);
		return;
	}

	if (params->type != JSMN_ARRAY && params->type != JSMN_OBJECT) {
		command_fail(jcon->current,
			     "Expected array or object for params");
		return;
	}

	cmd->dispatch(jcon->current, jcon->buffer, params);
}
예제 #2
0
static const char *get_first_input_addr(const tal_t *ctx,
					const char *buffer,
					const jsmntok_t *txid)
{
	const jsmntok_t *toks, *intxid, *onum, *type, *address;
	unsigned int outnum;
	const char *delve, *txstr;

	/* eg:
	getrawtransaction e84b0c87934a146d211fcaa6f1ec187da33e205fb250400cf66620a82a9111a0 1
	{
	    "hex" : "010000000193721eadf1bb2a40498b41ca6be2adaddf4c1780884637fedf05cf37015ac508000000006b4830450221008ce700a0c872af67612e5d5226f1e8bdcb2329549883b8fa02df002409f54c43022029b10a885ca3c5103574f06ab90e6f5a7c9c2cafe6e583f17316c967d678bab4012103c511c82cf0aae4541c026eee5d9f738dc1cb4a2114e20b3f5710a22dc94825ceffffffff02d0f88774030000001976a9144e81b0986efad3643012783f016ec10a9c3d35cd88ac005a6202000000001976a91434f89b68a07bd841bbca98f9b7b1521ce1a3d17688ac00000000",
	    "txid" : "e84b0c87934a146d211fcaa6f1ec187da33e205fb250400cf66620a82a9111a0",
	    "version" : 1,
	    "locktime" : 0,
	    "vin" : [
	        {
	            "txid" : "08c55a0137cf05dffe37468880174cdfadade26bca418b49402abbf1ad1e7293",
	            "vout" : 0,
	            "scriptSig" : {
	                "asm" : "30450221008ce700a0c872af67612e5d5226f1e8bdcb2329549883b8fa02df002409f54c43022029b10a885ca3c5103574f06ab90e6f5a7c9c2cafe6e583f17316c967d678bab401 03c511c82cf0aae4541c026eee5d9f738dc1cb4a2114e20b3f5710a22dc94825ce",
	                "hex" : "4830450221008ce700a0c872af67612e5d5226f1e8bdcb2329549883b8fa02df002409f54c43022029b10a885ca3c5103574f06ab90e6f5a7c9c2cafe6e583f17316c967d678bab4012103c511c82cf0aae4541c026eee5d9f738dc1cb4a2114e20b3f5710a22dc94825ce"
	            },
	            "sequence" : 4294967295
	        }
	    ],
	    "vout" : [
	        {
	            "value" : 148.39970000,
	            "n" : 0,
	            "scriptPubKey" : {
	                "asm" : "OP_DUP OP_HASH160 4e81b0986efad3643012783f016ec10a9c3d35cd OP_EQUALVERIFY OP_CHECKSIG",
	                "hex" : "76a9144e81b0986efad3643012783f016ec10a9c3d35cd88ac",
	                "reqSigs" : 1,
	                "type" : "pubkeyhash",
	                "addresses" : [
	                    "mng4N2LZqin7joL7GAjs4tp8WNNt8GjcYz"
	                ]
	            }
	        },
	        {
	            "value" : 0.40000000,
	            "n" : 1,
	            "scriptPubKey" : {
	                "asm" : "OP_DUP OP_HASH160 34f89b68a07bd841bbca98f9b7b1521ce1a3d176 OP_EQUALVERIFY OP_CHECKSIG",
	                "hex" : "76a91434f89b68a07bd841bbca98f9b7b1521ce1a3d17688ac",
	                "reqSigs" : 1,
	                "type" : "pubkeyhash",
	                "addresses" : [
	                    "mkM3FYuYoKFiXS3YL99JdJEdPM5HVGpZTj"
	                ]
	            }
	        }
	    ],
	    "blockhash" : "0000000022a3a02881f56c24bbe7556eef98b1e29267b4015a4fbfc83bab5735",
	    "confirmations" : 14,
	    "time" : 1406252550,
	    "blocktime" : 1406252550
	}
	*/
	txstr = tal_fmt(ctx, "%.*s", 
			(int)(txid->end - txid->start),
			buffer + txid->start);
	toks = json_bitcoind(ctx, &buffer,
			     "getrawtransaction", txstr, "1", NULL);
	if (!toks)
		err(1, "getrawtransaction of tx %s", txstr);

	/* This can happen in if someone aims their block reward at
	   the gateway. */
	intxid = json_delve(buffer, toks, ".vin[0].txid");
	onum = json_delve(buffer, toks, ".vin[0].vout");
	if (!intxid || !onum)
		errx(1, "Missing txid/vout in '%s'", buffer);

	/* Get this before we replace buffer. */
	outnum = num_of(buffer, onum);

	/* Get details of *that* tx. */
	txstr = tal_fmt(ctx, "%.*s", 
			(int)(intxid->end - intxid->start),
			buffer + intxid->start);

	toks = json_bitcoind(ctx, &buffer,
			     "getrawtransaction", txstr, "1", NULL);
	if (!toks)
		err(1, "getrawtransaction of input tx %s", txstr);

	/* make sure it's a pubkeyhash */
	delve = tal_fmt(ctx, ".vout[%u].scriptPubKey.type", outnum);
	type = json_delve(buffer, toks, delve);
	if (!type || !json_tok_streq(buffer, type, "pubkeyhash"))
		errx(1, "'%s' was not a pubkeyhash in '%s'", delve, buffer);

	delve = tal_fmt(ctx, ".vout[%u].scriptPubKey.addresses[0]", outnum);
	address = json_delve(buffer, toks, delve);
	if (!address)
		errx(1, "Can't find %s in '%s'", delve, buffer);

	return tal_strndup(ctx, buffer + address->start,
			   address->end - address->start);
}
예제 #3
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();
}