diff options
Diffstat (limited to 'src/cryptonote_basic')
-rw-r--r-- | src/cryptonote_basic/connection_context.h | 2 | ||||
-rw-r--r-- | src/cryptonote_basic/cryptonote_basic.h | 74 | ||||
-rw-r--r-- | src/cryptonote_basic/cryptonote_format_utils.cpp | 55 | ||||
-rw-r--r-- | src/cryptonote_basic/cryptonote_format_utils.h | 2 | ||||
-rw-r--r-- | src/cryptonote_basic/miner.cpp | 13 | ||||
-rw-r--r-- | src/cryptonote_basic/miner.h | 7 |
6 files changed, 106 insertions, 47 deletions
diff --git a/src/cryptonote_basic/connection_context.h b/src/cryptonote_basic/connection_context.h index 51076e8c0..5e8f6685d 100644 --- a/src/cryptonote_basic/connection_context.h +++ b/src/cryptonote_basic/connection_context.h @@ -55,7 +55,7 @@ namespace cryptonote }; state m_state; - std::vector<crypto::hash> m_needed_objects; + std::vector<std::pair<crypto::hash, uint64_t>> m_needed_objects; std::unordered_set<crypto::hash> m_requested_objects; uint64_t m_remote_blockchain_height; uint64_t m_last_response_height; diff --git a/src/cryptonote_basic/cryptonote_basic.h b/src/cryptonote_basic/cryptonote_basic.h index 055c4a22b..e2286ae8c 100644 --- a/src/cryptonote_basic/cryptonote_basic.h +++ b/src/cryptonote_basic/cryptonote_basic.h @@ -195,6 +195,7 @@ namespace cryptonote private: // hash cash mutable std::atomic<bool> hash_valid; + mutable std::atomic<bool> prunable_hash_valid; mutable std::atomic<bool> blob_size_valid; public: @@ -203,6 +204,7 @@ namespace cryptonote // hash cash mutable crypto::hash hash; + mutable crypto::hash prunable_hash; mutable size_t blob_size; bool pruned; @@ -211,22 +213,26 @@ namespace cryptonote std::atomic<unsigned int> prefix_size; transaction(); - transaction(const transaction &t): transaction_prefix(t), hash_valid(false), blob_size_valid(false), signatures(t.signatures), rct_signatures(t.rct_signatures), pruned(t.pruned), unprunable_size(t.unprunable_size.load()), prefix_size(t.prefix_size.load()) { if (t.is_hash_valid()) { hash = t.hash; set_hash_valid(true); } if (t.is_blob_size_valid()) { blob_size = t.blob_size; set_blob_size_valid(true); } } - transaction &operator=(const transaction &t) { transaction_prefix::operator=(t); set_hash_valid(false); set_blob_size_valid(false); signatures = t.signatures; rct_signatures = t.rct_signatures; if (t.is_hash_valid()) { hash = t.hash; set_hash_valid(true); } if (t.is_blob_size_valid()) { blob_size = t.blob_size; set_blob_size_valid(true); } pruned = t.pruned; unprunable_size = t.unprunable_size.load(); prefix_size = t.prefix_size.load(); return *this; } + transaction(const transaction &t); + transaction &operator=(const transaction &t); virtual ~transaction(); void set_null(); void invalidate_hashes(); bool is_hash_valid() const { return hash_valid.load(std::memory_order_acquire); } void set_hash_valid(bool v) const { hash_valid.store(v,std::memory_order_release); } + bool is_prunable_hash_valid() const { return prunable_hash_valid.load(std::memory_order_acquire); } + void set_prunable_hash_valid(bool v) const { prunable_hash_valid.store(v,std::memory_order_release); } bool is_blob_size_valid() const { return blob_size_valid.load(std::memory_order_acquire); } void set_blob_size_valid(bool v) const { blob_size_valid.store(v,std::memory_order_release); } - void set_hash(const crypto::hash &h) { hash = h; set_hash_valid(true); } - void set_blob_size(size_t sz) { blob_size = sz; set_blob_size_valid(true); } + void set_hash(const crypto::hash &h) const { hash = h; set_hash_valid(true); } + void set_prunable_hash(const crypto::hash &h) const { prunable_hash = h; set_prunable_hash_valid(true); } + void set_blob_size(size_t sz) const { blob_size = sz; set_blob_size_valid(true); } BEGIN_SERIALIZE_OBJECT() if (!typename Archive<W>::is_saving()) { set_hash_valid(false); + set_prunable_hash_valid(false); set_blob_size_valid(false); } @@ -327,6 +333,63 @@ namespace cryptonote static size_t get_signature_size(const txin_v& tx_in); }; + inline transaction::transaction(const transaction &t): + transaction_prefix(t), + hash_valid(false), + prunable_hash_valid(false), + blob_size_valid(false), + signatures(t.signatures), + rct_signatures(t.rct_signatures), + pruned(t.pruned), + unprunable_size(t.unprunable_size.load()), + prefix_size(t.prefix_size.load()) + { + if (t.is_hash_valid()) + { + hash = t.hash; + set_hash_valid(true); + } + if (t.is_blob_size_valid()) + { + blob_size = t.blob_size; + set_blob_size_valid(true); + } + if (t.is_prunable_hash_valid()) + { + prunable_hash = t.prunable_hash; + set_prunable_hash_valid(true); + } + } + + inline transaction &transaction::operator=(const transaction &t) + { + transaction_prefix::operator=(t); + + set_hash_valid(false); + set_prunable_hash_valid(false); + set_blob_size_valid(false); + signatures = t.signatures; + rct_signatures = t.rct_signatures; + if (t.is_hash_valid()) + { + hash = t.hash; + set_hash_valid(true); + } + if (t.is_prunable_hash_valid()) + { + prunable_hash = t.prunable_hash; + set_prunable_hash_valid(true); + } + if (t.is_blob_size_valid()) + { + blob_size = t.blob_size; + set_blob_size_valid(true); + } + pruned = t.pruned; + unprunable_size = t.unprunable_size.load(); + prefix_size = t.prefix_size.load(); + return *this; + } inline transaction::transaction() @@ -346,6 +409,7 @@ namespace cryptonote signatures.clear(); rct_signatures.type = rct::RCTTypeNull; set_hash_valid(false); + set_prunable_hash_valid(false); set_blob_size_valid(false); pruned = false; unprunable_size = 0; @@ -356,6 +420,7 @@ namespace cryptonote void transaction::invalidate_hashes() { set_hash_valid(false); + set_prunable_hash_valid(false); set_blob_size_valid(false); } @@ -408,6 +473,7 @@ namespace cryptonote void invalidate_hashes() { set_hash_valid(false); } bool is_hash_valid() const { return hash_valid.load(std::memory_order_acquire); } void set_hash_valid(bool v) const { hash_valid.store(v,std::memory_order_release); } + void set_hash(const crypto::hash &h) const { hash = h; set_hash_valid(true); } transaction miner_tx; std::vector<crypto::hash> tx_hashes; diff --git a/src/cryptonote_basic/cryptonote_format_utils.cpp b/src/cryptonote_basic/cryptonote_format_utils.cpp index 7d7de416d..3501c66c8 100644 --- a/src/cryptonote_basic/cryptonote_format_utils.cpp +++ b/src/cryptonote_basic/cryptonote_format_utils.cpp @@ -1011,7 +1011,19 @@ namespace cryptonote crypto::hash get_transaction_prunable_hash(const transaction& t, const cryptonote::blobdata *blobdata) { crypto::hash res; + if (t.is_prunable_hash_valid()) + { +#ifdef ENABLE_HASH_CASH_INTEGRITY_CHECK + CHECK_AND_ASSERT_THROW_MES(!calculate_transaction_prunable_hash(t, blobdata, res) || t.hash == res, "tx hash cash integrity failure"); +#endif + res = t.prunable_hash; + ++tx_hashes_cached_count; + return res; + } + + ++tx_hashes_calculated_count; CHECK_AND_ASSERT_THROW_MES(calculate_transaction_prunable_hash(t, blobdata, res), "Failed to calculate tx prunable hash"); + t.set_prunable_hash(res); return res; } //--------------------------------------------------------------- @@ -1047,11 +1059,14 @@ namespace cryptonote // the tx hash is the hash of the 3 hashes crypto::hash res = cn_fast_hash(hashes, sizeof(hashes)); + t.set_hash(res); return res; } //--------------------------------------------------------------- bool calculate_transaction_hash(const transaction& t, crypto::hash& res, size_t* blob_size) { + CHECK_AND_ASSERT_MES(!t.pruned, false, "Cannot calculate the hash of a pruned transaction"); + // v1 transactions hash the entire blob if (t.version == 1) { @@ -1091,8 +1106,7 @@ namespace cryptonote { if (!t.is_blob_size_valid()) { - t.blob_size = blob.size(); - t.set_blob_size_valid(true); + t.set_blob_size(blob.size()); } *blob_size = t.blob_size; } @@ -1112,8 +1126,7 @@ namespace cryptonote { if (!t.is_blob_size_valid()) { - t.blob_size = get_object_blobsize(t); - t.set_blob_size_valid(true); + t.set_blob_size(get_object_blobsize(t)); } *blob_size = t.blob_size; } @@ -1124,12 +1137,10 @@ namespace cryptonote bool ret = calculate_transaction_hash(t, res, blob_size); if (!ret) return false; - t.hash = res; - t.set_hash_valid(true); + t.set_hash(res); if (blob_size) { - t.blob_size = *blob_size; - t.set_blob_size_valid(true); + t.set_blob_size(*blob_size); } return true; } @@ -1206,8 +1217,7 @@ namespace cryptonote bool ret = calculate_block_hash(b, res); if (!ret) return false; - b.hash = res; - b.set_hash_valid(true); + b.set_hash(res); return true; } //--------------------------------------------------------------- @@ -1218,21 +1228,6 @@ namespace cryptonote return p; } //--------------------------------------------------------------- - bool get_block_longhash(const block& b, crypto::hash& res, uint64_t height) - { - // block 202612 bug workaround - if (height == 202612) - { - static const std::string longhash_202612 = "84f64766475d51837ac9efbef1926486e58563c95a19fef4aec3254f03000000"; - string_tools::hex_to_pod(longhash_202612, res); - return true; - } - blobdata bd = get_block_hashing_blob(b); - const int cn_variant = b.major_version >= 7 ? b.major_version - 6 : 0; - crypto::cn_slow_hash(bd.data(), bd.size(), res, cn_variant, height); - return true; - } - //--------------------------------------------------------------- std::vector<uint64_t> relative_output_offsets_to_absolute(const std::vector<uint64_t>& off) { std::vector<uint64_t> res = off; @@ -1253,13 +1248,6 @@ namespace cryptonote return res; } //--------------------------------------------------------------- - crypto::hash get_block_longhash(const block& b, uint64_t height) - { - crypto::hash p = null_hash; - get_block_longhash(b, p, height); - return p; - } - //--------------------------------------------------------------- bool parse_and_validate_block_from_blob(const blobdata& b_blob, block& b, crypto::hash *block_hash) { std::stringstream ss; @@ -1273,8 +1261,7 @@ namespace cryptonote { calculate_block_hash(b, *block_hash, &b_blob); ++block_hashes_calculated_count; - b.hash = *block_hash; - b.set_hash_valid(true); + b.set_hash(*block_hash); } return true; } diff --git a/src/cryptonote_basic/cryptonote_format_utils.h b/src/cryptonote_basic/cryptonote_format_utils.h index c9de2a56e..284494299 100644 --- a/src/cryptonote_basic/cryptonote_format_utils.h +++ b/src/cryptonote_basic/cryptonote_format_utils.h @@ -117,8 +117,6 @@ namespace cryptonote bool calculate_block_hash(const block& b, crypto::hash& res, const blobdata *blob = NULL); bool get_block_hash(const block& b, crypto::hash& res); crypto::hash get_block_hash(const block& b); - bool get_block_longhash(const block& b, crypto::hash& res, uint64_t height); - crypto::hash get_block_longhash(const block& b, uint64_t height); bool parse_and_validate_block_from_blob(const blobdata& b_blob, block& b, crypto::hash *block_hash); bool parse_and_validate_block_from_blob(const blobdata& b_blob, block& b); bool parse_and_validate_block_from_blob(const blobdata& b_blob, block& b, crypto::hash &block_hash); diff --git a/src/cryptonote_basic/miner.cpp b/src/cryptonote_basic/miner.cpp index 856cccdeb..0188bf114 100644 --- a/src/cryptonote_basic/miner.cpp +++ b/src/cryptonote_basic/miner.cpp @@ -36,8 +36,10 @@ #include "syncobj.h" #include "cryptonote_basic_impl.h" #include "cryptonote_format_utils.h" +#include "cryptonote_core/cryptonote_tx_utils.h" #include "file_io_utils.h" #include "common/command_line.h" +#include "common/util.h" #include "string_coding.h" #include "string_tools.h" #include "storages/portable_storage_template_helper.h" @@ -98,12 +100,13 @@ namespace cryptonote } - miner::miner(i_miner_handler* phandler):m_stop(1), + miner::miner(i_miner_handler* phandler, Blockchain* pbc):m_stop(1), m_template{}, m_template_no(0), m_diffic(0), m_thread_index(0), m_phandler(phandler), + m_pbc(pbc), m_height(0), m_threads_active(0), m_pausers_count(0), @@ -429,6 +432,7 @@ namespace cryptonote { boost::interprocess::ipcdetail::atomic_write32(&m_stop, 1); } + extern "C" void rx_stop_mining(void); //----------------------------------------------------------------------------------------------------- bool miner::stop() { @@ -461,15 +465,16 @@ namespace cryptonote MINFO("Mining has been stopped, " << m_threads.size() << " finished" ); m_threads.clear(); m_threads_autodetect.clear(); + rx_stop_mining(); return true; } //----------------------------------------------------------------------------------------------------- - bool miner::find_nonce_for_given_block(block& bl, const difficulty_type& diffic, uint64_t height) + bool miner::find_nonce_for_given_block(const Blockchain *pbc, block& bl, const difficulty_type& diffic, uint64_t height) { for(; bl.nonce != std::numeric_limits<uint32_t>::max(); bl.nonce++) { crypto::hash h; - get_block_longhash(bl, h, height); + get_block_longhash(pbc, bl, h, height, tools::get_max_concurrency()); if(check_hash(h, diffic)) { @@ -565,7 +570,7 @@ namespace cryptonote b.nonce = nonce; crypto::hash h; - get_block_longhash(b, h, height); + get_block_longhash(m_pbc, b, h, height, tools::get_max_concurrency()); if(check_hash(h, local_diff)) { diff --git a/src/cryptonote_basic/miner.h b/src/cryptonote_basic/miner.h index ac7a0381c..4efbcbec3 100644 --- a/src/cryptonote_basic/miner.h +++ b/src/cryptonote_basic/miner.h @@ -52,13 +52,15 @@ namespace cryptonote ~i_miner_handler(){}; }; + class Blockchain; + /************************************************************************/ /* */ /************************************************************************/ class miner { public: - miner(i_miner_handler* phandler); + miner(i_miner_handler* phandler, Blockchain* pbc); ~miner(); bool init(const boost::program_options::variables_map& vm, network_type nettype); static void init_options(boost::program_options::options_description& desc); @@ -74,7 +76,7 @@ namespace cryptonote bool on_idle(); void on_synchronized(); //synchronous analog (for fast calls) - static bool find_nonce_for_given_block(block& bl, const difficulty_type& diffic, uint64_t height); + static bool find_nonce_for_given_block(const Blockchain *pbc, block& bl, const difficulty_type& diffic, uint64_t height); void pause(); void resume(); void do_print_hashrate(bool do_hr); @@ -133,6 +135,7 @@ namespace cryptonote std::list<boost::thread> m_threads; epee::critical_section m_threads_lock; i_miner_handler* m_phandler; + Blockchain* m_pbc; account_public_address m_mine_address; epee::math_helper::once_a_time_seconds<5> m_update_block_template_interval; epee::math_helper::once_a_time_seconds<2> m_update_merge_hr_interval; |