Ejemplo n.º 1
0
static void init_peers(struct net_child_info *nci)
{
	/*
	 * read network peers
	 */
	struct peer_manager *peers;

	peers = peerman_read();
	if (!peers) {
		fprintf(plog, "net: initializing empty peer list\n");

		peers = peerman_seed(setting("no_dns") == NULL ? true : false);
		if (!peerman_write(peers)) {
			fprintf(plog, "net: failed to write peer list\n");
			exit(1);
		}
	}

	char *addnode = setting("addnode");
	if (addnode)
		peerman_addstr(peers, addnode);

	peerman_sort(peers);

	if (debugging)
		fprintf(plog, "net: have %u/%zu peers\n",
			bp_hashtab_size(peers->map_addr),
			clist_length(peers->addrlist));

	nci->peers = peers;
}
Ejemplo n.º 2
0
static void shutdown_daemon(struct net_child_info *nci)
{
	LOG_BEGIN;
	bool rc = peerman_write(nci->peers);
	fprintf(plog, "net: %s %u/%zu peers\n",
		rc ? "wrote" : "failed to write",
		bp_hashtab_size(nci->peers->map_addr),
		clist_length(nci->peers->addrlist));

	if (plog != stdout && plog != stderr) {
		fclose(plog);
		plog = NULL;
	}

	if (setting("free")) {
		shutdown_nci(nci);
		bp_hashtab_unref(orphans);
		bp_hashtab_unref(settings);
		blkdb_free(&db);
		bp_utxo_set_free(&uset);
	}
	LOG_END;
}
Ejemplo n.º 3
0
Archivo: net.c Proyecto: aido/picocoin
static void nc_conns_open(struct net_child_info *nci)
{
	log_debug("net: open connections (have %zu, want %zu more)",
		nci->conns->len,
		NC_MAX_CONN - nci->conns->len);

	while ((bp_hashtab_size(nci->peers->map_addr) > 0) &&
	       (nci->conns->len < NC_MAX_CONN)) {

		/* delete peer from front of address list.  it will be
		 * re-added before writing peer file, if successful
		 */
		struct peer *peer = peerman_pop(nci->peers);

		struct nc_conn *conn = nc_conn_new(peer);
		conn->nci = nci;
		peer_free(peer);
		free(peer);

		log_debug("net: connecting to %s",
			conn->addr_str);

		/* are we already connected to this IP? */
		if (nc_conn_ip_active(nci, conn->peer.addr.ip)) {
			log_info("net: already connected to %s",
				conn->addr_str);
			goto err_loop;
		}

		/* are we already connected to this network group? */
		if (nc_conn_group_active(nci, &conn->peer)) {
			log_info("net: already grouped to %s",
				conn->addr_str);
			goto err_loop;
		}

		/* initiate non-blocking connect(2) */
		if (!nc_conn_start(conn)) {
			log_info("net: failed to start connection to %s",
				conn->addr_str);
			goto err_loop;
		}

		/* add to our list of monitored event sources */
		conn->ev = event_new(nci->eb, conn->fd, EV_WRITE,
				     nc_conn_evt_connected, conn);
		if (!conn->ev) {
			log_info("net: event_new failed on %s",
				conn->addr_str);
			goto err_loop;
		}

		struct timeval timeout = { conn->nci->net_conn_timeout, };
		if (event_add(conn->ev, &timeout) != 0) {
			log_info("net: event_add failed on %s",
				conn->addr_str);
			goto err_loop;
		}

		/* add to our list of active connections */
		parr_add(nci->conns, conn);

		continue;

err_loop:
		nc_conn_kill(conn);
	}
}
Ejemplo n.º 4
0
static bool blkdb_connect(struct blkdb *db, struct blkinfo *bi,
			  struct blkdb_reorg *reorg_info)
{
	memset(reorg_info, 0, sizeof(*reorg_info));

	if (blkdb_lookup(db, &bi->hash))
		return false;

	bool rc = false;
	BIGNUM cur_work;
	BN_init(&cur_work);

	u256_from_compact(&cur_work, bi->hdr.nBits);

	bool best_chain = false;

	/* verify genesis block matches first record */
	if (bp_hashtab_size(db->blocks) == 0) {
		if (!bu256_equal(&bi->hdr.sha256, &db->block0))
			goto out;

		/* bi->prev = NULL; */
		bi->height = 0;

		BN_copy(&bi->work, &cur_work);

		best_chain = true;
	}

	/* lookup and verify previous block */
	else {
		struct blkinfo *prev = blkdb_lookup(db, &bi->hdr.hashPrevBlock);
		if (!prev)
			goto out;

		bi->prev = prev;
		bi->height = prev->height + 1;

		if (!BN_add(&bi->work, &cur_work, &prev->work))
			goto out;

		if (BN_cmp(&bi->work, &db->best_chain->work) > 0)
			best_chain = true;
	}

	/* add to block map */
	bp_hashtab_put(db->blocks, &bi->hash, bi);

	/* if new best chain found, update pointers */
	if (best_chain) {
		struct blkinfo *old_best = db->best_chain;
		struct blkinfo *new_best = bi;

		reorg_info->old_best = old_best;

		/* likely case: new best chain has greater height */
		if (!old_best) {
			while (new_best) {
				new_best = new_best->prev;
				reorg_info->conn++;
			}
		} else {
			while (new_best &&
			       (new_best->height > old_best->height)) {
				new_best = new_best->prev;
				reorg_info->conn++;
			}
		}

		/* unlikely case: old best chain has greater height */
		while (old_best && new_best &&
		       (old_best->height > new_best->height)) {
			old_best = old_best->prev;
			reorg_info->disconn++;
		}

		/* height matches, but we are still walking parallel chains */
		while (old_best && new_best && (old_best != new_best)) {
			new_best = new_best->prev;
			reorg_info->conn++;

			old_best = old_best->prev;
			reorg_info->disconn++;
		}

		/* reorg analyzed. update database's best-chain pointer */
		db->best_chain = bi;
	}

	rc = true;

out:
	BN_clear_free(&cur_work);
	return rc;
}