void connection_basic::sleep_before_packet(size_t packet_size, int phase,  int q_len) {
	double delay=0; // will be calculated
	do
	{ // rate limiting
		if (m_was_shutdown) { 
			_dbg2("m_was_shutdown - so abort sleep");
			return;
		}

		{ 
			CRITICAL_REGION_LOCAL(	network_throttle_manager::m_lock_get_global_throttle_out );
			delay = network_throttle_manager::get_global_throttle_out().get_sleep_time_after_tick( packet_size );
		}

		delay *= 0.50;
		if (delay > 0) {
            long int ms = (long int)(delay * 1000);
			MTRACE("Sleeping in " << __FUNCTION__ << " for " << ms << " ms before packet_size="<<packet_size); // debug sleep
			boost::this_thread::sleep(boost::posix_time::milliseconds( ms ) );
		}
	} while(delay > 0);

// XXX LATER XXX
	{
	  CRITICAL_REGION_LOCAL(	network_throttle_manager::m_lock_get_global_throttle_out );
		network_throttle_manager::get_global_throttle_out().handle_trafic_exact( packet_size ); // increase counter - global
	}

}
void connection_basic::set_rate_down_limit(uint64_t limit) {
	{
	  CRITICAL_REGION_LOCAL(	network_throttle_manager::m_lock_get_global_throttle_in );
		network_throttle_manager::get_global_throttle_in().set_target_speed(limit);
	}

	{
	  CRITICAL_REGION_LOCAL(	network_throttle_manager::m_lock_get_global_throttle_inreq );
		network_throttle_manager::get_global_throttle_inreq().set_target_speed(limit);
	}
    save_limit_to_file(limit);
}
Beispiel #3
0
void connection_basic::save_limit_to_file(int limit) {
    // saving limit to file
    if (!epee::net_utils::data_logger::m_save_graph)
        return;

    {
        CRITICAL_REGION_LOCAL(        network_throttle_manager::m_lock_get_global_throttle_out );
        epee::net_utils::data_logger::get_instance().add_data("upload_limit", network_throttle_manager::get_global_throttle_out().get_target_speed() / 1024);
    }

    {
        CRITICAL_REGION_LOCAL(        network_throttle_manager::m_lock_get_global_throttle_in );
        epee::net_utils::data_logger::get_instance().add_data("download_limit", network_throttle_manager::get_global_throttle_in().get_target_speed() / 1024);
    }
}
Beispiel #4
0
  //---------------------------------------------------------------------------------
  //proper tx_pool handling courtesy of CryptoZoidberg and Boolberry
  bool tx_memory_pool::remove_stuck_transactions()
  {
    CRITICAL_REGION_LOCAL(m_transactions_lock);
    for(auto it = m_transactions.begin(); it!= m_transactions.end();)
    {
      uint64_t tx_age = time(nullptr) - it->second.receive_time;

      if((tx_age > CRYPTONOTE_MEMPOOL_TX_LIVETIME && !it->second.kept_by_block) || 
         (tx_age > CRYPTONOTE_MEMPOOL_TX_FROM_ALT_BLOCK_LIVETIME && it->second.kept_by_block) )
      {
        LOG_PRINT_L1("Tx " << it->first << " removed from tx pool due to outdated, age: " << tx_age );
        remove_transaction_keyimages(it->second.tx);
        auto sorted_it = find_tx_in_sorted_container(it->first);
        if (sorted_it == m_txs_by_fee.end())
        {
          LOG_PRINT_L1("Removing tx " << it->first << " from tx pool, but it was not found in the sorted txs container!");
        }
        else
        {
          m_txs_by_fee.erase(sorted_it);
        }
        m_transactions.erase(it++);
      }else
        ++it;
    }
    return true;
  }
	//---------------------------------------------------------------------------------
	bool tx_memory_pool::have_tx(const crypto::hash &id)
	{
		CRITICAL_REGION_LOCAL(m_transactions_lock);
		if (m_transactions.count(id))
			return true;
		return false;
	}
