aboutsummaryrefslogtreecommitdiff
path: root/src/cryptonote_basic
diff options
context:
space:
mode:
Diffstat (limited to 'src/cryptonote_basic')
-rw-r--r--src/cryptonote_basic/cryptonote_basic.h2
-rw-r--r--src/cryptonote_basic/cryptonote_basic_impl.cpp5
-rw-r--r--src/cryptonote_basic/cryptonote_basic_impl.h1
-rw-r--r--src/cryptonote_basic/cryptonote_format_utils.cpp57
-rw-r--r--src/cryptonote_basic/cryptonote_format_utils.h14
-rw-r--r--src/cryptonote_basic/miner.cpp34
-rw-r--r--src/cryptonote_basic/miner.h4
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;