hash_number simple_chain_impl::sum_difficulty(size_t begin_index)
{
    hash_number total_work = 0;
    const auto last_height = interface_.blocks.last_height();
    BITCOIN_ASSERT(last_height != block_database::null_height);
    for (size_t index = begin_index; index <= last_height; ++index)
    {
        const auto bits = interface_.blocks.get(index).header().bits;
        total_work += block_work(bits);
    }

    return total_work;
}
big_number leveldb_chain_keeper::end_slice_difficulty(size_t slice_begin_index)
{
    big_number total_work = 0;
    leveldb_iterator it(db_blocks_->NewIterator(leveldb::ReadOptions()));
    data_chunk raw_depth = uncast_type(slice_begin_index);
    for (it->Seek(slice(raw_depth)); it->Valid(); it->Next())
    {
        std::stringstream ss;
        ss.str(it->value().ToString());
        protobuf::Block proto_block;
        proto_block.ParseFromIstream(&ss);
        total_work += block_work(proto_block.bits());
    }
    return total_work;
}
bool block_chain_impl::get_difficulty(hash_number& out_difficulty,
    uint64_t height)
{
    size_t top;
    if (!database_.blocks.top(top))
        return false;

    out_difficulty = 0;
    for (uint64_t index = height; index <= top; ++index)
    {
        const auto bits = database_.blocks.get(index).header().bits;
        out_difficulty += block_work(bits);
    }

    return true;
}
hash_number simple_chain_impl::sum_difficulty(uint64_t begin_index)
{
    hash_number total_work = 0;

    size_t last_height;
    if (!database_.blocks.top(last_height))
        return total_work;

    for (uint64_t height = begin_index; height <= last_height; ++height)
    {
        const auto bits = database_.blocks.get(height).header().bits;
        total_work += block_work(bits);
    }

    return total_work;
}
big_number leveldb_chain_keeper::end_slice_difficulty(size_t slice_begin_index)
{
    big_number total_work = 0;
    leveldb_iterator it(db_.block->NewIterator(leveldb::ReadOptions()));
    data_chunk raw_depth = uncast_type(slice_begin_index);
    for (it->Seek(slice(raw_depth)); it->Valid(); it->Next())
    {
        constexpr size_t bits_offset = 4 + 2 * hash_digest_size + 4;
        BITCOIN_ASSERT(it->value().size() >= 84);
        // Deserialize only the bits field of block header.
        std::string raw_bits(it->value().data(), 4);
        auto deserial = make_deserializer(raw_bits.begin(), raw_bits.end());
        uint32_t bits = deserial.read_4_bytes();
        // Accumulate the total work.
        total_work += block_work(bits);
    }
    return total_work;
}