diff options
-rw-r--r-- | README.md | 10 | ||||
-rw-r--r-- | contrib/gitian/README.md | 4 | ||||
-rw-r--r-- | src/blockchain_utilities/blockchain_export.cpp | 6 | ||||
-rw-r--r-- | src/blockchain_utilities/blockchain_import.cpp | 12 | ||||
-rw-r--r-- | src/blockchain_utilities/bootstrap_file.cpp | 75 | ||||
-rw-r--r-- | src/blockchain_utilities/bootstrap_file.h | 10 | ||||
-rw-r--r-- | src/blocks/checkpoints.dat | bin | 275780 -> 276292 bytes | |||
-rw-r--r-- | src/checkpoints/checkpoints.cpp | 1 | ||||
-rw-r--r-- | src/cryptonote_config.h | 2 | ||||
-rw-r--r-- | src/cryptonote_core/blockchain.cpp | 20 | ||||
-rw-r--r-- | src/p2p/net_node.inl | 27 | ||||
-rw-r--r-- | src/version.cpp.in | 2 | ||||
-rw-r--r-- | src/wallet/api/wallet.cpp | 5 | ||||
-rw-r--r-- | src/wallet/api/wallet.h | 1 | ||||
-rw-r--r-- | src/wallet/api/wallet2_api.h | 5 | ||||
-rw-r--r-- | src/wallet/wallet2.cpp | 8 |
16 files changed, 138 insertions, 50 deletions
@@ -134,8 +134,8 @@ Dates are provided in the format YYYY-MM-DD. | 1788000 | 2019-03-09 | v10 | v0.14.0.0 | v0.14.1.2 | New PoW based on Cryptonight-R, new block weight algorithm, slightly more efficient RingCT format | 1788720 | 2019-03-10 | v11 | v0.14.0.0 | v0.14.1.2 | forbid old RingCT transaction format | 1978433 | 2019-11-30* | v12 | v0.15.0.0 | v0.16.0.0 | New PoW based on RandomX, only allow >= 2 outputs, change to the block median used to calculate penalty, v1 coinbases are forbidden, rct sigs in coinbase forbidden, 10 block lock time for incoming outputs -| 2210000 | 2020-10-17 | v13 | v0.17.0.0 | v0.17.1.0 | New CLSAG transaction format -| 2210720 | 2020-10-18 | v14 | v0.17.0.0 | v0.17.1.0 | forbid old MLSAG transaction format +| 2210000 | 2020-10-17 | v13 | v0.17.0.0 | v0.17.1.1 | New CLSAG transaction format +| 2210720 | 2020-10-18 | v14 | v0.17.1.1 | v0.17.1.1 | forbid old MLSAG transaction format | XXXXXXX | XXX-XX-XX | XXX | vX.XX.X.X | vX.XX.X.X | XXX | X's indicate that these details have not been determined as of commit date. @@ -295,7 +295,7 @@ Tested on a Raspberry Pi Zero with a clean install of minimal Raspbian Stretch ( ```bash git clone https://github.com/monero-project/monero.git cd monero - git checkout tags/v0.17.1.0 + git checkout tags/v0.17.1.1 ``` * Build: @@ -412,10 +412,10 @@ application. cd monero ``` -* If you would like a specific [version/tag](https://github.com/monero-project/monero/tags), do a git checkout for that version. eg. 'v0.17.1.0'. If you don't care about the version and just want binaries from master, skip this step: +* If you would like a specific [version/tag](https://github.com/monero-project/monero/tags), do a git checkout for that version. eg. 'v0.17.1.1'. If you don't care about the version and just want binaries from master, skip this step: ```bash - git checkout v0.17.1.0 + git checkout v0.17.1.1 ``` * If you are on a 64-bit system, run: diff --git a/contrib/gitian/README.md b/contrib/gitian/README.md index 2b277f8c4..0a15f80b6 100644 --- a/contrib/gitian/README.md +++ b/contrib/gitian/README.md @@ -126,7 +126,7 @@ Setup for LXC: ```bash GH_USER=fluffypony -VERSION=v0.17.1.0 +VERSION=v0.17.1.1 ./gitian-build.py --setup $GH_USER $VERSION ``` @@ -182,7 +182,7 @@ If you chose to do detached signing using `--detach-sign` above (recommended), y ```bash GH_USER=fluffypony -VERSION=v0.17.1.0 +VERSION=v0.17.1.1 gpg --detach-sign ${VERSION}-linux/${GH_USER}/monero-linux-*-build.assert gpg --detach-sign ${VERSION}-win/${GH_USER}/monero-win-*-build.assert diff --git a/src/blockchain_utilities/blockchain_export.cpp b/src/blockchain_utilities/blockchain_export.cpp index e55930b00..87cd7945c 100644 --- a/src/blockchain_utilities/blockchain_export.cpp +++ b/src/blockchain_utilities/blockchain_export.cpp @@ -47,6 +47,7 @@ int main(int argc, char* argv[]) epee::string_tools::set_module_name_and_folder(argv[0]); uint32_t log_level = 0; + uint64_t block_start = 0; uint64_t block_stop = 0; bool blocks_dat = false; @@ -58,6 +59,7 @@ int main(int argc, char* argv[]) po::options_description desc_cmd_sett("Command line options and settings options"); const command_line::arg_descriptor<std::string> arg_output_file = {"output-file", "Specify output file", "", true}; const command_line::arg_descriptor<std::string> arg_log_level = {"log-level", "0-4 or categories", ""}; + const command_line::arg_descriptor<uint64_t> arg_block_start = {"block-start", "Start at block number", block_start}; const command_line::arg_descriptor<uint64_t> arg_block_stop = {"block-stop", "Stop at block number", block_stop}; const command_line::arg_descriptor<bool> arg_blocks_dat = {"blocksdat", "Output in blocks.dat format", blocks_dat}; @@ -67,6 +69,7 @@ int main(int argc, char* argv[]) command_line::add_arg(desc_cmd_sett, cryptonote::arg_testnet_on); command_line::add_arg(desc_cmd_sett, cryptonote::arg_stagenet_on); command_line::add_arg(desc_cmd_sett, arg_log_level); + command_line::add_arg(desc_cmd_sett, arg_block_start); command_line::add_arg(desc_cmd_sett, arg_block_stop); command_line::add_arg(desc_cmd_sett, arg_blocks_dat); @@ -97,6 +100,7 @@ int main(int argc, char* argv[]) mlog_set_log(command_line::get_arg(vm, arg_log_level).c_str()); else mlog_set_log(std::string(std::to_string(log_level) + ",bcutil:INFO").c_str()); + block_start = command_line::get_arg(vm, arg_block_start); block_stop = command_line::get_arg(vm, arg_block_stop); LOG_PRINT_L0("Starting..."); @@ -178,7 +182,7 @@ int main(int argc, char* argv[]) else { BootstrapFile bootstrap; - r = bootstrap.store_blockchain_raw(core_storage, NULL, output_file_path, block_stop); + r = bootstrap.store_blockchain_raw(core_storage, NULL, output_file_path, block_start, block_stop); } CHECK_AND_ASSERT_MES(r, 1, "Failed to export blockchain raw data"); LOG_PRINT_L0("Blockchain raw data exported OK"); diff --git a/src/blockchain_utilities/blockchain_import.cpp b/src/blockchain_utilities/blockchain_import.cpp index ab2313096..60c069c3b 100644 --- a/src/blockchain_utilities/blockchain_import.cpp +++ b/src/blockchain_utilities/blockchain_import.cpp @@ -227,6 +227,7 @@ int import_from_file(cryptonote::core& core, const std::string& import_file_path return false; } + uint64_t block_first, block_last; uint64_t start_height = 1, seek_height; if (opt_resume) start_height = core.get_blockchain_storage().get_current_blockchain_height(); @@ -235,10 +236,10 @@ int import_from_file(cryptonote::core& core, const std::string& import_file_path BootstrapFile bootstrap; std::streampos pos; // BootstrapFile bootstrap(import_file_path); - uint64_t total_source_blocks = bootstrap.count_blocks(import_file_path, pos, seek_height); - MINFO("bootstrap file last block number: " << total_source_blocks-1 << " (zero-based height) total blocks: " << total_source_blocks); + uint64_t total_source_blocks = bootstrap.count_blocks(import_file_path, pos, seek_height, block_first); + MINFO("bootstrap file last block number: " << total_source_blocks+block_first-1 << " (zero-based height) total blocks: " << total_source_blocks); - if (total_source_blocks-1 <= start_height) + if (total_source_blocks+block_first-1 <= start_height) { return false; } @@ -260,7 +261,8 @@ int import_from_file(cryptonote::core& core, const std::string& import_file_path // 4 byte magic + (currently) 1024 byte header structures uint8_t major_version, minor_version; - bootstrap.seek_to_first_chunk(import_file, major_version, minor_version); + uint64_t dummy; + bootstrap.seek_to_first_chunk(import_file, major_version, minor_version, dummy, dummy); std::string str1; char buffer1[1024]; @@ -275,7 +277,7 @@ int import_from_file(cryptonote::core& core, const std::string& import_file_path if (! block_stop) { - block_stop = total_source_blocks - 1; + block_stop = total_source_blocks+block_first - 1; } // These are what we'll try to use, and they don't have to be a determination diff --git a/src/blockchain_utilities/bootstrap_file.cpp b/src/blockchain_utilities/bootstrap_file.cpp index a4704626f..7050b9ab1 100644 --- a/src/blockchain_utilities/bootstrap_file.cpp +++ b/src/blockchain_utilities/bootstrap_file.cpp @@ -52,7 +52,7 @@ namespace -bool BootstrapFile::open_writer(const boost::filesystem::path& file_path) +bool BootstrapFile::open_writer(const boost::filesystem::path& file_path, uint64_t start_block, uint64_t stop_block) { const boost::filesystem::path dir_path = file_path.parent_path(); if (!dir_path.empty()) @@ -78,7 +78,7 @@ bool BootstrapFile::open_writer(const boost::filesystem::path& file_path) m_raw_data_file = new std::ofstream(); bool do_initialize_file = false; - uint64_t num_blocks = 0; + uint64_t num_blocks = 0, block_first = 0; if (! boost::filesystem::exists(file_path)) { @@ -88,10 +88,12 @@ bool BootstrapFile::open_writer(const boost::filesystem::path& file_path) } else { - num_blocks = count_blocks(file_path.string()); - MDEBUG("appending to existing file with height: " << num_blocks-1 << " total blocks: " << num_blocks); + std::streampos dummy_pos; + uint64_t dummy_height = 0; + num_blocks = count_blocks(file_path.string(), dummy_pos, dummy_height, block_first); + MDEBUG("appending to existing file with height: " << num_blocks+block_first-1 << " total blocks: " << num_blocks); } - m_height = num_blocks; + m_height = num_blocks+block_first; if (do_initialize_file) m_raw_data_file->open(file_path.string(), std::ios_base::binary | std::ios_base::out | std::ios::trunc); @@ -106,13 +108,12 @@ bool BootstrapFile::open_writer(const boost::filesystem::path& file_path) return false; if (do_initialize_file) - initialize_file(); + initialize_file(start_block, stop_block); return true; } - -bool BootstrapFile::initialize_file() +bool BootstrapFile::initialize_file(uint64_t first_block, uint64_t last_block) { const uint32_t file_magic = blockchain_raw_magic; @@ -129,8 +130,8 @@ bool BootstrapFile::initialize_file() bfi.header_size = header_size; bootstrap::blocks_info bbi; - bbi.block_first = 0; - bbi.block_last = 0; + bbi.block_first = first_block; + bbi.block_last = last_block; bbi.block_last_pos = 0; buffer_type buffer2; @@ -261,7 +262,7 @@ bool BootstrapFile::close() } -bool BootstrapFile::store_blockchain_raw(Blockchain* _blockchain_storage, tx_memory_pool* _tx_pool, boost::filesystem::path& output_file, uint64_t requested_block_stop) +bool BootstrapFile::store_blockchain_raw(Blockchain* _blockchain_storage, tx_memory_pool* _tx_pool, boost::filesystem::path& output_file, uint64_t start_block, uint64_t requested_block_stop) { uint64_t num_blocks_written = 0; m_max_chunk = 0; @@ -269,17 +270,11 @@ bool BootstrapFile::store_blockchain_raw(Blockchain* _blockchain_storage, tx_mem m_tx_pool = _tx_pool; uint64_t progress_interval = 100; MINFO("Storing blocks raw data..."); - if (!BootstrapFile::open_writer(output_file)) - { - MFATAL("failed to open raw file for write"); - return false; - } block b; // block_start, block_stop use 0-based height. m_height uses 1-based height. So to resume export // from last exported block, block_start doesn't need to add 1 here, as it's already at the next // height. - uint64_t block_start = m_height; uint64_t block_stop = 0; MINFO("source blockchain height: " << m_blockchain_storage->get_current_blockchain_height()-1); if ((requested_block_stop > 0) && (requested_block_stop < m_blockchain_storage->get_current_blockchain_height())) @@ -292,6 +287,13 @@ bool BootstrapFile::store_blockchain_raw(Blockchain* _blockchain_storage, tx_mem block_stop = m_blockchain_storage->get_current_blockchain_height() - 1; MINFO("Using block height of source blockchain: " << block_stop); } + if (!BootstrapFile::open_writer(output_file, start_block, block_stop)) + { + MFATAL("failed to open raw file for write"); + return false; + } + uint64_t block_start = m_height ? m_height : start_block; + MINFO("Starting block height: " << block_start); for (m_cur_height = block_start; m_cur_height <= block_stop; ++m_cur_height) { // this method's height refers to 0-based height (genesis block = height 0) @@ -323,7 +325,8 @@ bool BootstrapFile::store_blockchain_raw(Blockchain* _blockchain_storage, tx_mem return BootstrapFile::close(); } -uint64_t BootstrapFile::seek_to_first_chunk(std::ifstream& import_file, uint8_t &major_version, uint8_t &minor_version) +uint64_t BootstrapFile::seek_to_first_chunk(std::ifstream& import_file, uint8_t &major_version, uint8_t &minor_version, + uint64_t &block_first, uint64_t &block_last) { uint32_t file_magic; @@ -368,11 +371,35 @@ uint64_t BootstrapFile::seek_to_first_chunk(std::ifstream& import_file, uint8_t MINFO("bootstrap magic size: " << sizeof(file_magic)); MINFO("bootstrap header size: " << bfi.header_size); + uint32_t buflen_blocks_info; + + import_file.read(buf1, sizeof(buflen_blocks_info)); + str1.assign(buf1, sizeof(buflen_blocks_info)); + if (! import_file) + throw std::runtime_error("Error reading expected number of bytes"); + if (! ::serialization::parse_binary(str1, buflen_blocks_info)) + throw std::runtime_error("Error in deserialization of buflen_blocks_info"); + MINFO("bootstrap::blocks_info size: " << buflen_blocks_info); + + if (buflen_blocks_info > sizeof(buf1)) + throw std::runtime_error("Error: bootstrap::blocks_info size exceeds buffer size"); + import_file.read(buf1, buflen_blocks_info); + if (! import_file) + throw std::runtime_error("Error reading expected number of bytes"); + str1.assign(buf1, buflen_blocks_info); + bootstrap::blocks_info bbi; + if (! ::serialization::parse_binary(str1, bbi)) + throw std::runtime_error("Error in deserialization of bootstrap::blocks_info"); + MINFO("bootstrap first block:" << bbi.block_first); + MINFO("bootstrap last block:" << bbi.block_last); + uint64_t full_header_size = sizeof(file_magic) + bfi.header_size; import_file.seekg(full_header_size); major_version = bfi.major_version; minor_version = bfi.minor_version; + block_first = bbi.block_first; + block_last = bbi.block_last; return full_header_size; } @@ -436,13 +463,14 @@ uint64_t BootstrapFile::count_blocks(const std::string& import_file_path) { std::streampos dummy_pos; uint64_t dummy_height = 0; - return count_blocks(import_file_path, dummy_pos, dummy_height); + return count_blocks(import_file_path, dummy_pos, dummy_height, dummy_height); } // If seek_height is non-zero on entry, return a stream position <= this height when finished. // And return the actual height corresponding to this position. Allows the caller to locate its // starting position without having to reread the entire file again. -uint64_t BootstrapFile::count_blocks(const std::string& import_file_path, std::streampos &start_pos, uint64_t& seek_height) +uint64_t BootstrapFile::count_blocks(const std::string& import_file_path, std::streampos &start_pos, + uint64_t& seek_height, uint64_t &block_first) { boost::filesystem::path raw_file_path(import_file_path); boost::system::error_code ec; @@ -464,7 +492,8 @@ uint64_t BootstrapFile::count_blocks(const std::string& import_file_path, std::s uint64_t full_header_size; // 4 byte magic + length of header structures uint8_t major_version, minor_version; - full_header_size = seek_to_first_chunk(import_file, major_version, minor_version); + uint64_t block_last; + full_header_size = seek_to_first_chunk(import_file, major_version, minor_version, block_first, block_last); MINFO("Scanning blockchain from bootstrap file..."); bool quit = false; @@ -473,11 +502,11 @@ uint64_t BootstrapFile::count_blocks(const std::string& import_file_path, std::s while (! quit) { - if (start_height && h + progress_interval >= start_height - 1) + if (start_height && h + block_first + progress_interval >= start_height - 1) { start_height = 0; start_pos = import_file.tellg(); - seek_height = h; + seek_height = h + block_first; } bytes_read += count_bytes(import_file, progress_interval, blocks, quit); h += blocks; diff --git a/src/blockchain_utilities/bootstrap_file.h b/src/blockchain_utilities/bootstrap_file.h index 23dbb64d7..ff2875a61 100644 --- a/src/blockchain_utilities/bootstrap_file.h +++ b/src/blockchain_utilities/bootstrap_file.h @@ -57,12 +57,12 @@ class BootstrapFile public: uint64_t count_bytes(std::ifstream& import_file, uint64_t blocks, uint64_t& h, bool& quit); - uint64_t count_blocks(const std::string& dir_path, std::streampos& start_pos, uint64_t& seek_height); + uint64_t count_blocks(const std::string& dir_path, std::streampos& start_pos, uint64_t& seek_height, uint64_t& block_first); uint64_t count_blocks(const std::string& dir_path); - uint64_t seek_to_first_chunk(std::ifstream& import_file, uint8_t &major_version, uint8_t &minor_version); + uint64_t seek_to_first_chunk(std::ifstream& import_file, uint8_t &major_version, uint8_t &minor_version, uint64_t &block_first, uint64_t &block_last); bool store_blockchain_raw(cryptonote::Blockchain* cs, cryptonote::tx_memory_pool* txp, - boost::filesystem::path& output_file, uint64_t use_block_height=0); + boost::filesystem::path& output_file, uint64_t start_block=0, uint64_t stop_block=0); protected: @@ -75,8 +75,8 @@ protected: boost::iostreams::stream<boost::iostreams::back_insert_device<buffer_type>>* m_output_stream; // open export file for write - bool open_writer(const boost::filesystem::path& file_path); - bool initialize_file(); + bool open_writer(const boost::filesystem::path& file_path, uint64_t start_block, uint64_t stop_block); + bool initialize_file(uint64_t start_block, uint64_t stop_block); bool close(); void write_block(block& block); void flush_chunk(); diff --git a/src/blocks/checkpoints.dat b/src/blocks/checkpoints.dat Binary files differindex 1a39fda5d..5362e5f63 100644 --- a/src/blocks/checkpoints.dat +++ b/src/blocks/checkpoints.dat diff --git a/src/checkpoints/checkpoints.cpp b/src/checkpoints/checkpoints.cpp index 2d47ec922..b9accc952 100644 --- a/src/checkpoints/checkpoints.cpp +++ b/src/checkpoints/checkpoints.cpp @@ -239,6 +239,7 @@ namespace cryptonote ADD_CHECKPOINT2(2182500, "0d22b5f81982eff21d094af9e821dc2007e6342069e3b1a37b15d97646353124", "0xead4a874083492"); ADD_CHECKPOINT2(2193000, "6e91b917a40309f89f75f2c8d7be5a6d1a3c425634f07f7d1867bd32d2e602ed", "0xf085140f17389d"); ADD_CHECKPOINT2(2206500, "dd3c8590f33eaa546a4ce69d02f27fd58a2f115cd32d733bd9426f8278f0cb8a", "0xf8725275799f0d"); + ADD_CHECKPOINT2(2210500, "ed17259215ac6aabe6e8252b5b5eff613d2e69cc2111173e567109aa78301911", "0xfbcb50a9a6a433"); return true; } diff --git a/src/cryptonote_config.h b/src/cryptonote_config.h index a4db99f83..bc17b7e81 100644 --- a/src/cryptonote_config.h +++ b/src/cryptonote_config.h @@ -128,7 +128,7 @@ #define P2P_LOCAL_WHITE_PEERLIST_LIMIT 1000 #define P2P_LOCAL_GRAY_PEERLIST_LIMIT 5000 -#define P2P_DEFAULT_CONNECTIONS_COUNT 8 +#define P2P_DEFAULT_CONNECTIONS_COUNT 12 #define P2P_DEFAULT_HANDSHAKE_INTERVAL 60 //secondes #define P2P_DEFAULT_PACKET_MAX_SIZE 50000000 //50000000 bytes maximum packet size #define P2P_DEFAULT_PEERS_IN_HANDSHAKE 250 diff --git a/src/cryptonote_core/blockchain.cpp b/src/cryptonote_core/blockchain.cpp index 645123fae..b8b407dcf 100644 --- a/src/cryptonote_core/blockchain.cpp +++ b/src/cryptonote_core/blockchain.cpp @@ -3068,9 +3068,21 @@ bool Blockchain::check_tx_outputs(const transaction& tx, tx_verification_context if (tx.version >= 2) { if (tx.rct_signatures.type <= rct::RCTTypeBulletproof2) { - MERROR_VER("Ringct type " << (unsigned)tx.rct_signatures.type << " is not allowed from v" << (HF_VERSION_CLSAG + 1)); - tvc.m_invalid_output = true; - return false; + // two MLSAG txes went in due to a bug with txes that went into the txpool before the fork, grandfather them in + static const char * grandfathered[2] = { "c5151944f0583097ba0c88cd0f43e7fabb3881278aa2f73b3b0a007c5d34e910", "6f2f117cde6fbcf8d4a6ef8974fcac744726574ac38cf25d3322c996b21edd4c" }; + crypto::hash h0, h1; + epee::string_tools::hex_to_pod(grandfathered[0], h0); + epee::string_tools::hex_to_pod(grandfathered[1], h1); + if (cryptonote::get_transaction_hash(tx) == h0 || cryptonote::get_transaction_hash(tx) == h1) + { + MDEBUG("Grandfathering cryptonote::get_transaction_hash(tx) in"); + } + else + { + MERROR_VER("Ringct type " << (unsigned)tx.rct_signatures.type << " is not allowed from v" << (HF_VERSION_CLSAG + 1)); + tvc.m_invalid_output = true; + return false; + } } } } @@ -5364,7 +5376,7 @@ void Blockchain::cancel() } #if defined(PER_BLOCK_CHECKPOINT) -static const char expected_block_hashes_hash[] = "49db4105aadc7c296ffbf5d56de1785361684671544489f3c5e56cb40ef92a28"; +static const char expected_block_hashes_hash[] = "be42dfed51f6b9da134d7dcfd5f4b7e1df8cae93f1b41b846a5818f0aaf09fda"; void Blockchain::load_compiled_in_block_hashes(const GetCheckpointsCallback& get_checkpoints) { if (get_checkpoints == nullptr || !m_fast_sync) diff --git a/src/p2p/net_node.inl b/src/p2p/net_node.inl index c1d61eea2..f8cba41aa 100644 --- a/src/p2p/net_node.inl +++ b/src/p2p/net_node.inl @@ -1440,13 +1440,28 @@ namespace nodetool }); } + auto get_host_string = [](const epee::net_utils::network_address &address) { +#if BOOST_VERSION > 106600 + if (address.get_type_id() == epee::net_utils::ipv6_network_address::get_type_id()) + { + boost::asio::ip::address_v6 actual_ip = address.as<const epee::net_utils::ipv6_network_address>().ip(); + if (actual_ip.is_v4_mapped()) + { + boost::asio::ip::address_v4 v4ip = make_address_v4(boost::asio::ip::v4_mapped, actual_ip); + return epee::net_utils::ipv4_network_address(v4ip.to_uint(), 0).host_str(); + } + } +#endif + return address.host_str(); + }; + std::unordered_set<std::string> hosts_added; std::deque<size_t> filtered; const size_t limit = use_white_list ? 20 : std::numeric_limits<size_t>::max(); for (int step = 0; step < 2; ++step) { bool skip_duplicate_class_B = step == 0; size_t idx = 0, skipped = 0; - zone.m_peerlist.foreach (use_white_list, [&classB, &filtered, &idx, &skipped, skip_duplicate_class_B, limit, next_needed_pruning_stripe](const peerlist_entry &pe){ + zone.m_peerlist.foreach (use_white_list, [&classB, &filtered, &idx, &skipped, skip_duplicate_class_B, limit, next_needed_pruning_stripe, &hosts_added, &get_host_string](const peerlist_entry &pe){ if (filtered.size() >= limit) return false; bool skip = false; @@ -1456,6 +1471,15 @@ namespace nodetool uint32_t actual_ip = na.as<const epee::net_utils::ipv4_network_address>().ip(); skip = classB.find(actual_ip & 0x0000ffff) != classB.end(); } + + // consider each host once, to avoid giving undue inflence to hosts running several nodes + if (!skip) + { + const auto i = hosts_added.find(get_host_string(pe.adr)); + if (i != hosts_added.end()) + skip = true; + } + if (skip) ++skipped; else if (next_needed_pruning_stripe == 0 || pe.pruning_seed == 0) @@ -1463,6 +1487,7 @@ namespace nodetool else if (next_needed_pruning_stripe == tools::get_pruning_stripe(pe.pruning_seed)) filtered.push_front(idx); ++idx; + hosts_added.insert(get_host_string(pe.adr)); return true; }); if (skipped == 0 || !filtered.empty()) diff --git a/src/version.cpp.in b/src/version.cpp.in index 0c24fd45c..bd5caa039 100644 --- a/src/version.cpp.in +++ b/src/version.cpp.in @@ -1,5 +1,5 @@ #define DEF_MONERO_VERSION_TAG "@VERSIONTAG@" -#define DEF_MONERO_VERSION "0.17.1.0" +#define DEF_MONERO_VERSION "0.17.1.1" #define DEF_MONERO_RELEASE_NAME "Oxygen Orion" #define DEF_MONERO_VERSION_FULL DEF_MONERO_VERSION "-" DEF_MONERO_VERSION_TAG #define DEF_MONERO_VERSION_IS_RELEASE @VERSION_IS_RELEASE@ diff --git a/src/wallet/api/wallet.cpp b/src/wallet/api/wallet.cpp index 152a7dcd7..9acc8484c 100644 --- a/src/wallet/api/wallet.cpp +++ b/src/wallet/api/wallet.cpp @@ -910,6 +910,11 @@ std::string WalletImpl::path() const return m_wallet->path(); } +void WalletImpl::stop() +{ + m_wallet->stop(); +} + bool WalletImpl::store(const std::string &path) { clearStatus(); diff --git a/src/wallet/api/wallet.h b/src/wallet/api/wallet.h index caf1e9ed4..3bf3e759b 100644 --- a/src/wallet/api/wallet.h +++ b/src/wallet/api/wallet.h @@ -99,6 +99,7 @@ public: std::string publicSpendKey() const override; std::string publicMultisigSignerKey() const override; std::string path() const override; + void stop() override; bool store(const std::string &path) override; std::string filename() const override; std::string keysFilename() const override; diff --git a/src/wallet/api/wallet2_api.h b/src/wallet/api/wallet2_api.h index 50df7e5dd..999823ff1 100644 --- a/src/wallet/api/wallet2_api.h +++ b/src/wallet/api/wallet2_api.h @@ -507,6 +507,11 @@ struct Wallet virtual std::string publicMultisigSignerKey() const = 0; /*! + * \brief stop - interrupts wallet refresh() loop once (doesn't stop background refresh thread) + */ + virtual void stop() = 0; + + /*! * \brief store - stores wallet to file. * \param path - main filename to store wallet to. additionally stores address file and keys file. * to store to the same file - just pass empty string; diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index a3755ff08..7cbb4a910 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -2961,6 +2961,8 @@ void wallet2::update_pool_state(std::vector<std::tuple<cryptonote::transaction, MTRACE("update_pool_state got pool"); // remove any pending tx that's not in the pool + constexpr const std::chrono::seconds tx_propagation_timeout{CRYPTONOTE_DANDELIONPP_EMBARGO_AVERAGE * 3 / 2}; + const auto now = std::chrono::system_clock::now(); std::unordered_map<crypto::hash, wallet2::unconfirmed_transfer_details>::iterator it = m_unconfirmed_txs.begin(); while (it != m_unconfirmed_txs.end()) { @@ -2988,9 +2990,11 @@ void wallet2::update_pool_state(std::vector<std::tuple<cryptonote::transaction, LOG_PRINT_L1("Pending txid " << txid << " not in pool, marking as not in pool"); pit->second.m_state = wallet2::unconfirmed_transfer_details::pending_not_in_pool; } - else if (pit->second.m_state == wallet2::unconfirmed_transfer_details::pending_not_in_pool && refreshed) + else if (pit->second.m_state == wallet2::unconfirmed_transfer_details::pending_not_in_pool && refreshed && + now > std::chrono::system_clock::from_time_t(pit->second.m_sent_time) + tx_propagation_timeout) { - LOG_PRINT_L1("Pending txid " << txid << " not in pool, marking as failed"); + LOG_PRINT_L1("Pending txid " << txid << " not in pool after " << tx_propagation_timeout.count() << + " seconds, marking as failed"); pit->second.m_state = wallet2::unconfirmed_transfer_details::failed; // the inputs aren't spent anymore, since the tx failed |