bool daemon_backend::generate_wallet(const std::string& path, const std::string& password)
{
  CRITICAL_REGION_LOCAL(m_wallet_lock);
  try
  {
    if (m_wallet->get_wallet_path().size())
    {
      m_wallet->store();
      m_wallet.reset(new tools::wallet2());
    }

    m_wallet->generate(path, password);
  }
  catch (const std::exception& e)
  {
    m_pview->show_msg_box(std::string("Failed to generate wallet: ") + e.what());
    m_wallet.reset(new tools::wallet2());
    return false;
  }

  m_wallet->init(std::string("127.0.0.1:") + std::to_string(m_rpc_server.get_binded_port()));
  update_wallet_info();
  m_last_wallet_synch_height = 0;
  m_pview->show_wallet();
  return true;

}
	//---------------------------------------------------------------------------------
	bool tx_memory_pool::remove_transaction_keyimages(const transaction& tx)
	{
		CRITICAL_REGION_LOCAL(m_transactions_lock);
		BOOST_FOREACH(const txin_v& vi, tx.vin)
		{
			CHECKED_GET_SPECIFIC_VARIANT(vi, const txin_to_key, txin, false);
			auto it = m_spent_key_images.find(txin.k_image);
			CHECK_AND_ASSERT_MES(it != m_spent_key_images.end(), false, "failed to find transaction input in key images. img=" << txin.k_image << ENDL
				<< "transaction id = " << get_transaction_hash(tx));
			std::unordered_set<crypto::hash>& key_image_set = it->second;
			CHECK_AND_ASSERT_MES(key_image_set.size(), false, "empty key_image set, img=" << txin.k_image << ENDL
				<< "transaction id = " << get_transaction_hash(tx));

			auto it_in_set = key_image_set.find(get_transaction_hash(tx));
			CHECK_AND_ASSERT_MES(it_in_set != key_image_set.end(), false, "transaction id not found in key_image set, img=" << txin.k_image << ENDL
				<< "transaction id = " << get_transaction_hash(tx));
			key_image_set.erase(it_in_set);
			if (!key_image_set.size())
			{
				//it is now empty hash container for this key_image
				m_spent_key_images.erase(it);
			}

		}
		return true;
	}
	//---------------------------------------------------------------------------------
	void  tx_memory_pool::clear()
	{
		CRITICAL_REGION_LOCAL(m_transactions_lock);
		m_transactions.clear();
		m_spent_key_images.clear();
		m_aliases_to_txid.clear();
	}
Beispiel #9
0
//---------------------------------------------------------------------------------
std::string tx_memory_pool::print_pool(bool short_format)
{
    std::stringstream ss;
    CRITICAL_REGION_LOCAL(m_transactions_lock);
    BOOST_FOREACH(transactions_container::value_type& txe,  m_transactions)
    {
        if(short_format)
        {
            tx_details& txd = txe.second;
            ss << "id: " << txe.first << ENDL
               << "blob_size: " << txd.blob_size << ENDL
               << "fee: " << txd.fee << ENDL
               << "kept_by_block: " << txd.kept_by_block << ENDL
               << "max_used_block_height: " << txd.max_used_block_height << ENDL
               << "max_used_block_id: " << txd.max_used_block_id << ENDL
               << "last_failed_height: " << txd.last_failed_height << ENDL
               << "last_failed_id: " << txd.last_failed_id << ENDL;
        } else
        {
            tx_details& txd = txe.second;
            ss << "id: " << txe.first << ENDL
               <<  obj_to_json_str(txd.tx) << ENDL
               << "blob_size: " << txd.blob_size << ENDL
               << "fee: " << txd.fee << ENDL
               << "kept_by_block: " << txd.kept_by_block << ENDL
               << "max_used_block_height: " << txd.max_used_block_height << ENDL
               << "max_used_block_id: " << txd.max_used_block_id << ENDL
               << "last_failed_height: " << txd.last_failed_height << ENDL
               << "last_failed_id: " << txd.last_failed_id << ENDL;
        }

    }
    return ss.str();
}
Beispiel #10
0
  //------------------------------------------------------------------
  bool tx_memory_pool::get_transactions_and_spent_keys_info(std::vector<tx_info>& tx_infos, std::vector<spent_key_image_info>& key_image_infos) const
  {
    CRITICAL_REGION_LOCAL(m_transactions_lock);
    for (const auto& tx_vt : m_transactions)
    {
      tx_info txi;
      const tx_details& txd = tx_vt.second;
      txi.id_hash = epee::string_tools::pod_to_hex(tx_vt.first);
      txi.tx_json = obj_to_json_str(*const_cast<transaction*>(&txd.tx));
      txi.blob_size = txd.blob_size;
      txi.fee = txd.fee;
      txi.kept_by_block = txd.kept_by_block;
      txi.max_used_block_height = txd.max_used_block_height;
      txi.max_used_block_id_hash = epee::string_tools::pod_to_hex(txd.max_used_block_id);
      txi.last_failed_height = txd.last_failed_height;
      txi.last_failed_id_hash = epee::string_tools::pod_to_hex(txd.last_failed_id);
      txi.receive_time = txd.receive_time;
      tx_infos.push_back(txi);
    }

    for (const key_images_container::value_type& kee : m_spent_key_images) {
      const crypto::key_image& k_image = kee.first;
      const std::unordered_set<crypto::hash>& kei_image_set = kee.second;
      spent_key_image_info ki;
      ki.id_hash = epee::string_tools::pod_to_hex(k_image);
      for (const crypto::hash& tx_id_hash : kei_image_set)
      {
        ki.txs_hashes.push_back(epee::string_tools::pod_to_hex(tx_id_hash));
      }
      key_image_infos.push_back(ki);
    }
    return true;
  }
