aboutsummaryrefslogtreecommitdiff
path: root/src/cryptonote_core
diff options
context:
space:
mode:
authorHoward Chu <hyc@symas.com>2019-04-23 20:32:27 +0100
committerHoward Chu <hyc@symas.com>2019-09-25 21:29:42 +0100
commit81c2ad6d5b17cf280a4a55fd6159e8dde423f5a8 (patch)
tree7bb731b721183e73afbb60e01cf3759723e4948b /src/cryptonote_core
parentMerge pull request #5909 (diff)
downloadmonero-81c2ad6d5b17cf280a4a55fd6159e8dde423f5a8.tar.xz
RandomX integration
Support RandomX PoW algorithm
Diffstat (limited to 'src/cryptonote_core')
-rw-r--r--src/cryptonote_core/blockchain.cpp44
-rw-r--r--src/cryptonote_core/blockchain.h17
-rw-r--r--src/cryptonote_core/cryptonote_core.cpp4
-rw-r--r--src/cryptonote_core/cryptonote_tx_utils.cpp53
-rw-r--r--src/cryptonote_core/cryptonote_tx_utils.h7
5 files changed, 119 insertions, 6 deletions
diff --git a/src/cryptonote_core/blockchain.cpp b/src/cryptonote_core/blockchain.cpp
index 5cf4952ae..bcf99bbed 100644
--- a/src/cryptonote_core/blockchain.cpp
+++ b/src/cryptonote_core/blockchain.cpp
@@ -95,7 +95,8 @@ Blockchain::Blockchain(tx_memory_pool& tx_pool) :
m_difficulty_for_next_block_top_hash(crypto::null_hash),
m_difficulty_for_next_block(1),
m_btc_valid(false),
- m_batch_success(true)
+ m_batch_success(true),
+ m_prepare_height(0)
{
LOG_PRINT_L3("Blockchain::" << __func__);
}
@@ -754,6 +755,13 @@ crypto::hash Blockchain::get_block_id_by_height(uint64_t height) const
return null_hash;
}
//------------------------------------------------------------------
+crypto::hash Blockchain::get_pending_block_id_by_height(uint64_t height) const
+{
+ if (m_prepare_height && height >= m_prepare_height && height - m_prepare_height < m_prepare_nblocks)
+ return (*m_prepare_blocks)[height - m_prepare_height].hash;
+ return get_block_id_by_height(height);
+}
+//------------------------------------------------------------------
bool Blockchain::get_block_by_hash(const crypto::hash &h, block &blk, bool *orphan) const
{
LOG_PRINT_L3("Blockchain::" << __func__);
@@ -1029,6 +1037,7 @@ bool Blockchain::switch_to_alternative_blockchain(std::list<block_extended_info>
}
m_hardfork->reorganize_from_chain_height(split_height);
+ get_block_longhash_reorg(split_height);
std::shared_ptr<tools::Notify> reorg_notify = m_reorg_notify;
if (reorg_notify)
@@ -1684,7 +1693,30 @@ bool Blockchain::handle_alternative_block(const block& b, const crypto::hash& id
difficulty_type current_diff = get_next_difficulty_for_alternative_chain(alt_chain, bei);
CHECK_AND_ASSERT_MES(current_diff, false, "!!!!!!! DIFFICULTY OVERHEAD !!!!!!!");
crypto::hash proof_of_work = null_hash;
- get_block_longhash(bei.bl, proof_of_work, bei.height);
+ if (b.major_version >= RX_BLOCK_VERSION)
+ {
+ crypto::hash seedhash = null_hash;
+ uint64_t seedheight = rx_seedheight(bei.height);
+ // seedblock is on the alt chain somewhere
+ if (alt_chain.size() && alt_chain.front().height <= seedheight)
+ {
+ for (auto it=alt_chain.begin(); it != alt_chain.end(); it++)
+ {
+ if (it->height == seedheight+1)
+ {
+ seedhash = it->bl.prev_id;
+ break;
+ }
+ }
+ } else
+ {
+ seedhash = get_block_id_by_height(seedheight);
+ }
+ get_altblock_longhash(bei.bl, proof_of_work, get_current_blockchain_height(), bei.height, seedheight, seedhash);
+ } else
+ {
+ get_block_longhash(this, bei.bl, proof_of_work, bei.height, 0);
+ }
if(!check_hash(proof_of_work, current_diff))
{
MERROR_VER("Block with id: " << id << std::endl << " for alternative chain, does not have enough proof of work: " << proof_of_work << std::endl << " expected difficulty: " << current_diff);
@@ -3613,7 +3645,7 @@ leave:
proof_of_work = it->second;
}
else
- proof_of_work = get_block_longhash(bl, blockchain_height);
+ proof_of_work = get_block_longhash(this, bl, blockchain_height, 0);
// validate proof_of_work versus difficulty target
if(!check_hash(proof_of_work, current_diffic))
@@ -4114,7 +4146,7 @@ void Blockchain::block_longhash_worker(uint64_t height, const epee::span<const b
if (m_cancel)
break;
crypto::hash id = get_block_hash(block);
- crypto::hash pow = get_block_longhash(block, height++);
+ crypto::hash pow = get_block_longhash(this, block, height++, 0);
map.emplace(id, pow);
}
@@ -4430,6 +4462,9 @@ bool Blockchain::prepare_handle_incoming_blocks(const std::vector<block_complete
m_blocks_longhash_table.clear();
uint64_t thread_height = height;
tools::threadpool::waiter waiter;
+ m_prepare_height = height;
+ m_prepare_nblocks = blocks_entry.size();
+ m_prepare_blocks = &blocks;
for (unsigned int i = 0; i < threads; i++)
{
unsigned nblocks = batches;
@@ -4440,6 +4475,7 @@ bool Blockchain::prepare_handle_incoming_blocks(const std::vector<block_complete
}
waiter.wait(&tpool);
+ m_prepare_height = 0;
if (m_cancel)
return false;
diff --git a/src/cryptonote_core/blockchain.h b/src/cryptonote_core/blockchain.h
index 178b2cb24..552a53e89 100644
--- a/src/cryptonote_core/blockchain.h
+++ b/src/cryptonote_core/blockchain.h
@@ -206,6 +206,18 @@ namespace cryptonote
crypto::hash get_block_id_by_height(uint64_t height) const;
/**
+ * @brief gets a block's hash given a height
+ *
+ * Used only by prepare_handle_incoming_blocks. Will look in the list of incoming blocks
+ * if the height is contained there.
+ *
+ * @param height the height of the block
+ *
+ * @return the hash of the block at the requested height, or a zeroed hash if there is no such block
+ */
+ crypto::hash get_pending_block_id_by_height(uint64_t height) const;
+
+ /**
* @brief gets the block with a given hash
*
* @param h the hash to look for
@@ -1077,6 +1089,11 @@ namespace cryptonote
std::shared_ptr<tools::Notify> m_block_notify;
std::shared_ptr<tools::Notify> m_reorg_notify;
+ // for prepare_handle_incoming_blocks
+ uint64_t m_prepare_height;
+ uint64_t m_prepare_nblocks;
+ std::vector<block> *m_prepare_blocks;
+
/**
* @brief collects the keys for all outputs being "spent" as an input
*
diff --git a/src/cryptonote_core/cryptonote_core.cpp b/src/cryptonote_core/cryptonote_core.cpp
index e34ab8fbd..245be5778 100644
--- a/src/cryptonote_core/cryptonote_core.cpp
+++ b/src/cryptonote_core/cryptonote_core.cpp
@@ -219,7 +219,7 @@ namespace cryptonote
core::core(i_cryptonote_protocol* pprotocol):
m_mempool(m_blockchain_storage),
m_blockchain_storage(m_mempool),
- m_miner(this),
+ m_miner(this, &m_blockchain_storage),
m_starter_message_showed(false),
m_target_blockchain_height(0),
m_checkpoints_path(""),
@@ -655,6 +655,8 @@ namespace cryptonote
CHECK_AND_ASSERT_MES(r, false, "Failed to initialize blockchain storage");
block_sync_size = command_line::get_arg(vm, arg_block_sync_size);
+ if (block_sync_size > BLOCKS_SYNCHRONIZING_MAX_COUNT)
+ MERROR("Error --block-sync-size cannot be greater than " << BLOCKS_SYNCHRONIZING_MAX_COUNT);
MGINFO("Loading checkpoints");
diff --git a/src/cryptonote_core/cryptonote_tx_utils.cpp b/src/cryptonote_core/cryptonote_tx_utils.cpp
index 955d6a4b0..d2e022347 100644
--- a/src/cryptonote_core/cryptonote_tx_utils.cpp
+++ b/src/cryptonote_core/cryptonote_tx_utils.cpp
@@ -37,6 +37,7 @@ using namespace epee;
#include "common/apply_permutation.h"
#include "cryptonote_tx_utils.h"
#include "cryptonote_config.h"
+#include "blockchain.h"
#include "cryptonote_basic/miner.h"
#include "cryptonote_basic/tx_extra.h"
#include "crypto/crypto.h"
@@ -658,9 +659,59 @@ namespace cryptonote
bl.minor_version = CURRENT_BLOCK_MINOR_VERSION;
bl.timestamp = 0;
bl.nonce = nonce;
- miner::find_nonce_for_given_block(bl, 1, 0);
+ miner::find_nonce_for_given_block(NULL, bl, 1, 0);
bl.invalidate_hashes();
return true;
}
//---------------------------------------------------------------
+ void get_altblock_longhash(const block& b, crypto::hash& res, const uint64_t main_height, const uint64_t height, const uint64_t seed_height, const crypto::hash& seed_hash)
+ {
+ blobdata bd = get_block_hashing_blob(b);
+ rx_slow_hash(main_height, seed_height, seed_hash.data, bd.data(), bd.size(), res.data, 0, 1);
+ }
+
+ bool get_block_longhash(const Blockchain *pbc, const block& b, crypto::hash& res, const uint64_t height, const int miners)
+ {
+ // block 202612 bug workaround
+ if (height == 202612)
+ {
+ static const std::string longhash_202612 = "84f64766475d51837ac9efbef1926486e58563c95a19fef4aec3254f03000000";
+ epee::string_tools::hex_to_pod(longhash_202612, res);
+ return true;
+ }
+ blobdata bd = get_block_hashing_blob(b);
+ if (b.major_version >= RX_BLOCK_VERSION)
+ {
+ uint64_t seed_height, main_height;
+ crypto::hash hash;
+ if (pbc != NULL)
+ {
+ seed_height = rx_seedheight(height);
+ hash = pbc->get_pending_block_id_by_height(seed_height);
+ main_height = pbc->get_current_blockchain_height();
+ } else
+ {
+ memset(&hash, 0, sizeof(hash)); // only happens when generating genesis block
+ seed_height = 0;
+ main_height = 0;
+ }
+ rx_slow_hash(main_height, seed_height, hash.data, bd.data(), bd.size(), res.data, miners, 0);
+ } else {
+ const int pow_variant = b.major_version >= 7 ? b.major_version - 6 : 0;
+ crypto::cn_slow_hash(bd.data(), bd.size(), res, pow_variant, height);
+ }
+ return true;
+ }
+
+ crypto::hash get_block_longhash(const Blockchain *pbc, const block& b, const uint64_t height, const int miners)
+ {
+ crypto::hash p = crypto::null_hash;
+ get_block_longhash(pbc, b, p, height, miners);
+ return p;
+ }
+
+ void get_block_longhash_reorg(const uint64_t split_height)
+ {
+ rx_reorg(split_height);
+ }
}
diff --git a/src/cryptonote_core/cryptonote_tx_utils.h b/src/cryptonote_core/cryptonote_tx_utils.h
index b03eb6e70..309e4177f 100644
--- a/src/cryptonote_core/cryptonote_tx_utils.h
+++ b/src/cryptonote_core/cryptonote_tx_utils.h
@@ -132,6 +132,13 @@ namespace cryptonote
, uint32_t nonce
);
+ class Blockchain;
+ bool get_block_longhash(const Blockchain *pb, const block& b, crypto::hash& res, const uint64_t height, const int miners);
+ void get_altblock_longhash(const block& b, crypto::hash& res, const uint64_t main_height, const uint64_t height,
+ const uint64_t seed_height, const crypto::hash& seed_hash);
+ crypto::hash get_block_longhash(const Blockchain *pb, const block& b, const uint64_t height, const int miners);
+ void get_block_longhash_reorg(const uint64_t split_height);
+
}
BOOST_CLASS_VERSION(cryptonote::tx_source_entry, 1)