Ejemplo n.º 1
0
int main(void)
{
	jsmntok_t *toks_arr, *toks_obj,
		*arg1, *arg2, *arg3, *arg4, *arg5;
	const jsmntok_t *arr_params, *obj_params;
	void *ctx;
	bool valid;
	char *cmd_arr, *cmd_obj;
	struct protocol_double_sha sha;

	ctx = tal(NULL, char);

	cmd_arr = tal_strdup(ctx,
			     "{ \"method\" : \"dev-echo\", "
			     "\"params\" : [ null, [ 1, 2, 3 ], { \"one\" : 1 }, \"four\" ], "
			     "\"id\" : \"1\" }");

	cmd_obj = tal_strdup(ctx,
			     "{ \"method\" : \"dev-echo\", "
			     "\"params\" : { \"arg2\" : [ 1, 2, 3 ],"
				" \"arg3\" : { \"one\" : 1 },"
				" \"arg4\" : \"four\" }, "
			     "\"id\" : \"1\" }");

	/* Partial id we skip } */
	toks_arr = json_parse_input(cmd_arr, strlen(cmd_arr) - 1, &valid);
	assert(!toks_arr);
	assert(valid);
	toks_obj = json_parse_input(cmd_obj, strlen(cmd_obj) - 1, &valid);
	assert(!toks_obj);
	assert(valid);

	/* This should work */
	toks_arr = json_parse_input(cmd_arr, strlen(cmd_arr), &valid);
	assert(toks_arr);
	assert(tal_count(toks_arr) == 17);
	assert(valid);
	toks_obj = json_parse_input(cmd_obj, strlen(cmd_obj), &valid);
	assert(toks_obj);
	assert(tal_count(toks_obj) == 19);
	assert(valid);

	assert(toks_arr[0].type == JSMN_OBJECT);
	assert(json_tok_len(toks_arr) == strlen(cmd_arr));
	assert(strncmp(json_tok_contents(cmd_arr, toks_arr), cmd_arr,
		       json_tok_len(toks_arr)) == 0);

	assert(toks_obj[0].type == JSMN_OBJECT);
	assert(json_tok_len(toks_obj) == strlen(cmd_obj));
	assert(strncmp(json_tok_contents(cmd_obj, toks_obj), cmd_obj,
		       json_tok_len(toks_obj)) == 0);

	/* It's not a string, so this will fail. */
	assert(!json_tok_streq(cmd_arr, toks_arr, cmd_obj));
	assert(json_tok_streq(cmd_arr, toks_arr+1, "method"));
	assert(json_tok_streq(cmd_obj, toks_obj+1, "method"));

	assert(json_tok_is_null(cmd_arr, toks_arr + 5));
	assert(!json_tok_is_null(cmd_arr, toks_arr + 6));
	assert(!json_tok_is_null(cmd_arr, toks_arr + 7));

	assert(json_get_member(cmd_arr, toks_arr, "method") == toks_arr+2);
	assert(json_get_member(cmd_obj, toks_obj, "method") == toks_obj+2);
	assert(!json_get_member(cmd_arr, toks_arr, "dev-echo"));
	assert(!json_get_member(cmd_obj, toks_obj, "arg2"));

	arr_params = json_get_member(cmd_arr, toks_arr, "params");
	assert(arr_params == toks_arr+4);
	assert(arr_params->type == JSMN_ARRAY);
	obj_params = json_get_member(cmd_obj, toks_obj, "params");
	assert(obj_params == toks_obj+4);
	assert(obj_params->type == JSMN_OBJECT);

	assert(json_get_member(cmd_arr, toks_arr, "id") == toks_arr+15);
	assert(json_get_member(cmd_obj, toks_obj, "id") == toks_obj+17);

	/* get_member works in sub objects */
	assert(json_get_member(cmd_obj, obj_params, "arg4") == toks_obj + 15);

	json_get_params(cmd_arr, arr_params,
			"arg1", &arg1,
			"arg2", &arg2,
			"arg3", &arg3,
			"arg4", &arg4,
			"arg5", &arg5,
			NULL);
	assert(arg1 == NULL);
	assert(arg2 == toks_arr + 6);
	assert(arg2->type == JSMN_ARRAY);
	assert(arg3 == toks_arr + 10);
	assert(arg3->type == JSMN_OBJECT);
	assert(arg4 == toks_arr + 13);
	assert(arg4->type == JSMN_STRING);
	assert(arg5 == NULL);

	json_get_params(cmd_obj, obj_params,
			"arg1", &arg1,
			"arg2", &arg2,
			"arg3", &arg3,
			"arg4", &arg4,
			"arg5", &arg5,
			NULL);
	assert(arg1 == NULL);
	assert(arg2 == toks_obj + 6);
	assert(arg2->type == JSMN_ARRAY);
	assert(arg3 == toks_obj + 11);
	assert(arg3->type == JSMN_OBJECT);
	assert(arg4 == toks_obj + 15);
	assert(arg4->type == JSMN_STRING);	
	assert(arg5 == NULL);

	/* Test json_delve() */
	assert(json_delve(cmd_arr, toks_arr, ".method") == toks_arr + 2);
	assert(json_delve(cmd_arr, toks_arr, ".params[0]") == toks_arr + 5);
	assert(json_delve(cmd_arr, toks_arr, ".params[1]") == toks_arr + 6);
	assert(json_delve(cmd_arr, toks_arr, ".params[2]") == toks_arr + 10);
	assert(json_delve(cmd_arr, toks_arr, ".params[1][2]") == toks_arr + 9);
	assert(json_delve(cmd_arr, toks_arr, ".params[4]") == NULL);
	assert(json_delve(cmd_arr, toks_arr, ".params[1][4]") == NULL);
	assert(json_delve(cmd_arr, toks_arr, ".params[3][4]") == NULL);
	assert(json_delve(cmd_arr, toks_arr, ".unknown") == NULL);
	assert(json_delve(cmd_arr, toks_arr, ".unknown[1]") == NULL);
	assert(json_delve(cmd_arr, toks_arr, ".param") == NULL);
	assert(json_delve(cmd_arr, toks_arr, ".params\"") == NULL);
	assert(json_delve(cmd_arr, toks_arr, ".dev-echo") == NULL);
	assert(json_delve(cmd_arr, toks_arr, ".id[0]") == NULL);

	assert(json_delve(cmd_obj, toks_obj, ".params.arg3.one")
	       == toks_obj + 13);

	/* More exotic object creation */
	cmd_arr = tal_arr(ctx, char, 0);
	json_add_object(&cmd_arr,
			"arg2", JSMN_ARRAY, "[ 1, 2, 3 ]",
			"arg3", JSMN_OBJECT, "{ \"one\" : 1 }",
			"arg4", JSMN_STRING, "four",
			NULL);
	assert(streq(cmd_arr,
		     "{ \"arg2\" : [ 1, 2, 3 ],"
		     " \"arg3\" : { \"one\" : 1 },"
		     " \"arg4\" : \"four\" }"));

	cmd_arr = tal_arr(ctx, char, 0);
	json_object_start(&cmd_arr, NULL);

	json_add_pubkey(&cmd_arr, "key", helper_public_key(0));
	memset(&sha, 42, sizeof(sha));
	json_add_double_sha(&cmd_arr, "sha", &sha);
	json_add_address(&cmd_arr, "test-address", true, helper_addr(0));
	json_add_address(&cmd_arr, "address", false, helper_addr(0));
	json_object_end(&cmd_arr);

	assert(streq(cmd_arr, "{ \"key\" : \"0214f24666a59e62c8b92a0b4b58f2a1cdeb573ea377e42f411be028292ff81926\","
		     " \"sha\" : \"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a\","
		     " \"test-address\" : \"qKCafy33t92L9Nmoxx8H6NHDuiyGViqWBZ\","
		     " \"address\" : \"PZZyf1xcSbNFodrGQ6ot4LrsdSUu1bgmkc\" }"));
	tal_free(ctx);
	return 0;
}
Ejemplo n.º 2
0
int main(void)
{
	struct state *state;
	union protocol_tx *t, *t2;
	struct protocol_gateway_payment payment;
	u8 *prev_txhashes;
	enum input_ecode e;
	struct protocol_tx_id txid;
	unsigned int bad_input;
	bool too_old, already_known;
	const struct block *b;
	struct protocol_block_id prevs[PROTOCOL_NUM_PREV_IDS];
	struct protocol_input inputs[1];
	
	pseudorand_init();
	state = new_state(true);

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

	/* Create a block with a gateway tx in it. */
	payment.send_amount = cpu_to_le32(1000);
	payment.output_addr = *helper_addr(0);
	t = create_from_gateway_tx(state, helper_gateway_public_key(),
				   1, &payment, false, helper_gateway_key(state));
	hash_tx(t, &txid);
	log_unusual(state->log, "Gateway tx is ");
	log_add_struct(state->log, struct protocol_tx_id, &txid);

	e = add_pending_tx(state, t, &txid, &bad_input,
			   &too_old, &already_known);
	assert(e == ECODE_INPUT_OK);
	assert(!already_known);

	assert(state->pending->num_unknown == 0);
	assert(num_pending_known(state) == 1);

	b = solve_pending(state);

	/* Now we can spend it. */
	prev_txhashes = make_prev_txhashes(state, b, helper_addr(1));
	prevs[0] = b->sha;
	prevs[1] = genesis.sha;
	w = new_working_block(state, block_difficulty(&b->bi),
			      prev_txhashes, tal_count(prev_txhashes),
			      block_height(&b->bi) + 1,
			      next_shard_order(b),
			      prevs, helper_addr(1));

	hash_tx(t, &inputs[0].input);
	inputs[0].output = 0;
	inputs[0].unused = 0;

	t2 = t = create_normal_tx(state, helper_addr(1),
				  500, 500 - PROTOCOL_FEE(500), 1, true, inputs,
				  helper_private_key(state, 0));
	
	hash_tx(t, &txid);
	e = add_pending_tx(state, t, &txid, &bad_input,
			   &too_old, &already_known);
	assert(e == ECODE_INPUT_OK);
	assert(!already_known);
	assert(state->pending->num_unknown == 0);
	assert(num_pending_known(state) == 1);

	log_unusual(state->log, "Normal tx is ");
	log_add_struct(state->log, struct protocol_tx_id, &txid);

	/* Should recognize double spend */
	t = create_normal_tx(state, helper_addr(2),
			     300, 700 - PROTOCOL_FEE(300), 1, true, inputs,
			     helper_private_key(state, 0));
	
	hash_tx(t, &txid);
	e = add_pending_tx(state, t, &txid, &bad_input,
			   &too_old, &already_known);
	assert(e == ECODE_INPUT_DOUBLESPEND);
	assert(!already_known);

	assert(state->pending->num_unknown == 0);
	assert(num_pending_known(state) == 1);

	b = solve_pending(state);
	/* The first should be included. */
	assert(num_txs(b) == 1);

	/* There should be nothing left. */ 
	assert(state->pending->num_unknown == 0);
	assert(num_pending_known(state) == 0);

	/* Now retry double spend. */
	t = create_normal_tx(state, helper_addr(2),
			     300, 700 - PROTOCOL_FEE(300), 1, true, inputs,
			     helper_private_key(state, 0));
	
	hash_tx(t, &txid);
	e = add_pending_tx(state, t, &txid, &bad_input,
			   &too_old, &already_known);
	assert(e == ECODE_INPUT_DOUBLESPEND);
	assert(!too_old);
	assert(!already_known);

	/* Clear inputhash manually. */
	inputhash_del_tx(&state->inputhash, t2);

	dump_inputhash(state, &state->inputhash);
	tal_free(state);
	return 0;
}
Ejemplo n.º 3
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;
}