Merge pull request #469 from jeffro256/fcmp++-stage-randomxv2

cryptonote_core: support RandomX V2 and commitments in v17
This commit is contained in:
Justin Berman
2026-09-22 18:05:03 -07:00
committed by GitHub
16 changed files with 192 additions and 50 deletions
+52
View File
@@ -0,0 +1,52 @@
# Block hashing
## Background
In Bitcoin, block IDs and Proof-of-Work (PoW) hashes are calculated the same way, which is why on-chain block IDs always start
with many 0s. However, in Monero, block IDs and PoW hashes are calculated using different hash functions and slightly different
inputs. This is because the hash functions used for PoW (CryptoNight and RandomX) are much slower to run than other
cryptographic hash functions, specifically Keccak256, which Monero uses for block IDs. By contrast, Bitcoin uses SHA-256 for
both block IDs and PoW. The reason that CryptoNight and RandomX were chosen for PoW in Monero is to protect against
application-specific integrated circuits (ASICs) from dominanting the network hashrate like in Bitcoin. In theory, this
would restore the principle of "1 CPU, 1 vote" outlined in the Satoshi whitepaper, and bring greater decentralization to the
Monero exosystem. This document aims to describe exactly how block IDs and PoW hashes are calculated in the Monero reference
codebase.
## CryptoNight epoch
To be reductive, the underlying design of Cryptonight is to 1) fill a 2MB buffer of memory using a memory-hard function, 2)
perform over a millon random reads on that buffer to permutate some state, and then 3) do a final hash on the state using
a random choice between four independent hash fuctions. There are 4 variants of CryptoNight: v0, v1, v2, and v4. This is the
data flow for how block hashing in the CryptoNight epoch (Monero fork versions v1-v11) is performed:
![CryptoNight data flow](resources/cryptonight-data-flow.png)
## RandomX epoch
Like, CryptoNight, RandomX also uses a memory hard function to fill a large space of memory called a "cache". However, this
space is 256MB, not 2MB. It can be further expanded to 2GB to trade memory usage for compute speed. Unlike CryptoNight's cache,
the RandomX cache is computed only once every 2048 blocks, not once per block. Monero uses a "seed" block ID of a previous block
in the chain to fill the memory space. And to make ASICs even harder, RandomX uses random instruction execution as well. This
is the data flow for how block hashing in the RandomX epoch (Monero fork versions v12-present) is performed:
![RandomX data flow](resources/randomx-data-flow.png)
## RandomX, with commitments, epoch
Because RandomX can be slow to run, especially while building the cache (nearly 1/2 a second on my machine), it inadvertantly
can introduce a Denial-of-Service (DoS) vector. For this reason, RandomX hash commitments can be added, so the PoW can be
partially verified using only Blake2B, a much lighter hash function. For simplicity's sake, we can also remove the number of
transactions in the block from the block hashing blob. This is the data flow for how block hashing works with these changes:
![RandomX commitment data flow](resources/randomx-commitment-data-flow.png)
The way that the hashes are calculated allows us to do partial PoW verification like so:
![Partial RandomX verification data flow](resources/partial-pow-verify-data-flow.png)
A node can be given simply the block header, block content hash, and intermediate PoW hash, and verify that some PoW was done
using only `randomx_calculate_commitment()` (Blake2B underneath). Passing this partial verification requires PoW to be done using
Blake2B up to the relevant difficulty. While doing so is much easier than doing the full RandomX PoW, it still requires
significant work. It is very important that we can calculate the block ID from the same information (or a subset thereof)
that we calculate PoW from, since each block header contains the previous block ID. Binding the block headers as such makes
faking intermediate PoW on chains of blocks exponentially harder the longer the chain is.
Binary file not shown.

After

Width:  |  Height:  |  Size: 87 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 102 KiB

