aboutsummaryrefslogtreecommitdiff
path: root/src/cryptonote_core
diff options
context:
space:
mode:
Diffstat (limited to 'src/cryptonote_core')
-rw-r--r--src/cryptonote_core/blockchain.cpp29
-rw-r--r--src/cryptonote_core/blockchain.h2
-rw-r--r--src/cryptonote_core/cryptonote_core.cpp24
-rw-r--r--src/cryptonote_core/cryptonote_core.h9
-rw-r--r--src/cryptonote_core/cryptonote_tx_utils.cpp2
-rw-r--r--src/cryptonote_core/tx_pool.h1
6 files changed, 57 insertions, 10 deletions
diff --git a/src/cryptonote_core/blockchain.cpp b/src/cryptonote_core/blockchain.cpp
index 745608b9f..794dee8aa 100644
--- a/src/cryptonote_core/blockchain.cpp
+++ b/src/cryptonote_core/blockchain.cpp
@@ -279,7 +279,8 @@ uint64_t Blockchain::get_current_blockchain_height() const
bool Blockchain::init(BlockchainDB* db, const bool testnet, const cryptonote::test_options *test_options)
{
LOG_PRINT_L3("Blockchain::" << __func__);
- CRITICAL_REGION_LOCAL(m_blockchain_lock);
+ CRITICAL_REGION_LOCAL(m_tx_pool);
+ CRITICAL_REGION_LOCAL1(m_blockchain_lock);
bool fakechain = test_options != NULL;
@@ -3097,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())
{
@@ -3106,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))
{
@@ -3541,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);
}
@@ -3745,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..62e92ba30 100644
--- a/src/cryptonote_core/cryptonote_core.cpp
+++ b/src/cryptonote_core/cryptonote_core.cpp
@@ -414,6 +414,8 @@ namespace cryptonote
if (block_sync_size == 0)
block_sync_size = BLOCKS_SYNCHRONIZING_DEFAULT_COUNT;
+ MGINFO("Loading checkpoints");
+
// load json & DNS checkpoints, and verify them
// with respect to what blocks we already have
CHECK_AND_ASSERT_MES(update_checkpoints(), false, "One or more checkpoints loaded from json or dns conflicted with existing checkpoints.");
@@ -660,6 +662,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 +760,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
diff --git a/src/cryptonote_core/tx_pool.h b/src/cryptonote_core/tx_pool.h
index 1858ccdd8..47a41d070 100644
--- a/src/cryptonote_core/tx_pool.h
+++ b/src/cryptonote_core/tx_pool.h
@@ -493,7 +493,6 @@ private:
*/
std::unordered_set<crypto::hash> m_timed_out_transactions;
- std::string m_config_folder; //!< the folder to save state to
Blockchain& m_blockchain; //!< reference to the Blockchain object
};
}