Пример #1
0
bool deser_msg_vinv(struct msg_vinv *mv, struct const_buffer *buf)
{
	msg_vinv_free(mv);

	uint32_t vlen;
	if (!deser_varlen(&vlen, buf)) return false;

	mv->invs = parr_new(vlen, free);

	unsigned int i;
	for (i = 0; i < vlen; i++) {
		struct bp_inv *inv;

		inv = calloc(1, sizeof(*inv));
		if (!deser_bp_inv(inv, buf)) {
			free(inv);
			goto err_out;
		}

		parr_add(mv->invs, inv);
	}

	return true;

err_out:
	msg_vinv_free(mv);
	return false;
}
Пример #2
0
static bool nc_msg_inv(struct nc_conn *conn)
{
	struct const_buffer buf = { conn->msg.data, conn->msg.hdr.data_len };
	struct msg_vinv mv, mv_out;
	bool rc = false;

	msg_vinv_init(&mv);
	msg_vinv_init(&mv_out);

	if (!deser_msg_vinv(&mv, &buf))
		goto out;

	if (log_state->debug && mv.invs && mv.invs->len == 1) {
		struct bp_inv *inv = parr_idx(mv.invs, 0);
		char hexstr[BU256_STRSZ];
		bu256_hex(hexstr, &inv->hash);

		char typestr[32];
		switch (inv->type) {
		case MSG_TX: strcpy(typestr, "tx"); break;
		case MSG_BLOCK: strcpy(typestr, "block"); break;
		default: sprintf(typestr, "unknown 0x%x", inv->type); break;
		}

		log_debug("net: %s inv %s %s",
			conn->addr_str, typestr, hexstr);
	}
	else if (mv.invs) {
		log_debug("net: %s inv (%zu sz)",
			conn->addr_str, mv.invs->len);
	}

	if (!mv.invs || !mv.invs->len)
		goto out_ok;

	/* scan incoming inv's for interesting material */
	unsigned int i;
	for (i = 0; i < mv.invs->len; i++) {
		struct bp_inv *inv = parr_idx(mv.invs, i);
		switch (inv->type) {
		case MSG_BLOCK:
			if (conn->nci->inv_block_process(&inv->hash))
				msg_vinv_push(&mv_out, MSG_BLOCK, &inv->hash);
			break;

		case MSG_TX:
		default:
			break;
		}
	}

	/* send getdata, if they have anything we want */
	if (mv_out.invs && mv_out.invs->len) {
		cstring *s = ser_msg_vinv(&mv_out);

		rc = nc_conn_send(conn, "getdata", s->str, s->len);

		cstr_free(s, true);
	}

out_ok:
	rc = true;

out:
	msg_vinv_free(&mv);
	msg_vinv_free(&mv_out);
	return rc;
}
Пример #3
0
/*
 *
struct msg_vinv {
        parr    *invs;    array of bp_inv  
};

struct bp_inv {
        uint32_t        type;
        bu256_t         hash;
};
 *
 * */
static bool nc_msg_inv(struct nc_conn *conn)
{
	struct const_buffer buf = { conn->msg.data, conn->msg.hdr.data_len };
	struct msg_vinv mv, mv_out;
	bool rc = false;
	unsigned int i=0;
	
	int msg_tx, msg_block, msg_other;
		
	msg_tx = msg_block = msg_other = 0;

	msg_vinv_init(&mv);//memset
	msg_vinv_init(&mv_out);//memset

	if (!deser_msg_vinv(&mv, &buf))
		goto out;
	if (mv.invs){
		//LOG("Peer [%s] gave %d inventory vectors",conn->addr_str, mv.invs->len);
		for (i = 0;i < mv.invs->len; i++){
			struct bp_inv *inv = parr_idx(mv.invs, 0);
			switch (inv->type){
			case MSG_TX:
				msg_tx++;
				break;
			case MSG_BLOCK:
				msg_block++;
				break;
			default:
				msg_other++;
			} 
		}
		if (mv.invs->len > 0){
			LOG("Inventory vectors: msg[%d], block[%d], other[%d]",
				msg_tx, msg_block, msg_other);
		}
	}
		
	if (debugging && mv.invs && mv.invs->len == 1) {
		struct bp_inv *inv = parr_idx(mv.invs, 0);
		char hexstr[BU256_STRSZ];
		bu256_hex(hexstr, &inv->hash);

		char typestr[32];
		switch (inv->type) {
		case MSG_TX: strcpy(typestr, "tx"); break;
		case MSG_BLOCK: strcpy(typestr, "block"); break;
		default: sprintf(typestr, "unknown 0x%x", inv->type); break;
		}

		fprintf(plog, "net: %s inv %s %s\n",
			conn->addr_str, typestr, hexstr);
	}
	else if (debugging && mv.invs) {
		fprintf(plog, "net: %s inv (%zu sz)\n",
			conn->addr_str, mv.invs->len);
	}

	if (!mv.invs || !mv.invs->len)
		goto out_ok;

	/* scan incoming inv's for interesting material */
	/*declared at beginnning of function--> unsigned int i;*/
	for (i = 0; i < mv.invs->len; i++) {
		struct bp_inv *inv = parr_idx(mv.invs, i);
		switch (inv->type) {
		case MSG_BLOCK:
			if (!blkdb_lookup(&db, &inv->hash) &&
			    !have_orphan(&inv->hash))
				msg_vinv_push(&mv_out, MSG_BLOCK, &inv->hash);
			break;

		case MSG_TX:
		default:
			break;
		}
	}

	/* send getdata, if they have anything we want */
	if (mv_out.invs && mv_out.invs->len) {
		cstring *s = ser_msg_vinv(&mv_out);

		rc = nc_conn_send(conn, "getdata", s->str, s->len);

		cstr_free(s, true);
	}

out_ok:
	rc = true;

out:
	msg_vinv_free(&mv);
	msg_vinv_free(&mv_out);
	return rc;
}