+6 -1
View File
@@ -97,13 +97,18 @@ bool tree_branch(const char (*hashes)[HASH_SIZE], size_t count, const char *hash
bool tree_branch_hash(const char hash[HASH_SIZE], const char (*branch)[HASH_SIZE], size_t depth, uint32_t path, char root[HASH_SIZE]);
bool is_branch_in_tree(const char hash[HASH_SIZE], const char root[HASH_SIZE], const char (*branch)[HASH_SIZE], size_t depth, uint32_t path);
#define RX_BLOCK_VERSION 12
#define RX_VARIANT_1 1
#define RX_VARIANT_2 2
#define RX_VARIANT_LATEST 0
void rx_slow_hash_allocate_state(void);
void rx_slow_hash_free_state(void);
uint64_t rx_seedheight(const uint64_t height);
void rx_seedheights(const uint64_t height, uint64_t *seed_height, uint64_t *next_height);
void rx_set_main_seedhash(const char *seedhash, size_t max_dataset_init_threads);
void rx_slow_hash(const char *seedhash, const void *data, size_t length, char *result_hash);
void rx_slow_hash(const char *seedhash, const int variant, const void *data, size_t length, char *result_hash);
void rx_commitment(const void *data, size_t length, const void *rx_hash, char *result_commitment);
void rx_set_miner_thread(uint32_t value, size_t max_dataset_init_threads);
uint32_t rx_get_miner_thread(void);
+83 -32
View File
@@ -66,8 +66,11 @@ static int secondary_seedhash_set = 0;
#define THREADV _Thread_local
#endif
static THREADV int main_vm_full_variant = 0;
static THREADV randomx_vm *main_vm_full = NULL;
static THREADV int main_vm_light_variant = 0;
static THREADV randomx_vm *main_vm_light = NULL;
static THREADV int secondary_vm_light_variant = 0;
static THREADV randomx_vm *secondary_vm_light = NULL;
static THREADV uint32_t miner_thread = 0;
@@ -86,7 +89,7 @@ static void local_abort(const char *msg)
#endif
}
static void hash2hex(const char* hash, char* hex) {
static void hash2hex(const char hash[HASH_SIZE], char hex[HASH_SIZE * 2 + 1]) {
const char* d = "0123456789abcdef";
for (int i = 0; i < HASH_SIZE; ++i) {
const uint8_t b = hash[i];
@@ -116,6 +119,13 @@ static inline int disabled_flags(void) {
else {
flags = 0;
}
if (flags & RANDOMX_FLAG_V2)
{
mwarning(RX_LOGCAT,
"MONERO_RANDOMX_UMASK would mask RandomX V2, ignoring that bit...");
flags &= ~RANDOMX_FLAG_V2;
}
}
return flags;
@@ -133,6 +143,28 @@ static inline int enabled_flags(void) {
return flags;
}
static randomx_flags get_variant_flags(const int variant) {
switch (variant)
{
case RX_VARIANT_1:
break;
case RX_VARIANT_LATEST:
case RX_VARIANT_2:
return RANDOMX_FLAG_V2;
default:
local_abort("Unrecognized RandomX variant");
}
return RANDOMX_FLAG_DEFAULT;
}
static void rx_destroy_vm(randomx_vm** vm) {
if (*vm) {
randomx_destroy_vm(*vm);
*vm = NULL;
}
}
#define SEEDHASH_EPOCH_BLOCKS 2048 /* Must be same as BLOCKS_SYNCHRONIZING_MAX_COUNT in cryptonote_config.h */
#define SEEDHASH_EPOCH_LAG 64
@@ -189,7 +221,7 @@ void rx_seedheights(const uint64_t height, uint64_t *seedheight, uint64_t *nexth
*nextheight = rx_seedheight(height + get_seedhash_epoch_lag());
}
static void rx_alloc_dataset(randomx_flags flags, randomx_dataset** dataset, int ignore_env)
static void rx_alloc_dataset(randomx_dataset** dataset, int ignore_env)
{
if (*dataset) {
return;
@@ -213,6 +245,8 @@ static void rx_alloc_dataset(randomx_flags flags, randomx_dataset** dataset, int
return;
}
const randomx_flags flags = enabled_flags();
*dataset = randomx_alloc_dataset((flags | RANDOMX_FLAG_LARGE_PAGES) & ~disabled_flags());
if (!*dataset) {
alloc_err_msg("Couldn't allocate RandomX dataset using large pages");
@@ -223,12 +257,14 @@ static void rx_alloc_dataset(randomx_flags flags, randomx_dataset** dataset, int
}
}
static void rx_alloc_cache(randomx_flags flags, randomx_cache** cache)
static void rx_alloc_cache(randomx_cache** cache)
{
if (*cache) {
return;
}
const randomx_flags flags = enabled_flags();
*cache = randomx_alloc_cache((flags | RANDOMX_FLAG_LARGE_PAGES) & ~disabled_flags());
if (!*cache) {
alloc_err_msg("Couldn't allocate RandomX cache using large pages");
@@ -237,51 +273,72 @@ static void rx_alloc_cache(randomx_flags flags, randomx_cache** cache)
}
}
static void rx_init_full_vm(randomx_flags flags, randomx_vm** vm)
static void rx_init_full_vm(const int variant, randomx_vm** vm, int* vm_variant)
{
if (*vm || !main_dataset || (disabled_flags() & RANDOMX_FLAG_FULL_MEM)) {
if (!main_dataset || (disabled_flags() & RANDOMX_FLAG_FULL_MEM)) {
return;
}
else if (*vm && variant == *vm_variant) {
return;
}
else if (*vm)
{
// VM is already constructed, but has wrong variant
rx_destroy_vm(vm);
}
randomx_flags flags = enabled_flags();
if ((flags & RANDOMX_FLAG_JIT) && !miner_thread) {
flags |= RANDOMX_FLAG_SECURE;
}
flags |= RANDOMX_FLAG_LARGE_PAGES | RANDOMX_FLAG_FULL_MEM;
flags &= ~disabled_flags();
flags |= get_variant_flags(variant);
*vm = randomx_create_vm((flags | RANDOMX_FLAG_LARGE_PAGES | RANDOMX_FLAG_FULL_MEM) & ~disabled_flags(), NULL, main_dataset);
*vm = randomx_create_vm(flags, NULL, main_dataset);
*vm_variant = variant;
if (!*vm) {
static int shown = 0;
if (!shown) {
shown = 1;
alloc_err_msg("Couldn't allocate RandomX full VM using large pages (will print only once)");
}
*vm = randomx_create_vm((flags | RANDOMX_FLAG_FULL_MEM) & ~disabled_flags(), NULL, main_dataset);
*vm = randomx_create_vm(flags & ~RANDOMX_FLAG_LARGE_PAGES, NULL, main_dataset);
if (!*vm) {
merror(RX_LOGCAT, "Couldn't allocate RandomX full VM");
}
}
}
static void rx_init_light_vm(randomx_flags flags, randomx_vm** vm, randomx_cache* cache)
static void rx_init_light_vm(const int variant, randomx_vm** vm, int* vm_variant, randomx_cache* cache)
{
if (*vm) {
if (*vm && variant == *vm_variant) {
randomx_vm_set_cache(*vm, cache);
return;
}
else if (*vm)
{
// VM is already constructed, but has wrong variant
rx_destroy_vm(vm);
}
randomx_flags flags = enabled_flags();
if ((flags & RANDOMX_FLAG_JIT) && !miner_thread) {
flags |= RANDOMX_FLAG_SECURE;
}
flags |= RANDOMX_FLAG_LARGE_PAGES;
flags &= ~(disabled_flags() | RANDOMX_FLAG_FULL_MEM);
flags |= get_variant_flags(variant);
flags &= ~RANDOMX_FLAG_FULL_MEM;
*vm = randomx_create_vm((flags | RANDOMX_FLAG_LARGE_PAGES) & ~disabled_flags(), cache, NULL);
*vm = randomx_create_vm(flags, cache, NULL);
*vm_variant = variant;
if (!*vm) {
static int shown = 0;
if (!shown) {
shown = 1;
alloc_err_msg("Couldn't allocate RandomX light VM using large pages (will print only once)");
}
*vm = randomx_create_vm(flags & ~disabled_flags(), cache, NULL);
*vm = randomx_create_vm(flags & ~RANDOMX_FLAG_LARGE_PAGES, cache, NULL);
if (!*vm) local_abort("Couldn't allocate RandomX light VM");
}
}
@@ -367,9 +424,8 @@ static CTHR_THREAD_RTYPE rx_set_main_seedhash_thread(void *arg) {
hash2hex(main_seedhash, buf);
minfo(RX_LOGCAT, "RandomX new main seed hash is %s", buf);
const randomx_flags flags = enabled_flags() & ~disabled_flags();
rx_alloc_dataset(flags, &main_dataset, 0);
rx_alloc_cache(flags, &main_cache);
rx_alloc_dataset(&main_dataset, 0);
rx_alloc_cache(&main_cache);
randomx_init_cache(main_cache, info->seedhash, HASH_SIZE);
minfo(RX_LOGCAT, "RandomX main cache initialized");
@@ -405,8 +461,7 @@ void rx_set_main_seedhash(const char *seedhash, size_t max_dataset_init_threads)
CTHR_THREAD_CLOSE(t);
}
void rx_slow_hash(const char *seedhash, const void *data, size_t length, char *result_hash) {
const randomx_flags flags = enabled_flags() & ~disabled_flags();
void rx_slow_hash(const char *seedhash, const int variant, const void *data, size_t length, char *result_hash) {
int success = 0;
// Fast path (seedhash == main_seedhash)
@@ -416,7 +471,7 @@ void rx_slow_hash(const char *seedhash, const void *data, size_t length, char *r
if (main_dataset && CTHR_RWLOCK_TRYLOCK_READ(main_dataset_lock)) {
// Double check that main_seedhash didn't change
if (is_main(seedhash)) {
rx_init_full_vm(flags, &main_vm_full);
rx_init_full_vm(variant, &main_vm_full, &main_vm_full_variant);
if (main_vm_full) {
randomx_calculate_hash(main_vm_full, data, length, result_hash);
success = 1;
@@ -427,7 +482,7 @@ void rx_slow_hash(const char *seedhash, const void *data, size_t length, char *r
CTHR_RWLOCK_LOCK_READ(main_cache_lock);
// Double check that main_seedhash didn't change
if (is_main(seedhash)) {
rx_init_light_vm(flags, &main_vm_light, main_cache);
rx_init_light_vm(variant, &main_vm_light, &main_vm_light_variant, main_cache);
randomx_calculate_hash(main_vm_light, data, length, result_hash);
success = 1;
}
@@ -449,7 +504,7 @@ void rx_slow_hash(const char *seedhash, const void *data, size_t length, char *r
hash2hex(seedhash, buf);
minfo(RX_LOGCAT, "RandomX new secondary seed hash is %s", buf);
rx_alloc_cache(flags, &secondary_cache);
rx_alloc_cache(&secondary_cache);
randomx_init_cache(secondary_cache, seedhash, HASH_SIZE);
minfo(RX_LOGCAT, "RandomX secondary cache updated");
memcpy(secondary_seedhash, seedhash, HASH_SIZE);
@@ -460,7 +515,7 @@ void rx_slow_hash(const char *seedhash, const void *data, size_t length, char *r
CTHR_RWLOCK_LOCK_READ(secondary_cache_lock);
if (is_secondary(seedhash)) {
rx_init_light_vm(flags, &secondary_vm_light, secondary_cache);
rx_init_light_vm(variant, &secondary_vm_light, &secondary_vm_light_variant, secondary_cache);
randomx_calculate_hash(secondary_vm_light, data, length, result_hash);
success = 1;
}
@@ -482,11 +537,15 @@ void rx_slow_hash(const char *seedhash, const void *data, size_t length, char *r
memcpy(secondary_seedhash, seedhash, HASH_SIZE);
secondary_seedhash_set = 1;
}
rx_init_light_vm(flags, &secondary_vm_light, secondary_cache);
rx_init_light_vm(variant, &secondary_vm_light, &secondary_vm_light_variant, secondary_cache);
randomx_calculate_hash(secondary_vm_light, data, length, result_hash);
CTHR_RWLOCK_UNLOCK_WRITE(secondary_cache_lock);
}
void rx_commitment(const void *data, size_t length, const void *rx_hash, char *result_commitment) {
randomx_calculate_commitment(data, length, rx_hash, result_commitment);
}
void rx_set_miner_thread(uint32_t value, size_t max_dataset_init_threads) {
miner_thread = value;
@@ -497,8 +556,7 @@ void rx_set_miner_thread(uint32_t value, size_t max_dataset_init_threads) {
return;
}
const randomx_flags flags = enabled_flags() & ~disabled_flags();
rx_alloc_dataset(flags, &main_dataset, 1);
rx_alloc_dataset(&main_dataset, 1);
rx_init_dataset(max_dataset_init_threads);
CTHR_RWLOCK_UNLOCK_WRITE(main_dataset_lock);
@@ -510,13 +568,6 @@ uint32_t rx_get_miner_thread(void) {
void rx_slow_hash_allocate_state(void) {}
static void rx_destroy_vm(randomx_vm** vm) {
if (*vm) {
randomx_destroy_vm(*vm);
*vm = NULL;
}
}
void rx_slow_hash_free_state(void) {
rx_destroy_vm(&main_vm_full);
rx_destroy_vm(&main_vm_light);
@@ -2019,10 +2019,16 @@ namespace cryptonote
return false;
}
//---------------------------------------------------------------
int get_randomx_variant_for_hf_version(const std::uint8_t hf_version)
{
return (hf_version >= HF_VERSION_RANDOMX_V2) ? RX_VARIANT_2 : RX_VARIANT_1;
}
//---------------------------------------------------------------
crypto::hash get_block_longhash(const blobdata_ref block_hashing_blob,
const uint64_t height,
const uint8_t major_version,
const crypto::hash &seed_hash)
const crypto::hash &seed_hash,
crypto::hash &intermediate_hash_out)
{
crypto::hash res;
@@ -2031,7 +2037,12 @@ namespace cryptonote
if (major_version >= RX_BLOCK_VERSION) // RandomX
{
crypto::rx_slow_hash(seed_hash.data, block_hashing_blob.data(), block_hashing_blob.size(), res.data);
const int rx_variant = get_randomx_variant_for_hf_version(major_version);
crypto::rx_slow_hash(seed_hash.data, rx_variant,
block_hashing_blob.data(), block_hashing_blob.size(), res.data);
intermediate_hash_out = res;
if (major_version >= HF_VERSION_POW_COMMITMENT)
crypto::rx_commitment(block_hashing_blob.data(), block_hashing_blob.size(), res.data, res.data);
}
else // CryptoNight
{
@@ -2044,6 +2055,15 @@ namespace cryptonote
return res;
}
//---------------------------------------------------------------
crypto::hash get_block_longhash(const blobdata_ref block_hashing_blob,
const uint64_t height,
const uint8_t major_version,
const crypto::hash &seed_hash)
{
crypto::hash intermediate_hash;
return get_block_longhash(block_hashing_blob, height, major_version, seed_hash, intermediate_hash);
}
//---------------------------------------------------------------
bool is_valid_decomposed_amount(uint64_t amount)
{
if (0 == amount)
@@ -303,6 +303,12 @@ namespace cryptonote
void get_tx_tree_hash(const std::vector<crypto::hash>& tx_hashes, crypto::hash& h);
crypto::hash get_tx_tree_hash(const std::vector<crypto::hash>& tx_hashes);
crypto::hash get_tx_tree_hash(const block& b);
int get_randomx_variant_for_hf_version(const std::uint8_t hf_version);
crypto::hash get_block_longhash(const blobdata_ref block_hashing_blob,
const uint64_t height,
const uint8_t major_version,
const crypto::hash &seed_hash,
crypto::hash &intermediate_hash_out);
crypto::hash get_block_longhash(const blobdata_ref block_hashing_blob,
const uint64_t height,
const uint8_t major_version,
+2
View File
@@ -208,6 +208,8 @@
#define HF_VERSION_REJECT_UNMIXABLE_V1 17
#define HF_VERSION_REJECT_MANY_MINER_OUTPUTS 17
#define HF_VERSION_2026_SCALING 17
#define HF_VERSION_POW_COMMITMENT 17
#define HF_VERSION_RANDOMX_V2 17
#define MAX_HF_VERSION 18
#define PER_KB_FEE_QUANTIZATION_DECIMALS 8
+1 -1
View File
@@ -220,7 +220,7 @@ namespace cryptonote
m_mempool(m_bap.tx_pool),
m_blockchain_storage(m_bap.blockchain),
m_miner(this, [this](const cryptonote::block &b, uint64_t height, const crypto::hash *seed_hash, unsigned int threads, crypto::hash &hash) {
return cryptonote::get_block_longhash(&m_blockchain_storage, b, hash, height, seed_hash, threads);
return cryptonote::get_block_longhash(&m_blockchain_storage, b, hash, height, seed_hash);
}),
m_starter_message_showed(false),
m_target_blockchain_height(0),
+14 -8
View File
@@ -737,7 +737,7 @@ namespace cryptonote
bl.timestamp = 0;
bl.nonce = nonce;
miner::find_nonce_for_given_block([](const cryptonote::block &b, uint64_t height, const crypto::hash *seed_hash, unsigned int threads, crypto::hash &hash){
return cryptonote::get_block_longhash(NULL, b, hash, height, seed_hash, threads);
return cryptonote::get_block_longhash(NULL, b, hash, height, seed_hash);
}, bl, 1, 0, NULL);
bl.invalidate_hashes();
return true;
@@ -746,10 +746,13 @@ namespace cryptonote
void get_altblock_longhash(const block& b, crypto::hash& res, const crypto::hash& seed_hash)
{
blobdata bd = get_block_hashing_blob(b);
rx_slow_hash(seed_hash.data, bd.data(), bd.size(), res.data);
const int rx_variant = get_randomx_variant_for_hf_version(b.major_version);
crypto::rx_slow_hash(seed_hash.data, rx_variant, bd.data(), bd.size(), res.data);
if (b.major_version >= HF_VERSION_POW_COMMITMENT)
crypto::rx_commitment(bd.data(), bd.size(), res.data, res.data);
}
bool get_block_longhash(const Blockchain *pbc, const blobdata& bd, crypto::hash& res, const uint64_t height, const int major_version, const crypto::hash *seed_hash, const int miners)
bool get_block_longhash(const Blockchain *pbc, const blobdata& bd, crypto::hash& res, const uint64_t height, const int major_version, const crypto::hash *seed_hash, crypto::hash *intermediate_hash_out)
{
crypto::hash seed_hash_ = crypto::null_hash;
if (pbc != NULL && major_version >= RX_BLOCK_VERSION)
@@ -757,20 +760,23 @@ namespace cryptonote
const uint64_t seed_height = rx_seedheight(height);
seed_hash_ = seed_hash ? *seed_hash : pbc->get_pending_block_id_by_height(seed_height);
}
res = get_block_longhash(bd, height, major_version, seed_hash_);
crypto::hash intermediate_hash;
res = get_block_longhash(bd, height, major_version, seed_hash_, intermediate_hash);
if (intermediate_hash_out)
*intermediate_hash_out = intermediate_hash;
return true;
}
bool get_block_longhash(const Blockchain *pbc, const block& b, crypto::hash& res, const uint64_t height, const crypto::hash *seed_hash, const int miners)
bool get_block_longhash(const Blockchain *pbc, const block& b, crypto::hash& res, const uint64_t height, const crypto::hash *seed_hash, crypto::hash *intermediate_hash_out)
{
blobdata bd = get_block_hashing_blob(b);
return get_block_longhash(pbc, bd, res, height, b.major_version, seed_hash, miners);
return get_block_longhash(pbc, bd, res, height, b.major_version, seed_hash, intermediate_hash_out);
}
crypto::hash get_block_longhash(const Blockchain *pbc, const block& b, const uint64_t height, const crypto::hash *seed_hash, const int miners)
crypto::hash get_block_longhash(const Blockchain *pbc, const block& b, const uint64_t height, const crypto::hash *seed_hash, crypto::hash *intermediate_hash_out)
{
crypto::hash p = crypto::null_hash;
get_block_longhash(pbc, b, p, height, seed_hash, miners);
get_block_longhash(pbc, b, p, height, seed_hash, intermediate_hash_out);
return p;
}
}
+3 -3
View File
@@ -162,9 +162,9 @@ namespace cryptonote
);
class Blockchain;
bool get_block_longhash(const Blockchain *pb, const blobdata& bd, crypto::hash& res, const uint64_t height, const int major_version, const crypto::hash *seed_hash, const int miners = 0);
bool get_block_longhash(const Blockchain *pb, const block& b, crypto::hash& res, const uint64_t height, const crypto::hash *seed_hash = nullptr, const int miners = 0);
crypto::hash get_block_longhash(const Blockchain *pb, const block& b, const uint64_t height, const crypto::hash *seed_hash = nullptr, const int miners = 0);
bool get_block_longhash(const Blockchain *pb, const blobdata& bd, crypto::hash& res, const uint64_t height, const int major_version, const crypto::hash *seed_hash, crypto::hash *intermediate_hash_out = nullptr);
bool get_block_longhash(const Blockchain *pb, const block& b, crypto::hash& res, const uint64_t height, const crypto::hash *seed_hash = nullptr, crypto::hash *intermediate_hash_out = nullptr);
crypto::hash get_block_longhash(const Blockchain *pb, const block& b, const uint64_t height, const crypto::hash *seed_hash = nullptr, crypto::hash *intermediate_hash_out = nullptr);
void get_altblock_longhash(const block& b, crypto::hash& res, const crypto::hash& seed_hash);
}
+1 -1
View File
@@ -2164,7 +2164,7 @@ namespace cryptonote
return false;
}
miner::find_nonce_for_given_block([this](const cryptonote::block &b, uint64_t height, const crypto::hash *seed_hash, unsigned int threads, crypto::hash &hash) {
return cryptonote::get_block_longhash(&(m_core.get_blockchain_storage()), b, hash, height, seed_hash, threads);
return cryptonote::get_block_longhash(&(m_core.get_blockchain_storage()), b, hash, height, seed_hash);
}, b, template_res.difficulty, template_res.height, &seed_hash);
submit_req.front() = string_tools::buff_to_hex_nodelimer(block_to_blob(b));
+1 -1
View File
@@ -411,7 +411,7 @@ void test_generator::fill_nonce(cryptonote::block& blk, const difficulty_type& d
blk.nonce = 0;
while (!miner::find_nonce_for_given_block([blockchain](const cryptonote::block &b, uint64_t height, const crypto::hash *seed_hash, unsigned int threads, crypto::hash &hash){
return cryptonote::get_block_longhash(blockchain, b, hash, height, seed_hash, threads);
return cryptonote::get_block_longhash(blockchain, b, hash, height, seed_hash);
}, blk, diffic, height, NULL)) {
blk.timestamp++;
}