aboutsummaryrefslogtreecommitdiff
path: root/src/cryptonote_basic
diff options
context:
space:
mode:
Diffstat (limited to 'src/cryptonote_basic')
-rw-r--r--src/cryptonote_basic/connection_context.h2
-rw-r--r--src/cryptonote_basic/cryptonote_basic.h74
-rw-r--r--src/cryptonote_basic/cryptonote_format_utils.cpp55
-rw-r--r--src/cryptonote_basic/cryptonote_format_utils.h2
-rw-r--r--src/cryptonote_basic/miner.cpp13
-rw-r--r--src/cryptonote_basic/miner.h7
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;