Beispiel #11
0
//---------------------------------------------------------------------------------
bool tx_memory_pool::fill_block_template(block &bl, size_t median_size, uint64_t already_generated_coins, uint64_t already_donated_coins, size_t &total_size, uint64_t &fee) {
    typedef transactions_container::value_type txv;
    CRITICAL_REGION_LOCAL(m_transactions_lock);

    std::vector<txv *> txs(m_transactions.size());
    std::transform(m_transactions.begin(), m_transactions.end(), txs.begin(), [](txv &a) -> txv * { return &a; });
    std::sort(txs.begin(), txs.end(), [](txv *a, txv *b) -> bool {
        uint64_t a_hi, a_lo = mul128(a->second.fee, b->second.blob_size, &a_hi);
        uint64_t b_hi, b_lo = mul128(b->second.fee, a->second.blob_size, &b_hi);
        return a_hi > b_hi || (a_hi == b_hi && a_lo > b_lo);
    });

    size_t current_size = 0;
    uint64_t current_fee = 0;
    uint64_t best_money;
    uint64_t max_donation = 0;
    if (!get_block_reward(median_size, CURRENCY_COINBASE_BLOB_RESERVED_SIZE, already_generated_coins, already_donated_coins, best_money, max_donation)) {
        LOG_ERROR("Block with just a miner transaction is already too large!");
        return false;
    }
    size_t best_position = 0;
    total_size = 0;
    fee = 0;

    std::unordered_set<crypto::key_image> k_images;

    for (size_t i = 0; i < txs.size(); i++) {
        txv &tx(*txs[i]);

        if(!is_transaction_ready_to_go(tx.second) || have_key_images(k_images, tx.second.tx)) {
            txs[i] = NULL;
            continue;
        }
        append_key_images(k_images, tx.second.tx);

        current_size += tx.second.blob_size;
        current_fee += tx.second.fee;

        uint64_t current_reward;
        if (!get_block_reward(median_size, current_size + CURRENCY_COINBASE_BLOB_RESERVED_SIZE, already_generated_coins, already_donated_coins, current_reward, max_donation)) {
            break;
        }

        if (best_money < current_reward + current_fee) {
            best_money = current_reward + current_fee;
            best_position = i + 1;
            total_size = current_size;
            fee = current_fee;
        }
    }

    for (size_t i = 0; i < best_position; i++) {
        if (txs[i]) {
            bl.tx_hashes.push_back(txs[i]->first);
        }
    }

    return true;
}
Beispiel #12
0
	//---------------------------------------------------------------------------------
	bool tx_memory_pool::get_transactions(std::list<transaction>& txs)
	{
		CRITICAL_REGION_LOCAL(m_transactions_lock);
		BOOST_FOREACH(const auto& tx_vt, m_transactions)
			txs.push_back(tx_vt.second.tx);

		return true;
	}
