diff options
Diffstat (limited to 'tests')
-rw-r--r-- | tests/CMakeLists.txt | 2 | ||||
-rw-r--r-- | tests/core_proxy/CMakeLists.txt | 49 | ||||
-rw-r--r-- | tests/core_proxy/core_proxy.cpp | 295 | ||||
-rw-r--r-- | tests/core_proxy/core_proxy.h | 119 | ||||
-rwxr-xr-x | tests/functional_tests/transfer.py | 81 | ||||
-rw-r--r-- | tests/unit_tests/aligned.cpp | 1 | ||||
-rw-r--r-- | tests/unit_tests/epee_serialization.cpp | 87 | ||||
-rw-r--r-- | tests/unit_tests/epee_utils.cpp | 57 | ||||
-rw-r--r-- | tests/unit_tests/net.cpp | 79 |
9 files changed, 263 insertions, 507 deletions
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 736872b04..700039c90 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -83,7 +83,6 @@ else () add_subdirectory(crypto) add_subdirectory(functional_tests) add_subdirectory(performance_tests) - add_subdirectory(core_proxy) add_subdirectory(unit_tests) add_subdirectory(difficulty) add_subdirectory(block_weight) @@ -159,7 +158,6 @@ set(enabled_tests block_weight hash performance_tests - core_proxy fuzz unit_tests) diff --git a/tests/core_proxy/CMakeLists.txt b/tests/core_proxy/CMakeLists.txt deleted file mode 100644 index e0ee5d7f5..000000000 --- a/tests/core_proxy/CMakeLists.txt +++ /dev/null @@ -1,49 +0,0 @@ -# Copyright (c) 2014-2023, The Monero Project -# -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without modification, are -# permitted provided that the following conditions are met: -# -# 1. Redistributions of source code must retain the above copyright notice, this list of -# conditions and the following disclaimer. -# -# 2. Redistributions in binary form must reproduce the above copyright notice, this list -# of conditions and the following disclaimer in the documentation and/or other -# materials provided with the distribution. -# -# 3. Neither the name of the copyright holder nor the names of its contributors may be -# used to endorse or promote products derived from this software without specific -# prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY -# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL -# THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, -# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF -# THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -set(core_proxy_sources - core_proxy.cpp) - -set(core_proxy_headers - core_proxy.h) - -monero_add_minimal_executable(core_proxy - ${core_proxy_sources} - ${core_proxy_headers}) -target_link_libraries(core_proxy - PRIVATE - cryptonote_core - cryptonote_protocol - p2p - version - epee - ${CMAKE_THREAD_LIBS_INIT} - ${EXTRA_LIBRARIES}) -set_property(TARGET core_proxy - PROPERTY - FOLDER "tests") diff --git a/tests/core_proxy/core_proxy.cpp b/tests/core_proxy/core_proxy.cpp deleted file mode 100644 index fa5de5b3a..000000000 --- a/tests/core_proxy/core_proxy.cpp +++ /dev/null @@ -1,295 +0,0 @@ -// Copyright (c) 2014-2023, The Monero Project -// -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without modification, are -// permitted provided that the following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, this list of -// conditions and the following disclaimer. -// -// 2. Redistributions in binary form must reproduce the above copyright notice, this list -// of conditions and the following disclaimer in the documentation and/or other -// materials provided with the distribution. -// -// 3. Neither the name of the copyright holder nor the names of its contributors may be -// used to endorse or promote products derived from this software without specific -// prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY -// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL -// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, -// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF -// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers - -// node.cpp : Defines the entry point for the console application. -// - - -#include "include_base_utils.h" -#include "version.h" -#include <iostream> -#include <sstream> - -#include <boost/program_options.hpp> - -#include "common/command_line.h" -#include "console_handler.h" -#include "p2p/net_node.h" -#include "p2p/net_node.inl" -//#include "cryptonote_core/cryptonote_core.h" -#include "cryptonote_protocol/cryptonote_protocol_handler.h" -#include "cryptonote_protocol/cryptonote_protocol_handler.inl" -#include "core_proxy.h" - -#if defined(WIN32) -#include <crtdbg.h> -#endif - -namespace po = boost::program_options; -using namespace std; -using namespace epee; -using namespace cryptonote; -using namespace crypto; - - -BOOST_CLASS_VERSION(nodetool::node_server<cryptonote::t_cryptonote_protocol_handler<tests::proxy_core> >, 1); - -int main(int argc, char* argv[]) -{ - -#ifdef WIN32 - _CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF ); -#endif - - TRY_ENTRY(); - - tools::on_startup(); - string_tools::set_module_name_and_folder(argv[0]); - - //set up logging options - mlog_configure(mlog_get_default_log_path("core_proxy.log"), true); - mlog_set_log_level(2); - - - po::options_description desc("Allowed options"); - command_line::add_arg(desc, cryptonote::arg_data_dir); - nodetool::node_server<cryptonote::t_cryptonote_protocol_handler<tests::proxy_core> >::init_options(desc); - - po::variables_map vm; - bool r = command_line::handle_error_helper(desc, [&]() - { - po::store(po::parse_command_line(argc, argv, desc), vm); - po::notify(vm); - return true; - }); - if (!r) - return 1; - - MGINFO("Module folder: " << argv[0]); - MGINFO("Node starting ..."); - - - //create objects and link them - tests::proxy_core pr_core; - cryptonote::t_cryptonote_protocol_handler<tests::proxy_core> cprotocol(pr_core, NULL); - nodetool::node_server<cryptonote::t_cryptonote_protocol_handler<tests::proxy_core> > p2psrv { - cprotocol - }; - cprotocol.set_p2p_endpoint(&p2psrv); - //pr_core.set_cryptonote_protocol(&cprotocol); - //daemon_cmmands_handler dch(p2psrv); - - //initialize objects - - MGINFO("Initializing p2p server..."); - bool res = p2psrv.init(vm); - CHECK_AND_ASSERT_MES(res, 1, "Failed to initialize p2p server."); - MGINFO("P2p server initialized OK"); - - MGINFO("Initializing cryptonote protocol..."); - res = cprotocol.init(vm); - CHECK_AND_ASSERT_MES(res, 1, "Failed to initialize cryptonote protocol."); - MGINFO("Cryptonote protocol initialized OK"); - - //initialize core here - MGINFO("Initializing proxy core..."); - res = pr_core.init(vm); - CHECK_AND_ASSERT_MES(res, 1, "Failed to initialize core"); - MGINFO("Core initialized OK"); - - MGINFO("Starting p2p net loop..."); - p2psrv.run(); - MGINFO("p2p net loop stopped"); - - //deinitialize components - MGINFO("Deinitializing core..."); - pr_core.deinit(); - MGINFO("Deinitializing cryptonote_protocol..."); - cprotocol.deinit(); - MGINFO("Deinitializing p2p..."); - p2psrv.deinit(); - - - //pr_core.set_cryptonote_protocol(NULL); - cprotocol.set_p2p_endpoint(NULL); - - - MGINFO("Node stopped."); - return 0; - - CATCH_ENTRY_L0("main", 1); -} - -/* -string tx2str(const cryptonote::transaction& tx, const cryptonote::hash256& tx_hash, const cryptonote::hash256& tx_prefix_hash, const cryptonote::blobdata& blob) { - stringstream ss; - - ss << "{" << endl; - ss << "\tversion:" << tx.version << endl; - ss << "\tunlock_time:" << tx.unlock_time << endl; - ss << "\t" - - return ss.str(); -}*/ - -bool tests::proxy_core::handle_incoming_tx(const cryptonote::tx_blob_entry& tx_blob, cryptonote::tx_verification_context& tvc, cryptonote::relay_method tx_relay, bool relayed) { - if (tx_relay != cryptonote::relay_method::block) - return true; - - crypto::hash tx_hash = null_hash; - crypto::hash tx_prefix_hash = null_hash; - transaction tx; - - if (tx_blob.prunable_hash != crypto::null_hash) - { - cerr << "WRONG TRANSACTION, pruned blob rejected" << endl; - return false; - } - - if (!parse_and_validate_tx_from_blob(tx_blob.blob, tx, tx_hash, tx_prefix_hash)) { - cerr << "WRONG TRANSACTION BLOB, Failed to parse, rejected" << endl; - return false; - } - - cout << "TX " << endl << endl; - cout << tx_hash << endl; - cout << tx_prefix_hash << endl; - cout << tx_blob.blob.size() << endl; - //cout << string_tools::buff_to_hex_nodelimer(tx_blob) << endl << endl; - cout << obj_to_json_str(tx) << endl; - cout << endl << "ENDTX" << endl; - - return true; -} - -bool tests::proxy_core::handle_incoming_txs(const std::vector<tx_blob_entry>& tx_blobs, std::vector<tx_verification_context>& tvc, cryptonote::relay_method tx_relay, bool relayed) -{ - tvc.resize(tx_blobs.size()); - size_t i = 0; - for (const auto &tx_blob: tx_blobs) - { - if (!handle_incoming_tx(tx_blob, tvc[i], tx_relay, relayed)) - return false; - ++i; - } - return true; -} - -bool tests::proxy_core::handle_incoming_block(const cryptonote::blobdata& block_blob, const cryptonote::block *block_, cryptonote::block_verification_context& bvc, bool update_miner_blocktemplate) { - block b = AUTO_VAL_INIT(b); - - if(!parse_and_validate_block_from_blob(block_blob, b)) { - cerr << "Failed to parse and validate new block" << endl; - return false; - } - - crypto::hash h; - crypto::hash lh; - cout << "BLOCK" << endl << endl; - cout << (h = get_block_hash(b)) << endl; - cout << (lh = get_block_longhash(NULL, b, 0, 0)) << endl; - cout << get_transaction_hash(b.miner_tx) << endl; - cout << ::get_object_blobsize(b.miner_tx) << endl; - //cout << string_tools::buff_to_hex_nodelimer(block_blob) << endl; - cout << obj_to_json_str(b) << endl; - - cout << endl << "ENDBLOCK" << endl << endl; - - if (!add_block(h, lh, b, block_blob)) - return false; - - return true; -} - -bool tests::proxy_core::get_short_chain_history(std::list<crypto::hash>& ids) { - build_short_history(ids, m_lastblk); - return true; -} - -void tests::proxy_core::get_blockchain_top(uint64_t& height, crypto::hash& top_id) { - height = 0; - top_id = get_block_hash(m_genesis); -} - -bool tests::proxy_core::init(const boost::program_options::variables_map& /*vm*/) { - generate_genesis_block(m_genesis, config::GENESIS_TX, config::GENESIS_NONCE); - crypto::hash h = get_block_hash(m_genesis); - add_block(h, get_block_longhash(NULL, m_genesis, 0, 0), m_genesis, block_to_blob(m_genesis)); - return true; -} - -bool tests::proxy_core::have_block_unlocked(const crypto::hash& id, int *where) { - if (m_hash2blkidx.end() == m_hash2blkidx.find(id)) - return false; - if (where) *where = HAVE_BLOCK_MAIN_CHAIN; - return true; -} - -bool tests::proxy_core::have_block(const crypto::hash& id, int *where) { - return have_block_unlocked(id, where); -} - -void tests::proxy_core::build_short_history(std::list<crypto::hash> &m_history, const crypto::hash &m_start) { - m_history.push_front(get_block_hash(m_genesis)); - /*std::unordered_map<crypto::hash, tests::block_index>::const_iterator cit = m_hash2blkidx.find(m_lastblk); - - do { - m_history.push_front(cit->first); - - size_t n = 1 << m_history.size(); - while (m_hash2blkidx.end() != cit && crypto::null_hash != cit->second.blk.prev_id && n > 0) { - n--; - cit = m_hash2blkidx.find(cit->second.blk.prev_id); - } - } while (m_hash2blkidx.end() != cit && get_block_hash(cit->second.blk) != cit->first);*/ -} - -bool tests::proxy_core::add_block(const crypto::hash &_id, const crypto::hash &_longhash, const cryptonote::block &_blk, const cryptonote::blobdata &_blob) { - size_t height = 0; - - if (crypto::null_hash != _blk.prev_id) { - std::unordered_map<crypto::hash, tests::block_index>::const_iterator cit = m_hash2blkidx.find(_blk.prev_id); - if (m_hash2blkidx.end() == cit) { - cerr << "ERROR: can't find previous block with id \"" << _blk.prev_id << "\"" << endl; - return false; - } - - height = cit->second.height + 1; - } - - m_known_block_list.push_back(_id); - - block_index bi(height, _id, _longhash, _blk, _blob, txes); - m_hash2blkidx.insert(std::make_pair(_id, bi)); - txes.clear(); - m_lastblk = _id; - - return true; -} diff --git a/tests/core_proxy/core_proxy.h b/tests/core_proxy/core_proxy.h deleted file mode 100644 index f1f9bdb66..000000000 --- a/tests/core_proxy/core_proxy.h +++ /dev/null @@ -1,119 +0,0 @@ -// Copyright (c) 2014-2023, The Monero Project -// -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without modification, are -// permitted provided that the following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, this list of -// conditions and the following disclaimer. -// -// 2. Redistributions in binary form must reproduce the above copyright notice, this list -// of conditions and the following disclaimer in the documentation and/or other -// materials provided with the distribution. -// -// 3. Neither the name of the copyright holder nor the names of its contributors may be -// used to endorse or promote products derived from this software without specific -// prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY -// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL -// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, -// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF -// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers - -#pragma once - -#include <boost/program_options/variables_map.hpp> - -#include "cryptonote_basic/cryptonote_basic_impl.h" -#include "cryptonote_basic/verification_context.h" -#include "cryptonote_core/i_core_events.h" -#include <unordered_map> - -namespace tests -{ - struct block_index { - size_t height; - crypto::hash id; - crypto::hash longhash; - cryptonote::block blk; - cryptonote::blobdata blob; - std::list<cryptonote::transaction> txes; - - block_index() : height(0), id(crypto::null_hash), longhash(crypto::null_hash) { } - block_index(size_t _height, const crypto::hash &_id, const crypto::hash &_longhash, const cryptonote::block &_blk, const cryptonote::blobdata &_blob, const std::list<cryptonote::transaction> &_txes) - : height(_height), id(_id), longhash(_longhash), blk(_blk), blob(_blob), txes(_txes) { } - }; - - class proxy_core : public cryptonote::i_core_events - { - cryptonote::block m_genesis; - std::list<crypto::hash> m_known_block_list; - std::unordered_map<crypto::hash, block_index> m_hash2blkidx; - - crypto::hash m_lastblk; - std::list<cryptonote::transaction> txes; - - bool add_block(const crypto::hash &_id, const crypto::hash &_longhash, const cryptonote::block &_blk, const cryptonote::blobdata &_blob); - void build_short_history(std::list<crypto::hash> &m_history, const crypto::hash &m_start); - - - public: - virtual bool is_synchronized() const final { return true; } - void on_synchronized(){} - void safesyncmode(const bool){} - virtual uint64_t get_current_blockchain_height() const final {return 1;} - void set_target_blockchain_height(uint64_t) {} - bool init(const boost::program_options::variables_map& vm); - bool deinit(){return true;} - bool get_short_chain_history(std::list<crypto::hash>& ids); - bool have_block(const crypto::hash& id, int *where = NULL); - bool have_block_unlocked(const crypto::hash& id, int *where = NULL); - void get_blockchain_top(uint64_t& height, crypto::hash& top_id); - bool handle_incoming_tx(const cryptonote::tx_blob_entry& tx_blob, cryptonote::tx_verification_context& tvc, cryptonote::relay_method tx_relay, bool relayed); - bool handle_incoming_txs(const std::vector<cryptonote::tx_blob_entry>& tx_blobs, std::vector<cryptonote::tx_verification_context>& tvc, cryptonote::relay_method tx_relay, bool relayed); - bool handle_incoming_block(const cryptonote::blobdata& block_blob, const cryptonote::block *block, cryptonote::block_verification_context& bvc, bool update_miner_blocktemplate = true); - void pause_mine(){} - void resume_mine(){} - bool on_idle(){return true;} - bool find_blockchain_supplement(const std::list<crypto::hash>& qblock_ids, bool clip_pruned, cryptonote::NOTIFY_RESPONSE_CHAIN_ENTRY::request& resp){return true;} - bool handle_get_objects(cryptonote::NOTIFY_REQUEST_GET_OBJECTS::request& arg, cryptonote::NOTIFY_RESPONSE_GET_OBJECTS::request& rsp, cryptonote::cryptonote_connection_context& context){return true;} - cryptonote::Blockchain &get_blockchain_storage() { throw std::runtime_error("Called invalid member function: please never call get_blockchain_storage on the TESTING class proxy_core."); } - bool get_test_drop_download() {return true;} - bool get_test_drop_download_height() {return true;} - bool prepare_handle_incoming_blocks(const std::vector<cryptonote::block_complete_entry> &blocks_entry, std::vector<cryptonote::block> &blocks) { return true; } - bool cleanup_handle_incoming_blocks(bool force_sync = false) { return true; } - bool update_checkpoints(const bool skip_dns = false) { return true; } - uint64_t get_target_blockchain_height() const { return 1; } - size_t get_block_sync_size(uint64_t height) const { return BLOCKS_SYNCHRONIZING_DEFAULT_COUNT; } - virtual void on_transactions_relayed(epee::span<const cryptonote::blobdata> tx_blobs, cryptonote::relay_method tx_relay) {} - cryptonote::network_type get_nettype() const { return cryptonote::MAINNET; } - bool get_pool_transaction(const crypto::hash& id, cryptonote::blobdata& tx_blob, cryptonote::relay_category tx_category) const { return false; } - bool pool_has_tx(const crypto::hash &txid) const { return false; } - bool get_blocks(uint64_t start_offset, size_t count, std::vector<std::pair<cryptonote::blobdata, cryptonote::block>>& blocks, std::vector<cryptonote::blobdata>& txs) const { return false; } - bool get_transactions(const std::vector<crypto::hash>& txs_ids, std::vector<cryptonote::transaction>& txs, std::vector<crypto::hash>& missed_txs) const { return false; } - bool get_block_by_hash(const crypto::hash &h, cryptonote::block &blk, bool *orphan = NULL) const { return false; } - uint8_t get_ideal_hard_fork_version() const { return 0; } - uint8_t get_ideal_hard_fork_version(uint64_t height) const { return 0; } - uint8_t get_hard_fork_version(uint64_t height) const { return 0; } - uint64_t get_earliest_ideal_height_for_version(uint8_t version) const { return 0; } - cryptonote::difficulty_type get_block_cumulative_difficulty(uint64_t height) const { return 0; } - bool fluffy_blocks_enabled() const { return false; } - uint64_t prevalidate_block_hashes(uint64_t height, const std::vector<crypto::hash> &hashes, const std::vector<uint64_t> &weights) { return 0; } - bool has_block_weights(uint64_t height, uint64_t nblocks) const { return false; } - bool is_within_compiled_block_hash_area(uint64_t height) const { return false; } - bool pad_transactions() const { return false; } - uint32_t get_blockchain_pruning_seed() const { return 0; } - bool prune_blockchain(uint32_t pruning_seed) const { return true; } - bool get_txpool_complement(const std::vector<crypto::hash> &hashes, std::vector<cryptonote::blobdata> &txes) { return false; } - bool get_pool_transaction_hashes(std::vector<crypto::hash>& txs, bool include_unrelayed_txes = true) const { return false; } - crypto::hash get_block_id_by_height(uint64_t height) const { return crypto::null_hash; } - }; -} diff --git a/tests/functional_tests/transfer.py b/tests/functional_tests/transfer.py index ddc930eb0..56a2514d9 100755 --- a/tests/functional_tests/transfer.py +++ b/tests/functional_tests/transfer.py @@ -63,6 +63,7 @@ class TransferTest(): self.check_is_key_image_spent() self.check_multiple_submissions() self.check_scan_tx() + self.check_subtract_fee_from_outputs() def reset(self): print('Resetting blockchain') @@ -1081,5 +1082,85 @@ class TransferTest(): diff_transfers(receiver_wallet.get_transfers(), res) assert receiver_wallet.get_balance().balance == expected_receiver_balance + def check_subtract_fee_from_outputs(self): + daemon = Daemon() + + print('Testing fee-included transfers') + + def inner_test_external_transfer(dsts, subtract_fee_from_outputs): + # refresh wallet and get balance + self.wallet[0].refresh() + balance1 = self.wallet[0].get_balance().balance + + # Check that this transaction is possible with our current balance + other preconditions + dst_sum = sum(map(lambda x: x['amount'], dsts)) + assert balance1 >= dst_sum + if subtract_fee_from_outputs: + assert max(subtract_fee_from_outputs) < len(dsts) + + # transfer with subtractfeefrom=all + transfer_res = self.wallet[0].transfer(dsts, subtract_fee_from_outputs = subtract_fee_from_outputs, get_tx_metadata = True) + tx_hex = transfer_res.tx_metadata + tx_fee = transfer_res.fee + amount_spent = transfer_res.amount + amounts_by_dest = transfer_res.amounts_by_dest.amounts + + # Assert that fee and amount spent to outputs adds up + assert tx_fee != 0 + if subtract_fee_from_outputs: + assert tx_fee + amount_spent == dst_sum + else: + assert amount_spent == dst_sum + + # Check the amounts by each destination that only the destinations set as subtractable + # got subtracted and that the subtracted dests are approximately correct + assert len(amounts_by_dest) == len(dsts) # if this fails... idk + for i in range(len(dsts)): + if i in subtract_fee_from_outputs: # dest is subtractable + approx_subtraction = tx_fee // len(subtract_fee_from_outputs) + assert amounts_by_dest[i] < dsts[i]['amount'] + assert dsts[i]['amount'] - amounts_by_dest[i] - approx_subtraction <= 1 + else: + assert amounts_by_dest[i] == dsts[i]['amount'] + + # relay tx and generate block (not to us, to simplify balance change calculations) + relay_res = self.wallet[0].relay_tx(tx_hex) + daemon.generateblocks('44Kbx4sJ7JDRDV5aAhLJzQCjDz2ViLRduE3ijDZu3osWKBjMGkV1XPk4pfDUMqt1Aiezvephdqm6YD19GKFD9ZcXVUTp6BW', 1) + + # refresh and get balance again + self.wallet[0].refresh() + balance2 = self.wallet[0].get_balance().balance + + # Check that the wallet balance dropped by the correct amount + balance_drop = balance1 - balance2 + if subtract_fee_from_outputs: + assert balance_drop == dst_sum + else: + assert balance_drop == dst_sum + tx_fee + + dst1 = {'address': '44Kbx4sJ7JDRDV5aAhLJzQCjDz2ViLRduE3ijDZu3osWKBjMGkV1XPk4pfDUMqt1Aiezvephdqm6YD19GKFD9ZcXVUTp6BW', 'amount': 1100000000001} + dst2 = {'address': '46r4nYSevkfBUMhuykdK3gQ98XDqDTYW1hNLaXNvjpsJaSbNtdXh1sKMsdVgqkaihChAzEy29zEDPMR3NHQvGoZCLGwTerK', 'amount': 1200000000000} + dst3 = {'address': '46r4nYSevkfBUMhuykdK3gQ98XDqDTYW1hNLaXNvjpsJaSbNtdXh1sKMsdVgqkaihChAzEy29zEDPMR3NHQvGoZCLGwTerK', 'amount': 1} + + inner_test_external_transfer([dst1, dst2], [0, 1]) + inner_test_external_transfer([dst1, dst2], [0]) + inner_test_external_transfer([dst1, dst2], [1]) + inner_test_external_transfer([dst1, dst2], []) + inner_test_external_transfer([dst1], [0]) + inner_test_external_transfer([dst1], []) + inner_test_external_transfer([dst3], []) + try: + inner_test_external_transfer([dst1, dst3], [0, 1]) # Test subtractfeefrom if one of the outputs would underflow w/o good checks + raise ValueError('transfer request with tiny subtractable destination should have thrown') + except: + pass + + # Check for JSONRPC error on bad index + try: + transfer_res = self.wallet[0].transfer([dst1], subtract_fee_from_outputs = [1]) + raise ValueError('transfer request with index should have thrown') + except AssertionError: + pass + if __name__ == '__main__': TransferTest().run_test() diff --git a/tests/unit_tests/aligned.cpp b/tests/unit_tests/aligned.cpp index b64b03c5a..9ae43aeb3 100644 --- a/tests/unit_tests/aligned.cpp +++ b/tests/unit_tests/aligned.cpp @@ -29,6 +29,7 @@ #include "gtest/gtest.h" +#include <cstdint> #include "common/aligned.h" TEST(aligned, large_null) { ASSERT_TRUE(aligned_malloc((size_t)-1, 1) == NULL); } diff --git a/tests/unit_tests/epee_serialization.cpp b/tests/unit_tests/epee_serialization.cpp index 035f5e206..ecc26e971 100644 --- a/tests/unit_tests/epee_serialization.cpp +++ b/tests/unit_tests/epee_serialization.cpp @@ -29,8 +29,11 @@ #include <cstdint> #include <gtest/gtest.h> +#include <vector> +#include "serialization/keyvalue_serialization.h" #include "storages/portable_storage.h" +#include "storages/portable_storage_template_helper.h" #include "span.h" TEST(epee_binary, two_keys) @@ -54,3 +57,87 @@ TEST(epee_binary, duplicate_key) epee::serialization::portable_storage storage{}; EXPECT_FALSE(storage.load_from_binary(data)); } + +namespace +{ +struct ObjOfObjs +{ + std::vector<ObjOfObjs> x; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(x) + END_KV_SERIALIZE_MAP() +}; + +struct ObjOfInts +{ + std::list<int> x; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(x) + END_KV_SERIALIZE_MAP() +}; +} + +TEST(epee_binary, any_empty_seq) +{ + // Test that any c++ sequence type (std::vector, std::list, etc) can deserialize without error + // from an *empty* epee binary array of any type. This property is useful for other projects who + // maintain code which serializes epee binary but don't know the type of arrays until runtime. + // Without any elements to actually serialize, they don't know what type code to use for arrays + // and should be able to choose a default typecode. + + static constexpr const std::uint8_t data_empty_bool[] = { + 0x01, 0x11, 0x01, 0x1, 0x01, 0x01, 0x02, 0x1, 0x1, 0x04, 0x01, 'x', 0x8B /*array of bools*/, 0x00 /*length 0*/ + }; + + static constexpr const std::uint8_t data_empty_double[] = { + 0x01, 0x11, 0x01, 0x1, 0x01, 0x01, 0x02, 0x1, 0x1, 0x04, 0x01, 'x', 0x89 /*array of doubles*/, 0x00 /*length 0*/ + }; + + static constexpr const std::uint8_t data_empty_string[] = { + 0x01, 0x11, 0x01, 0x1, 0x01, 0x01, 0x02, 0x1, 0x1, 0x04, 0x01, 'x', 0x8A /*array of strings*/, 0x00 /*length 0*/ + }; + + static constexpr const std::uint8_t data_empty_int64[] = { + 0x01, 0x11, 0x01, 0x1, 0x01, 0x01, 0x02, 0x1, 0x1, 0x04, 0x01, 'x', 0x81 /*array of int64s*/, 0x00 /*length 0*/ + }; + + static constexpr const std::uint8_t data_empty_object[] = { + 0x01, 0x11, 0x01, 0x1, 0x01, 0x01, 0x02, 0x1, 0x1, 0x04, 0x01, 'x', 0x8C /*array of objects*/, 0x00 /*length 0*/ + }; + + ObjOfObjs o; + + EXPECT_TRUE(epee::serialization::load_t_from_binary(o, epee::span<const std::uint8_t>(data_empty_bool))); + EXPECT_EQ(0, o.x.size()); + + EXPECT_TRUE(epee::serialization::load_t_from_binary(o, epee::span<const std::uint8_t>(data_empty_double))); + EXPECT_EQ(0, o.x.size()); + + EXPECT_TRUE(epee::serialization::load_t_from_binary(o, epee::span<const std::uint8_t>(data_empty_string))); + EXPECT_EQ(0, o.x.size()); + + EXPECT_TRUE(epee::serialization::load_t_from_binary(o, epee::span<const std::uint8_t>(data_empty_int64))); + EXPECT_EQ(0, o.x.size()); + + EXPECT_TRUE(epee::serialization::load_t_from_binary(o, epee::span<const std::uint8_t>(data_empty_object))); + EXPECT_EQ(0, o.x.size()); + + ObjOfInts i; + + EXPECT_TRUE(epee::serialization::load_t_from_binary(i, epee::span<const std::uint8_t>(data_empty_bool))); + EXPECT_EQ(0, i.x.size()); + + EXPECT_TRUE(epee::serialization::load_t_from_binary(i, epee::span<const std::uint8_t>(data_empty_double))); + EXPECT_EQ(0, i.x.size()); + + EXPECT_TRUE(epee::serialization::load_t_from_binary(i, epee::span<const std::uint8_t>(data_empty_string))); + EXPECT_EQ(0, i.x.size()); + + EXPECT_TRUE(epee::serialization::load_t_from_binary(i, epee::span<const std::uint8_t>(data_empty_int64))); + EXPECT_EQ(0, i.x.size()); + + EXPECT_TRUE(epee::serialization::load_t_from_binary(i, epee::span<const std::uint8_t>(data_empty_object))); + EXPECT_EQ(0, i.x.size()); +} diff --git a/tests/unit_tests/epee_utils.cpp b/tests/unit_tests/epee_utils.cpp index c776fbcc9..dd3aafaa6 100644 --- a/tests/unit_tests/epee_utils.cpp +++ b/tests/unit_tests/epee_utils.cpp @@ -1852,3 +1852,60 @@ TEST(parsing, unicode) epee::misc_utils::parse::match_string2(si, s.end(), bs); EXPECT_EQ(bs, "あまやかす"); } + +TEST(parsing, strtoul) +{ + long ul; + const char* p; + const char* endp; + + errno = 0; // Some libc's only set errno on failure, some set it to 0 on success + + p = "0"; + endp = nullptr; + ul = std::strtoul(p, const_cast<char**>(&endp), 10); + EXPECT_EQ(0, errno); + EXPECT_EQ(0, ul); + EXPECT_EQ(p + 1, endp); + + p = "000000"; + endp = nullptr; + ul = std::strtoul(p, const_cast<char**>(&endp), 10); + EXPECT_EQ(0, errno); + EXPECT_EQ(0, ul); + EXPECT_EQ(p + 6, endp); + + p = "1"; + endp = nullptr; + ul = std::strtoul(p, const_cast<char**>(&endp), 10); + EXPECT_EQ(0, errno); + EXPECT_EQ(1, ul); + EXPECT_EQ(p + 1, endp); + + p = "0q"; + endp = nullptr; + ul = std::strtoul(p, const_cast<char**>(&endp), 10); + EXPECT_EQ(0, errno); + EXPECT_EQ(0, ul); + EXPECT_EQ(p + 1, endp); + + p = " \t 0"; + endp = nullptr; + ul = std::strtoul(p, const_cast<char**>(&endp), 10); + EXPECT_EQ(0, errno); + EXPECT_EQ(0, ul); + EXPECT_EQ(p + 9, endp); + + p = "q"; + endp = nullptr; + ul = std::strtoul(p, const_cast<char**>(&endp), 10); + EXPECT_EQ(0, errno); + EXPECT_EQ(0, ul); + EXPECT_EQ(p, endp); + + p = "999999999999999999999999999999999999999"; + endp = nullptr; + ul = std::strtoul(p, const_cast<char**>(&endp), 10); + EXPECT_EQ(ERANGE, errno); + EXPECT_EQ(ULLONG_MAX, ul); +} diff --git a/tests/unit_tests/net.cpp b/tests/unit_tests/net.cpp index 2b565f7d0..c9099b99b 100644 --- a/tests/unit_tests/net.cpp +++ b/tests/unit_tests/net.cpp @@ -472,8 +472,6 @@ TEST(i2p_address, invalid) EXPECT_TRUE(net::i2p_address::make(".b32.i2p:").has_error()); EXPECT_TRUE(net::i2p_address::make(b32_i2p + 1).has_error()); EXPECT_TRUE(net::i2p_address::make(boost::string_ref{b32_i2p, sizeof(b32_i2p) - 2}).has_error()); - EXPECT_TRUE(net::i2p_address::make(std::string{b32_i2p} + ":65536").has_error()); - EXPECT_TRUE(net::i2p_address::make(std::string{b32_i2p} + ":-1").has_error()); std::string i2p{b32_i2p}; i2p.at(10) = 1; @@ -487,7 +485,7 @@ TEST(i2p_address, unblockable_types) ASSERT_NE(nullptr, i2p.host_str()); EXPECT_STREQ("<unknown i2p host>", i2p.host_str()); EXPECT_STREQ("<unknown i2p host>", i2p.str().c_str()); - EXPECT_EQ(0u, i2p.port()); + EXPECT_EQ(1u, i2p.port()); EXPECT_TRUE(i2p.is_unknown()); EXPECT_FALSE(i2p.is_local()); EXPECT_FALSE(i2p.is_loopback()); @@ -498,7 +496,7 @@ TEST(i2p_address, unblockable_types) ASSERT_NE(nullptr, i2p.host_str()); EXPECT_STREQ("<unknown i2p host>", i2p.host_str()); EXPECT_STREQ("<unknown i2p host>", i2p.str().c_str()); - EXPECT_EQ(0u, i2p.port()); + EXPECT_EQ(1u, i2p.port()); EXPECT_TRUE(i2p.is_unknown()); EXPECT_FALSE(i2p.is_local()); EXPECT_FALSE(i2p.is_loopback()); @@ -513,14 +511,14 @@ TEST(i2p_address, valid) const auto address1 = net::i2p_address::make(b32_i2p); ASSERT_TRUE(address1.has_value()); - EXPECT_EQ(0u, address1->port()); + EXPECT_EQ(1u, address1->port()); EXPECT_STREQ(b32_i2p, address1->host_str()); EXPECT_STREQ(b32_i2p, address1->str().c_str()); EXPECT_TRUE(address1->is_blockable()); net::i2p_address address2{*address1}; - EXPECT_EQ(0u, address2.port()); + EXPECT_EQ(1u, address2.port()); EXPECT_STREQ(b32_i2p, address2.host_str()); EXPECT_STREQ(b32_i2p, address2.str().c_str()); EXPECT_TRUE(address2.is_blockable()); @@ -537,9 +535,9 @@ TEST(i2p_address, valid) address2 = MONERO_UNWRAP(net::i2p_address::make(std::string{b32_i2p_2} + ":6545")); - EXPECT_EQ(6545, address2.port()); + EXPECT_EQ(1u, address2.port()); EXPECT_STREQ(b32_i2p_2, address2.host_str()); - EXPECT_EQ(std::string{b32_i2p_2} + ":6545", address2.str().c_str()); + EXPECT_EQ(std::string{b32_i2p_2}, address2.str().c_str()); EXPECT_TRUE(address2.is_blockable()); EXPECT_FALSE(address2.equal(*address1)); EXPECT_FALSE(address1->equal(address2)); @@ -552,22 +550,22 @@ TEST(i2p_address, valid) EXPECT_FALSE(address2.less(*address1)); EXPECT_TRUE(address1->less(address2)); - net::i2p_address address3 = MONERO_UNWRAP(net::i2p_address::make(std::string{b32_i2p} + ":", 65535)); + net::i2p_address address3 = MONERO_UNWRAP(net::i2p_address::make(std::string{b32_i2p} + ":65535")); - EXPECT_EQ(65535, address3.port()); + EXPECT_EQ(1u, address3.port()); EXPECT_STREQ(b32_i2p, address3.host_str()); - EXPECT_EQ(std::string{b32_i2p} + ":65535", address3.str().c_str()); + EXPECT_EQ(std::string{b32_i2p}, address3.str().c_str()); EXPECT_TRUE(address3.is_blockable()); - EXPECT_FALSE(address3.equal(*address1)); - EXPECT_FALSE(address1->equal(address3)); - EXPECT_FALSE(address3 == *address1); - EXPECT_FALSE(*address1 == address3); - EXPECT_TRUE(address3 != *address1); - EXPECT_TRUE(*address1 != address3); + EXPECT_TRUE(address3.equal(*address1)); + EXPECT_TRUE(address1->equal(address3)); + EXPECT_TRUE(address3 == *address1); + EXPECT_TRUE(*address1 == address3); + EXPECT_FALSE(address3 != *address1); + EXPECT_FALSE(*address1 != address3); EXPECT_TRUE(address3.is_same_host(*address1)); EXPECT_TRUE(address1->is_same_host(address3)); EXPECT_FALSE(address3.less(*address1)); - EXPECT_TRUE(address1->less(address3)); + EXPECT_FALSE(address1->less(address3)); EXPECT_FALSE(address3.equal(address2)); EXPECT_FALSE(address2.equal(address3)); @@ -583,8 +581,8 @@ TEST(i2p_address, valid) TEST(i2p_address, generic_network_address) { - const epee::net_utils::network_address i2p1{MONERO_UNWRAP(net::i2p_address::make(b32_i2p, 8080))}; - const epee::net_utils::network_address i2p2{MONERO_UNWRAP(net::i2p_address::make(b32_i2p, 8080))}; + const epee::net_utils::network_address i2p1{MONERO_UNWRAP(net::i2p_address::make(b32_i2p))}; + const epee::net_utils::network_address i2p2{MONERO_UNWRAP(net::i2p_address::make(b32_i2p))}; const epee::net_utils::network_address ip{epee::net_utils::ipv4_network_address{100, 200}}; EXPECT_EQ(i2p1, i2p2); @@ -592,7 +590,7 @@ TEST(i2p_address, generic_network_address) EXPECT_LT(ip, i2p1); EXPECT_STREQ(b32_i2p, i2p1.host_str().c_str()); - EXPECT_EQ(std::string{b32_i2p} + ":8080", i2p1.str()); + EXPECT_STREQ(b32_i2p, i2p1.str().c_str()); EXPECT_EQ(epee::net_utils::address_type::i2p, i2p1.get_type_id()); EXPECT_EQ(epee::net_utils::address_type::i2p, i2p2.get_type_id()); EXPECT_EQ(epee::net_utils::address_type::ipv4, ip.get_type_id()); @@ -620,11 +618,11 @@ TEST(i2p_address, epee_serializev_b32) { epee::byte_slice buffer{}; { - test_command_i2p command{MONERO_UNWRAP(net::i2p_address::make(b32_i2p, 10))}; + test_command_i2p command{MONERO_UNWRAP(net::i2p_address::make(b32_i2p))}; EXPECT_FALSE(command.i2p.is_unknown()); EXPECT_NE(net::i2p_address{}, command.i2p); EXPECT_STREQ(b32_i2p, command.i2p.host_str()); - EXPECT_EQ(10u, command.i2p.port()); + EXPECT_EQ(1u, command.i2p.port()); epee::serialization::portable_storage stg{}; EXPECT_TRUE(command.store(stg)); @@ -636,7 +634,7 @@ TEST(i2p_address, epee_serializev_b32) EXPECT_TRUE(command.i2p.is_unknown()); EXPECT_EQ(net::i2p_address{}, command.i2p); EXPECT_STREQ(net::i2p_address::unknown_str(), command.i2p.host_str()); - EXPECT_EQ(0u, command.i2p.port()); + EXPECT_EQ(1u, command.i2p.port()); epee::serialization::portable_storage stg{}; EXPECT_TRUE(stg.load_from_binary(epee::to_span(buffer))); @@ -645,7 +643,7 @@ TEST(i2p_address, epee_serializev_b32) EXPECT_FALSE(command.i2p.is_unknown()); EXPECT_NE(net::i2p_address{}, command.i2p); EXPECT_STREQ(b32_i2p, command.i2p.host_str()); - EXPECT_EQ(10u, command.i2p.port()); + EXPECT_EQ(1u, command.i2p.port()); // make sure that exceeding max buffer doesn't destroy i2p_address::_load { @@ -664,7 +662,7 @@ TEST(i2p_address, epee_serializev_b32) EXPECT_TRUE(command.i2p.is_unknown()); EXPECT_EQ(net::i2p_address{}, command.i2p); EXPECT_STRNE(b32_i2p, command.i2p.host_str()); - EXPECT_EQ(0u, command.i2p.port()); + EXPECT_EQ(1u, command.i2p.port()); } TEST(i2p_address, epee_serialize_unknown) @@ -675,7 +673,7 @@ TEST(i2p_address, epee_serialize_unknown) EXPECT_TRUE(command.i2p.is_unknown()); EXPECT_EQ(net::i2p_address{}, command.i2p); EXPECT_STREQ(net::i2p_address::unknown_str(), command.i2p.host_str()); - EXPECT_EQ(0u, command.i2p.port()); + EXPECT_EQ(1u, command.i2p.port()); epee::serialization::portable_storage stg{}; EXPECT_TRUE(command.store(stg)); @@ -687,7 +685,7 @@ TEST(i2p_address, epee_serialize_unknown) EXPECT_TRUE(command.i2p.is_unknown()); EXPECT_EQ(net::i2p_address{}, command.i2p); EXPECT_STRNE(b32_i2p, command.i2p.host_str()); - EXPECT_EQ(0u, command.i2p.port()); + EXPECT_EQ(1u, command.i2p.port()); epee::serialization::portable_storage stg{}; EXPECT_TRUE(stg.load_from_binary(epee::to_span(buffer))); @@ -696,7 +694,7 @@ TEST(i2p_address, epee_serialize_unknown) EXPECT_TRUE(command.i2p.is_unknown()); EXPECT_EQ(net::i2p_address{}, command.i2p); EXPECT_STREQ(net::i2p_address::unknown_str(), command.i2p.host_str()); - EXPECT_EQ(0u, command.i2p.port()); + EXPECT_EQ(1u, command.i2p.port()); // make sure that exceeding max buffer doesn't destroy i2p_address::_load { @@ -715,18 +713,18 @@ TEST(i2p_address, epee_serialize_unknown) EXPECT_TRUE(command.i2p.is_unknown()); EXPECT_EQ(net::i2p_address{}, command.i2p); EXPECT_STRNE(b32_i2p, command.i2p.host_str()); - EXPECT_EQ(0u, command.i2p.port()); + EXPECT_EQ(1u, command.i2p.port()); } TEST(i2p_address, boost_serialize_b32) { std::string buffer{}; { - const net::i2p_address i2p = MONERO_UNWRAP(net::i2p_address::make(b32_i2p, 10)); + const net::i2p_address i2p = MONERO_UNWRAP(net::i2p_address::make(b32_i2p)); EXPECT_FALSE(i2p.is_unknown()); EXPECT_NE(net::i2p_address{}, i2p); EXPECT_STREQ(b32_i2p, i2p.host_str()); - EXPECT_EQ(10u, i2p.port()); + EXPECT_EQ(1u, i2p.port()); std::ostringstream stream{}; { @@ -741,7 +739,7 @@ TEST(i2p_address, boost_serialize_b32) EXPECT_TRUE(i2p.is_unknown()); EXPECT_EQ(net::i2p_address{}, i2p); EXPECT_STREQ(net::i2p_address::unknown_str(), i2p.host_str()); - EXPECT_EQ(0u, i2p.port()); + EXPECT_EQ(1u, i2p.port()); std::istringstream stream{buffer}; boost::archive::portable_binary_iarchive archive{stream}; @@ -750,7 +748,7 @@ TEST(i2p_address, boost_serialize_b32) EXPECT_FALSE(i2p.is_unknown()); EXPECT_NE(net::i2p_address{}, i2p); EXPECT_STREQ(b32_i2p, i2p.host_str()); - EXPECT_EQ(10u, i2p.port()); + EXPECT_EQ(1u, i2p.port()); } TEST(i2p_address, boost_serialize_unknown) @@ -761,7 +759,7 @@ TEST(i2p_address, boost_serialize_unknown) EXPECT_TRUE(i2p.is_unknown()); EXPECT_EQ(net::i2p_address::unknown(), i2p); EXPECT_STREQ(net::i2p_address::unknown_str(), i2p.host_str()); - EXPECT_EQ(0u, i2p.port()); + EXPECT_EQ(1u, i2p.port()); std::ostringstream stream{}; { @@ -776,7 +774,7 @@ TEST(i2p_address, boost_serialize_unknown) EXPECT_TRUE(i2p.is_unknown()); EXPECT_EQ(net::i2p_address{}, i2p); EXPECT_STREQ(net::i2p_address::unknown_str(), i2p.host_str()); - EXPECT_EQ(0u, i2p.port()); + EXPECT_EQ(1u, i2p.port()); std::istringstream stream{buffer}; boost::archive::portable_binary_iarchive archive{stream}; @@ -785,7 +783,7 @@ TEST(i2p_address, boost_serialize_unknown) EXPECT_TRUE(i2p.is_unknown()); EXPECT_EQ(net::i2p_address::unknown(), i2p); EXPECT_STREQ(net::i2p_address::unknown_str(), i2p.host_str()); - EXPECT_EQ(0u, i2p.port()); + EXPECT_EQ(1u, i2p.port()); } TEST(get_network_address, i2p) @@ -801,16 +799,13 @@ TEST(get_network_address, i2p) ASSERT_TRUE(bool(address)); EXPECT_EQ(epee::net_utils::address_type::i2p, address->get_type_id()); EXPECT_STREQ(b32_i2p, address->host_str().c_str()); - EXPECT_EQ(std::string{b32_i2p} + ":1000", address->str()); + EXPECT_EQ(std::string{b32_i2p}, address->str()); address = net::get_network_address(std::string{b32_i2p} + ":2000", 1000); ASSERT_TRUE(bool(address)); EXPECT_EQ(epee::net_utils::address_type::i2p, address->get_type_id()); EXPECT_STREQ(b32_i2p, address->host_str().c_str()); - EXPECT_EQ(std::string{b32_i2p} + ":2000", address->str()); - - address = net::get_network_address(std::string{b32_i2p} + ":65536", 1000); - EXPECT_EQ(net::error::invalid_port, address); + EXPECT_EQ(std::string{b32_i2p}, address->str()); } TEST(get_network_address, ipv4) |