void handle_stop(const std::error_code& ec) { if (ec) log_error() << "Stopped: " << ec.message(); log_info() << "Channel stopped."; channode->send(message::verack(), handle_send); }
void handle_connect(const std::error_code& ec, channel_ptr node) { // if this node dies then the connection is closed duh // and the accepted node (recver) also closes... duh sender = node; node->send(message::ping(), [](const std::error_code&) {}); }
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 protocol::setup_new_channel(channel_ptr node) { subscribe_address(node); node->send(get_address_type(), handle_send); // Notify subscribers channel_subscribe_->relay(std::error_code(), node); }
void getx_responder::chain_tx(const std::error_code& code, const transaction_type& tx, channel_ptr node) { if (!code) { BITCOIN_ASSERT(node); node->send(tx, [](const std::error_code&) {}); } }
void getx_responder::send_block(const std::error_code& code, const block_type& block, channel_ptr node) { if (!code) { BITCOIN_ASSERT(node); node->send(block, [](const std::error_code&) {}); } }
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 session::request_tx_data(bool tx_exists, const hash_digest& tx_hash, channel_ptr node) { if (tx_exists) return; get_data_type request_tx; request_tx.inventories.push_back( {inventory_type_id::transaction, tx_hash}); node->send(request_tx, handle_send_get_data); }
void ask_blocks2(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(); message::get_blocks packet; packet.start_hashes = loc; packet.hash_stop = hash_stop; node->send(packet, std::bind(&handle_send_packet, _1)); }
void handshake::receive_version( const std::error_code& ec, const version_type&, channel_ptr node, handshake::handshake_handler completion_callback) { if (ec) completion_callback(ec); else node->send(verack_type(), strand_.wrap(std::bind(&handshake::handle_message_sent, this, _1, completion_callback))); }
void protocol::setup_new_channel(channel_ptr node) { // Remove channel from list of connections node->subscribe_stop( strand_.wrap(std::bind(&protocol::channel_stopped, this, _1, node))); subscribe_address(node); node->send(get_address_type(), handle_send); // Notify subscribers channel_subscribe_->relay(std::error_code(), node); }
// Not having orphans will cause a stall void poller::ask_blocks(const std::error_code& ec, const block_locator_type& locator, const hash_digest& hash_stop, channel_ptr node) { if (!node) return; if (ec) { log_debug(LOG_POLLER) << "Failed to fetch block locator: " << ec.message(); return; } if (is_duplicate_block_ask(locator, hash_stop, node)) { log_debug(LOG_POLLER) << "Skipping duplicate ask blocks with locator front [" << encode_hash(locator.front()) << "]"; return; } log_debug(LOG_POLLER) << "Ask for blocks with stop [" << encode_hash(hash_stop) << "]"; const auto handle_error = [node](const std::error_code& ec) { if (!node) return; if (ec) { log_debug(LOG_POLLER) << "Send get blocks problem: " << ec.message(); // TODO: modify send() to terminate the connection on send failure. node->stop(); } }; // Send get_blocks request. const get_blocks_type packet{ locator, hash_stop }; node->send(packet, handle_error); // Update last values. last_locator_begin_ = locator.front(); last_hash_stop_ = hash_stop; last_requested_node_ = node.get(); }
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 handle_connect(const std::error_code& ec, channel_ptr node) { recv_node = node; message::get_data getdat; getdat.inventories.push_back( {message::inventory_type::transaction, hash_from_pretty<hash_digest>("e72e4f025695446cfd5c5349d1720beb38801f329a00281f350cb7e847153397")}); getdat.inventories.push_back( {message::inventory_type::block, hash_from_pretty<hash_digest>("000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f")}); node->subscribe_block(handle_blk); sleep(1); node->send(getdat, handle_send); }
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 getx_responder::pool_tx(const std::error_code& code, const transaction_type& tx, const hash_digest& tx_hash, channel_ptr node) { if (code) { chain_.fetch_transaction(tx_hash, std::bind(&getx_responder::chain_tx, this, _1, _2, node)); } else { BITCOIN_ASSERT(node); node->send(tx, [](const std::error_code&) {}); } }
void send_tx(const std::error_code& ec, channel_ptr node, transaction_type& tx) { check_error(ec); std::cout << "sendtx: Sending " << hash_transaction(tx) << std::endl; auto handle_send = [node](const std::error_code& ec) { if (ec) log_warning() << "Send failed: " << ec.message(); else std::cout << "sendtx: Sent " << time(nullptr) << std::endl; stopped = true; }; node->send(tx, handle_send); }
void handshake::ready(channel_ptr node, handshake::handshake_handler handle_handshake) { auto completion_callback = async_parallel(handle_handshake, 3); version_type session_version = template_version_; session_version.timestamp = time(NULL); node->send(session_version, strand_.wrap(std::bind(&handshake::handle_message_sent, this, _1, completion_callback))); node->subscribe_version( strand_.wrap(std::bind(&handshake::receive_version, this, _1, _2, node, completion_callback))); node->subscribe_verack( strand_.wrap(std::bind(&handshake::receive_verack, this, _1, _2, completion_callback))); }
void send_tx(const std::error_code& ec, channel_ptr node, protocol& prot, transaction_type& tx) { check_error(ec); std::cout << "sendtx-p2p: Sending " << hash_transaction(tx) << std::endl; auto handle_send = [](const std::error_code& ec) { if (ec) log_warning() << "Send failed: " << ec.message(); else std::cout << "sendtx-p2p: Sent " << time(nullptr) << std::endl; }; node->send(tx, handle_send); prot.subscribe_channel( std::bind(send_tx, _1, _2, std::ref(prot), std::ref(tx))); }
void handshake::ready(channel_ptr node, handshake::handshake_handler handle_handshake) { atomic_counter_ptr counter = std::make_shared<atomic_counter>(0); version_type session_version = template_version_; session_version.timestamp = time(NULL); node->send(session_version, strand_.wrap(std::bind(&handshake::handle_message_sent, this, _1, counter, handle_handshake))); node->subscribe_version( strand_.wrap(std::bind(&handshake::receive_version, this, _1, _2, node, counter, handle_handshake))); node->subscribe_verack( strand_.wrap(std::bind(&handshake::receive_verack, this, _1, _2, counter, handle_handshake))); }
void protocol::seeds::request_addresses( const std::error_code& ec, channel_ptr dns_seed_node) { if (ec) { log_error(LOG_PROTOCOL) << "Failed to connect to seed node: " << ec.message(); error_case(ec); } else { dns_seed_node->send(get_address_type(), strand_.wrap(std::bind(&protocol::seeds::handle_send_get_address, shared_from_this(), _1))); dns_seed_node->subscribe_address( strand_.wrap(std::bind(&protocol::seeds::save_addresses, shared_from_this(), _1, _2, dns_seed_node))); } }
void poller::ask_blocks(const std::error_code& ec, const message::block_locator& locator, const hash_digest& hash_stop, channel_ptr node) { if (ec) { log_error(log_domain::poller) << "Ask for blocks: " << ec.message(); return; } if (last_hash_end_ == locator.front()) { log_debug(log_domain::poller) << "Skipping duplicate ask blocks: " << pretty_hex(locator.front()); return; } message::get_blocks packet; packet.start_hashes = locator; packet.hash_stop = hash_stop; node->send(packet, std::bind(&handle_send_packet, _1)); last_hash_end_ = locator.front(); }
void poller::ask_blocks(const std::error_code& ec, const block_locator_type& locator, const hash_digest& hash_stop, channel_ptr node) { if (ec) { log_error(LOG_POLLER) << "Ask for blocks: " << ec.message(); return; } if (last_locator_begin_ == locator.front() && last_hash_stop_ == hash_stop) { log_debug(LOG_POLLER) << "Skipping duplicate ask blocks: " << encode_hex(locator.front()); return; } get_blocks_type packet; packet.start_hashes = locator; packet.hash_stop = hash_stop; node->send(packet, std::bind(&handle_send_packet, _1)); last_locator_begin_ = locator.front(); last_hash_stop_ = hash_stop; }