Beispiel #13
0
uint64_t connection_basic::get_rate_down_limit() {
    uint64_t limit;
    {
         CRITICAL_REGION_LOCAL( network_throttle_manager::m_lock_get_global_throttle_in );
         limit = network_throttle_manager::get_global_throttle_in().get_target_speed();
	}
    return limit;
}
Beispiel #14
0
	//---------------------------------------------------------------------------------
	bool tx_memory_pool::get_transaction(const crypto::hash& id, transaction& tx)
	{
		CRITICAL_REGION_LOCAL(m_transactions_lock);
		auto it = m_transactions.find(id);
		if (it == m_transactions.end())
			return false;
		tx = it->second.tx;
		return true;
	}
  //-----------------------------------------------------------------------------------------------
  bool core::handle_incoming_tx(const blobdata& tx_blob, tx_verification_context& tvc, bool keeped_by_block)
  {
    tvc = boost::value_initialized<tx_verification_context>();
    //want to process all transactions sequentially
    CRITICAL_REGION_LOCAL(m_incoming_tx_lock);

    if(tx_blob.size() > m_currency.maxTxSize())
    {
      LOG_PRINT_L0("WRONG TRANSACTION BLOB, too big size " << tx_blob.size() << ", rejected");
      tvc.m_verifivation_failed = true;
      return false;
    }

    crypto::hash tx_hash = null_hash;
    crypto::hash tx_prefixt_hash = null_hash;
    Transaction tx;

    if(!parse_tx_from_blob(tx, tx_hash, tx_prefixt_hash, tx_blob))
    {
      LOG_PRINT_L0("WRONG TRANSACTION BLOB, Failed to parse, rejected");
      tvc.m_verifivation_failed = true;
      return false;
    }
    //std::cout << "!"<< tx.vin.size() << std::endl;

    if(!check_tx_syntax(tx))
    {
      LOG_PRINT_L0("WRONG TRANSACTION BLOB, Failed to check tx " << tx_hash << " syntax, rejected");
      tvc.m_verifivation_failed = true;
      return false;
    }

    if(!check_tx_semantic(tx, keeped_by_block))
    {
      LOG_PRINT_L0("WRONG TRANSACTION BLOB, Failed to check tx " << tx_hash << " semantic, rejected");
      tvc.m_verifivation_failed = true;
      return false;
    }

    bool r = add_new_tx(tx, tx_hash, tx_prefixt_hash, tx_blob.size(), tvc, keeped_by_block);
    if(tvc.m_verifivation_failed) {
      if (!tvc.m_tx_fee_too_small) {
        LOG_PRINT_RED_L0("Transaction verification failed: " << tx_hash);
      } else {
        LOG_PRINT_L0("Transaction verification failed: " << tx_hash);
      }
    } else if(tvc.m_verifivation_impossible) {
      LOG_PRINT_RED_L0("Transaction verification impossible: " << tx_hash);
    }

    if (tvc.m_added_to_pool) {
      LOG_PRINT_L1("tx added: " << tx_hash);
      poolUpdated();
    }

    return r;
  }
