forked from lthn/blockchain
merged from develop
This commit is contained in:
commit
19d3ba7fb2
14 changed files with 458 additions and 94 deletions
|
|
@ -117,34 +117,34 @@ namespace net_utils
|
|||
//some helpers
|
||||
|
||||
|
||||
inline
|
||||
std::string print_connection_context(const connection_context_base& ctx)
|
||||
inline std::string print_connection_context(const connection_context_base& ctx)
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << epee::string_tools::get_ip_string_from_int32(ctx.m_remote_ip) << ":" << ctx.m_remote_port << " " << epee::string_tools::get_str_from_guid_a(ctx.m_connection_id) << (ctx.m_is_income ? " INC":" OUT");
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
inline
|
||||
void print_connection_context_short(const connection_context_base& ctx, std::stringstream& ss)
|
||||
inline std::ostream &operator <<(std::ostream &o, const connection_context_base& ctx)
|
||||
{
|
||||
ss << epee::string_tools::get_ip_string_from_int32(ctx.m_remote_ip) << ":" << ctx.m_remote_port << (ctx.m_is_income ? " INC" : " OUT");
|
||||
}
|
||||
o << epee::string_tools::get_ip_string_from_int32(ctx.m_remote_ip) << ":" << ctx.m_remote_port << (ctx.m_is_income ? " INC" : " OUT");
|
||||
return o;
|
||||
}
|
||||
|
||||
inline
|
||||
std::string print_connection_context_short(const connection_context_base& ctx)
|
||||
inline std::string print_connection_context_short(const connection_context_base& ctx)
|
||||
{
|
||||
std::stringstream ss;
|
||||
print_connection_context_short(ctx, ss);
|
||||
ss << ctx;
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
inline std::string print_connection_context_list(const std::list<connection_context_base>& contexts)
|
||||
inline std::string print_connection_context_list(const std::list<connection_context_base>& contexts, const std::string& delim = std::string("\n"))
|
||||
{
|
||||
std::stringstream ss;
|
||||
for (auto& c : contexts)
|
||||
{
|
||||
ss << epee::string_tools::get_ip_string_from_int32(c.m_remote_ip) << ":" << c.m_remote_port << (c.m_is_income ? " INC" : " OUT") << ENDL;
|
||||
if (ss.tellp())
|
||||
ss << delim;
|
||||
ss << c;
|
||||
}
|
||||
return ss.str();
|
||||
}
|
||||
|
|
@ -179,7 +179,7 @@ namespace net_utils
|
|||
|
||||
#define CHECK_AND_ASSERT_MES_CC(condition, return_val, err_message) CHECK_AND_ASSERT_MES(condition, return_val, "[" << epee::net_utils::print_connection_context_short(context) << "]" << err_message)
|
||||
|
||||
}
|
||||
}
|
||||
} // namespace net_utils
|
||||
} // namespace epee
|
||||
|
||||
#endif //_NET_UTILS_BASE_H_
|
||||
|
|
|
|||
|
|
@ -34,6 +34,8 @@ DISABLE_VS_WARNINGS(4244 4345 4503) //'boost::foreach_detail_::or_' : decorated
|
|||
|
||||
#define CURRENCY_POOLDATA_FOLDERNAME_SUFFIX "_v1"
|
||||
|
||||
#define CONFLICT_KEY_IMAGE_SPENT_DEPTH_TO_REMOVE_TX_FROM_POOL 50 // if there's a conflict in key images between tx in the pool and in the blockchain this much depth in required to remove correspongin tx from pool
|
||||
|
||||
#undef LOG_DEFAULT_CHANNEL
|
||||
#define LOG_DEFAULT_CHANNEL "tx_pool"
|
||||
ENABLE_CHANNEL_BY_DEFAULT("tx_pool");
|
||||
|
|
@ -429,18 +431,41 @@ namespace currency
|
|||
int64_t tx_age = get_core_time() - tx_entry.receive_time;
|
||||
if ((tx_age > CURRENCY_MEMPOOL_TX_LIVETIME ))
|
||||
{
|
||||
|
||||
LOG_PRINT_L0("Tx " << h << " removed from tx pool, reason: outdated, age: " << tx_age);
|
||||
LOG_PRINT_L0("tx " << h << " is about to be removed from tx pool, reason: outdated, age: " << tx_age << " = " << misc_utils::get_time_interval_string(tx_age));
|
||||
to_delete.push_back(tx_to_delete_entry(h, tx_entry.tx, tx_entry.kept_by_block));
|
||||
}
|
||||
|
||||
// expiration time check - remove expired
|
||||
if (is_tx_expired(tx_entry.tx, tx_expiration_ts_median) )
|
||||
{
|
||||
LOG_PRINT_L0("Tx " << h << " removed from tx pool, reason: expired, expiration time: " << get_tx_expiration_time(tx_entry.tx) << ", blockchain median: " << tx_expiration_ts_median);
|
||||
LOG_PRINT_L0("tx " << h << " is about to be removed from tx pool, reason: expired, expiration time: " << get_tx_expiration_time(tx_entry.tx) << ", blockchain median: " << tx_expiration_ts_median);
|
||||
to_delete.push_back(tx_to_delete_entry(h, tx_entry.tx, tx_entry.kept_by_block));
|
||||
}
|
||||
|
||||
// if a tx has at least one key image already used in blockchain (deep enough) -- remove such tx, as it cannot be added to any block
|
||||
// although it will be removed by the age check above, we consider desireable
|
||||
// to remove it from the pool faster in order to unblock related key images used in the same tx
|
||||
uint64_t should_be_spent_before_height = m_blockchain.get_current_blockchain_size() - 1;
|
||||
if (should_be_spent_before_height > CONFLICT_KEY_IMAGE_SPENT_DEPTH_TO_REMOVE_TX_FROM_POOL)
|
||||
{
|
||||
should_be_spent_before_height -= CONFLICT_KEY_IMAGE_SPENT_DEPTH_TO_REMOVE_TX_FROM_POOL;
|
||||
for (auto& in : tx_entry.tx.vin)
|
||||
{
|
||||
if (in.type() == typeid(txin_to_key))
|
||||
{
|
||||
// if at least one key image is spent deep enought -- remove such tx
|
||||
const crypto::key_image& ki = boost::get<txin_to_key>(in).k_image;
|
||||
if (m_blockchain.have_tx_keyimg_as_spent(ki, should_be_spent_before_height))
|
||||
{
|
||||
LOG_PRINT_L0("tx " << h << " is about to be removed from tx pool, reason: ki was spent in the blockchain before height " << should_be_spent_before_height << ", tx age: " << misc_utils::get_time_interval_string(tx_age));
|
||||
to_delete.push_back(tx_to_delete_entry(h, tx_entry.tx, tx_entry.kept_by_block));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@
|
|||
PUSH_VS_WARNINGS
|
||||
DISABLE_VS_WARNINGS(4355)
|
||||
|
||||
#define ASYNC_RELAY_MODE
|
||||
#define ASYNC_RELAY_MODE // relay transactions asyncronously via m_relay_que
|
||||
|
||||
namespace currency
|
||||
{
|
||||
|
|
@ -117,25 +117,25 @@ namespace currency
|
|||
int64_t m_last_ntp2local_time_difference;
|
||||
|
||||
template<class t_parametr>
|
||||
bool post_notify(typename t_parametr::request& arg, currency_connection_context& context)
|
||||
{
|
||||
LOG_PRINT_L2("[POST]" << typeid(t_parametr).name());
|
||||
std::string blob;
|
||||
epee::serialization::store_t_to_binary(arg, blob);
|
||||
return m_p2p->invoke_notify_to_peer(t_parametr::ID, blob, context);
|
||||
}
|
||||
bool post_notify(typename t_parametr::request& arg, currency_connection_context& context)
|
||||
{
|
||||
LOG_PRINT_L3("[POST]" << typeid(t_parametr).name() << " to " << context);
|
||||
std::string blob;
|
||||
epee::serialization::store_t_to_binary(arg, blob);
|
||||
return m_p2p->invoke_notify_to_peer(t_parametr::ID, blob, context);
|
||||
}
|
||||
|
||||
template<class t_parametr>
|
||||
bool relay_post_notify(typename t_parametr::request& arg, currency_connection_context& exlude_context)
|
||||
{
|
||||
std::string arg_buff;
|
||||
epee::serialization::store_t_to_binary(arg, arg_buff);
|
||||
std::list<epee::net_utils::connection_context_base> relayed_peers;
|
||||
bool r = m_p2p->relay_notify_to_all(t_parametr::ID, arg_buff, exlude_context, relayed_peers);
|
||||
template<class t_parametr>
|
||||
bool relay_post_notify(typename t_parametr::request& arg, currency_connection_context& exlude_context)
|
||||
{
|
||||
std::string arg_buff;
|
||||
epee::serialization::store_t_to_binary(arg, arg_buff);
|
||||
std::list<epee::net_utils::connection_context_base> relayed_peers;
|
||||
bool r = m_p2p->relay_notify_to_all(t_parametr::ID, arg_buff, exlude_context, relayed_peers);
|
||||
|
||||
LOG_PRINT_GREEN("[POST RELAY] " << typeid(t_parametr).name() << " relayed contexts list: " << ENDL << print_connection_context_list(relayed_peers), LOG_LEVEL_2);
|
||||
return r;
|
||||
}
|
||||
LOG_PRINT_GREEN("[POST RELAY] " << typeid(t_parametr).name() << " to (" << relayed_peers.size() << "): " << print_connection_context_list(relayed_peers, ", "), LOG_LEVEL_2);
|
||||
return r;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -94,22 +94,32 @@ namespace currency
|
|||
<< std::setw(20) << "Peer id"
|
||||
<< std::setw(25) << "Recv/Sent (idle,sec)"
|
||||
<< std::setw(25) << "State"
|
||||
<< std::setw(20) << "Livetime(seconds)"
|
||||
<< std::setw(20) << "Livetime"
|
||||
<< std::setw(20) << "Client version" << ENDL;
|
||||
|
||||
size_t incoming_count = 0, outgoing_count = 0;
|
||||
std::multimap<time_t, std::string> conn_map;
|
||||
m_p2p->for_each_connection([&](const connection_context& cntxt, nodetool::peerid_type peer_id)
|
||||
{
|
||||
ss << std::setw(29) << std::left << std::string(cntxt.m_is_income ? "[INC]":"[OUT]") +
|
||||
std::stringstream conn_ss;
|
||||
time_t livetime = time(NULL) - cntxt.m_started;
|
||||
conn_ss << std::setw(29) << std::left << std::string(cntxt.m_is_income ? "[INC]":"[OUT]") +
|
||||
string_tools::get_ip_string_from_int32(cntxt.m_remote_ip) + ":" + std::to_string(cntxt.m_remote_port)
|
||||
<< std::setw(20) << std::hex << peer_id
|
||||
<< std::setw(25) << std::to_string(cntxt.m_recv_cnt)+ "(" + std::to_string(time(NULL) - cntxt.m_last_recv) + ")" + "/" + std::to_string(cntxt.m_send_cnt) + "(" + std::to_string(time(NULL) - cntxt.m_last_send) + ")"
|
||||
<< std::setw(25) << get_protocol_state_string(cntxt.m_state)
|
||||
<< std::setw(20) << std::to_string(time(NULL) - cntxt.m_started)
|
||||
<< std::setw(20) << epee::misc_utils::get_time_interval_string(livetime)
|
||||
<< std::setw(20) << cntxt.m_remote_version
|
||||
<< ENDL;
|
||||
conn_map.insert(std::make_pair(livetime, conn_ss.str()));
|
||||
(cntxt.m_is_income ? incoming_count : outgoing_count) += 1;
|
||||
return true;
|
||||
});
|
||||
LOG_PRINT_L0("Connections: " << ENDL << ss.str());
|
||||
|
||||
for(auto it = conn_map.rbegin(); it != conn_map.rend(); ++it)
|
||||
ss << it->second;
|
||||
|
||||
LOG_PRINT_L0("Connections (" << incoming_count << " in, " << outgoing_count << " out, " << incoming_count + outgoing_count << " total):" << ENDL << ss.str());
|
||||
}
|
||||
//------------------------------------------------------------------------------------------------------------------------
|
||||
template<class t_core>
|
||||
|
|
@ -235,7 +245,6 @@ namespace currency
|
|||
if(context.m_state != currency_connection_context::state_normal)
|
||||
return 1;
|
||||
|
||||
|
||||
//check if block already exists
|
||||
block b = AUTO_VAL_INIT(b);
|
||||
block_verification_context bvc = AUTO_VAL_INIT(bvc);
|
||||
|
|
@ -245,6 +254,7 @@ namespace currency
|
|||
m_p2p->drop_connection(context);
|
||||
return 1;
|
||||
}
|
||||
|
||||
crypto::hash block_id = get_block_hash(b);
|
||||
LOG_PRINT_GREEN("[HANDLE]NOTIFY_NEW_BLOCK " << block_id << " HEIGHT " << get_block_height(b) << " (hop " << arg.hop << ")", LOG_LEVEL_2);
|
||||
|
||||
|
|
@ -314,11 +324,11 @@ namespace currency
|
|||
m_p2p->drop_connection(context);
|
||||
return 1;
|
||||
}
|
||||
LOG_PRINT_GREEN("[HANDLE]NOTIFY_NEW_BLOCK EXTRA: id: " << block_id
|
||||
<< ",bvc.m_added_to_main_chain " << bvc.m_added_to_main_chain
|
||||
//<< ",prevalidate_result " << prevalidate_relayed
|
||||
<< ",bvc.added_to_altchain " << bvc.added_to_altchain
|
||||
<< ",bvc.m_marked_as_orphaned " << bvc.m_marked_as_orphaned, LOG_LEVEL_2);
|
||||
LOG_PRINT_GREEN("[HANDLE]NOTIFY_NEW_BLOCK EXTRA " << block_id
|
||||
<< " bvc.m_added_to_main_chain=" << bvc.m_added_to_main_chain
|
||||
//<< ", prevalidate_result=" << prevalidate_relayed
|
||||
<< ", bvc.added_to_altchain=" << bvc.added_to_altchain
|
||||
<< ", bvc.m_marked_as_orphaned=" << bvc.m_marked_as_orphaned, LOG_LEVEL_2);
|
||||
|
||||
if (bvc.m_added_to_main_chain || (bvc.added_to_altchain && bvc.height_difference < 2))
|
||||
{
|
||||
|
|
@ -723,13 +733,14 @@ namespace currency
|
|||
if (req.txs.size())
|
||||
{
|
||||
post_notify<NOTIFY_NEW_TRANSACTIONS>(req, cc);
|
||||
print_connection_context_short(cc, debug_ss);
|
||||
debug_ss << ": " << req.txs.size() << ENDL;
|
||||
|
||||
if (debug_ss.tellp())
|
||||
debug_ss << ", ";
|
||||
debug_ss << cc << ": " << req.txs.size();
|
||||
}
|
||||
}
|
||||
TIME_MEASURE_FINISH_MS(ms);
|
||||
LOG_PRINT_GREEN("[POST RELAY] NOTIFY_NEW_TRANSACTIONS relayed (" << ms << "ms)contexts list: " << debug_ss.str(), LOG_LEVEL_2);
|
||||
|
||||
LOG_PRINT_GREEN("[POST RELAY] NOTIFY_NEW_TRANSACTIONS relayed (" << ms << "ms) to: " << debug_ss.str(), LOG_LEVEL_2);
|
||||
}
|
||||
//------------------------------------------------------------------------------------------------------------------------
|
||||
template<class t_core>
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ using namespace epee;
|
|||
|
||||
#undef LOG_DEFAULT_CHANNEL
|
||||
#define LOG_DEFAULT_CHANNEL "p2p"
|
||||
ENABLE_CHANNEL_BY_DEFAULT(LOG_DEFAULT_CHANNEL);
|
||||
|
||||
#define CURRENT_P2P_STORAGE_ARCHIVE_VER (CURRENCY_FORMATION_VERSION+13)
|
||||
|
||||
|
|
@ -198,6 +199,7 @@ namespace nodetool
|
|||
bool make_new_connection_from_peerlist(bool use_white_list);
|
||||
bool try_to_connect_and_handshake_with_new_peer(const net_address& na, bool just_take_peerlist = false, uint64_t last_seen_stamp = 0, bool white = true);
|
||||
size_t get_random_index_with_fixed_probability(size_t max_index);
|
||||
bool is_peer_id_used(const peerid_type id);
|
||||
bool is_peer_used(const peerlist_entry& peer);
|
||||
bool is_addr_connected(const net_address& peer);
|
||||
template<class t_callback>
|
||||
|
|
|
|||
|
|
@ -511,6 +511,13 @@ namespace nodetool
|
|||
return;
|
||||
}
|
||||
|
||||
if (is_peer_id_used(rsp.node_data.peer_id))
|
||||
{
|
||||
LOG_PRINT_L0("It seems that peer " << std::hex << rsp.node_data.peer_id << " has already been connected, dropping connection");
|
||||
hsh_result = false;
|
||||
return;
|
||||
}
|
||||
|
||||
pi = context.peer_id = rsp.node_data.peer_id;
|
||||
m_peerlist.set_peer_just_seen(rsp.node_data.peer_id, context.m_remote_ip, context.m_remote_port);
|
||||
|
||||
|
|
@ -535,7 +542,7 @@ namespace nodetool
|
|||
|
||||
if(!hsh_result)
|
||||
{
|
||||
LOG_PRINT_CC_L0(context_, "COMMAND_HANDSHAKE Failed");
|
||||
LOG_PRINT_CC_L0(context_, "COMMAND_HANDSHAKE Failed, closing connection");
|
||||
m_net_server.get_config_object().close(context_.m_connection_id);
|
||||
}
|
||||
|
||||
|
|
@ -597,6 +604,26 @@ namespace nodetool
|
|||
}
|
||||
//-----------------------------------------------------------------------------------
|
||||
template<class t_payload_net_handler>
|
||||
bool node_server<t_payload_net_handler>::is_peer_id_used(const peerid_type id)
|
||||
{
|
||||
if (id == m_config.m_peer_id)
|
||||
return true; // ourself
|
||||
|
||||
bool used = false;
|
||||
m_net_server.get_config_object().foreach_connection([&](const p2p_connection_context& cntxt)
|
||||
{
|
||||
if (id == cntxt.peer_id)
|
||||
{
|
||||
used = true;
|
||||
return false; // stop enumerating
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
return used;
|
||||
}
|
||||
//-----------------------------------------------------------------------------------
|
||||
template<class t_payload_net_handler>
|
||||
bool node_server<t_payload_net_handler>::is_peer_used(const peerlist_entry& peer)
|
||||
{
|
||||
|
||||
|
|
@ -638,7 +665,7 @@ namespace nodetool
|
|||
template<class t_payload_net_handler>
|
||||
bool node_server<t_payload_net_handler>::try_to_connect_and_handshake_with_new_peer(const net_address& na, bool just_take_peerlist, uint64_t last_seen_stamp, bool white)
|
||||
{
|
||||
LOG_PRINT_L0("Connecting to " << string_tools::get_ip_string_from_int32(na.ip) << ":" << string_tools::num_to_string_fast(na.port) << "(white=" << white << ", last_seen: " << (last_seen_stamp?misc_utils::get_time_interval_string(time(NULL) - last_seen_stamp):"never" ) << ")...");
|
||||
LOG_PRINT_L1("Connecting to " << string_tools::get_ip_string_from_int32(na.ip) << ":" << string_tools::num_to_string_fast(na.port) << "(white=" << white << ", last_seen: " << (last_seen_stamp?misc_utils::get_time_interval_string(time(NULL) - last_seen_stamp):"never" ) << ")...");
|
||||
|
||||
typename net_server::t_connection_context con = AUTO_VAL_INIT(con);
|
||||
bool res = m_net_server.connect(string_tools::get_ip_string_from_int32(na.ip),
|
||||
|
|
@ -647,7 +674,7 @@ namespace nodetool
|
|||
con);
|
||||
if(!res)
|
||||
{
|
||||
LOG_PRINT_L0("Connect failed to "
|
||||
LOG_PRINT_L1("Connect failed to "
|
||||
<< string_tools::get_ip_string_from_int32(na.ip)
|
||||
<< ":" << string_tools::num_to_string_fast(na.port)
|
||||
/*<< ", try " << try_count*/);
|
||||
|
|
@ -661,9 +688,11 @@ namespace nodetool
|
|||
LOG_PRINT_CC_L0(con, "Failed to HANDSHAKE with peer "
|
||||
<< string_tools::get_ip_string_from_int32(na.ip)
|
||||
<< ":" << string_tools::num_to_string_fast(na.port)
|
||||
/*<< ", try " << try_count*/);
|
||||
<< ", closing connection");
|
||||
m_net_server.get_config_object().close(con.m_connection_id);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(just_take_peerlist)
|
||||
{
|
||||
m_net_server.get_config_object().close(con.m_connection_id);
|
||||
|
|
@ -807,7 +836,10 @@ namespace nodetool
|
|||
|
||||
if(is_addr_connected(na))
|
||||
continue;
|
||||
try_to_connect_and_handshake_with_new_peer(na);
|
||||
if (!try_to_connect_and_handshake_with_new_peer(na))
|
||||
{
|
||||
LOG_PRINT_L0("connection to priority node " << string_tools::get_ip_string_from_int32(na.ip) << ":" << string_tools::num_to_string_fast(na.port) << " failed");
|
||||
}
|
||||
}
|
||||
if(m_use_only_priority_peers)
|
||||
return true;
|
||||
|
|
@ -1310,6 +1342,13 @@ namespace nodetool
|
|||
return 1;
|
||||
}
|
||||
|
||||
if (is_peer_id_used(arg.node_data.peer_id))
|
||||
{
|
||||
LOG_PRINT_CCONTEXT_L1("COMMAND_HANDSHAKE came, but seems that peer " << std::hex << arg.node_data.peer_id << " has already been connected to this node, dropping connection");
|
||||
drop_connection(context);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!tools::check_remote_client_version(arg.payload_data.client_version))
|
||||
{
|
||||
LOG_PRINT_CCONTEXT_L2("COMMAND_HANDSHAKE: wrong client version: " << arg.payload_data.client_version << ", closing connection.");
|
||||
|
|
|
|||
|
|
@ -8,6 +8,6 @@
|
|||
#define PROJECT_REVISION "2"
|
||||
#define PROJECT_VERSION PROJECT_MAJOR_VERSION "." PROJECT_MINOR_VERSION "." PROJECT_REVISION
|
||||
|
||||
#define PROJECT_VERSION_BUILD_NO 67
|
||||
#define PROJECT_VERSION_BUILD_NO 68
|
||||
#define PROJECT_VERSION_BUILD_NO_STR STRINGIFY_EXPAND(PROJECT_VERSION_BUILD_NO)
|
||||
#define PROJECT_VERSION_LONG PROJECT_VERSION "." PROJECT_VERSION_BUILD_NO_STR "[" BUILD_COMMIT_ID "]"
|
||||
|
|
|
|||
|
|
@ -2066,7 +2066,7 @@ void wallet2::store(const std::wstring& path_to_save, const std::string& passwor
|
|||
{
|
||||
LOG_PRINT_L0("(before storing: pending_key_images: " << m_pending_key_images.size() << ", pki file elements: " << m_pending_key_images_file_container.size() << ", tx_keys: " << m_tx_keys.size() << ")");
|
||||
|
||||
check_for_free_space_and_throw_if_it_lacks(path_to_save);
|
||||
// check_for_free_space_and_throw_if_it_lacks(path_to_save); temporary disabled, wallet saving implemented in two-stage scheme to avoid data loss due to lack of space
|
||||
|
||||
std::string ascii_path_to_save = epee::string_encoding::convert_to_ansii(path_to_save);
|
||||
|
||||
|
|
@ -2099,8 +2099,9 @@ void wallet2::store(const std::wstring& path_to_save, const std::string& passwor
|
|||
r = tools::portble_serialize_obj_to_stream(*this, data_file);
|
||||
if (!r)
|
||||
{
|
||||
data_file.close();
|
||||
boost::filesystem::remove(tmp_file_path); // remove tmp file if smth went wrong
|
||||
WLT_THROW_IF_FALSE_WALLET_CMN_ERR_EX(false, "portble_serialize_obj_to_stream failed for wallet " << tmp_file_path.string());
|
||||
WLT_THROW_IF_FALSE_WALLET_CMN_ERR_EX(false, "IO error while storing wallet to " << tmp_file_path.string() << " (portble_serialize_obj_to_stream failed)");
|
||||
}
|
||||
|
||||
data_file.flush();
|
||||
|
|
@ -2229,7 +2230,7 @@ uint64_t wallet2::balance(uint64_t& unlocked, uint64_t& awaiting_in, uint64_t& a
|
|||
|
||||
for(auto& td : m_transfers)
|
||||
{
|
||||
if (td.is_spendable() || td.is_reserved_for_escrow())
|
||||
if (td.is_spendable() || (td.is_reserved_for_escrow() && !td.is_spent()))
|
||||
{
|
||||
balance_total += td.amount();
|
||||
if (is_transfer_unlocked(td))
|
||||
|
|
|
|||
|
|
@ -731,6 +731,7 @@ int main(int argc, char* argv[])
|
|||
GENERATE_AND_PLAY(escrow_cancellation_acceptance_expiration);
|
||||
// GENERATE_AND_PLAY(escrow_proposal_acceptance_in_alt_chain); -- work in progress
|
||||
GENERATE_AND_PLAY(escrow_zero_amounts);
|
||||
GENERATE_AND_PLAY(escrow_acceptance_and_balance);
|
||||
|
||||
GENERATE_AND_PLAY(escrow_altchain_meta_test<0>);
|
||||
GENERATE_AND_PLAY(escrow_altchain_meta_test<1>);
|
||||
|
|
|
|||
|
|
@ -3095,3 +3095,200 @@ bool escrow_zero_amounts::c1(currency::core& c, size_t ev_index, const std::vect
|
|||
|
||||
return true;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
escrow_acceptance_and_balance::escrow_acceptance_and_balance()
|
||||
: m_alice_bob_start_amount(0)
|
||||
, m_alice_bob_start_chunk_amount(0)
|
||||
, m_alice_fee_proposal(0)
|
||||
, m_bob_fee_accept(0)
|
||||
, m_bob_fee_release(0)
|
||||
{
|
||||
REGISTER_CALLBACK_METHOD(escrow_acceptance_and_balance, check_balance_after_proposal_not_confirmed);
|
||||
REGISTER_CALLBACK_METHOD(escrow_acceptance_and_balance, check_balance_after_proposal_confirmed);
|
||||
REGISTER_CALLBACK_METHOD(escrow_acceptance_and_balance, check_balance_after_acceptance_not_confirmed);
|
||||
REGISTER_CALLBACK_METHOD(escrow_acceptance_and_balance, check_balance_after_acceptance_confirmed);
|
||||
}
|
||||
|
||||
bool escrow_acceptance_and_balance::generate(std::vector<test_event_entry>& events) const
|
||||
{
|
||||
m_accounts.resize(TOTAL_ACCS_COUNT);
|
||||
account_base& miner_acc = m_accounts[MINER_ACC_IDX]; miner_acc.generate();
|
||||
account_base& alice_acc = m_accounts[ALICE_ACC_IDX]; alice_acc.generate();
|
||||
account_base& bob_acc = m_accounts[BOB_ACC_IDX]; bob_acc.generate();
|
||||
|
||||
MAKE_GENESIS_BLOCK(events, blk_0, miner_acc, test_core_time::get_time());
|
||||
REWIND_BLOCKS_N_WITH_TIME(events, blk_0r, blk_0, miner_acc, CURRENCY_MINED_MONEY_UNLOCK_WINDOW);
|
||||
|
||||
m_alice_bob_start_amount = MK_TEST_COINS(200);
|
||||
uint64_t amount_chunks = 10;
|
||||
m_alice_bob_start_chunk_amount = m_alice_bob_start_amount / 10;
|
||||
|
||||
transaction tx_0 = AUTO_VAL_INIT(tx_0);
|
||||
bool r = construct_tx_with_many_outputs(events, blk_0r, miner_acc.get_keys(), alice_acc.get_public_address(), m_alice_bob_start_amount, 10, TESTS_DEFAULT_FEE, tx_0);
|
||||
CHECK_AND_ASSERT_MES(r, false, "construct_tx_with_many_outputs failed");
|
||||
events.push_back(tx_0);
|
||||
|
||||
transaction tx_1 = AUTO_VAL_INIT(tx_1);
|
||||
r = construct_tx_with_many_outputs(events, blk_0r, miner_acc.get_keys(), bob_acc.get_public_address(), m_alice_bob_start_amount, 10, TESTS_DEFAULT_FEE, tx_1);
|
||||
CHECK_AND_ASSERT_MES(r, false, "construct_tx_with_many_outputs failed");
|
||||
events.push_back(tx_1);
|
||||
|
||||
MAKE_NEXT_BLOCK_TX_LIST(events, blk_1, blk_0r, miner_acc, std::list<transaction>({tx_0, tx_1}));
|
||||
|
||||
REWIND_BLOCKS_N_WITH_TIME(events, blk_1r, blk_1, miner_acc, WALLET_DEFAULT_TX_SPENDABLE_AGE);
|
||||
|
||||
// prepare contract details
|
||||
m_cpd = AUTO_VAL_INIT(m_cpd);
|
||||
m_cpd.amount_a_pledge = MK_TEST_COINS(7);
|
||||
m_cpd.amount_b_pledge = MK_TEST_COINS(5);
|
||||
m_cpd.amount_to_pay = MK_TEST_COINS(3);
|
||||
m_cpd.a_addr = alice_acc.get_public_address();
|
||||
m_cpd.b_addr = bob_acc.get_public_address();
|
||||
m_alice_fee_proposal = MK_TEST_COINS(4);
|
||||
m_bob_fee_accept = MK_TEST_COINS(2);
|
||||
m_bob_fee_release = MK_TEST_COINS(9); // Alice states that Bob should pay this much money for upcoming contract release (which will be sent by Alice)
|
||||
|
||||
std::vector<tx_source_entry> used_sources;
|
||||
|
||||
// escrow proposal
|
||||
bc_services::proposal_body prop = AUTO_VAL_INIT(prop);
|
||||
transaction escrow_proposal_tx = AUTO_VAL_INIT(escrow_proposal_tx);
|
||||
r = build_custom_escrow_proposal(events, blk_1r, alice_acc.get_keys(), m_cpd, 0, 0, 0, blk_1r.timestamp + 36000, 0, m_alice_fee_proposal, m_bob_fee_release, eccf_normal, escrow_proposal_tx, used_sources, &prop);
|
||||
CHECK_AND_ASSERT_MES(r, false, "build_custom_escrow_proposal failed");
|
||||
events.push_back(escrow_proposal_tx);
|
||||
|
||||
DO_CALLBACK(events, "check_balance_after_proposal_not_confirmed");
|
||||
|
||||
MAKE_NEXT_BLOCK_TX1(events, blk_2, blk_1r, miner_acc, escrow_proposal_tx);
|
||||
|
||||
DO_CALLBACK(events, "check_balance_after_proposal_confirmed");
|
||||
|
||||
MAKE_NEXT_BLOCK(events, blk_3, blk_2, miner_acc);
|
||||
|
||||
DO_CALLBACK(events, "check_balance_after_proposal_confirmed");
|
||||
|
||||
// escrow proposal acceptance
|
||||
transaction escrow_normal_acceptance_tx = prop.tx_template;
|
||||
uint64_t normal_acceptance_mask = eccf_normal;
|
||||
r = build_custom_escrow_accept_proposal(events, blk_2, 0, bob_acc.get_keys(), m_cpd, 0, 0, 0, 0, m_bob_fee_accept, m_bob_fee_release, normal_acceptance_mask, prop.tx_onetime_secret_key, escrow_normal_acceptance_tx, used_sources);
|
||||
CHECK_AND_ASSERT_MES(r, false, "build_custom_escrow_accept_proposal failed");
|
||||
|
||||
events.push_back(escrow_normal_acceptance_tx);
|
||||
|
||||
DO_CALLBACK(events, "check_balance_after_acceptance_not_confirmed");
|
||||
|
||||
MAKE_NEXT_BLOCK_TX1(events, blk_4, blk_3, miner_acc, escrow_normal_acceptance_tx);
|
||||
|
||||
DO_CALLBACK(events, "check_balance_after_acceptance_confirmed");
|
||||
|
||||
MAKE_NEXT_BLOCK(events, blk_5, blk_4, miner_acc);
|
||||
|
||||
DO_CALLBACK(events, "check_balance_after_acceptance_confirmed");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool escrow_acceptance_and_balance::check_balance_after_proposal_not_confirmed(currency::core& c, size_t ev_index, const std::vector<test_event_entry>& events)
|
||||
{
|
||||
std::shared_ptr<tools::wallet2> alice_wlt = init_playtime_test_wallet(events, c, ALICE_ACC_IDX);
|
||||
std::shared_ptr<tools::wallet2> bob_wlt = init_playtime_test_wallet(events, c, BOB_ACC_IDX);
|
||||
|
||||
CHECK_AND_ASSERT_MES(refresh_wallet_and_check_balance("", "Alice", alice_wlt,
|
||||
m_alice_bob_start_amount - m_alice_fee_proposal, // total
|
||||
true, UINT64_MAX,
|
||||
m_alice_bob_start_amount - 2 * m_alice_bob_start_chunk_amount, // unlocked
|
||||
0, // mined
|
||||
MK_TEST_COINS(0), // awaited in
|
||||
MK_TEST_COINS(0) // awainted out
|
||||
), false, "");
|
||||
|
||||
CHECK_AND_ASSERT_MES(refresh_wallet_and_check_balance("", "Bob", bob_wlt,
|
||||
m_alice_bob_start_amount, // total
|
||||
true, UINT64_MAX,
|
||||
m_alice_bob_start_amount, // unlocked
|
||||
0, // mined
|
||||
MK_TEST_COINS(0), // awaited in
|
||||
MK_TEST_COINS(0) // awaited out
|
||||
), false, "");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool escrow_acceptance_and_balance::check_balance_after_proposal_confirmed(currency::core& c, size_t ev_index, const std::vector<test_event_entry>& events)
|
||||
{
|
||||
std::shared_ptr<tools::wallet2> alice_wlt = init_playtime_test_wallet(events, c, ALICE_ACC_IDX);
|
||||
std::shared_ptr<tools::wallet2> bob_wlt = init_playtime_test_wallet(events, c, BOB_ACC_IDX);
|
||||
|
||||
CHECK_AND_ASSERT_MES(refresh_wallet_and_check_balance("", "Alice", alice_wlt,
|
||||
m_alice_bob_start_amount - m_alice_fee_proposal, // total
|
||||
true, UINT64_MAX,
|
||||
m_alice_bob_start_amount - 2 * m_alice_bob_start_chunk_amount, // unlocked
|
||||
0, // mined
|
||||
MK_TEST_COINS(0), // awaited in
|
||||
MK_TEST_COINS(0) // awaited out
|
||||
), false, "");
|
||||
|
||||
CHECK_AND_ASSERT_MES(refresh_wallet_and_check_balance("", "Bob", bob_wlt,
|
||||
m_alice_bob_start_amount, // total
|
||||
true, UINT64_MAX,
|
||||
m_alice_bob_start_amount, // unlocked
|
||||
0, // mined
|
||||
MK_TEST_COINS(0), // awaited in
|
||||
MK_TEST_COINS(0) // awaited out
|
||||
), false, "");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool escrow_acceptance_and_balance::check_balance_after_acceptance_not_confirmed(currency::core& c, size_t ev_index, const std::vector<test_event_entry>& events)
|
||||
{
|
||||
std::shared_ptr<tools::wallet2> alice_wlt = init_playtime_test_wallet(events, c, ALICE_ACC_IDX);
|
||||
std::shared_ptr<tools::wallet2> bob_wlt = init_playtime_test_wallet(events, c, BOB_ACC_IDX);
|
||||
|
||||
CHECK_AND_ASSERT_MES(refresh_wallet_and_check_balance("", "Alice", alice_wlt,
|
||||
m_alice_bob_start_amount - m_alice_fee_proposal - m_cpd.amount_a_pledge - m_cpd.amount_to_pay, // total
|
||||
true, UINT64_MAX,
|
||||
m_alice_bob_start_amount - 2 * m_alice_bob_start_chunk_amount, // unlocked
|
||||
0, // mined
|
||||
MK_TEST_COINS(0), // awaited in
|
||||
m_cpd.amount_a_pledge + m_cpd.amount_to_pay), // awaited out
|
||||
false, "");
|
||||
|
||||
CHECK_AND_ASSERT_MES(refresh_wallet_and_check_balance("", "Bob", bob_wlt,
|
||||
m_alice_bob_start_amount - m_cpd.amount_b_pledge - m_bob_fee_release - m_bob_fee_accept, // total
|
||||
true, UINT64_MAX,
|
||||
m_alice_bob_start_amount - 1 * m_alice_bob_start_chunk_amount, // unlocked
|
||||
0, // mined
|
||||
MK_TEST_COINS(0), // awaited in
|
||||
m_cpd.amount_b_pledge + m_bob_fee_release), // awaited out
|
||||
false, "");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool escrow_acceptance_and_balance::check_balance_after_acceptance_confirmed(currency::core& c, size_t ev_index, const std::vector<test_event_entry>& events)
|
||||
{
|
||||
std::shared_ptr<tools::wallet2> alice_wlt = init_playtime_test_wallet(events, c, ALICE_ACC_IDX);
|
||||
std::shared_ptr<tools::wallet2> bob_wlt = init_playtime_test_wallet(events, c, BOB_ACC_IDX);
|
||||
|
||||
CHECK_AND_ASSERT_MES(refresh_wallet_and_check_balance("", "Alice", alice_wlt,
|
||||
m_alice_bob_start_amount - m_alice_fee_proposal - m_cpd.amount_a_pledge - m_cpd.amount_to_pay, // total
|
||||
true, UINT64_MAX,
|
||||
m_alice_bob_start_amount - 2 * m_alice_bob_start_chunk_amount, // unlocked
|
||||
0, // mined
|
||||
MK_TEST_COINS(0), // awaited in
|
||||
MK_TEST_COINS(0) // awaited out
|
||||
), false, "");
|
||||
|
||||
CHECK_AND_ASSERT_MES(refresh_wallet_and_check_balance("", "Bob", bob_wlt,
|
||||
m_alice_bob_start_amount - m_cpd.amount_b_pledge - m_bob_fee_release - m_bob_fee_accept, // total
|
||||
true, UINT64_MAX,
|
||||
m_alice_bob_start_amount - 1 * m_alice_bob_start_chunk_amount, // unlocked
|
||||
0, // mined
|
||||
MK_TEST_COINS(0), // awaited in
|
||||
MK_TEST_COINS(0) // awaited out
|
||||
), false, "");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -141,3 +141,20 @@ struct escrow_zero_amounts : public wallet_test
|
|||
bool generate(std::vector<test_event_entry>& events) const;
|
||||
bool c1(currency::core& c, size_t ev_index, const std::vector<test_event_entry>& events);
|
||||
};
|
||||
|
||||
struct escrow_acceptance_and_balance : public wallet_test
|
||||
{
|
||||
escrow_acceptance_and_balance();
|
||||
bool generate(std::vector<test_event_entry>& events) const;
|
||||
bool check_balance_after_proposal_not_confirmed(currency::core& c, size_t ev_index, const std::vector<test_event_entry>& events);
|
||||
bool check_balance_after_proposal_confirmed(currency::core& c, size_t ev_index, const std::vector<test_event_entry>& events);
|
||||
bool check_balance_after_acceptance_not_confirmed(currency::core& c, size_t ev_index, const std::vector<test_event_entry>& events);
|
||||
bool check_balance_after_acceptance_confirmed(currency::core& c, size_t ev_index, const std::vector<test_event_entry>& events);
|
||||
|
||||
mutable uint64_t m_alice_bob_start_amount;
|
||||
mutable uint64_t m_alice_bob_start_chunk_amount;
|
||||
mutable uint64_t m_alice_fee_proposal;
|
||||
mutable uint64_t m_bob_fee_release;
|
||||
mutable uint64_t m_bob_fee_accept;
|
||||
mutable bc_services::contract_private_details m_cpd;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1453,14 +1453,13 @@ bool tx_expiration_time_and_chain_switching::generate(std::vector<test_event_ent
|
|||
|
||||
//------------------------------------------------------------------
|
||||
|
||||
tx_key_image_pool_conflict::tx_key_image_pool_conflict()
|
||||
{
|
||||
REGISTER_CALLBACK_METHOD(tx_key_image_pool_conflict, c1);
|
||||
REGISTER_CALLBACK_METHOD(tx_key_image_pool_conflict, c2);
|
||||
}
|
||||
|
||||
bool tx_key_image_pool_conflict::generate(std::vector<test_event_entry>& events) const
|
||||
{
|
||||
// Test idea: check tx that is stuck in tx pool because one on its key images is already spent in the blockchain
|
||||
// 1) if it's linked to an alt block -- tx will not be removed as long as linked alt block exists (in order to be able to switch)
|
||||
// 2) if it's not linked to an alt block -- it will be removed after CONFLICT_KEY_IMAGE_SPENT_DEPTH_TO_REMOVE_TX_FROM_POOL confirmations of conflicted tx
|
||||
// or it will be removed once tx is old enough (CURRENCY_MEMPOOL_TX_LIVETIME)
|
||||
|
||||
bool r = false;
|
||||
|
||||
m_miner_acc.generate();
|
||||
|
|
@ -1534,44 +1533,49 @@ bool tx_key_image_pool_conflict::generate(std::vector<test_event_entry>& events)
|
|||
// however, it does not remove tx from the pool
|
||||
DO_CALLBACK_PARAMS(events, "check_tx_pool_count", static_cast<size_t>(2));
|
||||
|
||||
//
|
||||
// make sure stuck tx will be removed from the pool when it's too old
|
||||
//
|
||||
|
||||
MAKE_NEXT_BLOCK(events, blk_2, blk_1, m_miner_acc);
|
||||
|
||||
DO_CALLBACK(events, "remove_stuck_txs");
|
||||
|
||||
// remove_stuck_txs should not remove anything, tx_1 and tx_2 should be in the pool
|
||||
DO_CALLBACK(events, "remove_stuck_txs");
|
||||
DO_CALLBACK_PARAMS(events, "check_tx_pool_count", static_cast<size_t>(2));
|
||||
|
||||
// shift time by CURRENCY_MEMPOOL_TX_LIVETIME
|
||||
events.push_back(event_core_time(CURRENCY_MEMPOOL_TX_LIVETIME + 1, true));
|
||||
|
||||
// remove_stuck_txs should remove only tx_2 and left tx_1
|
||||
// remove_stuck_txs should have removed tx_2 because it's too old
|
||||
DO_CALLBACK(events, "remove_stuck_txs");
|
||||
DO_CALLBACK_PARAMS(events, "check_tx_pool_count", static_cast<size_t>(1));
|
||||
|
||||
//
|
||||
// make sure stuck tx will be removed from the pool as soon as one of its key images is spent deep enough in the blockchain
|
||||
// (even if it's not too old to be removed by age)
|
||||
//
|
||||
|
||||
MAKE_NEXT_BLOCK(events, blk_3, blk_2, m_miner_acc);
|
||||
|
||||
// re-add tx_2 with kept_by_block flag
|
||||
events.push_back(event_visitor_settings(event_visitor_settings::set_txs_kept_by_block, true));
|
||||
events.push_back(tx_2);
|
||||
events.push_back(event_visitor_settings(event_visitor_settings::set_txs_kept_by_block, false));
|
||||
|
||||
DO_CALLBACK_PARAMS(events, "check_tx_pool_count", static_cast<size_t>(2));
|
||||
|
||||
// remove_stuck_txs should not remove anything, tx_1 and tx_2 should be in the pool
|
||||
DO_CALLBACK(events, "remove_stuck_txs");
|
||||
DO_CALLBACK_PARAMS(events, "check_tx_pool_count", static_cast<size_t>(2));
|
||||
|
||||
// rewind 50 blocks so tx_0 spending its key image will be deep enough
|
||||
REWIND_BLOCKS_N_WITH_TIME(events, blk_3r, blk_3, m_miner_acc, 50);
|
||||
|
||||
// remove_stuck_txs should remove only tx_2 and left tx_1 (linked to alt block)
|
||||
DO_CALLBACK(events, "remove_stuck_txs");
|
||||
DO_CALLBACK_PARAMS(events, "check_tx_pool_count", static_cast<size_t>(1));
|
||||
|
||||
DO_CALLBACK(events, "print_tx_pool");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool tx_key_image_pool_conflict::c1(currency::core& c, size_t ev_index, const std::vector<test_event_entry>& events)
|
||||
{
|
||||
bool r = false;
|
||||
|
||||
CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 1, false, "incorrect tx pool count = " << c.get_pool_transactions_count());
|
||||
|
||||
// try to mine a block and make sure tx_1 is still in the pool (was not added to the blocktemplate)
|
||||
block b;
|
||||
r = mine_next_pow_block_in_playtime(m_miner_acc.get_public_address(), c, &b);
|
||||
CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_block_in_playtime failed");
|
||||
|
||||
// make sure tx_1 is still here
|
||||
CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 1, false, "incorrect tx pool count = " << c.get_pool_transactions_count());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool tx_key_image_pool_conflict::c2(currency::core& c, size_t ev_index, const std::vector<test_event_entry>& events)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -150,10 +150,6 @@ struct tx_expiration_time_and_chain_switching : public test_chain_unit_enchanced
|
|||
|
||||
struct tx_key_image_pool_conflict : public test_chain_unit_enchanced
|
||||
{
|
||||
tx_key_image_pool_conflict();
|
||||
bool generate(std::vector<test_event_entry>& events) const;
|
||||
bool c1(currency::core& c, size_t ev_index, const std::vector<test_event_entry>& events);
|
||||
bool c2(currency::core& c, size_t ev_index, const std::vector<test_event_entry>& events);
|
||||
|
||||
mutable currency::account_base m_miner_acc;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -11,6 +11,8 @@
|
|||
|
||||
#include "misc_log_ex.h"
|
||||
|
||||
namespace fs = boost::filesystem;
|
||||
|
||||
std::string exec(const char* cmd)
|
||||
{
|
||||
std::array<char, 1024> buffer;
|
||||
|
|
@ -32,11 +34,59 @@ std::string exec(const char* cmd)
|
|||
return result;
|
||||
}
|
||||
|
||||
bool try_write_test_file(size_t size_bytes)
|
||||
{
|
||||
|
||||
static const std::string filename = "test_out_file";
|
||||
static const fs::path filename_p = filename;
|
||||
|
||||
try
|
||||
{
|
||||
fs::ofstream s;
|
||||
s.open(filename, std::ios_base::binary | std::ios_base::out| std::ios::trunc);
|
||||
if(s.fail())
|
||||
return false;
|
||||
|
||||
uint8_t block[32 * 1024] = {};
|
||||
crypto::generate_random_bytes(sizeof block, &block);
|
||||
size_t size_total = 0;
|
||||
for (size_t i = 0; i < size_bytes / (sizeof block); ++i)
|
||||
{
|
||||
s.write((const char*)&block, sizeof block);
|
||||
size_total += sizeof block;
|
||||
}
|
||||
|
||||
if (size_bytes > size_total)
|
||||
s.write((const char*)&block, size_bytes - size_total);
|
||||
|
||||
s.close();
|
||||
|
||||
size_t size_actual = fs::file_size(filename_p);
|
||||
CHECK_AND_ASSERT_MES(size_bytes == size_actual, false, "size_bytes = " << size_bytes << ", size_actual = " << size_actual);
|
||||
|
||||
CHECK_AND_ASSERT_MES(fs::remove(filename_p), false, "remove failed");
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
LOG_PRINT_RED("caught: " << e.what(), LOG_LEVEL_0);
|
||||
return false;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
LOG_PRINT_RED("caught unknown exception", LOG_LEVEL_0);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void free_space_check()
|
||||
{
|
||||
static const size_t test_file_size = 1024 * 1024;
|
||||
namespace fs = boost::filesystem;
|
||||
|
||||
std::string output;
|
||||
bool r = false;
|
||||
|
||||
#ifdef WIN32
|
||||
output = exec("dir");
|
||||
|
|
@ -46,9 +96,13 @@ void free_space_check()
|
|||
|
||||
LOG_PRINT_L0("test command output:" << std::endl << output);
|
||||
|
||||
r = try_write_test_file(test_file_size);
|
||||
LOG_PRINT_L0("test file write: " << (r ? "OK" : "fail"));
|
||||
|
||||
boost::filesystem::path current_path(".");
|
||||
|
||||
size_t counter = 0;
|
||||
bool need_backspace = false;
|
||||
while (true)
|
||||
{
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds( 900 ));
|
||||
|
|
@ -59,26 +113,43 @@ void free_space_check()
|
|||
{
|
||||
// free space is ok
|
||||
counter = (counter + 1) % 4;
|
||||
std::cout << '\b';
|
||||
if (need_backspace)
|
||||
std::cout << '\b';
|
||||
std::cout << ( counter == 0 ? '*' : counter == 1 ? '\\' : counter == 2 ? '|' : '/' );
|
||||
std::cout << std::flush;
|
||||
need_backspace = true;
|
||||
continue;
|
||||
}
|
||||
// free space is not ok!
|
||||
LOG_PRINT_YELLOW("free space available: " << si.available, LOG_LEVEL_0);
|
||||
LOG_PRINT_YELLOW("1) fs::space() : available: " << si.available << ", free: " << si.free << ", capacity: " << si.capacity, LOG_LEVEL_0);
|
||||
#ifdef WIN32
|
||||
output = exec("dir");
|
||||
#else
|
||||
output = exec("df -h");
|
||||
#endif
|
||||
LOG_PRINT_YELLOW(output, LOG_LEVEL_0);
|
||||
|
||||
// try one again asap
|
||||
si = fs::space(current_path);
|
||||
LOG_PRINT_YELLOW("2) fs::space() : available: " << si.available << ", free: " << si.free << ", capacity: " << si.capacity, LOG_LEVEL_0);
|
||||
|
||||
if (!try_write_test_file(test_file_size))
|
||||
{
|
||||
LOG_PRINT_YELLOW("try_write_test_file(" << test_file_size << ") failed", LOG_LEVEL_0);
|
||||
}
|
||||
|
||||
|
||||
need_backspace = false;
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
LOG_ERROR("failed to determine free space: " << e.what());
|
||||
need_backspace = false;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
LOG_ERROR("failed to determine free space: unknown exception");
|
||||
need_backspace = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue