void poller::receive_inv(const std::error_code& ec, const inventory_type& packet, channel_ptr node) { if (ec) { log_error(LOG_POLLER) << "Received bad inventory: " << ec.message(); return; } // Filter out only block inventories get_data_type getdata; for (const inventory_vector_type& ivv: packet.inventories) { if (ivv.type != inventory_type_id::block) continue; // Already got this block if (ivv.hash == last_block_hash_) continue; getdata.inventories.push_back(ivv); } if (!getdata.inventories.empty()) { last_block_hash_ = getdata.inventories.back().hash; node->send(getdata, handle_send_packet); } node->subscribe_inventory( strand_.wrap(std::bind(&poller::receive_inv, this, _1, _2, node))); }
void poller::monitor(channel_ptr node) { node->subscribe_inventory( strand_.wrap(std::bind(&poller::receive_inv, this, _1, _2, node))); node->subscribe_block( std::bind(&poller::receive_block, this, _1, _2, node)); }
void handle_handshake(const std::error_code& ec, channel_ptr node, handshake& hs) { if (ec) error_exit(ec.message()); node->subscribe_inventory(std::bind(&receive_inv, _1, _2, node)); node->send(create_getblocks_message(), std::bind(&handle_send_getblock, _1)); hs.fetch_network_address(show_ip); }
void ask_blocks(const std::error_code& ec, channel_ptr node, const message::block_locator& loc, blockchain_ptr chain, const hash_digest& hash_stop) { if (ec) log_error() << ec.message(); node->subscribe_inventory(std::bind(recv_inv, _1, _2, node)); node->subscribe_block(std::bind(recv_blk, _1, _2, node, chain)); message::get_blocks packet; packet.start_hashes = loc; packet.hash_stop = hash_stop; node->send(packet, std::bind(&handle_send_packet, _1)); }
void recv_inv(const std::error_code &ec, const message::inventory& packet, channel_ptr node) { if (ec) log_error() << ec.message(); message::get_data getdata; for (const message::inventory_vector& ivv: packet.inventories) { if (ivv.type != message::inventory_type::block) continue; getdata.inventories.push_back(ivv); } node->send(getdata, handle_send_packet); node->subscribe_inventory(std::bind(&recv_inv, _1, _2, node)); }
void inventory_received(const std::error_code& ec, const inventory_type& inv, channel_ptr node, tx_watch& watch) { check_error(ec); // Loop through inventory hashes. for (const inventory_vector_type& ivec: inv.inventories) { // We're only interested in transactions. Discard everything else. if (ivec.type != inventory_type_id::transaction) continue; watch.push(ivec.hash); } // Resubscribe to inventory packets. node->subscribe_inventory( std::bind(inventory_received, _1, _2, node, std::ref(watch))); }
void connection_started(const std::error_code& ec, channel_ptr node, protocol& prot, tx_watch& watch) { if (ec) { log_warning() << "Couldn't start connection: " << ec.message(); return; } log_info() << "Connection established."; // Subscribe to inventory packets. node->subscribe_inventory( std::bind(inventory_received, _1, _2, node, std::ref(watch))); // Resubscribe to new nodes. prot.subscribe_channel( std::bind(connection_started, _1, _2, std::ref(prot), std::ref(watch))); }
void session::new_channel(const std::error_code& ec, channel_ptr node) { if (ec) { log_warning(LOG_SESSION) << "New channel: " << ec.message(); return; } BITCOIN_ASSERT(node); node->subscribe_inventory( std::bind(&session::inventory, this, _1, _2, node)); node->subscribe_get_data( std::bind(&session::get_data, this, _1, _2, node)); node->subscribe_get_blocks( std::bind(&session::get_blocks, this, _1, _2, node)); // tx // block protocol_.subscribe_channel( std::bind(&session::new_channel, this, _1, _2)); poll_.monitor(node); }
void session::inventory(const std::error_code& ec, const inventory_type& packet, channel_ptr node) { if (ec) { log_error(LOG_SESSION) << "inventory: " << ec.message(); return; } for (const inventory_vector_type& ivec: packet.inventories) { if (ivec.type == inventory_type_id::transaction) strand_.post( std::bind(&session::new_tx_inventory, this, ivec.hash, node)); else if (ivec.type == inventory_type_id::block); // Do nothing. Handled by poller. else log_warning(LOG_SESSION) << "Ignoring unknown inventory type"; } node->subscribe_inventory( std::bind(&session::inventory, this, _1, _2, node)); }