Beispiel #16
0
//---------------------------------------------------------------------------------
bool tx_memory_pool::have_tx_keyimges_as_spent(const transaction& tx)
{
    CRITICAL_REGION_LOCAL(m_transactions_lock);
    BOOST_FOREACH(const auto& in, tx.vin)
    {
        CHECKED_GET_SPECIFIC_VARIANT(in, const txin_to_key, tokey_in, true);//should never fail
        if(have_tx_keyimg_as_spent(tokey_in.k_image))
            return true;
    }
    return false;
}
Beispiel #17
0
void connection_basic::set_rate_up_limit(uint64_t limit) {

    // TODO remove __SCALING_FACTOR...
    const double SCALING_FACTOR = 2.1; // to acheve the best performance
    limit *= SCALING_FACTOR;
    {
        CRITICAL_REGION_LOCAL(	network_throttle_manager::m_lock_get_global_throttle_out );
        network_throttle_manager::get_global_throttle_out().set_target_speed(limit);
        network_throttle_manager::get_global_throttle_out().set_real_target_speed(limit / SCALING_FACTOR);
    }
    save_limit_to_file(limit);
}
Beispiel #18
0
//---------------------------------------------------------------------------------
bool tx_memory_pool::take_tx(const crypto::hash &id, transaction &tx, size_t& blob_size, uint64_t& fee)
{
    CRITICAL_REGION_LOCAL(m_transactions_lock);
    auto it = m_transactions.find(id);
    if(it == m_transactions.end())
        return false;

    tx = it->second.tx;
    blob_size = it->second.blob_size;
    fee = it->second.fee;
    remove_transaction_keyimages(it->second.tx);
    m_transactions.erase(it);
    return true;
}
Beispiel #19
0
	//---------------------------------------------------------------------------------
	crypto::hash  tx_memory_pool::find_alias(std::string & alias)
	{
		//remove_alias
		if (alias.size())
		{
			CRITICAL_REGION_LOCAL(m_aliases_lock);
			auto it = m_aliases_to_txid.find(alias);
			if (it != m_aliases_to_txid.end())
			{
				return it->second;
			}
		}
		return null_hash;
	}
bool daemon_backend::update_wallet_info()
{
  CRITICAL_REGION_LOCAL(m_wallet_lock);


  view::wallet_info wi = AUTO_VAL_INIT(wi);
  wi.address = m_wallet->get_account().get_public_address_str();
  wi.tracking_hey = string_tools::pod_to_hex(m_wallet->get_account().get_keys().m_view_secret_key);
  wi.balance = currency::print_money(m_wallet->balance());
  wi.unlocked_balance = currency::print_money(m_wallet->unlocked_balance());
  wi.path = m_wallet->get_wallet_path();
  m_pview->update_wallet_info(wi);
  return true;
}
Beispiel #21
0
	//---------------------------------------------------------------------------------
	bool  tx_memory_pool::remove_alias_tx_pair(crypto::hash id)
	{
		CRITICAL_REGION_LOCAL(m_aliases_lock);
		bool bFound = false;
		for (auto it = m_aliases_to_txid.begin(); it != m_aliases_to_txid.end(); it++)
		{
			crypto::hash hash = it->second;
			if (hash == id)
			{
				m_aliases_to_txid.erase(it);
				bFound = true;
				break;
			}
		}
		return bFound;
	}
  //-----------------------------------------------------------------------------------------------
  //bool core::get_outs(uint64_t amount, std::list<crypto::public_key>& pkeys)
  //{
  //  return m_blockchain_storage.get_outs(amount, pkeys);
  //}
  //-----------------------------------------------------------------------------------------------
  bool core::add_new_tx(const Transaction& tx, const crypto::hash& tx_hash, const crypto::hash& tx_prefix_hash, size_t blob_size, tx_verification_context& tvc, bool keeped_by_block) {
    if (m_blockchain_storage.have_tx(tx_hash)) {
      LOG_PRINT_L2("tx " << tx_hash << " is already in blockchain");
      return true;
    }

    // It's not very good to lock on m_mempool here, because it's very hard to understand the order of locking
    // tx_memory_pool::m_transactions_lock, blockchain_storage::m_blockchain_lock, and core::m_incoming_tx_lock
    CRITICAL_REGION_LOCAL(m_mempool);
    if (m_mempool.have_tx(tx_hash)) {
      LOG_PRINT_L2("tx " << tx_hash << " is already in transaction pool");
      return true;
    }

    return m_mempool.add_tx(tx, tx_hash, blob_size, tvc, keeped_by_block);
  }
