Beispiel #1
0
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);
}
Beispiel #2
0
 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&) {});
 }
Beispiel #3
0
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&) {});
    }
}
Beispiel #7
0
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);
}
Beispiel #8
0
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);
}
Beispiel #9
0
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));
}
Beispiel #10
0
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)));
}
Beispiel #11
0
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);
}
Beispiel #12
0
// 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();
}
Beispiel #13
0
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));
}
Beispiel #14
0
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);
}
Beispiel #15
0
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&) {});
    }
}
Beispiel #17
0
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);
}
Beispiel #18
0
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)));
}
Beispiel #19
0
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)));
}
Beispiel #20
0
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)));
    }

}
Beispiel #22
0
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();
}
Beispiel #23
0
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;
}