diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/blockchain_db/lmdb/db_lmdb.cpp | 24 | ||||
-rw-r--r-- | src/common/stack_trace.cpp | 2 | ||||
-rw-r--r-- | src/cryptonote_core/cryptonote_core.cpp | 12 | ||||
-rw-r--r-- | src/p2p/net_node.h | 14 | ||||
-rw-r--r-- | src/p2p/net_node.inl | 118 | ||||
-rw-r--r-- | src/p2p/net_peerlist.h | 52 | ||||
-rw-r--r-- | src/ringct/rctSigs.cpp | 34 | ||||
-rw-r--r-- | src/rpc/core_rpc_server.h | 2 | ||||
-rw-r--r-- | src/simplewallet/simplewallet.cpp | 18 | ||||
-rw-r--r-- | src/wallet/api/wallet.cpp | 4 | ||||
-rw-r--r-- | src/wallet/api/wallet_manager.cpp | 5 | ||||
-rw-r--r-- | src/wallet/wallet2_api.h | 1 |
12 files changed, 239 insertions, 47 deletions
diff --git a/src/blockchain_db/lmdb/db_lmdb.cpp b/src/blockchain_db/lmdb/db_lmdb.cpp index 343fd1fa4..7d548afed 100644 --- a/src/blockchain_db/lmdb/db_lmdb.cpp +++ b/src/blockchain_db/lmdb/db_lmdb.cpp @@ -441,7 +441,7 @@ void BlockchainLMDB::do_resize(uint64_t increase_size) if (result) throw0(DB_ERROR(lmdb_error("Failed to set new mapsize: ", result).c_str())); - MINFO("LMDB Mapsize increased." << " Old: " << mei.me_mapsize / (1024 * 1024) << "MiB" << ", New: " << new_mapsize / (1024 * 1024) << "MiB"); + MGINFO("LMDB Mapsize increased." << " Old: " << mei.me_mapsize / (1024 * 1024) << "MiB" << ", New: " << new_mapsize / (1024 * 1024) << "MiB"); mdb_txn_safe::allow_new_txns(); } @@ -525,7 +525,7 @@ void BlockchainLMDB::check_and_resize_for_batch(uint64_t batch_num_blocks) // size-based check if (need_resize(threshold_size)) { - LOG_PRINT_L0("[batch] DB resize needed"); + MGINFO("[batch] DB resize needed"); do_resize(increase_size); } } @@ -1172,7 +1172,7 @@ void BlockchainLMDB::open(const std::string& filename, const int mdb_flags) { if (*(const uint32_t*)v.mv_data > VERSION) { - MINFO("Existing lmdb database was made by a later version. We don't know how it will change yet."); + MWARNING("Existing lmdb database was made by a later version. We don't know how it will change yet."); compatible = false; } #if VERSION > 0 @@ -2301,11 +2301,11 @@ void BlockchainLMDB::batch_commit() if (! m_batch_transactions) throw0(DB_ERROR("batch transactions not enabled")); if (! m_batch_active) - throw0(DB_ERROR("batch transaction not in progress")); + throw1(DB_ERROR("batch transaction not in progress")); if (m_write_batch_txn == nullptr) - throw0(DB_ERROR("batch transaction not in progress")); + throw1(DB_ERROR("batch transaction not in progress")); if (m_writer != boost::this_thread::get_id()) - return; // batch txn owned by other thread + throw1(DB_ERROR("batch transaction owned by other thread")); check_open(); @@ -2328,11 +2328,11 @@ void BlockchainLMDB::batch_stop() if (! m_batch_transactions) throw0(DB_ERROR("batch transactions not enabled")); if (! m_batch_active) - throw0(DB_ERROR("batch transaction not in progress")); + throw1(DB_ERROR("batch transaction not in progress")); if (m_write_batch_txn == nullptr) - throw0(DB_ERROR("batch transaction not in progress")); + throw1(DB_ERROR("batch transaction not in progress")); if (m_writer != boost::this_thread::get_id()) - return; // batch txn owned by other thread + throw1(DB_ERROR("batch transaction owned by other thread")); check_open(); LOG_PRINT_L3("batch transaction: committing..."); TIME_MEASURE_START(time1); @@ -2354,9 +2354,11 @@ void BlockchainLMDB::batch_abort() if (! m_batch_transactions) throw0(DB_ERROR("batch transactions not enabled")); if (! m_batch_active) - throw0(DB_ERROR("batch transaction not in progress")); + throw1(DB_ERROR("batch transaction not in progress")); + if (m_write_batch_txn == nullptr) + throw1(DB_ERROR("batch transaction not in progress")); if (m_writer != boost::this_thread::get_id()) - return; // batch txn owned by other thread + throw1(DB_ERROR("batch transaction owned by other thread")); check_open(); // for destruction of batch transaction m_write_txn = nullptr; diff --git a/src/common/stack_trace.cpp b/src/common/stack_trace.cpp index ce05b7e04..99e4bda2c 100644 --- a/src/common/stack_trace.cpp +++ b/src/common/stack_trace.cpp @@ -38,7 +38,7 @@ #undef MONERO_DEFAULT_LOG_CATEGORY #define MONERO_DEFAULT_LOG_CATEGORY "stacktrace" -#define ST_LOG(x) CERROR(el::base::Writer,el::base::DispatchAction::FileOnlyLog,MONERO_DEFAULT_LOG_CATEGORY) << x +#define ST_LOG(x) CINFO(el::base::Writer,el::base::DispatchAction::FileOnlyLog,MONERO_DEFAULT_LOG_CATEGORY) << x // from http://stackoverflow.com/questions/11665829/how-can-i-print-stack-trace-for-caught-exceptions-in-c-code-injection-in-c diff --git a/src/cryptonote_core/cryptonote_core.cpp b/src/cryptonote_core/cryptonote_core.cpp index 055606769..c8103d720 100644 --- a/src/cryptonote_core/cryptonote_core.cpp +++ b/src/cryptonote_core/cryptonote_core.cpp @@ -496,6 +496,18 @@ namespace cryptonote return false; } + if(m_mempool.have_tx(tx_hash)) + { + LOG_PRINT_L2("tx " << tx_hash << "already have transaction in tx_pool"); + return true; + } + + if(m_blockchain_storage.have_tx(tx_hash)) + { + LOG_PRINT_L2("tx " << tx_hash << " already have transaction in blockchain"); + return true; + } + if(!check_tx_syntax(tx)) { LOG_PRINT_L1("WRONG TRANSACTION BLOB, Failed to check tx " << tx_hash << " syntax, rejected"); diff --git a/src/p2p/net_node.h b/src/p2p/net_node.h index cc6a486d3..40598fc0f 100644 --- a/src/p2p/net_node.h +++ b/src/p2p/net_node.h @@ -110,7 +110,12 @@ namespace nodetool void serialize(Archive &a, const t_version_type ver) { a & m_peerlist; - a & m_config.m_peer_id; + if (ver == 0) + { + // from v1, we do not store the peer id anymore + peerid_type peer_id; + a & peer_id; + } } // debug functions bool log_peerlist(); @@ -162,6 +167,7 @@ namespace nodetool #endif int handle_get_support_flags(int command, COMMAND_REQUEST_SUPPORT_FLAGS::request& arg, COMMAND_REQUEST_SUPPORT_FLAGS::response& rsp, p2p_connection_context& context); bool init_config(); + bool make_default_peer_id(); bool make_default_config(); bool store_config(); bool check_trust(const proof_of_trust& tr); @@ -227,6 +233,11 @@ namespace nodetool bool set_rate_down_limit(const boost::program_options::variables_map& vm, int64_t limit); bool set_rate_limit(const boost::program_options::variables_map& vm, int64_t limit); + bool has_too_many_connections(const uint32_t ip); + + bool check_connection_and_handshake_with_peer(const net_address& na, uint64_t last_seen_stamp); + bool gray_peerlist_housekeeping(); + void kill() { ///< will be called e.g. from deinit() _info("Killing the net_node"); is_closing = true; @@ -287,6 +298,7 @@ namespace nodetool epee::math_helper::once_a_time_seconds<P2P_DEFAULT_HANDSHAKE_INTERVAL> m_peer_handshake_idle_maker_interval; epee::math_helper::once_a_time_seconds<1> m_connections_maker_interval; epee::math_helper::once_a_time_seconds<60*30, false> m_peerlist_store_interval; + epee::math_helper::once_a_time_seconds<60> m_gray_peerlist_housekeeping_interval; std::string m_bind_ip; std::string m_port; diff --git a/src/p2p/net_node.inl b/src/p2p/net_node.inl index 34a3f9363..0e43d9579 100644 --- a/src/p2p/net_node.inl +++ b/src/p2p/net_node.inl @@ -173,6 +173,9 @@ namespace nodetool make_default_config(); } + // always recreate a new peer id + make_default_peer_id(); + //at this moment we have hardcoded config m_config.m_net_config.handshake_interval = P2P_DEFAULT_HANDSHAKE_INTERVAL; m_config.m_net_config.packet_max_size = P2P_DEFAULT_PACKET_MAX_SIZE; //20 MB limit @@ -205,20 +208,26 @@ namespace nodetool if(time(nullptr) >= it->second) { m_blocked_ips.erase(it); - MLOG_CYAN(el::Level::Info, "IP " << epee::string_tools::get_ip_string_from_int32(addr) << " unblocked."); + MCLOG_CYAN(el::Level::Info, "global", "IP " << epee::string_tools::get_ip_string_from_int32(addr) << " unblocked."); return true; } return false; } //----------------------------------------------------------------------------------- template<class t_payload_net_handler> - bool node_server<t_payload_net_handler>::make_default_config() + bool node_server<t_payload_net_handler>::make_default_peer_id() { m_config.m_peer_id = crypto::rand<uint64_t>(); return true; } //----------------------------------------------------------------------------------- template<class t_payload_net_handler> + bool node_server<t_payload_net_handler>::make_default_config() + { + return make_default_peer_id(); + } + //----------------------------------------------------------------------------------- + template<class t_payload_net_handler> bool node_server<t_payload_net_handler>::block_ip(uint32_t addr, time_t seconds) { CRITICAL_REGION_LOCAL(m_blocked_ips_lock); @@ -237,7 +246,7 @@ namespace nodetool for (const auto &c: conns) m_net_server.get_config_object().close(c); - MLOG_CYAN(el::Level::Info, "IP " << epee::string_tools::get_ip_string_from_int32(addr) << " blocked."); + MCLOG_CYAN(el::Level::Info, "global", "IP " << epee::string_tools::get_ip_string_from_int32(addr) << " blocked."); return true; } //----------------------------------------------------------------------------------- @@ -249,7 +258,7 @@ namespace nodetool if (i == m_blocked_ips.end()) return false; m_blocked_ips.erase(i); - MLOG_CYAN(el::Level::Info, "IP " << epee::string_tools::get_ip_string_from_int32(addr) << " unblocked."); + MCLOG_CYAN(el::Level::Info, "global", "IP " << epee::string_tools::get_ip_string_from_int32(addr) << " unblocked."); return true; } //----------------------------------------------------------------------------------- @@ -926,6 +935,50 @@ namespace nodetool return true; } + template<class t_payload_net_handler> + bool node_server<t_payload_net_handler>::check_connection_and_handshake_with_peer(const net_address& na, uint64_t last_seen_stamp) + { + LOG_PRINT_L1("Connecting to " << epee::string_tools::get_ip_string_from_int32(na.ip) << ":" + << epee::string_tools::num_to_string_fast(na.port) << "(last_seen: " + << (last_seen_stamp ? epee::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(epee::string_tools::get_ip_string_from_int32(na.ip), + epee::string_tools::num_to_string_fast(na.port), + m_config.m_net_config.connection_timeout, + con); + + if (!res) { + bool is_priority = is_priority_node(na); + + LOG_PRINT_CC_PRIORITY_NODE(is_priority, con, "Connect failed to " + << epee::string_tools::get_ip_string_from_int32(na.ip) + << ":" << epee::string_tools::num_to_string_fast(na.port)); + + return false; + } + + peerid_type pi = AUTO_VAL_INIT(pi); + res = do_handshake_with_peer(pi, con, true); + + if (!res) { + bool is_priority = is_priority_node(na); + + LOG_PRINT_CC_PRIORITY_NODE(is_priority, con, "Failed to HANDSHAKE with peer " + << epee::string_tools::get_ip_string_from_int32(na.ip) + << ":" << epee::string_tools::num_to_string_fast(na.port)); + + return false; + } + + m_net_server.get_config_object().close(con.m_connection_id); + + LOG_DEBUG_CC(con, "CONNECTION HANDSHAKED OK AND CLOSED."); + + return true; + } + #undef LOG_PRINT_CC_PRIORITY_NODE //----------------------------------------------------------------------------------- @@ -1097,6 +1150,7 @@ namespace nodetool { m_peer_handshake_idle_maker_interval.do_call(boost::bind(&node_server<t_payload_net_handler>::peer_sync_idle_maker, this)); m_connections_maker_interval.do_call(boost::bind(&node_server<t_payload_net_handler>::connections_maker, this)); + m_gray_peerlist_housekeeping_interval.do_call(boost::bind(&node_server<t_payload_net_handler>::gray_peerlist_housekeeping, this)); m_peerlist_store_interval.do_call(boost::bind(&node_server<t_payload_net_handler>::store_config, this)); return true; } @@ -1456,6 +1510,14 @@ namespace nodetool drop_connection(context); return 1; } + + if(has_too_many_connections(context.m_remote_ip)) + { + LOG_PRINT_CCONTEXT_L1("CONNECTION FROM " << epee::string_tools::get_ip_string_from_int32(context.m_remote_ip) << " REFUSED, too many connections from the same address"); + drop_connection(context); + return 1; + } + //associate peer_id with this connection context.peer_id = arg.node_data.peer_id; @@ -1674,4 +1736,52 @@ namespace nodetool return true; } + + template<class t_payload_net_handler> + bool node_server<t_payload_net_handler>::has_too_many_connections(const uint32_t ip) + { + const uint8_t max_connections = 1; + uint8_t count = 0; + + m_net_server.get_config_object().foreach_connection([&](const p2p_connection_context& cntxt) + { + if (cntxt.m_is_income && cntxt.m_remote_ip == ip) { + count++; + + if (count > max_connections) { + return false; + } + } + + return true; + }); + + return count > max_connections; + } + + template<class t_payload_net_handler> + bool node_server<t_payload_net_handler>::gray_peerlist_housekeeping() + { + peerlist_entry pe = AUTO_VAL_INIT(pe); + + if (!m_peerlist.get_random_gray_peer(pe)) { + return false; + } + + bool success = check_connection_and_handshake_with_peer(pe.adr, pe.last_seen); + + if (!success) { + m_peerlist.remove_from_peer_gray(pe); + + LOG_PRINT_L2("PEER EVICTED FROM GRAY PEER LIST IP address: " << epee::string_tools::get_ip_string_from_int32(pe.adr.ip) << " Peer ID: " << std::hex << pe.id); + + return true; + } + + m_peerlist.set_peer_just_seen(pe.id, pe.adr); + + LOG_PRINT_L2("PEER PROMOTED TO WHITE PEER LIST IP address: " << epee::string_tools::get_ip_string_from_int32(pe.adr.ip) << " Peer ID: " << std::hex << pe.id); + + return true; + } } diff --git a/src/p2p/net_peerlist.h b/src/p2p/net_peerlist.h index fa69abd6e..4797eb82b 100644 --- a/src/p2p/net_peerlist.h +++ b/src/p2p/net_peerlist.h @@ -81,6 +81,8 @@ namespace nodetool 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); private: @@ -285,9 +287,11 @@ namespace nodetool { if(!vl.last_seen) continue; - bs_head.push_back(vl); - if(cnt++ > depth) + + if(cnt++ >= depth) break; + + bs_head.push_back(vl); } return true; } @@ -394,6 +398,50 @@ namespace nodetool return true; } //-------------------------------------------------------------------------------------------------- + inline + bool peerlist_manager::get_random_gray_peer(peerlist_entry& pe) + { + TRY_ENTRY(); + + CRITICAL_REGION_LOCAL(m_peerlist_lock); + + if (m_peers_gray.empty()) { + return false; + } + + size_t x = crypto::rand<size_t>() % (m_peers_gray.size() + 1); + size_t res = (x * x * x) / (m_peers_gray.size() * m_peers_gray.size()); //parabola \/ + + LOG_PRINT_L3("Random gray peer index=" << res << "(x="<< x << ", max_index=" << m_peers_gray.size() << ")"); + + peers_indexed::index<by_time>::type& by_time_index = m_peers_gray.get<by_time>(); + pe = *epee::misc_utils::move_it_backward(--by_time_index.end(), res); + + return true; + + CATCH_ENTRY_L0("peerlist_manager::get_random_gray_peer()", false); + return true; + } + //-------------------------------------------------------------------------------------------------- + inline + bool peerlist_manager::remove_from_peer_gray(const peerlist_entry& pe) + { + TRY_ENTRY(); + + CRITICAL_REGION_LOCAL(m_peerlist_lock); + + peers_indexed::index_iterator<by_addr>::type iterator = m_peers_gray.get<by_addr>().find(pe.adr); + + if (iterator != m_peers_gray.get<by_addr>().end()) { + m_peers_gray.erase(iterator); + } + + return true; + + CATCH_ENTRY_L0("peerlist_manager::remove_from_peer_gray()", false); + return true; + } + //-------------------------------------------------------------------------------------------------- } BOOST_CLASS_VERSION(nodetool::peerlist_manager, CURRENT_PEERLIST_STORAGE_ARCHIVE_VER) diff --git a/src/ringct/rctSigs.cpp b/src/ringct/rctSigs.cpp index 74fed0ede..b8f3596e8 100644 --- a/src/ringct/rctSigs.cpp +++ b/src/ringct/rctSigs.cpp @@ -797,23 +797,6 @@ namespace rct { tools::thread_group threadpool(tools::thread_group::optimal_with_max(threads)); if (semantics) { - results.clear(); - results.resize(rv.outPk.size()); - tools::task_region(threadpool, [&] (tools::task_region_handle& region) { - for (size_t i = 0; i < rv.outPk.size(); i++) { - region.run([&, i] { - results[i] = verRange(rv.outPk[i].mask, rv.p.rangeSigs[i]); - }); - } - }); - - for (size_t i = 0; i < results.size(); ++i) { - if (!results[i]) { - LOG_PRINT_L1("Range proof verified failed for output " << i); - return false; - } - } - key sumOutpks = identity(); for (size_t i = 0; i < rv.outPk.size(); i++) { addKeys(sumOutpks, sumOutpks, rv.outPk[i].mask); @@ -833,6 +816,23 @@ namespace rct { LOG_PRINT_L1("Sum check failed"); return false; } + + results.clear(); + results.resize(rv.outPk.size()); + tools::task_region(threadpool, [&] (tools::task_region_handle& region) { + for (size_t i = 0; i < rv.outPk.size(); i++) { + region.run([&, i] { + results[i] = verRange(rv.outPk[i].mask, rv.p.rangeSigs[i]); + }); + } + }); + + for (size_t i = 0; i < results.size(); ++i) { + if (!results[i]) { + LOG_PRINT_L1("Range proof verified failed for output " << i); + return false; + } + } } else { const key message = get_pre_mlsag_hash(rv); diff --git a/src/rpc/core_rpc_server.h b/src/rpc/core_rpc_server.h index 84871e8bb..767bcc715 100644 --- a/src/rpc/core_rpc_server.h +++ b/src/rpc/core_rpc_server.h @@ -194,3 +194,5 @@ private: bool m_restricted; }; } + +BOOST_CLASS_VERSION(nodetool::node_server<cryptonote::t_cryptonote_protocol_handler<cryptonote::core> >, 1); diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp index 68781dd73..50509040c 100644 --- a/src/simplewallet/simplewallet.cpp +++ b/src/simplewallet/simplewallet.cpp @@ -1958,7 +1958,7 @@ bool simple_wallet::print_ring_members(const std::vector<tools::wallet2::pending return false; } // available for RPC version 1.4 or higher - if (version < 0x10004) + if (version < MAKE_CORE_RPC_VERSION(1, 4)) return true; std::string err; uint64_t blockchain_height = get_daemon_blockchain_height(err); @@ -2317,9 +2317,9 @@ bool simple_wallet::transfer_main(int transfer_type, const std::vector<std::stri LOG_ERROR("RPC error: " << e.to_string()); fail_msg_writer() << tr("RPC error: ") << e.what(); } - catch (const tools::error::get_random_outs_error&) + catch (const tools::error::get_random_outs_error &e) { - fail_msg_writer() << tr("failed to get random outputs to mix"); + fail_msg_writer() << tr("failed to get random outputs to mix: ") << e.what(); } catch (const tools::error::not_enough_money& e) { @@ -2495,9 +2495,9 @@ bool simple_wallet::sweep_unmixable(const std::vector<std::string> &args_) LOG_ERROR("RPC error: " << e.to_string()); fail_msg_writer() << tr("RPC error: ") << e.what(); } - catch (const tools::error::get_random_outs_error&) + catch (const tools::error::get_random_outs_error &e) { - fail_msg_writer() << tr("failed to get random outputs to mix"); + fail_msg_writer() << tr("failed to get random outputs to mix: ") << e.what(); } catch (const tools::error::not_enough_money& e) { @@ -2756,9 +2756,9 @@ bool simple_wallet::sweep_all(const std::vector<std::string> &args_) LOG_ERROR("RPC error: " << e.to_string()); fail_msg_writer() << tr("RPC error: ") << e.what(); } - catch (const tools::error::get_random_outs_error&) + catch (const tools::error::get_random_outs_error &e) { - fail_msg_writer() << tr("failed to get random outputs to mix"); + fail_msg_writer() << tr("failed to get random outputs to mix: ") << e.what(); } catch (const tools::error::not_enough_money& e) { @@ -3041,9 +3041,9 @@ bool simple_wallet::submit_transfer(const std::vector<std::string> &args_) LOG_ERROR("Unknown RPC error: " << e.to_string()); fail_msg_writer() << tr("RPC error: ") << e.what(); } - catch (const tools::error::get_random_outs_error&) + catch (const tools::error::get_random_outs_error &e) { - fail_msg_writer() << tr("failed to get random outputs to mix"); + fail_msg_writer() << tr("failed to get random outputs to mix: ") << e.what(); } catch (const tools::error::not_enough_money& e) { diff --git a/src/wallet/api/wallet.cpp b/src/wallet/api/wallet.cpp index 5f7d8e522..52ecc2e6a 100644 --- a/src/wallet/api/wallet.cpp +++ b/src/wallet/api/wallet.cpp @@ -834,8 +834,8 @@ PendingTransaction *WalletImpl::createTransaction(const string &dst_addr, const } catch (const tools::error::wallet_rpc_error& e) { m_errorString = tr("RPC error: ") + e.to_string(); m_status = Status_Error; - } catch (const tools::error::get_random_outs_error&) { - m_errorString = tr("failed to get random outputs to mix"); + } catch (const tools::error::get_random_outs_error &e) { + m_errorString = (boost::format(tr("failed to get random outputs to mix: %s")) % e.what()).str(); m_status = Status_Error; } catch (const tools::error::not_enough_money& e) { diff --git a/src/wallet/api/wallet_manager.cpp b/src/wallet/api/wallet_manager.cpp index 12bce0285..904338a72 100644 --- a/src/wallet/api/wallet_manager.cpp +++ b/src/wallet/api/wallet_manager.cpp @@ -448,6 +448,11 @@ void WalletManagerFactory::setLogLevel(int level) mlog_set_log_level(level); } +void WalletManagerFactory::setLogCategories(const std::string &categories) +{ + mlog_set_categories(categories.c_str()); +} + } diff --git a/src/wallet/wallet2_api.h b/src/wallet/wallet2_api.h index 5a13205c5..78caddc0b 100644 --- a/src/wallet/wallet2_api.h +++ b/src/wallet/wallet2_api.h @@ -708,6 +708,7 @@ struct WalletManagerFactory static WalletManager * getWalletManager(); static void setLogLevel(int level); + static void setLogCategories(const std::string &categories); }; |