diff options
Diffstat (limited to 'src/cryptonote_basic')
-rw-r--r-- | src/cryptonote_basic/cryptonote_basic.h | 2 | ||||
-rw-r--r-- | src/cryptonote_basic/cryptonote_basic_impl.cpp | 5 | ||||
-rw-r--r-- | src/cryptonote_basic/cryptonote_basic_impl.h | 1 | ||||
-rw-r--r-- | src/cryptonote_basic/cryptonote_format_utils.cpp | 57 | ||||
-rw-r--r-- | src/cryptonote_basic/cryptonote_format_utils.h | 14 | ||||
-rw-r--r-- | src/cryptonote_basic/miner.cpp | 34 | ||||
-rw-r--r-- | src/cryptonote_basic/miner.h | 4 |
7 files changed, 88 insertions, 29 deletions
diff --git a/src/cryptonote_basic/cryptonote_basic.h b/src/cryptonote_basic/cryptonote_basic.h index 03caafbb0..20d92bdf1 100644 --- a/src/cryptonote_basic/cryptonote_basic.h +++ b/src/cryptonote_basic/cryptonote_basic.h @@ -422,6 +422,8 @@ namespace cryptonote FIELDS(*static_cast<block_header *>(this)) FIELD(miner_tx) FIELD(tx_hashes) + if (tx_hashes.size() > CRYPTONOTE_MAX_TX_PER_BLOCK) + return false; END_SERIALIZE() }; diff --git a/src/cryptonote_basic/cryptonote_basic_impl.cpp b/src/cryptonote_basic/cryptonote_basic_impl.cpp index e336cc1d1..d8de65b81 100644 --- a/src/cryptonote_basic/cryptonote_basic_impl.cpp +++ b/src/cryptonote_basic/cryptonote_basic_impl.cpp @@ -76,11 +76,6 @@ namespace cryptonote { return CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V5; } //----------------------------------------------------------------------------------------------- - size_t get_max_block_size() - { - return CRYPTONOTE_MAX_BLOCK_SIZE; - } - //----------------------------------------------------------------------------------------------- size_t get_max_tx_size() { return CRYPTONOTE_MAX_TX_SIZE; diff --git a/src/cryptonote_basic/cryptonote_basic_impl.h b/src/cryptonote_basic/cryptonote_basic_impl.h index 036273f0e..c7198a16f 100644 --- a/src/cryptonote_basic/cryptonote_basic_impl.h +++ b/src/cryptonote_basic/cryptonote_basic_impl.h @@ -87,7 +87,6 @@ namespace cryptonote { /* Cryptonote helper functions */ /************************************************************************/ size_t get_min_block_weight(uint8_t version); - size_t get_max_block_size(); size_t get_max_tx_size(); bool get_block_reward(size_t median_weight, size_t current_block_weight, uint64_t already_generated_coins, uint64_t &reward, uint8_t version); uint8_t get_account_address_checksum(const public_address_outer_blob& bl); diff --git a/src/cryptonote_basic/cryptonote_format_utils.cpp b/src/cryptonote_basic/cryptonote_format_utils.cpp index 094057b1f..566622c1a 100644 --- a/src/cryptonote_basic/cryptonote_format_utils.cpp +++ b/src/cryptonote_basic/cryptonote_format_utils.cpp @@ -1065,8 +1065,6 @@ namespace cryptonote // prefix get_transaction_prefix_hash(t, hashes[0]); - transaction &tt = const_cast<transaction&>(t); - const blobdata blob = tx_to_blob(t); const unsigned int unprunable_size = t.unprunable_size; const unsigned int prefix_size = t.prefix_size; @@ -1090,7 +1088,14 @@ namespace cryptonote // we still need the size if (blob_size) - *blob_size = get_object_blobsize(t); + { + if (!t.is_blob_size_valid()) + { + t.blob_size = blob.size(); + t.set_blob_size_valid(true); + } + *blob_size = t.blob_size; + } return true; } @@ -1143,21 +1148,37 @@ namespace cryptonote return blob; } //--------------------------------------------------------------- - bool calculate_block_hash(const block& b, crypto::hash& res) + bool calculate_block_hash(const block& b, crypto::hash& res, const blobdata *blob) { + blobdata bd; + if (!blob) + { + bd = block_to_blob(b); + blob = &bd; + } + + bool hash_result = get_object_hash(get_block_hashing_blob(b), res); + if (!hash_result) + return false; + + if (b.miner_tx.vin.size() == 1 && b.miner_tx.vin[0].type() == typeid(cryptonote::txin_gen)) + { + const cryptonote::txin_gen &txin_gen = boost::get<cryptonote::txin_gen>(b.miner_tx.vin[0]); + if (txin_gen.height != 202612) + return true; + } + // EXCEPTION FOR BLOCK 202612 const std::string correct_blob_hash_202612 = "3a8a2b3a29b50fc86ff73dd087ea43c6f0d6b8f936c849194d5c84c737903966"; const std::string existing_block_id_202612 = "bbd604d2ba11ba27935e006ed39c9bfdd99b76bf4a50654bc1e1e61217962698"; - crypto::hash block_blob_hash = get_blob_hash(block_to_blob(b)); + crypto::hash block_blob_hash = get_blob_hash(*blob); if (string_tools::pod_to_hex(block_blob_hash) == correct_blob_hash_202612) { string_tools::hex_to_pod(existing_block_id_202612, res); return true; } - bool hash_result = get_object_hash(get_block_hashing_blob(b), res); - if (hash_result) { // make sure that we aren't looking at a block with the 202612 block id but not the correct blobdata if (string_tools::pod_to_hex(res) == existing_block_id_202612) @@ -1200,9 +1221,9 @@ namespace cryptonote bool get_block_longhash(const block& b, crypto::hash& res, uint64_t height) { // block 202612 bug workaround - const std::string longhash_202612 = "84f64766475d51837ac9efbef1926486e58563c95a19fef4aec3254f03000000"; if (height == 202612) { + static const std::string longhash_202612 = "84f64766475d51837ac9efbef1926486e58563c95a19fef4aec3254f03000000"; string_tools::hex_to_pod(longhash_202612, res); return true; } @@ -1239,7 +1260,7 @@ namespace cryptonote return p; } //--------------------------------------------------------------- - 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) { std::stringstream ss; ss << b_blob; @@ -1248,9 +1269,26 @@ namespace cryptonote CHECK_AND_ASSERT_MES(r, false, "Failed to parse block from blob"); b.invalidate_hashes(); b.miner_tx.invalidate_hashes(); + if (block_hash) + { + calculate_block_hash(b, *block_hash, &b_blob); + ++block_hashes_calculated_count; + b.hash = *block_hash; + b.set_hash_valid(true); + } return true; } //--------------------------------------------------------------- + bool parse_and_validate_block_from_blob(const blobdata& b_blob, block& b) + { + return parse_and_validate_block_from_blob(b_blob, b, NULL); + } + //--------------------------------------------------------------- + bool parse_and_validate_block_from_blob(const blobdata& b_blob, block& b, crypto::hash &block_hash) + { + return parse_and_validate_block_from_blob(b_blob, b, &block_hash); + } + //--------------------------------------------------------------- blobdata block_to_blob(const block& b) { return t_serializable_object_to_blob(b); @@ -1286,6 +1324,7 @@ namespace cryptonote crypto::hash get_tx_tree_hash(const block& b) { std::vector<crypto::hash> txs_ids; + txs_ids.reserve(1 + b.tx_hashes.size()); crypto::hash h = null_hash; size_t bl_sz = 0; get_transaction_hash(b.miner_tx, h, bl_sz); diff --git a/src/cryptonote_basic/cryptonote_format_utils.h b/src/cryptonote_basic/cryptonote_format_utils.h index 40a9907be..c9de2a56e 100644 --- a/src/cryptonote_basic/cryptonote_format_utils.h +++ b/src/cryptonote_basic/cryptonote_format_utils.h @@ -114,12 +114,14 @@ namespace cryptonote crypto::hash get_pruned_transaction_hash(const transaction& t, const crypto::hash &pruned_data_hash); blobdata get_block_hashing_blob(const block& b); - bool calculate_block_hash(const block& b, crypto::hash& res); + 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); bool get_inputs_money_amount(const transaction& tx, uint64_t& money); uint64_t get_outs_money_amount(const transaction& tx); bool check_inputs_types_supported(const transaction& tx); @@ -140,6 +142,16 @@ namespace cryptonote std::string print_money(uint64_t amount, unsigned int decimal_point = -1); //--------------------------------------------------------------- template<class t_object> + bool t_serializable_object_from_blob(t_object& to, const blobdata& b_blob) + { + std::stringstream ss; + ss << b_blob; + binary_archive<false> ba(ss); + bool r = ::serialization::serialize(ba, to); + return r; + } + //--------------------------------------------------------------- + template<class t_object> bool t_serializable_object_to_blob(const t_object& to, blobdata& b_blob) { std::stringstream ss; diff --git a/src/cryptonote_basic/miner.cpp b/src/cryptonote_basic/miner.cpp index 4e2edc20f..e6c6bddb6 100644 --- a/src/cryptonote_basic/miner.cpp +++ b/src/cryptonote_basic/miner.cpp @@ -106,6 +106,7 @@ namespace cryptonote m_thread_index(0), m_phandler(phandler), m_height(0), + m_threads_active(0), m_pausers_count(0), m_threads_total(0), m_starter_nonce(0), @@ -264,8 +265,8 @@ namespace cryptonote { CRITICAL_REGION_LOCAL(m_threads_lock); boost::interprocess::ipcdetail::atomic_write32(&m_stop, 1); - for(boost::thread& th: m_threads) - th.join(); + while (m_threads_active > 0) + misc_utils::sleep_no_w(100); m_threads.clear(); } boost::interprocess::ipcdetail::atomic_write32(&m_stop, 0); @@ -447,15 +448,17 @@ namespace cryptonote // In case background mining was active and the miner threads are waiting // on the background miner to signal start. - m_is_background_mining_started_cond.notify_all(); - - for(boost::thread& th: m_threads) - th.join(); + while (m_threads_active > 0) + { + m_is_background_mining_started_cond.notify_all(); + misc_utils::sleep_no_w(100); + } // The background mining thread could be sleeping for a long time, so we // interrupt it just in case m_background_mining_thread.interrupt(); m_background_mining_thread.join(); + m_is_background_mining_enabled = false; MINFO("Mining has been stopped, " << m_threads.size() << " finished" ); m_threads.clear(); @@ -573,7 +576,8 @@ namespace cryptonote //we lucky! ++m_config.current_extra_message_index; MGINFO_GREEN("Found block " << get_block_hash(b) << " at height " << height << " for difficulty: " << local_diff); - if(!m_phandler->handle_block_found(b)) + cryptonote::block_verification_context bvc; + if(!m_phandler->handle_block_found(b, bvc) || !bvc.m_added_to_main_chain) { --m_config.current_extra_message_index; }else @@ -589,6 +593,7 @@ namespace cryptonote } slow_hash_free_state(); MGINFO("Miner thread stopped ["<< th_local_index << "]"); + --m_threads_active; return true; } //----------------------------------------------------------------------------------------------------- @@ -747,10 +752,10 @@ namespace cryptonote uint8_t idle_percentage = get_percent_of_total(idle_diff, total_diff); uint8_t process_percentage = get_percent_of_total(process_diff, total_diff); - MGINFO("idle percentage is " << unsigned(idle_percentage) << "\%, miner percentage is " << unsigned(process_percentage) << "\%, ac power : " << on_ac_power); + MDEBUG("idle percentage is " << unsigned(idle_percentage) << "\%, miner percentage is " << unsigned(process_percentage) << "\%, ac power : " << on_ac_power); if( idle_percentage + process_percentage < get_idle_threshold() || !on_ac_power ) { - MGINFO("cpu is " << unsigned(idle_percentage) << "% idle, idle threshold is " << unsigned(get_idle_threshold()) << "\%, ac power : " << on_ac_power << ", background mining stopping, thanks for your contribution!"); + MINFO("cpu is " << unsigned(idle_percentage) << "% idle, idle threshold is " << unsigned(get_idle_threshold()) << "\%, ac power : " << on_ac_power << ", background mining stopping, thanks for your contribution!"); m_is_background_mining_started = false; // reset process times @@ -788,10 +793,10 @@ namespace cryptonote uint64_t idle_diff = (current_idle_time - prev_idle_time); uint8_t idle_percentage = get_percent_of_total(idle_diff, total_diff); - MGINFO("idle percentage is " << unsigned(idle_percentage)); + MDEBUG("idle percentage is " << unsigned(idle_percentage)); if( idle_percentage >= get_idle_threshold() && on_ac_power ) { - MGINFO("cpu is " << unsigned(idle_percentage) << "% idle, idle threshold is " << unsigned(get_idle_threshold()) << "\%, ac power : " << on_ac_power << ", background mining started, good luck!"); + MINFO("cpu is " << unsigned(idle_percentage) << "% idle, idle threshold is " << unsigned(get_idle_threshold()) << "\%, ac power : " << on_ac_power << ", background mining started, good luck!"); m_is_background_mining_started = true; m_is_background_mining_started_cond.notify_all(); @@ -1049,7 +1054,12 @@ namespace cryptonote if (boost::logic::indeterminate(on_battery)) { - LOG_ERROR("couldn't query power status from " << power_supply_class_path); + static bool error_shown = false; + if (!error_shown) + { + LOG_ERROR("couldn't query power status from " << power_supply_class_path); + error_shown = true; + } } return on_battery; diff --git a/src/cryptonote_basic/miner.h b/src/cryptonote_basic/miner.h index 08b1bd7f1..285075f51 100644 --- a/src/cryptonote_basic/miner.h +++ b/src/cryptonote_basic/miner.h @@ -34,6 +34,7 @@ #include <boost/logic/tribool_fwd.hpp> #include <atomic> #include "cryptonote_basic.h" +#include "verification_context.h" #include "difficulty.h" #include "math_helper.h" #ifdef _WIN32 @@ -45,7 +46,7 @@ namespace cryptonote struct i_miner_handler { - virtual bool handle_block_found(block& b) = 0; + virtual bool handle_block_found(block& b, block_verification_context &bvc) = 0; virtual bool get_block_template(block& b, const account_public_address& adr, difficulty_type& diffic, uint64_t& height, uint64_t& expected_reward, const blobdata& ex_nonce) = 0; protected: ~i_miner_handler(){}; @@ -125,6 +126,7 @@ namespace cryptonote uint64_t m_height; volatile uint32_t m_thread_index; volatile uint32_t m_threads_total; + std::atomic<uint32_t> m_threads_active; std::atomic<int32_t> m_pausers_count; epee::critical_section m_miners_count_lock; |