diff options
| -rw-r--r-- | src/cryptonote_core/blockchain.cpp | 4 | ||||
| -rw-r--r-- | src/cryptonote_core/cryptonote_core.cpp | 4 | ||||
| -rw-r--r-- | src/cryptonote_core/cryptonote_core.h | 3 | ||||
| -rw-r--r-- | src/cryptonote_core/cryptonote_tx_utils.cpp | 3 | ||||
| -rw-r--r-- | src/cryptonote_core/tx_pool.cpp | 12 | ||||
| -rw-r--r-- | src/cryptonote_core/tx_pool.h | 3 | ||||
| -rw-r--r-- | src/multisig/multisig_tx_builder_ringct.cpp | 4 | ||||
| -rw-r--r-- | src/net/i2p_address.cpp | 12 | ||||
| -rw-r--r-- | src/net/tor_address.cpp | 14 | ||||
| -rw-r--r-- | src/rpc/daemon_handler.cpp | 2 | ||||
| -rw-r--r-- | src/wallet/wallet2.cpp | 1 | ||||
| -rw-r--r-- | src/wallet/wallet_errors.h | 2 | ||||
| -rw-r--r-- | tests/core_tests/tx_pool.cpp | 2 | ||||
| -rwxr-xr-x | tests/functional_tests/address_book.py | 6 | ||||
| -rw-r--r-- | tests/unit_tests/net.cpp | 28 |
15 files changed, 69 insertions, 31 deletions
diff --git a/src/cryptonote_core/blockchain.cpp b/src/cryptonote_core/blockchain.cpp index 97fb8b8e3..f20bd1e26 100644 --- a/src/cryptonote_core/blockchain.cpp +++ b/src/cryptonote_core/blockchain.cpp @@ -2214,9 +2214,7 @@ bool Blockchain::handle_get_objects(NOTIFY_REQUEST_GET_OBJECTS::request& arg, NO //pack block e.block = std::move(bl.first); - e.block_weight = 0; - if (arg.prune && m_db->block_exists(arg.blocks[i])) - e.block_weight = m_db->get_block_weight(m_db->get_block_height(arg.blocks[i])); + e.block_weight = arg.prune ? m_db->get_block_weight(get_block_height(bl.second)) : 0; } return true; diff --git a/src/cryptonote_core/cryptonote_core.cpp b/src/cryptonote_core/cryptonote_core.cpp index f50c9ad3f..4d7a454b2 100644 --- a/src/cryptonote_core/cryptonote_core.cpp +++ b/src/cryptonote_core/cryptonote_core.cpp @@ -1548,9 +1548,9 @@ namespace cryptonote return m_mempool.get_transactions_and_spent_keys_info(tx_infos, key_image_infos, include_sensitive_data); } //----------------------------------------------------------------------------------------------- - bool core::get_pool_for_rpc(std::vector<cryptonote::rpc::tx_in_pool>& tx_infos, cryptonote::rpc::key_images_with_tx_hashes& key_image_infos) const + bool core::get_pool_for_rpc(std::vector<cryptonote::rpc::tx_in_pool>& tx_infos, cryptonote::rpc::key_images_with_tx_hashes& key_image_infos, bool include_sensitive) const { - return m_mempool.get_pool_for_rpc(tx_infos, key_image_infos); + return m_mempool.get_pool_for_rpc(tx_infos, key_image_infos, include_sensitive); } //----------------------------------------------------------------------------------------------- bool core::get_short_chain_history(std::list<crypto::hash>& ids, uint64_t& current_height) const diff --git a/src/cryptonote_core/cryptonote_core.h b/src/cryptonote_core/cryptonote_core.h index 777de3319..19d9c6e65 100644 --- a/src/cryptonote_core/cryptonote_core.h +++ b/src/cryptonote_core/cryptonote_core.h @@ -556,10 +556,11 @@ namespace cryptonote /** * @copydoc tx_memory_pool::get_pool_for_rpc + * @param include_sensitive include node-private fields (timing) * * @note see tx_memory_pool::get_pool_for_rpc */ - bool get_pool_for_rpc(std::vector<cryptonote::rpc::tx_in_pool>& tx_infos, cryptonote::rpc::key_images_with_tx_hashes& key_image_infos) const; + bool get_pool_for_rpc(std::vector<cryptonote::rpc::tx_in_pool>& tx_infos, cryptonote::rpc::key_images_with_tx_hashes& key_image_infos, bool include_sensitive) const; /** * @copydoc tx_memory_pool::get_transactions_count diff --git a/src/cryptonote_core/cryptonote_tx_utils.cpp b/src/cryptonote_core/cryptonote_tx_utils.cpp index c350e24c4..7aea5cf50 100644 --- a/src/cryptonote_core/cryptonote_tx_utils.cpp +++ b/src/cryptonote_core/cryptonote_tx_utils.cpp @@ -453,11 +453,12 @@ namespace cryptonote crypto::public_key out_eph_public_key; crypto::view_tag view_tag; - hwdev.generate_output_ephemeral_keys(tx.version,sender_account_keys, txkey_pub, tx_key, + const bool r = hwdev.generate_output_ephemeral_keys(tx.version,sender_account_keys, txkey_pub, tx_key, dst_entr, change_addr, output_index, need_additional_txkeys, additional_tx_keys, additional_tx_public_keys, amount_keys, out_eph_public_key, use_view_tags, view_tag); + CHECK_AND_ASSERT_MES(r, false, "Failed to generate output ephemeral keys"); tx_out out; cryptonote::set_tx_out(dst_entr.amount, out_eph_public_key, use_view_tags, view_tag, out); diff --git a/src/cryptonote_core/tx_pool.cpp b/src/cryptonote_core/tx_pool.cpp index badcde361..8af654185 100644 --- a/src/cryptonote_core/tx_pool.cpp +++ b/src/cryptonote_core/tx_pool.cpp @@ -416,7 +416,7 @@ namespace cryptonote break; try { - const crypto::hash &txid = it->second; + const crypto::hash txid = it->second; txpool_tx_meta_t meta; if (!m_blockchain.get_txpool_tx_meta(txid, meta)) { @@ -1241,13 +1241,13 @@ namespace cryptonote return true; } //--------------------------------------------------------------------------------- - bool tx_memory_pool::get_pool_for_rpc(std::vector<cryptonote::rpc::tx_in_pool>& tx_infos, cryptonote::rpc::key_images_with_tx_hashes& key_image_infos) const + bool tx_memory_pool::get_pool_for_rpc(std::vector<cryptonote::rpc::tx_in_pool>& tx_infos, cryptonote::rpc::key_images_with_tx_hashes& key_image_infos, bool include_sensitive) const { CRITICAL_REGION_LOCAL(m_transactions_lock); CRITICAL_REGION_LOCAL1(m_blockchain); tx_infos.reserve(m_blockchain.get_txpool_tx_count()); key_image_infos.reserve(m_blockchain.get_txpool_tx_count()); - m_blockchain.for_all_txpool_txes([&tx_infos, key_image_infos](const crypto::hash &txid, const txpool_tx_meta_t &meta, const cryptonote::blobdata_ref *bd){ + m_blockchain.for_all_txpool_txes([&tx_infos, key_image_infos, include_sensitive](const crypto::hash &txid, const txpool_tx_meta_t &meta, const cryptonote::blobdata_ref *bd){ cryptonote::rpc::tx_in_pool txi; txi.tx_hash = txid; if (!(meta.pruned ? parse_and_validate_tx_base_from_blob(*bd, txi.tx) : parse_and_validate_tx_from_blob(*bd, txi.tx))) @@ -1265,9 +1265,11 @@ namespace cryptonote txi.max_used_block_hash = meta.max_used_block_id; txi.last_failed_block_height = meta.last_failed_height; txi.last_failed_block_hash = meta.last_failed_id; - txi.receive_time = meta.receive_time; + // In restricted mode we do not include this data: + txi.receive_time = include_sensitive ? meta.receive_time : 0; txi.relayed = meta.relayed; - txi.last_relayed_time = meta.dandelionpp_stem ? 0 : meta.last_relayed_time; + // In restricted mode we do not include this data: + txi.last_relayed_time = (include_sensitive && !meta.dandelionpp_stem) ? meta.last_relayed_time : 0; txi.do_not_relay = meta.do_not_relay; txi.double_spend_seen = meta.double_spend_seen; tx_infos.push_back(txi); diff --git a/src/cryptonote_core/tx_pool.h b/src/cryptonote_core/tx_pool.h index f3630368b..f84983f05 100644 --- a/src/cryptonote_core/tx_pool.h +++ b/src/cryptonote_core/tx_pool.h @@ -323,10 +323,11 @@ namespace cryptonote * * @param tx_infos [out] the transactions' information * @param key_image_infos [out] the spent key images' information + * @param include_sensitive include fields that are sensitive to node privacy * * @return true */ - bool get_pool_for_rpc(std::vector<cryptonote::rpc::tx_in_pool>& tx_infos, cryptonote::rpc::key_images_with_tx_hashes& key_image_infos) const; + bool get_pool_for_rpc(std::vector<cryptonote::rpc::tx_in_pool>& tx_infos, cryptonote::rpc::key_images_with_tx_hashes& key_image_infos, bool include_sensitive) const; /** * @brief check for presence of key images in the pool diff --git a/src/multisig/multisig_tx_builder_ringct.cpp b/src/multisig/multisig_tx_builder_ringct.cpp index 33c0396dc..3220246ec 100644 --- a/src/multisig/multisig_tx_builder_ringct.cpp +++ b/src/multisig/multisig_tx_builder_ringct.cpp @@ -254,7 +254,7 @@ static void make_tx_secret_key_seed(const crypto::secret_key& tx_secret_key_entr rct::keyV hash_context; hash_context.reserve(2 + sources.size()); auto hash_context_wiper = epee::misc_utils::create_scope_leave_handler([&]{ - memwipe(hash_context.data(), hash_context.size()); + memwipe(hash_context.data(), hash_context.size() * sizeof(rct::key)); }); hash_context.emplace_back(); rct::cn_fast_hash(hash_context.back(), domain_separator.data(), domain_separator.size()); //domain sep @@ -282,7 +282,7 @@ static void make_tx_secret_keys(const crypto::secret_key& tx_secret_key_seed, rct::keyV hash_context; hash_context.resize(2); auto hash_context_wiper = epee::misc_utils::create_scope_leave_handler([&]{ - memwipe(hash_context.data(), hash_context.size()); + memwipe(hash_context.data(), hash_context.size() * sizeof(rct::key)); }); hash_context[0] = rct::sk2rct(tx_secret_key_seed); rct::cn_fast_hash(hash_context[1], domain_separator.data(), domain_separator.size()); diff --git a/src/net/i2p_address.cpp b/src/net/i2p_address.cpp index e793048c0..e24e7da01 100644 --- a/src/net/i2p_address.cpp +++ b/src/net/i2p_address.cpp @@ -117,11 +117,15 @@ namespace net bool i2p_address::_load(epee::serialization::portable_storage& src, epee::serialization::section* hparent) { i2p_serialized in{}; - if (in._load(src, hparent) && in.host.size() < sizeof(host_) && (in.host == unknown_host || !host_check(in.host).has_error())) + if (in._load(src, hparent) && in.host.size() < sizeof(host_)) { - std::memcpy(host_, in.host.data(), in.host.size()); - std::memset(host_ + in.host.size(), 0, sizeof(host_) - in.host.size()); - return true; + net::canonicalize_host(in.host); + if (in.host == unknown_host || !host_check(in.host).has_error()) + { + std::memcpy(host_, in.host.data(), in.host.size()); + std::memset(host_ + in.host.size(), 0, sizeof(host_) - in.host.size()); + return true; + } } static_assert(sizeof(unknown_host) <= sizeof(host_), "bad buffer size"); std::memcpy(host_, unknown_host, sizeof(unknown_host)); // include null terminator diff --git a/src/net/tor_address.cpp b/src/net/tor_address.cpp index 35bd8e9a2..25f9fde66 100644 --- a/src/net/tor_address.cpp +++ b/src/net/tor_address.cpp @@ -129,12 +129,16 @@ namespace net bool tor_address::_load(epee::serialization::portable_storage& src, epee::serialization::section* hparent) { tor_serialized in{}; - if (in._load(src, hparent) && in.host.size() < sizeof(host_) && (in.host == unknown_host || !host_check(in.host).has_error())) + if (in._load(src, hparent) && in.host.size() < sizeof(host_)) { - std::memcpy(host_, in.host.data(), in.host.size()); - std::memset(host_ + in.host.size(), 0, sizeof(host_) - in.host.size()); - port_ = in.port; - return true; + net::canonicalize_host(in.host); + if (in.host == unknown_host || !host_check(in.host).has_error()) + { + std::memcpy(host_, in.host.data(), in.host.size()); + std::memset(host_ + in.host.size(), 0, sizeof(host_) - in.host.size()); + port_ = in.port; + return true; + } } static_assert(sizeof(unknown_host) <= sizeof(host_), "bad buffer size"); std::memcpy(host_, unknown_host, sizeof(unknown_host)); // include null terminator diff --git a/src/rpc/daemon_handler.cpp b/src/rpc/daemon_handler.cpp index 10b20282e..add8bca8f 100644 --- a/src/rpc/daemon_handler.cpp +++ b/src/rpc/daemon_handler.cpp @@ -756,7 +756,7 @@ namespace rpc void DaemonHandler::handle(const GetTransactionPool::Request& req, GetTransactionPool::Response& res) { - bool r = m_core.get_pool_for_rpc(res.transactions, res.key_images); + bool r = m_core.get_pool_for_rpc(res.transactions, res.key_images, !m_restricted); if (!r) res.status = Message::STATUS_FAILED; else res.status = Message::STATUS_OK; diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index 4c8d54f61..61f49481e 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -9116,7 +9116,6 @@ void wallet2::light_wallet_get_outs(std::vector<std::vector<tools::wallet2::get_ { const boost::lock_guard<boost::recursive_mutex> lock{m_daemon_rpc_mutex}; bool r = epee::net_utils::invoke_http_json("/get_random_outs", oreq, ores, *m_http_client, rpc_timeout, "POST"); - m_daemon_rpc_mutex.unlock(); THROW_WALLET_EXCEPTION_IF(!r, error::no_connection_to_daemon, "get_random_outs"); THROW_WALLET_EXCEPTION_IF(ores.amount_outs.empty() , error::wallet_internal_error, "No outputs received from light wallet node. Error: " + ores.Error); } diff --git a/src/wallet/wallet_errors.h b/src/wallet/wallet_errors.h index c54cd3499..e0a767159 100644 --- a/src/wallet/wallet_errors.h +++ b/src/wallet/wallet_errors.h @@ -440,7 +440,7 @@ namespace tools struct out_of_hashchain_bounds_error : public refresh_error { explicit out_of_hashchain_bounds_error(std::string&& loc) - : refresh_error(std::move(loc), "Index out of bounds of of hashchain") + : refresh_error(std::move(loc), "Index out of bounds of hashchain") { } diff --git a/tests/core_tests/tx_pool.cpp b/tests/core_tests/tx_pool.cpp index fab40a972..9ec89a936 100644 --- a/tests/core_tests/tx_pool.cpp +++ b/tests/core_tests/tx_pool.cpp @@ -455,7 +455,7 @@ bool txpool_double_spend_base::check_changed(cryptonote::core& c, const size_t e { std::vector<cryptonote::rpc::tx_in_pool> infos{}; cryptonote::rpc::key_images_with_tx_hashes key_images{}; - if (!c.get_pool_for_rpc(infos, key_images) || infos.size() != m_broadcasted_hashes.size() || key_images.size() != m_broadcasted_hashes.size()) + if (!c.get_pool_for_rpc(infos, key_images, true) || infos.size() != m_broadcasted_hashes.size() || key_images.size() != m_broadcasted_hashes.size()) { MERROR("Expected broadcasted rpc data to return " << m_broadcasted_hashes.size() << " but got " << infos.size() << " infos and " << key_images.size() << "key images"); return false; diff --git a/tests/functional_tests/address_book.py b/tests/functional_tests/address_book.py index 396ce505e..a315a1cdc 100755 --- a/tests/functional_tests/address_book.py +++ b/tests/functional_tests/address_book.py @@ -98,15 +98,15 @@ class AddressBookTest(): # request (partially) out of range ok = False - try: res = wallet.get_address_book[4, 2] + try: res = wallet.get_address_book([4, 2]) except: ok = True assert ok ok = False - try: res = wallet.get_address_book[0, 2] + try: res = wallet.get_address_book([0, 2]) except: ok = True assert ok ok = False - try: res = wallet.get_address_book[2, 0] + try: res = wallet.get_address_book([2, 0]) except: ok = True assert ok diff --git a/tests/unit_tests/net.cpp b/tests/unit_tests/net.cpp index 9633f50e5..291f1e6ab 100644 --- a/tests/unit_tests/net.cpp +++ b/tests/unit_tests/net.cpp @@ -343,6 +343,20 @@ TEST(tor_address, epee_serializev_v3) EXPECT_STREQ(v3_onion, command.tor.host_str()); EXPECT_EQ(10u, command.tor.port()); + // make sure tor_address::_load canonicalizes incoming hosts + { + epee::serialization::portable_storage stg{}; + stg.load_from_binary(epee::to_span(buffer)); + + EXPECT_TRUE(stg.set_value("host", std::string{v3_onion_upper}, stg.open_section("tor", nullptr, false))); + EXPECT_TRUE(command.load(stg)); + } + + EXPECT_FALSE(command.tor.is_unknown()); + EXPECT_NE(net::tor_address{}, command.tor); + EXPECT_STREQ(v3_onion, command.tor.host_str()); + EXPECT_EQ(10u, command.tor.port()); + // make sure that exceeding max buffer doesn't destroy tor_address::_load { epee::serialization::portable_storage stg{}; @@ -751,6 +765,20 @@ TEST(i2p_address, epee_serializev_b32) EXPECT_STREQ(b32_i2p, command.i2p.host_str()); EXPECT_EQ(1u, command.i2p.port()); + // make sure i2p_address::_load canonicalizes incoming hosts + { + epee::serialization::portable_storage stg{}; + stg.load_from_binary(epee::to_span(buffer)); + + EXPECT_TRUE(stg.set_value("host", std::string{b32_i2p_upper}, stg.open_section("i2p", nullptr, false))); + EXPECT_TRUE(command.load(stg)); + } + + EXPECT_FALSE(command.i2p.is_unknown()); + EXPECT_NE(net::i2p_address{}, command.i2p); + EXPECT_STREQ(b32_i2p, command.i2p.host_str()); + EXPECT_EQ(1u, command.i2p.port()); + // make sure that exceeding max buffer doesn't destroy i2p_address::_load { epee::serialization::portable_storage stg{}; |
