Beispiel #1
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)));
}
Beispiel #2
0
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));
}
Beispiel #3
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 #4
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 #5
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));
}
Beispiel #6
0
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)));
}
Beispiel #7
0
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)));
}
Beispiel #8
0
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);
}
Beispiel #9
0
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));
}