예제 #1
0
            /**
             * Copy constructor
             * @param other The other data_buffer.
             */
			data_buffer(const data_buffer & other)
			    : m_read_ptr(0)
                , file_offset_(other.file_offset_)
                , file_(other.file_)
			{
                clear();
                
			    write_bytes(other.data(), other.size());
                
                m_read_ptr = m_data.size() > 0 ? &m_data[0] : 0;
			}
예제 #2
0
bool db_tx::read(const data_buffer & key, T & value)
{
    if (m_Db == 0)
    {
        return false;
    }
    
    Dbt dbt_key(key.data(), static_cast<std::uint32_t> (key.size()));

    Dbt dbt_value;
    
    dbt_value.set_flags(DB_DBT_MALLOC);
    
    auto ret = m_Db->get(m_DbTxn, &dbt_key, &dbt_value, 0);
    
    std::memset(dbt_key.get_data(), 0, dbt_key.get_size());
    
    if (dbt_value.get_data() == 0)
    {
        return false;
    }
    
    try
    {
        /**
         * Allocate the data_buffer.
         */
        data_buffer buffer(
            static_cast<char *>(dbt_value.get_data()), dbt_value.get_size()
        );
        
        /**
         * Decode the value from the buffer.
         */
        value.decode(buffer);
    }
    catch (std::exception & e)
    {
        log_error("DB TX read failed, what = " << e.what() << ".");
        
        return false;
    }

    std::memset(dbt_value.get_data(), 0, dbt_value.get_size());
    
    free(dbt_value.get_data());
    
    return ret == 0;
}
예제 #3
0
 /**
  * Copy constructor
  * @param other The other data_buffer.
  */
 data_buffer(const data_buffer & other)
     : m_read_ptr(0)
     , file_offset_(0)
 {
     write_bytes(other.data(), other.size());
 }
예제 #4
0
bool utility::add_orphan_tx(const data_buffer & buffer)
{
    /**
     * Copy the buffer.
     */
    auto buffer_copy = std::make_shared<data_buffer> (
        buffer.data(), buffer.size()
    );
    
    /**
     * Allocate the transaction.
     */
    transaction tx;
    
    /**
     * Decode the transaction from the buffer.
     */
    tx.decode(*buffer_copy);
    
    /**
     * Rewind the buffer.
     */
    buffer_copy->rewind();
    
    /**
     * Get the hash of the transaction.
     */
    auto hash_tx = tx.get_hash();
    
    if (globals::instance().orphan_transactions().count(hash_tx) > 0)
    {
        return false;
    }

    /**
     * Ignore big transactions, to avoid a send-big-orphans memory
     * exhaustion attack. If a peer has a legitimate large transaction
     * with a missing parent then we assume it will rebroadcast it later,
     * after the parent transaction(s) have been mined or received.
     * 10,000 orphans, each of which is at most 5,000 bytes big is at most 
     * 500 megabytes of orphans.
     */
    if (buffer_copy->size() > 5000)
    {
        log_debug(
            "Utility, add orphan tx ignoring large orphan tx size = " <<
            buffer_copy->size() << ", hash = " <<
            hash_tx.to_string().substr(0, 10)  << "."
        );

        return false;
    }

    globals::instance().orphan_transactions()[hash_tx] = buffer_copy;
    
    for (auto & i : tx.transactions_in())
    {
        globals::instance().orphan_transactions_by_previous()[
            i.previous_out().get_hash()].insert(
            std::make_pair(hash_tx, buffer_copy)
        );
    }

    log_debug(
        "Utility, add orphan tx stored orphan tx " <<
        hash_tx.to_string().substr(0, 10) << ", orphans = " <<
        globals::instance().orphan_transactions().size() << "."
    );
    
    return true;
}