Beispiel #23
0
//---------------------------------------------------------------------------------
bool tx_memory_pool::remove_stuck_transactions()
{
    CRITICAL_REGION_LOCAL(m_transactions_lock);
    for(auto it = m_transactions.begin(); it!= m_transactions.end();)
    {
        uint64_t tx_age = time(nullptr) - it->second.receive_time;

        if((tx_age > CURRENCY_MEMPOOL_TX_LIVETIME && !it->second.kept_by_block) /*||
         (tx_age > CURRENCY_MEMPOOL_TX_FROM_ALT_BLOCK_LIVETIME && it->second.kept_by_block) */)
        {
            LOG_PRINT_L0("Tx " << it->first << " removed from tx pool due to outdated, age: " << tx_age );
            m_transactions.erase(it++);
        } else
            ++it;
    }
    return true;
}
Beispiel #24
0
	//---------------------------------------------------------------------------------
	bool tx_memory_pool::add_alias_tx_pair(std::string & alias, crypto::hash id)
	{
		//check alias repeat or not
		if (alias.size())
		{
			CRITICAL_REGION_LOCAL(m_aliases_lock);
			crypto::hash h = find_alias(alias);
			if (h != null_hash)
			{
				LOG_ERROR("the same alias " << alias << " exists in pool, id: " << h << ", so tx: " << id << " can't be added to pool.");
				return false;
			}
			m_aliases_to_txid[alias] = id;
			LOG_PRINT_L2("Add alias: " << alias << " into pool with tx: " << id);
		}
		return true;
	}
