/** * 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; }
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; }
/** * 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()); }
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; }