void protocol::inbound_channel_stopped(const code& ec, channel::ptr node, const std::string& address) { log_debug(LOG_PROTOCOL) << "Channel stopped (inbound) [" << address << "] " << ec.message(); // We never attempt to reconnect inbound connections. remove_connection(inbound_connections_, node); }
// new blocks come in - remove txs in new // old blocks taken out - resubmit txs in old bool transaction_pool::handle_reorganized(const code& ec, size_t fork_point, const block::ptr_list& new_blocks, const block::ptr_list& replaced_blocks) { if (ec == error::service_stopped) { log::debug(LOG_BLOCKCHAIN) << "Stopping transaction pool: " << ec.message(); return false; } if (ec) { log::debug(LOG_BLOCKCHAIN) << "Failure in tx pool reorganize handler: " << ec.message(); return false; } log::debug(LOG_BLOCKCHAIN) << "Reorganize: tx pool size (" << buffer_.size() << ") forked at (" << fork_point << ") new blocks (" << new_blocks.size() << ") replace blocks (" << replaced_blocks.size() << ")"; if (replaced_blocks.empty()) { // Remove memory pool transactions that also exist in new blocks. dispatch_.ordered( std::bind(&transaction_pool::remove, this, new_blocks)); } else { // See http://www.jwz.org/doc/worse-is-better.html // for why we take this approach. We return with an error_code. // An alternative would be resubmit all tx from the cleared blocks. dispatch_.ordered( std::bind(&transaction_pool::clear, this, error::blockchain_reorganized)); } return true; }
void session_manual::handle_channel_stop(const code& ec, const std::string& hostname, uint16_t port) { LOG_DEBUG(LOG_NETWORK) << "Manual channel stopped: " << ec.message(); // Special case for already connected, do not keep trying. // After a stop we don't use the caller's start handler, but keep connecting. if (ec != error::address_in_use) connect(hostname, port); }
void protocol_base_base::handle_timer(const code& ec) { if (stopped() || deadline::canceled(ec)) return; log_debug(LOG_PROTOCOL) << "Fired " << name_ << " protocol timer on [" << authority() << "] " << ec.message(); callback(error::channel_timeout); }
bool callback_state::succeeded(const code& ec, const std::string& format) { if (ec) { // May want to change the behavior to decrement vs. zeroizing refs. error(boost::format(format) % ec.message()); stop(console_result::failure); return false; } return true; }
void protocol_address::handle_store_addresses(const code& ec) { if (stopped()) return; if (ec) { log_error(LOG_PROTOCOL) << "Failure storing addresses from [" << authority() << "] " << ec.message(); stop(ec); } }
void protocol_address::handle_send_get_address(const code& ec) { if (stopped()) return; if (ec) { log_debug(LOG_PROTOCOL) << "Failure sending get_address [" << authority() << "] " << ec.message(); stop(ec); } }
// input: // code guess - a code object containing the user's guess // output: // int incorrect - the number of digits in the guess that exist in the secret, but are not correctly placed // // Check how many digits are part of the secret code, but were guessed at wrong positions. If an index is set to 6 // we know that the index has been covered and will skip it. If an element in the same spot in secretDigits is set to 6, // this also means that the value has been covered. // ASSUMPTION: This is called AFTER checkIncorrect so that it will only check indices that haven't been confirmed int code::checkIncorrect(code guess) { vector<int> userGuess = guess.getGuess(); vector<int> secretCode = guess.getSecret(); vector<int> secretDigits = getDigits(); int incorrect = 0; for (int i=0; i < userGuess.size(); i++) { //Index has already been confirmed, move on if (userGuess[i] == 6) { continue; } //Digit IS part of solution, HAS NOT been verified by checkCorrect, but in wrong place if (find(secretDigits.begin(), secretDigits.end(), userGuess[i]) != secretDigits.end() && userGuess[i] != secretDigits[i] && secretDigits[i] != 6) { incorrect += 1; userGuess[i] = 6; secretDigits[distance( secretDigits.begin(), find(secretDigits.begin(), secretDigits.end(), userGuess[i]))] = 6; } } setDigits(secretDigits); return incorrect; }
void session_inbound::handle_channel_start(const code& ec, channel::ptr channel) { if (ec) { LOG_INFO(LOG_NETWORK) << "Inbound channel failed to start [" << channel->authority() << "] " << ec.message(); return; } attach_protocols(channel); };
void protocol::outbound_channel_stopped(const code& ec, channel::ptr node, const std::string& address) { log_debug(LOG_PROTOCOL) << "Channel stopped (outbound) [" << address << "] " << ec.message(); remove_connection(outbound_connections_, node); // If not shutdown we always create a replacement oubound connection. if (ec != error::service_stopped) new_connection(); }
void p2p::handle_running(const code& ec, result_handler handler) { if (ec) { LOG_ERROR(LOG_NETWORK) << "Error starting outbound session: " << ec.message(); handler(ec); return; } // This is the end of the run sequence. handler(error::success); }
void protocol::manual_channel_stopped(const code& ec, channel::ptr node, const std::string& address, bool relay, size_t retries) { log_debug(LOG_PROTOCOL) << "Channel stopped (manual) [" << address << "] " << ec.message(); remove_connection(manual_connections_, node); // If not shutdown we always attempt to reconnect manual connections. if (ec != error::service_stopped) retry_manual_connection(address, relay, retries); }
void protocol_ping::handle_send_pong(const code& ec) { if (stopped()) return; if (ec) { log::debug(LOG_NETWORK) << "Failure sending pong to [" << authority() << "] " << ec.message(); stop(ec); } }
void protocol_header_sync::handle_send(const code& ec, event_handler complete) { if (stopped()) return; if (ec) { log::debug(LOG_PROTOCOL) << "Failure sending get headers to sync [" << authority() << "] " << ec.message(); complete(ec); } }
void protocol_version_31402::handle_verack_sent(const code& ec) { if (stopped()) return; if (ec) { LOG_DEBUG(LOG_NETWORK) << "Failure sending verack to [" << authority() << "] " << ec.message(); set_event(ec); return; } }
bool protocol_header_sync::handle_receive(const code& ec, headers::ptr message, event_handler complete) { if (stopped()) return false; if (ec) { log::debug(LOG_PROTOCOL) << "Failure receiving headers from sync [" << authority() << "] " << ec.message(); complete(ec); return false; } // A merge failure includes automatic rollback to last trust point. if (!hashes_.enqueue(message)) { log::warning(LOG_PROTOCOL) << "Failure merging headers from [" << authority() << "]"; complete(error::previous_block_invalid); return false; } const auto next = next_height(); log::info(LOG_PROTOCOL) << "Synced headers " << next - message->elements.size() << "-" << (next - 1) << " from [" << authority() << "]"; // If we reached the last height the sync is complete/success. if (next > final_height_) { complete(error::success); return false; } // If we received fewer than 2000 the peer is exhausted, try another. if (message->elements.size() < max_header_response) { complete(error::operation_failed); return false; } // This peer has more headers. send_get_headers(complete); return true; }
void protocol::handle_accept(const code& ec, channel::ptr node, acceptor::ptr accept) { // Relisten for connections. start_accept(ec, accept); if (ec) { log_debug(LOG_PROTOCOL) << "Failure accepting connection: " << ec.message(); return; } if (inbound_connections_.size() >= max_inbound_) { log_debug(LOG_PROTOCOL) << "Rejected inbound connection due to connection limit"; return; } const auto address = node->address(); if (is_blacklisted(node->address())) { log_debug(LOG_PROTOCOL) << "Rejected inbound connection due to blacklisted address"; return; } if (is_loopback(node)) { log_debug(LOG_PROTOCOL) << "Rejected inbound connection from self"; return; } // Save the connection as we are now assured of getting stop event. inbound_connections_.push_back(node); // Accepted! log_info(LOG_PROTOCOL) << "Accepted connection from [" << address << "] (" << inbound_connections_.size() << " total)"; const auto stop_handler = dispatch_.ordered_delegate(&protocol::inbound_channel_stopped, this, _1, node, address.to_string()); start_talking(node, stop_handler, relay_); }
void protocol_base_base::handle_stop(const code& ec) { if (stopped()) return; log_debug(LOG_PROTOCOL) << "Stopped " << name_ << " protocol on [" << authority() << "] " << ec.message(); stopped_ = true; if (deadline_) deadline_->cancel(); callback(ec); }
void session::handle_starting(const code& ec, channel::ptr channel, result_handler handle_started) { if (ec) { LOG_INFO(LOG_NETWORK) << "Channel failed to start [" << channel->authority() << "] " << ec.message(); handle_started(ec); return; } attach_handshake_protocols(channel, BIND_3(handle_handshake, _1, channel, handle_started)); }
int operator%(const code &lhs, const vector<int> &rhs) // Overloaded operator that returns the number of digits in the code // in the lhs that match the vector rhs. { int count = 0; if (lhs.size() != rhs.size()) throw rangeError(); for (int i = 0; i < rhs.size(); i++) if (lhs.seq[i] == rhs[i]) count++; return count; }
void session_inbound::handle_channel_start(const code& ec, channel::ptr channel) { if (ec) { log::info(LOG_NETWORK) << "Inbound channel failed to start [" << channel->authority() << "] " << ec.message(); return; } attach<protocol_ping>(channel)->start(); attach<protocol_address>(channel)->start(); }
void protocol_ping::handle_send_ping(const code& ec) { if (stopped()) return; if (ec) { log::debug(LOG_PROTOCOL) << "Failure sending ping to [" << authority() << "] " << ec.message(); stop(ec); return; } reset_timer(); }
void protocol::start_accept(const code& ec, acceptor::ptr accept) { BITCOIN_ASSERT(accept); if (ec) { log_error(LOG_PROTOCOL) << "Error starting listener: " << ec.message(); return; } // ACCEPT INCOMING CONNECTIONS accept->accept( dispatch_.ordered_delegate(&protocol::handle_accept, this, _1, _2, accept)); }
void session_outbound::handle_channel_start(const code& ec, connector::ptr connect, channel::ptr channel) { // Treat a start failure just like a stop. if (ec) { log::debug(LOG_NETWORK) << "Outbound channel failed to start [" << channel->authority() << "] " << ec.message(); new_connection(connect); return; } attach_protocols(channel); };
// This is fired by the callback (i.e. base timer and stop handler). void protocol_ping_31402::send_ping(const code& ec) { if (stopped()) return; if (ec && ec != error::channel_timeout) { LOG_DEBUG(LOG_NETWORK) << "Failure in ping timer for [" << authority() << "] " << ec.message(); stop(ec); return; } SEND2(ping{}, handle_send, _1, pong::command); }
void protocol::handle_handshake(const code& ec, channel::ptr node) { if (ec) { log_debug(LOG_PROTOCOL) << "Failure in peer handshake [" << node->address() << "] " << ec.message(); node->stop(ec); return; } // Attach ping protocol to the new connection (until node stop event). std::make_shared<protocol_ping>(node, pool_, timeouts_.heartbeat)->start(); // Attach address protocol to the new connection (until node stop event). std::make_shared<protocol_address>(node, pool_, hosts_, self_)->start(); }
void session::handle_handshake(const code& ec, channel::ptr channel, result_handler handle_started) { if (ec) { LOG_DEBUG(LOG_NETWORK) << "Failure in handshake with [" << channel->authority() << "] " << ec.message(); handle_started(ec); return; } // This will fail if the IP address or nonce is already connected. network_.store(channel, handle_started); }
void protocol_seed::handle_send_get_address(const code& ec) { if (stopped()) return; if (ec) { log::debug(LOG_PROTOCOL) << "Failure sending get_address to seed [" << authority() << "] " << ec.message(); set_event(ec); return; } // 2 of 3 set_event(error::success); }
void protocol::start_connecting(const code& ec, completion_handler handle_complete) { if (ec) { log_debug(LOG_PROTOCOL) << "Error seeding hosts: " << ec.message(); handle_complete(ec); return; } // Start outbound connection attempts (not concurrent because of strand). for (size_t channel = 0; channel < max_outbound_; ++channel) new_connection(); handle_complete(error::success); }
void session_inbound::start_accept(const code& ec, acceptor::ptr accept) { if (stopped()) return; if (ec) { log::error(LOG_NETWORK) << "Error starting listener: " << ec.message(); return; } // ACCEPT THE NEXT INCOMING CONNECTION accept->accept( dispatch_.ordered_delegate(&session_inbound::handle_accept, shared_from_base<session_inbound>(), _1, _2, accept)); }