diff options
Diffstat (limited to 'src')
26 files changed, 289 insertions, 70 deletions
diff --git a/src/cryptonote_config.h b/src/cryptonote_config.h index abfa665ff..8dbf1b53b 100644 --- a/src/cryptonote_config.h +++ b/src/cryptonote_config.h @@ -109,6 +109,7 @@ #define P2P_DEFAULT_INVOKE_TIMEOUT 60*2*1000 //2 minutes #define P2P_DEFAULT_HANDSHAKE_INVOKE_TIMEOUT 5000 //5 seconds #define P2P_DEFAULT_WHITELIST_CONNECTIONS_PERCENT 70 +#define P2P_DEFAULT_ANCHOR_CONNECTIONS_COUNT 2 #define P2P_FAILED_ADDR_FORGET_SECONDS (60*60) //1 hour #define P2P_IP_BLOCKTIME (60*60*24) //24 hour diff --git a/src/mnemonics/CMakeLists.txt b/src/mnemonics/CMakeLists.txt index 4db19d195..c521a0932 100644 --- a/src/mnemonics/CMakeLists.txt +++ b/src/mnemonics/CMakeLists.txt @@ -41,7 +41,7 @@ set(mnemonics_private_headers italian.h japanese.h language_base.h - old_english.h + english_old.h portuguese.h russian.h singleton.h diff --git a/src/mnemonics/chinese_simplified.h b/src/mnemonics/chinese_simplified.h index 413186733..a85bbe963 100644 --- a/src/mnemonics/chinese_simplified.h +++ b/src/mnemonics/chinese_simplified.h @@ -72,7 +72,7 @@ namespace Language class Chinese_Simplified: public Base
{
public:
- Chinese_Simplified(): Base("Chinese (Simplified)", std::vector<std::string>({
+ Chinese_Simplified(): Base("简体中文 (中国)", std::vector<std::string>({
"的",
"一",
"是",
diff --git a/src/mnemonics/dutch.h b/src/mnemonics/dutch.h index 0d7a637e6..1cf9b606e 100644 --- a/src/mnemonics/dutch.h +++ b/src/mnemonics/dutch.h @@ -49,7 +49,7 @@ namespace Language class Dutch: public Base
{
public:
- Dutch(): Base("Dutch", std::vector<std::string>({
+ Dutch(): Base("Nederlands", std::vector<std::string>({
"aalglad",
"aalscholver",
"aambeeld",
diff --git a/src/mnemonics/electrum-words.cpp b/src/mnemonics/electrum-words.cpp index 501495f0b..ef1100a10 100644 --- a/src/mnemonics/electrum-words.cpp +++ b/src/mnemonics/electrum-words.cpp @@ -61,7 +61,7 @@ #include "portuguese.h" #include "japanese.h" #include "russian.h" -#include "old_english.h" +#include "english_old.h" #include "language_base.h" #include "singleton.h" @@ -95,7 +95,7 @@ namespace Language::Singleton<Language::Portuguese>::instance(), Language::Singleton<Language::Japanese>::instance(), Language::Singleton<Language::Russian>::instance(), - Language::Singleton<Language::OldEnglish>::instance() + Language::Singleton<Language::EnglishOld>::instance() }); Language::Base *fallback = NULL; @@ -318,39 +318,39 @@ namespace crypto { language = Language::Singleton<Language::English>::instance(); } - else if (language_name == "Dutch") + else if (language_name == "Nederlands") { language = Language::Singleton<Language::Dutch>::instance(); } - else if (language_name == "French") + else if (language_name == "Français") { language = Language::Singleton<Language::French>::instance(); } - else if (language_name == "Spanish") + else if (language_name == "Español") { language = Language::Singleton<Language::Spanish>::instance(); } - else if (language_name == "Portuguese") + else if (language_name == "Português") { language = Language::Singleton<Language::Portuguese>::instance(); } - else if (language_name == "Japanese") + else if (language_name == "日本語") { language = Language::Singleton<Language::Japanese>::instance(); } - else if (language_name == "Italian") + else if (language_name == "Italiano") { language = Language::Singleton<Language::Italian>::instance(); } - else if (language_name == "German") + else if (language_name == "Deutsch") { language = Language::Singleton<Language::German>::instance(); } - else if (language_name == "Russian") + else if (language_name == "русский язык") { language = Language::Singleton<Language::Russian>::instance(); } - else if (language_name == "Chinese (Simplified)") + else if (language_name == "简体中文 (中国)") { language = Language::Singleton<Language::Chinese_Simplified>::instance(); } @@ -399,16 +399,16 @@ namespace crypto void get_language_list(std::vector<std::string> &languages) { std::vector<Language::Base*> language_instances({ - Language::Singleton<Language::Chinese_Simplified>::instance(), + Language::Singleton<Language::German>::instance(), Language::Singleton<Language::English>::instance(), - Language::Singleton<Language::Dutch>::instance(), - Language::Singleton<Language::French>::instance(), Language::Singleton<Language::Spanish>::instance(), - Language::Singleton<Language::German>::instance(), + Language::Singleton<Language::French>::instance(), Language::Singleton<Language::Italian>::instance(), + Language::Singleton<Language::Dutch>::instance(), Language::Singleton<Language::Portuguese>::instance(), Language::Singleton<Language::Russian>::instance(), - Language::Singleton<Language::Japanese>::instance() + Language::Singleton<Language::Japanese>::instance(), + Language::Singleton<Language::Chinese_Simplified>::instance() }); for (std::vector<Language::Base*>::iterator it = language_instances.begin(); it != language_instances.end(); it++) diff --git a/src/mnemonics/electrum-words.h b/src/mnemonics/electrum-words.h index d1aa65939..3655dd201 100644 --- a/src/mnemonics/electrum-words.h +++ b/src/mnemonics/electrum-words.h @@ -60,7 +60,7 @@ namespace crypto { const int seed_length = 24; - const std::string old_language_name = "OldEnglish"; + const std::string old_language_name = "EnglishOld"; /*! * \brief Converts seed words to bytes (secret key). * \param words String containing the words separated by spaces. diff --git a/src/mnemonics/old_english.h b/src/mnemonics/english_old.h index 21ac95de3..9fa5e81e1 100644 --- a/src/mnemonics/old_english.h +++ b/src/mnemonics/english_old.h @@ -29,13 +29,13 @@ // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/*!
- * \file old_english.h
+ * \file english_old.h
*
- * \brief Old English word list and map.
+ * \brief Older version of English word list and map.
*/
-#ifndef OLD_ENGLISH_H
-#define OLD_ENGLISH_H
+#ifndef ENGLISH_OLD_H
+#define ENGLISH_OLD_H
#include <vector>
#include <unordered_map>
@@ -48,10 +48,10 @@ */
namespace Language
{
- class OldEnglish: public Base
+ class EnglishOld: public Base
{
public:
- OldEnglish(): Base("OldEnglish", std::vector<std::string>({
+ EnglishOld(): Base("EnglishOld", std::vector<std::string>({
"like",
"just",
"love",
diff --git a/src/mnemonics/french.h b/src/mnemonics/french.h index 6cf44a197..ef951b2cc 100644 --- a/src/mnemonics/french.h +++ b/src/mnemonics/french.h @@ -49,7 +49,7 @@ namespace Language class French: public Base { public: - French(): Base("French", std::vector<std::string>({ + French(): Base("Français", std::vector<std::string>({ "abandon", "abattre", "aboi", diff --git a/src/mnemonics/german.h b/src/mnemonics/german.h index 1a1e6b467..46a8cf1fe 100644 --- a/src/mnemonics/german.h +++ b/src/mnemonics/german.h @@ -51,7 +51,7 @@ namespace Language class German: public Base
{
public:
- German(): Base("German", std::vector<std::string>({
+ German(): Base("Deutsch", std::vector<std::string>({
"Abakus",
"Abart",
"abbilden",
@@ -1678,11 +1678,11 @@ namespace Language "Zündung",
"Zweck",
"Zyklop"
- }), 4) - { + }), 4)
+ {
populate_maps();
}
};
}
-#endif +#endif
diff --git a/src/mnemonics/italian.h b/src/mnemonics/italian.h index 28cee9d9a..da0e1363c 100644 --- a/src/mnemonics/italian.h +++ b/src/mnemonics/italian.h @@ -51,7 +51,7 @@ namespace Language class Italian: public Base
{
public:
- Italian(): Base("Italian", std::vector<std::string>({
+ Italian(): Base("Italiano", std::vector<std::string>({
"abbinare",
"abbonato",
"abisso",
@@ -1678,11 +1678,11 @@ namespace Language "zolfo",
"zombie",
"zucchero"
- }), 4) - { + }), 4)
+ {
populate_maps();
}
};
}
-#endif +#endif
diff --git a/src/mnemonics/japanese.h b/src/mnemonics/japanese.h index d5ab4bc84..fd5425fb1 100644 --- a/src/mnemonics/japanese.h +++ b/src/mnemonics/japanese.h @@ -71,7 +71,7 @@ namespace Language class Japanese: public Base
{
public:
- Japanese(): Base("Japanese", std::vector<std::string>({
+ Japanese(): Base("日本語", std::vector<std::string>({
"あいこくしん",
"あいさつ",
"あいだ",
diff --git a/src/mnemonics/portuguese.h b/src/mnemonics/portuguese.h index f9d66afc4..bb1fe8ee5 100644 --- a/src/mnemonics/portuguese.h +++ b/src/mnemonics/portuguese.h @@ -72,7 +72,7 @@ namespace Language class Portuguese: public Base
{
public:
- Portuguese(): Base("Portuguese", std::vector<std::string>({
+ Portuguese(): Base("Português", std::vector<std::string>({
"abaular",
"abdominal",
"abeto",
diff --git a/src/mnemonics/russian.h b/src/mnemonics/russian.h index b3db4aa4c..bfe970b9d 100644 --- a/src/mnemonics/russian.h +++ b/src/mnemonics/russian.h @@ -51,7 +51,7 @@ namespace Language class Russian: public Base
{
public:
- Russian(): Base("Russian", std::vector<std::string>({
+ Russian(): Base("русский язык", std::vector<std::string>({
"абажур",
"абзац",
"абонент",
@@ -1678,11 +1678,11 @@ namespace Language "яхта",
"ячейка",
"ящик"
- }), 4) - { + }), 4)
+ {
populate_maps();
}
};
}
-#endif +#endif
diff --git a/src/mnemonics/spanish.h b/src/mnemonics/spanish.h index 117890ada..9db2a03f3 100644 --- a/src/mnemonics/spanish.h +++ b/src/mnemonics/spanish.h @@ -72,7 +72,7 @@ namespace Language class Spanish: public Base
{
public:
- Spanish(): Base("Spanish", std::vector<std::string>({
+ Spanish(): Base("Español", std::vector<std::string>({
"ábaco",
"abdomen",
"abeja",
diff --git a/src/p2p/net_node.h b/src/p2p/net_node.h index 4582a3236..13cd3f5b0 100644 --- a/src/p2p/net_node.h +++ b/src/p2p/net_node.h @@ -155,6 +155,8 @@ namespace nodetool CHAIN_INVOKE_MAP_TO_OBJ_FORCE_CONTEXT(m_payload_handler, typename t_payload_net_handler::connection_context&) END_INVOKE_MAP2() + enum PeerType { anchor = 0, white, gray }; + //----------------- commands handlers ---------------------------------------------- int handle_handshake(int command, typename COMMAND_HANDSHAKE::request& arg, typename COMMAND_HANDSHAKE::response& rsp, p2p_connection_context& context); int handle_timed_sync(int command, typename COMMAND_TIMED_SYNC::request& arg, typename COMMAND_TIMED_SYNC::response& rsp, p2p_connection_context& context); @@ -205,15 +207,17 @@ namespace nodetool bool do_handshake_with_peer(peerid_type& pi, p2p_connection_context& context, bool just_take_peerlist = false); bool do_peer_timed_sync(const epee::net_utils::connection_context_base& context, peerid_type peer_id); + bool make_new_connection_from_anchor_peerlist(const std::vector<anchor_peerlist_entry>& anchor_peerlist); 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); + bool try_to_connect_and_handshake_with_new_peer(const net_address& na, bool just_take_peerlist = false, uint64_t last_seen_stamp = 0, PeerType peer_type = white, uint64_t first_seen_stamp = 0); size_t get_random_index_with_fixed_probability(size_t max_index); bool is_peer_used(const peerlist_entry& peer); + bool is_peer_used(const anchor_peerlist_entry& peer); bool is_addr_connected(const net_address& peer); template<class t_callback> bool try_ping(basic_node_data& node_data, p2p_connection_context& context, t_callback cb); bool try_get_support_flags(const p2p_connection_context& context, std::function<void(p2p_connection_context&, const uint32_t&)> f); - bool make_expected_connections_count(bool white_list, size_t expected_connections); + bool make_expected_connections_count(PeerType peer_type, size_t expected_connections); void cache_connect_fail_info(const net_address& addr); bool is_addr_recently_failed(const net_address& addr); bool is_priority_node(const net_address& na); diff --git a/src/p2p/net_node.inl b/src/p2p/net_node.inl index 2e2dffab8..5c903b1f5 100644 --- a/src/p2p/net_node.inl +++ b/src/p2p/net_node.inl @@ -874,6 +874,30 @@ namespace nodetool } //----------------------------------------------------------------------------------- template<class t_payload_net_handler> + bool node_server<t_payload_net_handler>::is_peer_used(const anchor_peerlist_entry& peer) + { + if(m_config.m_peer_id == peer.id) { + return true;//dont make connections to ourself + } + + bool used = false; + + m_net_server.get_config_object().foreach_connection([&](const p2p_connection_context& cntxt) + { + if(cntxt.peer_id == peer.id || (!cntxt.m_is_income && peer.adr.ip == cntxt.m_remote_ip && peer.adr.port == cntxt.m_remote_port)) + { + used = true; + + return false;//stop enumerating + } + + return true; + }); + + return used; + } + //----------------------------------------------------------------------------------- + template<class t_payload_net_handler> bool node_server<t_payload_net_handler>::is_addr_connected(const net_address& peer) { bool connected = false; @@ -900,7 +924,7 @@ namespace nodetool } while(0) 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) + 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, PeerType peer_type, uint64_t first_seen_stamp) { if (m_current_number_of_out_peers == m_config.m_net_config.connections_count) // out peers limit { @@ -913,7 +937,7 @@ namespace nodetool return false; } MDEBUG("Connecting to " << epee::string_tools::get_ip_string_from_int32(na.ip) << ":" - << epee::string_tools::num_to_string_fast(na.port) << "(white=" << white << ", last_seen: " + << epee::string_tools::num_to_string_fast(na.port) << "(peer_type=" << peer_type << ", last_seen: " << (last_seen_stamp ? epee::misc_utils::get_time_interval_string(time(NULL) - last_seen_stamp):"never") << ")..."); @@ -963,6 +987,13 @@ namespace nodetool m_peerlist.append_with_peer_white(pe_local); //update last seen and push it to peerlist manager + anchor_peerlist_entry ape = AUTO_VAL_INIT(ape); + ape.adr = na; + ape.id = pi; + ape.first_seen = first_seen_stamp ? first_seen_stamp : time(nullptr); + + m_peerlist.append_with_peer_anchor(ape); + LOG_DEBUG_CC(con, "CONNECTION HANDSHAKED OK."); return true; } @@ -1029,6 +1060,41 @@ namespace nodetool } //----------------------------------------------------------------------------------- template<class t_payload_net_handler> + bool node_server<t_payload_net_handler>::make_new_connection_from_anchor_peerlist(const std::vector<anchor_peerlist_entry>& anchor_peerlist) + { + for (const auto& pe: anchor_peerlist) { + _note("Considering connecting (out) to peer: " << pe.id << " " << epee::string_tools::get_ip_string_from_int32(pe.adr.ip) << ":" << boost::lexical_cast<std::string>(pe.adr.port)); + + if(is_peer_used(pe)) { + _note("Peer is used"); + continue; + } + + if(!is_remote_ip_allowed(pe.adr.ip)) { + continue; + } + + if(is_addr_recently_failed(pe.adr)) { + continue; + } + + MDEBUG("Selected peer: " << pe.id << " " << epee::string_tools::get_ip_string_from_int32(pe.adr.ip) + << ":" << boost::lexical_cast<std::string>(pe.adr.port) + << "[peer_type=" << anchor + << "] first_seen: " << epee::misc_utils::get_time_interval_string(time(NULL) - pe.first_seen)); + + if(!try_to_connect_and_handshake_with_new_peer(pe.adr, false, 0, anchor, pe.first_seen)) { + _note("Handshake failed"); + continue; + } + + return true; + } + + return false; + } + //----------------------------------------------------------------------------------- + template<class t_payload_net_handler> bool node_server<t_payload_net_handler>::make_new_connection_from_peerlist(bool use_white_list) { size_t local_peers_count = use_white_list ? m_peerlist.get_white_peers_count():m_peerlist.get_gray_peers_count(); @@ -1079,10 +1145,10 @@ namespace nodetool MDEBUG("Selected peer: " << pe.id << " " << epee::string_tools::get_ip_string_from_int32(pe.adr.ip) << ":" << boost::lexical_cast<std::string>(pe.adr.port) - << "[white=" << use_white_list + << "[peer_list=" << (use_white_list ? white : gray) << "] last_seen: " << (pe.last_seen ? epee::misc_utils::get_time_interval_string(time(NULL) - pe.last_seen) : "never")); - if(!try_to_connect_and_handshake_with_new_peer(pe.adr, false, pe.last_seen, use_white_list)) { + if(!try_to_connect_and_handshake_with_new_peer(pe.adr, false, pe.last_seen, use_white_list ? white : gray)) { _note("Handshake failed"); continue; } @@ -1144,19 +1210,22 @@ namespace nodetool { if(conn_count < expected_white_connections) { - //start from white list - if(!make_expected_connections_count(true, expected_white_connections)) + //start from anchor list + if(!make_expected_connections_count(anchor, P2P_DEFAULT_ANCHOR_CONNECTIONS_COUNT)) return false; - //and then do grey list - if(!make_expected_connections_count(false, m_config.m_net_config.connections_count)) + //then do white list + if(!make_expected_connections_count(white, expected_white_connections)) + return false; + //then do grey list + if(!make_expected_connections_count(gray, m_config.m_net_config.connections_count)) return false; }else { //start from grey list - if(!make_expected_connections_count(false, m_config.m_net_config.connections_count)) + if(!make_expected_connections_count(gray, m_config.m_net_config.connections_count)) return false; //and then do white list - if(!make_expected_connections_count(true, m_config.m_net_config.connections_count)) + if(!make_expected_connections_count(white, m_config.m_net_config.connections_count)) return false; } } @@ -1165,11 +1234,17 @@ namespace nodetool } //----------------------------------------------------------------------------------- template<class t_payload_net_handler> - bool node_server<t_payload_net_handler>::make_expected_connections_count(bool white_list, size_t expected_connections) + bool node_server<t_payload_net_handler>::make_expected_connections_count(PeerType peer_type, size_t expected_connections) { if (m_offline) return true; + std::vector<anchor_peerlist_entry> apl; + + if (peer_type == anchor) { + m_peerlist.get_and_empty_anchor_peerlist(apl); + } + size_t conn_count = get_outgoing_connections_count(); //add new connections from white peers while(conn_count < expected_connections) @@ -1177,8 +1252,18 @@ namespace nodetool if(m_net_server.is_stop_signal_sent()) return false; - if(!make_new_connection_from_peerlist(white_list)) + if (peer_type == anchor && !make_new_connection_from_anchor_peerlist(apl)) { + break; + } + + if (peer_type == white && !make_new_connection_from_peerlist(true)) { + break; + } + + if (peer_type == gray && !make_new_connection_from_peerlist(false)) { break; + } + conn_count = get_outgoing_connections_count(); } return true; @@ -1660,6 +1745,14 @@ namespace nodetool template<class t_payload_net_handler> void node_server<t_payload_net_handler>::on_connection_close(p2p_connection_context& context) { + if (!m_net_server.is_stop_signal_sent() && !context.m_is_income) { + nodetool::net_address na = AUTO_VAL_INIT(na); + na.ip = context.m_remote_ip; + na.port = context.m_remote_port; + + m_peerlist.remove_from_peer_anchor(na); + } + MINFO("["<< epee::net_utils::print_connection_context(context) << "] CLOSE CONNECTION"); } diff --git a/src/p2p/net_peerlist.h b/src/p2p/net_peerlist.h index 11d995995..de0f51cc3 100644 --- a/src/p2p/net_peerlist.h +++ b/src/p2p/net_peerlist.h @@ -54,7 +54,7 @@ #include "net_peerlist_boost_serialization.h" -#define CURRENT_PEERLIST_STORAGE_ARCHIVE_VER 4 +#define CURRENT_PEERLIST_STORAGE_ARCHIVE_VER 5 namespace nodetool { @@ -77,13 +77,15 @@ namespace nodetool bool get_gray_peer_by_index(peerlist_entry& p, size_t i); bool append_with_peer_white(const peerlist_entry& pr); bool append_with_peer_gray(const peerlist_entry& pr); + bool append_with_peer_anchor(const anchor_peerlist_entry& ple); bool set_peer_just_seen(peerid_type peer, uint32_t ip, uint32_t port); bool set_peer_just_seen(peerid_type peer, const net_address& addr); bool set_peer_unreachable(const peerlist_entry& pr); bool is_ip_allowed(uint32_t ip); bool get_random_gray_peer(peerlist_entry& pe); bool remove_from_peer_gray(const peerlist_entry& pe); - + bool get_and_empty_anchor_peerlist(std::vector<anchor_peerlist_entry>& apl); + bool remove_from_peer_anchor(const net_address& addr); private: struct by_time{}; @@ -145,6 +147,16 @@ namespace nodetool boost::multi_index::ordered_non_unique<boost::multi_index::tag<by_time>, boost::multi_index::member<peerlist_entry,int64_t,&peerlist_entry::last_seen> > > > peers_indexed_old; + + typedef boost::multi_index_container< + anchor_peerlist_entry, + boost::multi_index::indexed_by< + // access by anchor_peerlist_entry::net_adress + boost::multi_index::ordered_unique<boost::multi_index::tag<by_addr>, boost::multi_index::member<anchor_peerlist_entry,net_address,&anchor_peerlist_entry::adr> >, + // sort by anchor_peerlist_entry::first_seen + boost::multi_index::ordered_non_unique<boost::multi_index::tag<by_time>, boost::multi_index::member<anchor_peerlist_entry,int64_t,&anchor_peerlist_entry::first_seen> > + > + > anchor_peers_indexed; public: template <class Archive, class t_version_type> @@ -161,8 +173,15 @@ namespace nodetool peers_indexed_from_old(pio, m_peers_white); return; } + a & m_peers_white; a & m_peers_gray; + + if(ver < 5) { + return; + } + + a & m_peers_anchor; } private: @@ -178,6 +197,7 @@ namespace nodetool peers_indexed m_peers_gray; peers_indexed m_peers_white; + anchor_peers_indexed m_peers_anchor; }; //-------------------------------------------------------------------------------------------------- inline @@ -398,6 +418,24 @@ namespace nodetool } //-------------------------------------------------------------------------------------------------- inline + bool peerlist_manager::append_with_peer_anchor(const anchor_peerlist_entry& ple) + { + TRY_ENTRY(); + + CRITICAL_REGION_LOCAL(m_peerlist_lock); + + auto by_addr_it_anchor = m_peers_anchor.get<by_addr>().find(ple.adr); + + if(by_addr_it_anchor == m_peers_anchor.get<by_addr>().end()) { + m_peers_anchor.insert(ple); + } + + return true; + + CATCH_ENTRY_L0("peerlist_manager::append_with_peer_anchor()", false); + } + //-------------------------------------------------------------------------------------------------- + inline bool peerlist_manager::get_random_gray_peer(peerlist_entry& pe) { TRY_ENTRY(); @@ -435,7 +473,46 @@ namespace nodetool CATCH_ENTRY_L0("peerlist_manager::remove_from_peer_gray()", false); } - //-------------------------------------------------------------------------------------------------- + //-------------------------------------------------------------------------------------------------- + inline + bool peerlist_manager::get_and_empty_anchor_peerlist(std::vector<anchor_peerlist_entry>& apl) + { + TRY_ENTRY(); + + CRITICAL_REGION_LOCAL(m_peerlist_lock); + + auto begin = m_peers_anchor.get<by_time>().begin(); + auto end = m_peers_anchor.get<by_time>().end(); + + std::for_each(begin, end, [&apl](const anchor_peerlist_entry &a) { + apl.push_back(a); + }); + + m_peers_anchor.get<by_time>().clear(); + + return true; + + CATCH_ENTRY_L0("peerlist_manager::get_and_empty_anchor_peerlist()", false); + } + //-------------------------------------------------------------------------------------------------- + inline + bool peerlist_manager::remove_from_peer_anchor(const net_address& addr) + { + TRY_ENTRY(); + + CRITICAL_REGION_LOCAL(m_peerlist_lock); + + anchor_peers_indexed::index_iterator<by_addr>::type iterator = m_peers_anchor.get<by_addr>().find(addr); + + if (iterator != m_peers_anchor.get<by_addr>().end()) { + m_peers_anchor.erase(iterator); + } + + return true; + + CATCH_ENTRY_L0("peerlist_manager::remove_from_peer_anchor()", false); + } + //-------------------------------------------------------------------------------------------------- } BOOST_CLASS_VERSION(nodetool::peerlist_manager, CURRENT_PEERLIST_STORAGE_ARCHIVE_VER) diff --git a/src/p2p/net_peerlist_boost_serialization.h b/src/p2p/net_peerlist_boost_serialization.h index 260f16919..6891ac80c 100644 --- a/src/p2p/net_peerlist_boost_serialization.h +++ b/src/p2p/net_peerlist_boost_serialization.h @@ -49,6 +49,14 @@ namespace boost a & pl.adr; a & pl.id; a & pl.last_seen; - } + } + + template <class Archive, class ver_type> + inline void serialize(Archive &a, nodetool::anchor_peerlist_entry& pl, const ver_type ver) + { + a & pl.adr; + a & pl.id; + a & pl.first_seen; + } } } diff --git a/src/p2p/p2p_protocol_defs.h b/src/p2p/p2p_protocol_defs.h index 97e75f5ca..5ec012714 100644 --- a/src/p2p/p2p_protocol_defs.h +++ b/src/p2p/p2p_protocol_defs.h @@ -56,6 +56,13 @@ namespace nodetool int64_t last_seen; }; + struct anchor_peerlist_entry + { + net_address adr; + peerid_type id; + int64_t first_seen; + }; + struct connection_entry { net_address adr; diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp index b755ef12f..6c2df4b22 100644 --- a/src/simplewallet/simplewallet.cpp +++ b/src/simplewallet/simplewallet.cpp @@ -684,6 +684,7 @@ simple_wallet::simple_wallet() m_cmd_binder.set_handler("locked_transfer", boost::bind(&simple_wallet::locked_transfer, this, _1), tr("locked_transfer [<mixin_count>] <addr> <amount> <lockblocks>(Number of blocks to lock the transaction for, max 1000000) [<payment_id>]")); m_cmd_binder.set_handler("sweep_unmixable", boost::bind(&simple_wallet::sweep_unmixable, this, _1), tr("Send all unmixable outputs to yourself with mixin 0")); m_cmd_binder.set_handler("sweep_all", boost::bind(&simple_wallet::sweep_all, this, _1), tr("sweep_all [mixin] address [payment_id] - Send all unlocked balance to an address")); + m_cmd_binder.set_handler("sweep_below", boost::bind(&simple_wallet::sweep_below, this, _1), tr("sweep_below <amount_threshold> [mixin] address [payment_id] - Send all unlocked outputs below the threshold to an address")); m_cmd_binder.set_handler("donate", boost::bind(&simple_wallet::donate, this, _1), tr("donate [<mixin_count>] <amount> [payment_id] - Donate <amount> to the development team (donate.getmonero.org)")); m_cmd_binder.set_handler("sign_transfer", boost::bind(&simple_wallet::sign_transfer, this, _1), tr("Sign a transaction from a file")); m_cmd_binder.set_handler("submit_transfer", boost::bind(&simple_wallet::submit_transfer, this, _1), tr("Submit a signed transaction from a file")); @@ -2600,7 +2601,7 @@ bool simple_wallet::sweep_unmixable(const std::vector<std::string> &args_) return true; } //---------------------------------------------------------------------------------------------------- -bool simple_wallet::sweep_all(const std::vector<std::string> &args_) +bool simple_wallet::sweep_main(uint64_t below, const std::vector<std::string> &args_) { if (m_wallet->ask_password() && !get_and_verify_password()) { return true; } if (!try_connect_to_daemon()) @@ -2708,7 +2709,7 @@ bool simple_wallet::sweep_all(const std::vector<std::string> &args_) try { // figure out what tx will be necessary - auto ptx_vector = m_wallet->create_transactions_all(address, fake_outs_count, 0 /* unlock_time */, 0 /* unused fee arg*/, extra, m_trusted_daemon); + auto ptx_vector = m_wallet->create_transactions_all(below, address, fake_outs_count, 0 /* unlock_time */, 0 /* unused fee arg*/, extra, m_trusted_daemon); if (ptx_vector.empty()) { @@ -2861,6 +2862,27 @@ bool simple_wallet::sweep_all(const std::vector<std::string> &args_) return true; } //---------------------------------------------------------------------------------------------------- +bool simple_wallet::sweep_all(const std::vector<std::string> &args_) +{ + return sweep_main(0, args_); +} +//---------------------------------------------------------------------------------------------------- +bool simple_wallet::sweep_below(const std::vector<std::string> &args_) +{ + uint64_t below = 0; + if (args_.size() < 1) + { + fail_msg_writer() << tr("missing amount threshold"); + return true; + } + if (!cryptonote::parse_amount(below, args_[0])) + { + fail_msg_writer() << tr("invalid amount threshold"); + return true; + } + return sweep_main(below, std::vector<std::string>(++args_.begin(), args_.end())); +} +//---------------------------------------------------------------------------------------------------- bool simple_wallet::donate(const std::vector<std::string> &args_) { std::vector<std::string> local_args = args_; diff --git a/src/simplewallet/simplewallet.h b/src/simplewallet/simplewallet.h index 14722e942..1b58ff32a 100644 --- a/src/simplewallet/simplewallet.h +++ b/src/simplewallet/simplewallet.h @@ -134,7 +134,9 @@ namespace cryptonote bool transfer(const std::vector<std::string> &args); bool transfer_new(const std::vector<std::string> &args); bool locked_transfer(const std::vector<std::string> &args); + bool sweep_main(uint64_t below, const std::vector<std::string> &args); bool sweep_all(const std::vector<std::string> &args); + bool sweep_below(const std::vector<std::string> &args); bool sweep_unmixable(const std::vector<std::string> &args); bool donate(const std::vector<std::string> &args); bool sign_transfer(const std::vector<std::string> &args); diff --git a/src/wallet/api/wallet.cpp b/src/wallet/api/wallet.cpp index fc2d6e755..21760ac49 100644 --- a/src/wallet/api/wallet.cpp +++ b/src/wallet/api/wallet.cpp @@ -952,7 +952,7 @@ PendingTransaction *WalletImpl::createTransaction(const string &dst_addr, const static_cast<uint32_t>(priority), extra, m_trustedDaemon); } else { - transaction->m_pending_tx = m_wallet->create_transactions_all(addr, fake_outs_count, 0 /* unlock_time */, + transaction->m_pending_tx = m_wallet->create_transactions_all(0, addr, fake_outs_count, 0 /* unlock_time */, static_cast<uint32_t>(priority), extra, m_trustedDaemon); } diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index 4adec0719..9069789ca 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -4581,7 +4581,7 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryp return ptx_vector; } -std::vector<wallet2::pending_tx> wallet2::create_transactions_all(const cryptonote::account_public_address &address, const size_t fake_outs_count, const uint64_t unlock_time, uint32_t priority, const std::vector<uint8_t> extra, bool trusted_daemon) +std::vector<wallet2::pending_tx> wallet2::create_transactions_all(uint64_t below, const cryptonote::account_public_address &address, const size_t fake_outs_count, const uint64_t unlock_time, uint32_t priority, const std::vector<uint8_t> extra, bool trusted_daemon) { std::vector<size_t> unused_transfers_indices; std::vector<size_t> unused_dust_indices; @@ -4593,10 +4593,13 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_all(const cryptono const transfer_details& td = m_transfers[i]; if (!td.m_spent && (use_rct ? true : !td.is_rct()) && is_transfer_unlocked(td)) { - if (td.is_rct() || is_valid_decomposed_amount(td.amount())) - unused_transfers_indices.push_back(i); - else - unused_dust_indices.push_back(i); + if (below == 0 || td.amount() < below) + { + if (td.is_rct() || is_valid_decomposed_amount(td.amount())) + unused_transfers_indices.push_back(i); + else + unused_dust_indices.push_back(i); + } } } diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h index e228dac4f..03c6a431b 100644 --- a/src/wallet/wallet2.h +++ b/src/wallet/wallet2.h @@ -414,7 +414,7 @@ namespace tools bool load_tx(const std::string &signed_filename, std::vector<tools::wallet2::pending_tx> &ptx, std::function<bool(const signed_tx_set&)> accept_func = NULL); std::vector<pending_tx> create_transactions(std::vector<cryptonote::tx_destination_entry> dsts, const size_t fake_outs_count, const uint64_t unlock_time, uint32_t priority, const std::vector<uint8_t> extra, bool trusted_daemon); std::vector<wallet2::pending_tx> create_transactions_2(std::vector<cryptonote::tx_destination_entry> dsts, const size_t fake_outs_count, const uint64_t unlock_time, uint32_t priority, const std::vector<uint8_t> extra, bool trusted_daemon); - std::vector<wallet2::pending_tx> create_transactions_all(const cryptonote::account_public_address &address, const size_t fake_outs_count, const uint64_t unlock_time, uint32_t priority, const std::vector<uint8_t> extra, bool trusted_daemon); + std::vector<wallet2::pending_tx> create_transactions_all(uint64_t below, const cryptonote::account_public_address &address, const size_t fake_outs_count, const uint64_t unlock_time, uint32_t priority, const std::vector<uint8_t> extra, bool trusted_daemon); std::vector<wallet2::pending_tx> create_transactions_from(const cryptonote::account_public_address &address, std::vector<size_t> unused_transfers_indices, std::vector<size_t> unused_dust_indices, const size_t fake_outs_count, const uint64_t unlock_time, uint32_t priority, const std::vector<uint8_t> extra, bool trusted_daemon); std::vector<pending_tx> create_unmixable_sweep_transactions(bool trusted_daemon); bool check_connection(uint32_t *version = NULL, uint32_t timeout = 200000); diff --git a/src/wallet/wallet_rpc_server.cpp b/src/wallet/wallet_rpc_server.cpp index 5a7325a06..f2b3dcaf5 100644 --- a/src/wallet/wallet_rpc_server.cpp +++ b/src/wallet/wallet_rpc_server.cpp @@ -631,7 +631,7 @@ namespace tools try { - std::vector<wallet2::pending_tx> ptx_vector = m_wallet->create_transactions_all(dsts[0].addr, req.mixin, req.unlock_time, req.priority, extra, m_trusted_daemon); + std::vector<wallet2::pending_tx> ptx_vector = m_wallet->create_transactions_all(req.below_amount, dsts[0].addr, req.mixin, req.unlock_time, req.priority, extra, m_trusted_daemon); m_wallet->commit_tx(ptx_vector); diff --git a/src/wallet/wallet_rpc_server_commands_defs.h b/src/wallet/wallet_rpc_server_commands_defs.h index 51fcf02b5..3c10dc41f 100644 --- a/src/wallet/wallet_rpc_server_commands_defs.h +++ b/src/wallet/wallet_rpc_server_commands_defs.h @@ -234,6 +234,7 @@ namespace wallet_rpc uint64_t unlock_time; std::string payment_id; bool get_tx_keys; + uint64_t below_amount; BEGIN_KV_SERIALIZE_MAP() KV_SERIALIZE(address) @@ -242,6 +243,7 @@ namespace wallet_rpc KV_SERIALIZE(unlock_time) KV_SERIALIZE(payment_id) KV_SERIALIZE(get_tx_keys) + KV_SERIALIZE(below_amount) END_KV_SERIALIZE_MAP() }; |