diff options
Diffstat (limited to 'src/cryptonote_core')
-rw-r--r-- | src/cryptonote_core/blockchain.cpp | 26 | ||||
-rw-r--r-- | src/cryptonote_core/blockchain.h | 2 | ||||
-rw-r--r-- | src/cryptonote_core/cryptonote_core.cpp | 22 | ||||
-rw-r--r-- | src/cryptonote_core/cryptonote_core.h | 9 | ||||
-rw-r--r-- | src/cryptonote_core/cryptonote_tx_utils.cpp | 2 |
5 files changed, 53 insertions, 8 deletions
diff --git a/src/cryptonote_core/blockchain.cpp b/src/cryptonote_core/blockchain.cpp index e037a224e..794dee8aa 100644 --- a/src/cryptonote_core/blockchain.cpp +++ b/src/cryptonote_core/blockchain.cpp @@ -3098,6 +3098,8 @@ bool Blockchain::handle_block_to_main_chain(const block& bl, const crypto::hash& CRITICAL_REGION_LOCAL(m_blockchain_lock); TIME_MEASURE_START(t1); + static bool seen_future_version = false; + m_db->block_txn_start(true); if(bl.prev_id != get_tail_id()) { @@ -3107,6 +3109,18 @@ leave: return false; } + // warn users if they're running an old version + if (!seen_future_version && bl.major_version > m_hardfork->get_ideal_version()) + { + seen_future_version = true; + const el::Level level = el::Level::Warning; + MCLOG_RED(level, "global", "**********************************************************************"); + MCLOG_RED(level, "global", "A block was seen on the network with a version higher than the last"); + MCLOG_RED(level, "global", "known one. This may be an old version of the daemon, and a software"); + MCLOG_RED(level, "global", "update may be required to sync further. Try running: update check"); + MCLOG_RED(level, "global", "**********************************************************************"); + } + // this is a cheap test if (!m_hardfork->check(bl)) { @@ -3542,19 +3556,17 @@ void Blockchain::set_enforce_dns_checkpoints(bool enforce_checkpoints) } //------------------------------------------------------------------ -void Blockchain::block_longhash_worker(const uint64_t height, const std::vector<block> &blocks, std::unordered_map<crypto::hash, crypto::hash> &map) const +void Blockchain::block_longhash_worker(uint64_t height, const std::vector<block> &blocks, std::unordered_map<crypto::hash, crypto::hash> &map) const { TIME_MEASURE_START(t); slow_hash_allocate_state(); - //FIXME: height should be changing here, as get_block_longhash expects - // the height of the block passed to it for (const auto & block : blocks) { if (m_cancel) - return; + break; crypto::hash id = get_block_hash(block); - crypto::hash pow = get_block_longhash(block, height); + crypto::hash pow = get_block_longhash(block, height++); map.emplace(id, pow); } @@ -3746,9 +3758,11 @@ bool Blockchain::prepare_handle_incoming_blocks(const std::list<block_complete_e if (!blocks_exist) { m_blocks_longhash_table.clear(); + uint64_t thread_height = height; for (uint64_t i = 0; i < threads; i++) { - thread_list.push_back(new boost::thread(attrs, boost::bind(&Blockchain::block_longhash_worker, this, height + (i * batches), std::cref(blocks[i]), std::ref(maps[i])))); + thread_list.push_back(new boost::thread(attrs, boost::bind(&Blockchain::block_longhash_worker, this, thread_height, std::cref(blocks[i]), std::ref(maps[i])))); + thread_height += blocks[i].size(); } for (size_t j = 0; j < thread_list.size(); j++) diff --git a/src/cryptonote_core/blockchain.h b/src/cryptonote_core/blockchain.h index 4f2e4f0d3..564b53af3 100644 --- a/src/cryptonote_core/blockchain.h +++ b/src/cryptonote_core/blockchain.h @@ -846,7 +846,7 @@ namespace cryptonote * @param blocks the blocks to be hashed * @param map return-by-reference the hashes for each block */ - void block_longhash_worker(const uint64_t height, const std::vector<block> &blocks, + void block_longhash_worker(uint64_t height, const std::vector<block> &blocks, std::unordered_map<crypto::hash, crypto::hash> &map) const; /** diff --git a/src/cryptonote_core/cryptonote_core.cpp b/src/cryptonote_core/cryptonote_core.cpp index 4cfa52441..da8ec68dd 100644 --- a/src/cryptonote_core/cryptonote_core.cpp +++ b/src/cryptonote_core/cryptonote_core.cpp @@ -660,6 +660,12 @@ namespace cryptonote return false; } + if (!check_tx_inputs_ring_members_diff(tx)) + { + MERROR_VER("tx uses duplicate ring members"); + return false; + } + if (!check_tx_inputs_keyimages_domain(tx)) { MERROR_VER("tx uses key image not in the valid domain"); @@ -752,6 +758,22 @@ namespace cryptonote return true; } //----------------------------------------------------------------------------------------------- + bool core::check_tx_inputs_ring_members_diff(const transaction& tx) const + { + const uint8_t version = m_blockchain_storage.get_current_hard_fork_version(); + if (version >= 6) + { + for(const auto& in: tx.vin) + { + CHECKED_GET_SPECIFIC_VARIANT(in, const txin_to_key, tokey_in, false); + for (size_t n = 1; n < tokey_in.key_offsets.size(); ++n) + if (tokey_in.key_offsets[n] == 0) + return false; + } + } + return true; + } + //----------------------------------------------------------------------------------------------- bool core::check_tx_inputs_keyimages_domain(const transaction& tx) const { std::unordered_set<crypto::key_image> ki; diff --git a/src/cryptonote_core/cryptonote_core.h b/src/cryptonote_core/cryptonote_core.h index e5fbf7f91..4ced91e23 100644 --- a/src/cryptonote_core/cryptonote_core.h +++ b/src/cryptonote_core/cryptonote_core.h @@ -781,6 +781,15 @@ namespace cryptonote bool check_tx_inputs_keyimages_diff(const transaction& tx) const; /** + * @brief verify that each ring uses distinct members + * + * @param tx the transaction to check + * + * @return false if any ring uses duplicate members, true otherwise + */ + bool check_tx_inputs_ring_members_diff(const transaction& tx) const; + + /** * @brief verify that each input key image in a transaction is in * the valid domain * diff --git a/src/cryptonote_core/cryptonote_tx_utils.cpp b/src/cryptonote_core/cryptonote_tx_utils.cpp index 26d5fb767..abb4b31ec 100644 --- a/src/cryptonote_core/cryptonote_tx_utils.cpp +++ b/src/cryptonote_core/cryptonote_tx_utils.cpp @@ -265,7 +265,7 @@ namespace cryptonote // "Shuffle" outs std::vector<tx_destination_entry> shuffled_dsts(destinations); - std::sort(shuffled_dsts.begin(), shuffled_dsts.end(), [](const tx_destination_entry& de1, const tx_destination_entry& de2) { return de1.amount < de2.amount; } ); + std::random_shuffle(shuffled_dsts.begin(), shuffled_dsts.end(), [](int i) { return crypto::rand<int>() % i; }); uint64_t summary_outs_money = 0; //fill outputs |