bool daemon_backend::close_wallet()
{
  CRITICAL_REGION_LOCAL(m_wallet_lock);
  try
  {
    if (m_wallet->get_wallet_path().size())
    {
      m_wallet->store();
      m_wallet.reset(new tools::wallet2());
    }
  }

  catch (const std::exception& e)
  {
    m_pview->show_msg_box(std::string("Failed to close wallet: ") + e.what());
    return false;
  }
  m_pview->hide_wallet();
  return true;
}
Beispiel #26
0
	//---------------------------------------------------------------------------------
	bool tx_memory_pool::have_tx_keyimges_as_spent(const transaction& tx)
	{
		CRITICAL_REGION_LOCAL(m_transactions_lock);
		BOOST_FOREACH(const auto& in, tx.vin)
		{
			CHECKED_GET_SPECIFIC_VARIANT(in, const txin_to_key, tokey_in, true);//should never fail
			if (have_tx_keyimg_as_spent(tokey_in.k_image))
			{
				LOG_PRINT_L2("tx_memory_pool: key img spent: " << tokey_in.k_image << ", amount: " << tokey_in.amount);
				std::stringstream ss;
				ss << "keyoffsets: ";

				BOOST_FOREACH(const auto& of, tokey_in.key_offsets)
				{
					ss << of << " ";
				}
				LOG_PRINT_L2(ss.str());
				return true;
			}
		}
bool daemon_backend::update_wallets()
{
  CRITICAL_REGION_LOCAL(m_wallet_lock);
  if(m_wallet->get_wallet_path().size())
  {//wallet is opened
    if(m_last_daemon_height != m_last_wallet_synch_height)
    {
      view::wallet_status_info wsi = AUTO_VAL_INIT(wsi);
      wsi.wallet_state = view::wallet_status_info::wallet_state_synchronizing;
      m_pview->update_wallet_status(wsi);
      try
      {
        m_wallet->refresh();
      }
      
      catch (const tools::error::daemon_busy& /*e*/)
      {
        LOG_PRINT_L0("Daemon busy while wallet refresh");
        return true;
      }

      catch (const std::exception& e)
      {
        LOG_PRINT_L0("Failed to refresh wallet: " << e.what());
        return false;
      }

      catch (...)
      {
        LOG_PRINT_L0("Failed to refresh wallet, unknownk exception");
        return false;
      }

      m_last_wallet_synch_height = m_ccore.get_current_blockchain_height();
      wsi.wallet_state = view::wallet_status_info::wallet_state_ready;
      m_pview->update_wallet_status(wsi);
      update_wallet_info();
    }
  }
  return true;
}
Beispiel #28
0
  //---------------------------------------------------------------------------------
  std::string tx_memory_pool::print_pool(bool short_format) const
  {
    std::stringstream ss;
    CRITICAL_REGION_LOCAL(m_transactions_lock);
    for (const transactions_container::value_type& txe : m_transactions) {
      const tx_details& txd = txe.second;
      ss << "id: " << txe.first << std::endl;
      if (!short_format) {
        ss << obj_to_json_str(*const_cast<transaction*>(&txd.tx)) << std::endl;
      }
      ss << "blob_size: " << txd.blob_size << std::endl
        << "fee: " << print_money(txd.fee) << std::endl
        << "kept_by_block: " << (txd.kept_by_block ? 'T' : 'F') << std::endl
        << "max_used_block_height: " << txd.max_used_block_height << std::endl
        << "max_used_block_id: " << txd.max_used_block_id << std::endl
        << "last_failed_height: " << txd.last_failed_height << std::endl
        << "last_failed_id: " << txd.last_failed_id << std::endl;
    }

    return ss.str();
  }
Beispiel #29
0
  //---------------------------------------------------------------------------------
  bool tx_memory_pool::init(const std::string& config_folder)
  {
    CRITICAL_REGION_LOCAL(m_transactions_lock);

    m_config_folder = config_folder;
    std::string state_file_path = config_folder + "/" + CRYPTONOTE_POOLDATA_FILENAME;
    boost::system::error_code ec;
    if(!boost::filesystem::exists(state_file_path, ec))
      return true;
    bool res = tools::unserialize_obj_from_file(*this, state_file_path);
    if(!res)
    {
      LOG_PRINT_L1("Failed to load memory pool from file " << state_file_path);

      m_transactions.clear();
      m_txs_by_fee.clear();
      m_spent_key_images.clear();
    }

    for (auto it = m_transactions.begin(); it != m_transactions.end(); ) {
      if (it->second.blob_size >= TRANSACTION_SIZE_LIMIT) {
        LOG_PRINT_L1("Transaction " << get_transaction_hash(it->second.tx) << " is too big (" << it->second.blob_size << " bytes), removing it from pool");
        remove_transaction_keyimages(it->second.tx);
        m_transactions.erase(it);
      }
      it++;
    }

    // no need to store queue of sorted transactions, as it's easy to generate.
    for (const auto& tx : m_transactions)
    {
      m_txs_by_fee.emplace((double)tx.second.blob_size / tx.second.fee, tx.first);
    }

    // Ignore deserialization error
    return true;
  }
Beispiel #30
0
  //---------------------------------------------------------------------------------
  std::string tx_memory_pool::print_pool(bool short_format)
  {
    std::stringstream ss;
    CRITICAL_REGION_LOCAL(m_transactions_lock);
    BOOST_FOREACH(transactions_container::value_type& txe,  m_transactions)
    {
      if(short_format)
      {
        tx_details& txd = txe.second;
        ss << "id: " << txe.first << ENDL
          << "blob_size: " << txd.blob_size << ENDL
          << "fee: " << txd.fee << ENDL
          << "kept_by_block: " << (txd.kept_by_block ? "true":"false") << ENDL
          << "max_used_block_height: " << txd.max_used_block_height << ENDL
          << "max_used_block_id: " << txd.max_used_block_id << ENDL
          << "last_failed_height: " << txd.last_failed_height << ENDL
          << "last_failed_id: " << txd.last_failed_id << ENDL
          << "live_time: " << epee::misc_utils::get_time_interval_string(time(nullptr) - txd.receive_time) << ENDL;
      }else
      {
        tx_details& txd = txe.second;
        ss << "id: " << txe.first << ENDL
          <<  obj_to_json_str(txd.tx) << ENDL
          << "blob_size: " << txd.blob_size << ENDL
          << "fee: " << txd.fee << ENDL
          << "kept_by_block: " << (txd.kept_by_block ? "true":"false") << ENDL
          << "max_used_block_height: " << txd.max_used_block_height << ENDL
          << "max_used_block_id: " << txd.max_used_block_id << ENDL
          << "last_failed_height: " << txd.last_failed_height << ENDL
          << "last_failed_id: " << txd.last_failed_id << ENDL
          << "live_time: " << epee::misc_utils::get_time_interval_string(time(nullptr) - txd.receive_time) << ENDL;
      }

    }
    return ss.str();
  }