mirror of
https://git.wownero.com/wownero/wownero.git
synced 2025-01-08 19:48:52 +00:00
RandomX integration
Support RandomX PoW algorithm
This commit is contained in:
parent
4dcd3cd0b2
commit
c319796355
3
.gitmodules
vendored
3
.gitmodules
vendored
@ -12,3 +12,6 @@
|
|||||||
[submodule "external/trezor-common"]
|
[submodule "external/trezor-common"]
|
||||||
path = external/trezor-common
|
path = external/trezor-common
|
||||||
url = https://github.com/trezor/trezor-common.git
|
url = https://github.com/trezor/trezor-common.git
|
||||||
|
[submodule "external/randomx"]
|
||||||
|
path = external/randomx
|
||||||
|
url = https://github.com/tevador/RandomX
|
||||||
|
@ -205,6 +205,7 @@ if(NOT MANUAL_SUBMODULES)
|
|||||||
check_submodule(external/unbound)
|
check_submodule(external/unbound)
|
||||||
check_submodule(external/rapidjson)
|
check_submodule(external/rapidjson)
|
||||||
check_submodule(external/trezor-common)
|
check_submodule(external/trezor-common)
|
||||||
|
check_submodule(external/randomx)
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
1
external/CMakeLists.txt
vendored
1
external/CMakeLists.txt
vendored
@ -100,3 +100,4 @@ endif()
|
|||||||
|
|
||||||
add_subdirectory(db_drivers)
|
add_subdirectory(db_drivers)
|
||||||
add_subdirectory(easylogging++)
|
add_subdirectory(easylogging++)
|
||||||
|
add_subdirectory(randomx)
|
||||||
|
1
external/randomx
vendored
Submodule
1
external/randomx
vendored
Submodule
@ -0,0 +1 @@
|
|||||||
|
Subproject commit 1276d67d2f594ea4a8e9cde28253b1a74769aeb9
|
@ -46,6 +46,7 @@ set(crypto_sources
|
|||||||
random.c
|
random.c
|
||||||
skein.c
|
skein.c
|
||||||
slow-hash.c
|
slow-hash.c
|
||||||
|
rx-slow-hash.c
|
||||||
CryptonightR_JIT.c
|
CryptonightR_JIT.c
|
||||||
tree-hash.c)
|
tree-hash.c)
|
||||||
|
|
||||||
@ -53,6 +54,8 @@ if(ARCH_ID STREQUAL "i386" OR ARCH_ID STREQUAL "x86_64" OR ARCH_ID STREQUAL "x86
|
|||||||
list(APPEND crypto_sources CryptonightR_template.S)
|
list(APPEND crypto_sources CryptonightR_template.S)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
include_directories(${RANDOMX_INCLUDE})
|
||||||
|
|
||||||
set(crypto_headers)
|
set(crypto_headers)
|
||||||
|
|
||||||
set(crypto_private_headers
|
set(crypto_private_headers
|
||||||
@ -86,6 +89,7 @@ monero_add_library(cncrypto
|
|||||||
target_link_libraries(cncrypto
|
target_link_libraries(cncrypto
|
||||||
PUBLIC
|
PUBLIC
|
||||||
epee
|
epee
|
||||||
|
randomx
|
||||||
${Boost_SYSTEM_LIBRARY}
|
${Boost_SYSTEM_LIBRARY}
|
||||||
${SODIUM_LIBRARY}
|
${SODIUM_LIBRARY}
|
||||||
PRIVATE
|
PRIVATE
|
||||||
|
56
src/crypto/c_threads.h
Normal file
56
src/crypto/c_threads.h
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
// Copyright (c) 2019, The Monero Project
|
||||||
|
//
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without modification, are
|
||||||
|
// permitted provided that the following conditions are met:
|
||||||
|
//
|
||||||
|
// 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||||
|
// conditions and the following disclaimer.
|
||||||
|
//
|
||||||
|
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||||
|
// of conditions and the following disclaimer in the documentation and/or other
|
||||||
|
// materials provided with the distribution.
|
||||||
|
//
|
||||||
|
// 3. Neither the name of the copyright holder nor the names of its contributors may be
|
||||||
|
// used to endorse or promote products derived from this software without specific
|
||||||
|
// prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
||||||
|
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
||||||
|
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||||
|
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
/* Brain-dead simple portability wrapper over thread APIs for C */
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#include <windows.h>
|
||||||
|
#define CTHR_MUTEX_TYPE HANDLE
|
||||||
|
#define CTHR_MUTEX_INIT NULL
|
||||||
|
#define CTHR_MUTEX_LOCK(x) do { if (x == NULL) { \
|
||||||
|
HANDLE p = CreateMutex(NULL, FALSE, NULL); \
|
||||||
|
if (InterlockedCompareExchangePointer((PVOID*)&x, (PVOID)p, NULL) != NULL) \
|
||||||
|
CloseHandle(p); \
|
||||||
|
} WaitForSingleObject(x, INFINITE) == WAIT_FAILED; } while(0)
|
||||||
|
#define CTHR_MUTEX_UNLOCK(x) (ReleaseMutex(x) == 0)
|
||||||
|
#define CTHR_THREAD_TYPE HANDLE
|
||||||
|
#define CTHR_THREAD_RTYPE void
|
||||||
|
#define CTHR_THREAD_CREATE(thr, func, arg) thr = _beginthread(func, 0, arg)
|
||||||
|
#define CTHR_THREAD_JOIN(thr) WaitForSingleObject(thr, INFINITE)
|
||||||
|
#else
|
||||||
|
#include <pthread.h>
|
||||||
|
#define CTHR_MUTEX_TYPE pthread_mutex_t
|
||||||
|
#define CTHR_MUTEX_INIT PTHREAD_MUTEX_INITIALIZER
|
||||||
|
#define CTHR_MUTEX_LOCK(x) pthread_mutex_lock(&x)
|
||||||
|
#define CTHR_MUTEX_UNLOCK(x) pthread_mutex_unlock(&x)
|
||||||
|
#define CTHR_THREAD_TYPE pthread_t
|
||||||
|
#define CTHR_THREAD_RTYPE void *
|
||||||
|
#define CTHR_THREAD_CREATE(thr, func, arg) pthread_create(&thr, NULL, func, arg)
|
||||||
|
#define CTHR_THREAD_JOIN(thr) pthread_join(thr, NULL)
|
||||||
|
#endif
|
@ -87,3 +87,14 @@ void hash_extra_jh(const void *data, size_t length, char *hash);
|
|||||||
void hash_extra_skein(const void *data, size_t length, char *hash);
|
void hash_extra_skein(const void *data, size_t length, char *hash);
|
||||||
|
|
||||||
void tree_hash(const char (*hashes)[HASH_SIZE], size_t count, char *root_hash);
|
void tree_hash(const char (*hashes)[HASH_SIZE], size_t count, char *root_hash);
|
||||||
|
|
||||||
|
#define RX_BLOCK_VERSION 12
|
||||||
|
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);
|
||||||
|
bool rx_needhash(const uint64_t height, uint64_t *seedheight);
|
||||||
|
void rx_seedhash(const uint64_t seedheight, const char *hash, const int miners);
|
||||||
|
void rx_slow_hash(const void *data, size_t length, char *hash, const int miners);
|
||||||
|
void rx_alt_slowhash(const uint64_t mainheight, const uint64_t seedheight, const char *seedhash, const void *data, size_t length, char *hash);
|
||||||
|
void rx_reorg(const uint64_t split_height);
|
||||||
|
349
src/crypto/rx-slow-hash.c
Normal file
349
src/crypto/rx-slow-hash.c
Normal file
@ -0,0 +1,349 @@
|
|||||||
|
// Copyright (c) 2019, The Monero Project
|
||||||
|
//
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without modification, are
|
||||||
|
// permitted provided that the following conditions are met:
|
||||||
|
//
|
||||||
|
// 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||||
|
// conditions and the following disclaimer.
|
||||||
|
//
|
||||||
|
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||||
|
// of conditions and the following disclaimer in the documentation and/or other
|
||||||
|
// materials provided with the distribution.
|
||||||
|
//
|
||||||
|
// 3. Neither the name of the copyright holder nor the names of its contributors may be
|
||||||
|
// used to endorse or promote products derived from this software without specific
|
||||||
|
// prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
||||||
|
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
||||||
|
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||||
|
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "randomx.h"
|
||||||
|
#include "c_threads.h"
|
||||||
|
#include "hash-ops.h"
|
||||||
|
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
#define THREADV __declspec(thread)
|
||||||
|
#else
|
||||||
|
#define THREADV __thread
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static CTHR_MUTEX_TYPE rx_mutex = CTHR_MUTEX_INIT;
|
||||||
|
|
||||||
|
typedef struct rx_state {
|
||||||
|
volatile uint64_t rs_height;
|
||||||
|
randomx_cache *rs_cache;
|
||||||
|
} rx_state;
|
||||||
|
|
||||||
|
static rx_state rx_s[2];
|
||||||
|
|
||||||
|
static randomx_dataset *rx_dataset;
|
||||||
|
THREADV int rx_s_toggle;
|
||||||
|
THREADV randomx_vm *rx_vm = NULL;
|
||||||
|
|
||||||
|
static void local_abort(const char *msg)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "%s\n", msg);
|
||||||
|
#ifdef NDEBUG
|
||||||
|
_exit(1);
|
||||||
|
#else
|
||||||
|
abort();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief uses cpuid to determine if the CPU supports the AES instructions
|
||||||
|
* @return true if the CPU supports AES, false otherwise
|
||||||
|
*/
|
||||||
|
|
||||||
|
static inline int force_software_aes(void)
|
||||||
|
{
|
||||||
|
static int use = -1;
|
||||||
|
|
||||||
|
if (use != -1)
|
||||||
|
return use;
|
||||||
|
|
||||||
|
const char *env = getenv("MONERO_USE_SOFTWARE_AES");
|
||||||
|
if (!env) {
|
||||||
|
use = 0;
|
||||||
|
}
|
||||||
|
else if (!strcmp(env, "0") || !strcmp(env, "no")) {
|
||||||
|
use = 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
use = 1;
|
||||||
|
}
|
||||||
|
return use;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void cpuid(int CPUInfo[4], int InfoType)
|
||||||
|
{
|
||||||
|
#if defined(__x86_64__)
|
||||||
|
__asm __volatile__
|
||||||
|
(
|
||||||
|
"cpuid":
|
||||||
|
"=a" (CPUInfo[0]),
|
||||||
|
"=b" (CPUInfo[1]),
|
||||||
|
"=c" (CPUInfo[2]),
|
||||||
|
"=d" (CPUInfo[3]) :
|
||||||
|
"a" (InfoType), "c" (0)
|
||||||
|
);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
static inline int check_aes_hw(void)
|
||||||
|
{
|
||||||
|
#if defined(__x86_64__)
|
||||||
|
int cpuid_results[4];
|
||||||
|
static int supported = -1;
|
||||||
|
|
||||||
|
if(supported >= 0)
|
||||||
|
return supported;
|
||||||
|
|
||||||
|
cpuid(cpuid_results,1);
|
||||||
|
return supported = cpuid_results[2] & (1 << 25);
|
||||||
|
#else
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static volatile int use_rx_jit_flag = -1;
|
||||||
|
|
||||||
|
static inline int use_rx_jit(void)
|
||||||
|
{
|
||||||
|
#if defined(__x86_64__)
|
||||||
|
|
||||||
|
if (use_rx_jit_flag != -1)
|
||||||
|
return use_rx_jit_flag;
|
||||||
|
|
||||||
|
const char *env = getenv("MONERO_USE_RX_JIT");
|
||||||
|
if (!env) {
|
||||||
|
use_rx_jit_flag = 1;
|
||||||
|
}
|
||||||
|
else if (!strcmp(env, "0") || !strcmp(env, "no")) {
|
||||||
|
use_rx_jit_flag = 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
use_rx_jit_flag = 1;
|
||||||
|
}
|
||||||
|
return use_rx_jit_flag;
|
||||||
|
#else
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#define SEEDHASH_EPOCH_BLOCKS 2048 /* Must be same as BLOCKS_SYNCHRONIZING_MAX_COUNT in cryptonote_config.h */
|
||||||
|
#define SEEDHASH_EPOCH_LAG 64
|
||||||
|
|
||||||
|
void rx_reorg(const uint64_t split_height) {
|
||||||
|
int i;
|
||||||
|
CTHR_MUTEX_LOCK(rx_mutex);
|
||||||
|
for (i=0; i<2; i++) {
|
||||||
|
if (split_height < rx_s[i].rs_height)
|
||||||
|
rx_s[i].rs_height = 1; /* set to an invalid seed height */
|
||||||
|
}
|
||||||
|
CTHR_MUTEX_UNLOCK(rx_mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t rx_seedheight(const uint64_t height) {
|
||||||
|
uint64_t s_height = (height <= SEEDHASH_EPOCH_BLOCKS+SEEDHASH_EPOCH_LAG) ? 0 :
|
||||||
|
(height - SEEDHASH_EPOCH_LAG - 1) & ~(SEEDHASH_EPOCH_BLOCKS-1);
|
||||||
|
return s_height;
|
||||||
|
}
|
||||||
|
|
||||||
|
void rx_seedheights(const uint64_t height, uint64_t *seedheight, uint64_t *nextheight) {
|
||||||
|
*seedheight = rx_seedheight(height);
|
||||||
|
*nextheight = rx_seedheight(height + SEEDHASH_EPOCH_LAG);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool rx_needhash(const uint64_t height, uint64_t *seedheight) {
|
||||||
|
rx_state *rx_sp;
|
||||||
|
uint64_t s_height = rx_seedheight(height);
|
||||||
|
int toggle = (s_height & SEEDHASH_EPOCH_BLOCKS) != 0;
|
||||||
|
bool ret;
|
||||||
|
bool changed = (toggle != rx_s_toggle);
|
||||||
|
*seedheight = s_height;
|
||||||
|
rx_s_toggle = toggle;
|
||||||
|
rx_sp = &rx_s[rx_s_toggle];
|
||||||
|
ret = (rx_sp->rs_cache == NULL) || (rx_sp->rs_height != s_height);
|
||||||
|
/* if cache is ok but we've flipped caches, reset vm */
|
||||||
|
if (!ret && changed && rx_vm != NULL)
|
||||||
|
randomx_vm_set_cache(rx_vm, rx_sp->rs_cache);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef struct seedinfo {
|
||||||
|
randomx_cache *si_cache;
|
||||||
|
unsigned long si_start;
|
||||||
|
unsigned long si_count;
|
||||||
|
} seedinfo;
|
||||||
|
|
||||||
|
static CTHR_THREAD_RTYPE rx_seedthread(void *arg) {
|
||||||
|
seedinfo *si = arg;
|
||||||
|
randomx_init_dataset(rx_dataset, si->si_cache, si->si_start, si->si_count);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rx_initdata(randomx_cache *rs_cache, const int miners) {
|
||||||
|
if (miners > 1) {
|
||||||
|
unsigned long delta = randomx_dataset_item_count() / miners;
|
||||||
|
unsigned long start = 0;
|
||||||
|
int i;
|
||||||
|
seedinfo *si;
|
||||||
|
CTHR_THREAD_TYPE *st;
|
||||||
|
si = malloc(miners * sizeof(seedinfo));
|
||||||
|
if (si == NULL)
|
||||||
|
local_abort("Couldn't allocate RandomX mining threadinfo");
|
||||||
|
st = malloc(miners * sizeof(CTHR_THREAD_TYPE));
|
||||||
|
if (st == NULL) {
|
||||||
|
free(si);
|
||||||
|
local_abort("Couldn't allocate RandomX mining threadlist");
|
||||||
|
}
|
||||||
|
for (i=0; i<miners-1; i++) {
|
||||||
|
si[i].si_cache = rs_cache;
|
||||||
|
si[i].si_start = start;
|
||||||
|
si[i].si_count = delta;
|
||||||
|
start += delta;
|
||||||
|
}
|
||||||
|
si[i].si_cache = rs_cache;
|
||||||
|
si[i].si_start = start;
|
||||||
|
si[i].si_count = randomx_dataset_item_count() - start;
|
||||||
|
for (i=1; i<miners; i++) {
|
||||||
|
CTHR_THREAD_CREATE(st[i], rx_seedthread, &si[i]);
|
||||||
|
}
|
||||||
|
randomx_init_dataset(rx_dataset, rs_cache, 0, si[0].si_count);
|
||||||
|
for (i=1; i<miners; i++) {
|
||||||
|
CTHR_THREAD_JOIN(st[i]);
|
||||||
|
}
|
||||||
|
free(st);
|
||||||
|
free(si);
|
||||||
|
} else {
|
||||||
|
randomx_init_dataset(rx_dataset, rs_cache, 0, randomx_dataset_item_count());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rx_seedhash_int(rx_state *rx_sp, const uint64_t height, const char *hash, const int miners) {
|
||||||
|
randomx_flags flags = RANDOMX_FLAG_DEFAULT;
|
||||||
|
randomx_cache *cache;
|
||||||
|
CTHR_MUTEX_LOCK(rx_mutex);
|
||||||
|
cache = rx_sp->rs_cache;
|
||||||
|
if (rx_sp->rs_height != height || cache == NULL) {
|
||||||
|
if (use_rx_jit())
|
||||||
|
flags |= RANDOMX_FLAG_JIT;
|
||||||
|
if (cache == NULL) {
|
||||||
|
cache = randomx_alloc_cache(flags | RANDOMX_FLAG_LARGE_PAGES);
|
||||||
|
if (cache == NULL)
|
||||||
|
cache = randomx_alloc_cache(flags);
|
||||||
|
if (cache == NULL)
|
||||||
|
local_abort("Couldn't allocate RandomX cache");
|
||||||
|
}
|
||||||
|
randomx_init_cache(cache, hash, 32);
|
||||||
|
if (miners && rx_dataset != NULL)
|
||||||
|
rx_initdata(cache, miners);
|
||||||
|
rx_sp->rs_height = height;
|
||||||
|
if (rx_sp->rs_cache == NULL)
|
||||||
|
rx_sp->rs_cache = cache;
|
||||||
|
}
|
||||||
|
CTHR_MUTEX_UNLOCK(rx_mutex);
|
||||||
|
if (rx_vm != NULL)
|
||||||
|
randomx_vm_set_cache(rx_vm, rx_sp->rs_cache);
|
||||||
|
}
|
||||||
|
|
||||||
|
void rx_seedhash(const uint64_t height, const char *hash, const int miners) {
|
||||||
|
rx_state *rx_sp = &rx_s[rx_s_toggle];
|
||||||
|
rx_seedhash_int(rx_sp, height, hash, miners);
|
||||||
|
}
|
||||||
|
|
||||||
|
static char rx_althash[32]; // seedhash for alternate blocks
|
||||||
|
|
||||||
|
void rx_alt_slowhash(const uint64_t mainheight, const uint64_t seedheight, const char *seedhash, const void *data, size_t length, char *hash) {
|
||||||
|
uint64_t s_height = rx_seedheight(mainheight);
|
||||||
|
int alt_toggle = (s_height & SEEDHASH_EPOCH_BLOCKS) == 0;
|
||||||
|
rx_state *rx_sp = &rx_s[alt_toggle];
|
||||||
|
if (rx_sp->rs_height != seedheight || rx_sp->rs_cache == NULL || memcmp(hash, rx_althash, sizeof(rx_althash))) {
|
||||||
|
memcpy(rx_althash, seedhash, sizeof(rx_althash));
|
||||||
|
rx_sp->rs_height = 1;
|
||||||
|
rx_seedhash_int(rx_sp, seedheight, seedhash, 0);
|
||||||
|
}
|
||||||
|
if (rx_vm == NULL) {
|
||||||
|
randomx_flags flags = RANDOMX_FLAG_DEFAULT;
|
||||||
|
if (use_rx_jit())
|
||||||
|
flags |= RANDOMX_FLAG_JIT;
|
||||||
|
if(!force_software_aes() && check_aes_hw())
|
||||||
|
flags |= RANDOMX_FLAG_HARD_AES;
|
||||||
|
rx_vm = randomx_create_vm(flags | RANDOMX_FLAG_LARGE_PAGES, rx_sp->rs_cache, NULL);
|
||||||
|
if(rx_vm == NULL) //large pages failed
|
||||||
|
rx_vm = randomx_create_vm(flags, rx_sp->rs_cache, NULL);
|
||||||
|
if(rx_vm == NULL) {//fallback if everything fails
|
||||||
|
flags = RANDOMX_FLAG_DEFAULT;
|
||||||
|
rx_vm = randomx_create_vm(flags, rx_sp->rs_cache, NULL);
|
||||||
|
}
|
||||||
|
if (rx_vm == NULL)
|
||||||
|
local_abort("Couldn't allocate RandomX VM");
|
||||||
|
}
|
||||||
|
randomx_calculate_hash(rx_vm, data, length, hash);
|
||||||
|
}
|
||||||
|
|
||||||
|
void rx_slow_hash(const void *data, size_t length, char *hash, int miners) {
|
||||||
|
if (rx_vm == NULL) {
|
||||||
|
rx_state *rx_sp = &rx_s[rx_s_toggle];
|
||||||
|
randomx_flags flags = RANDOMX_FLAG_DEFAULT;
|
||||||
|
if (use_rx_jit())
|
||||||
|
flags |= RANDOMX_FLAG_JIT;
|
||||||
|
if(!force_software_aes() && check_aes_hw())
|
||||||
|
flags |= RANDOMX_FLAG_HARD_AES;
|
||||||
|
if (miners) {
|
||||||
|
if (rx_dataset == NULL) {
|
||||||
|
CTHR_MUTEX_LOCK(rx_mutex);
|
||||||
|
if (rx_dataset == NULL) {
|
||||||
|
rx_dataset = randomx_alloc_dataset(RANDOMX_FLAG_LARGE_PAGES);
|
||||||
|
if (rx_dataset == NULL)
|
||||||
|
rx_dataset = randomx_alloc_dataset(RANDOMX_FLAG_DEFAULT);
|
||||||
|
if (rx_dataset != NULL)
|
||||||
|
rx_initdata(rx_sp->rs_cache, miners);
|
||||||
|
}
|
||||||
|
CTHR_MUTEX_UNLOCK(rx_mutex);
|
||||||
|
}
|
||||||
|
if (rx_dataset != NULL)
|
||||||
|
flags |= RANDOMX_FLAG_FULL_MEM;
|
||||||
|
else
|
||||||
|
miners = 0;
|
||||||
|
}
|
||||||
|
rx_vm = randomx_create_vm(flags | RANDOMX_FLAG_LARGE_PAGES, rx_sp->rs_cache, rx_dataset);
|
||||||
|
if(rx_vm == NULL) //large pages failed
|
||||||
|
rx_vm = randomx_create_vm(flags, rx_sp->rs_cache, rx_dataset);
|
||||||
|
if(rx_vm == NULL) {//fallback if everything fails
|
||||||
|
flags = RANDOMX_FLAG_DEFAULT | (miners ? RANDOMX_FLAG_FULL_MEM : 0);
|
||||||
|
rx_vm = randomx_create_vm(flags, rx_sp->rs_cache, rx_dataset);
|
||||||
|
}
|
||||||
|
if (rx_vm == NULL)
|
||||||
|
local_abort("Couldn't allocate RandomX VM");
|
||||||
|
}
|
||||||
|
randomx_calculate_hash(rx_vm, data, length, hash);
|
||||||
|
}
|
||||||
|
|
||||||
|
void rx_slow_hash_allocate_state(void) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void rx_slow_hash_free_state(void) {
|
||||||
|
if (rx_vm != NULL) {
|
||||||
|
randomx_destroy_vm(rx_vm);
|
||||||
|
rx_vm = NULL;
|
||||||
|
}
|
||||||
|
}
|
@ -653,7 +653,7 @@ BOOL SetLockPagesPrivilege(HANDLE hProcess, BOOL bEnable)
|
|||||||
* the allocated buffer.
|
* the allocated buffer.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void slow_hash_allocate_state(void)
|
void cn_slow_hash_allocate_state(void)
|
||||||
{
|
{
|
||||||
if(hp_state != NULL)
|
if(hp_state != NULL)
|
||||||
return;
|
return;
|
||||||
@ -686,7 +686,7 @@ void slow_hash_allocate_state(void)
|
|||||||
*@brief frees the state allocated by slow_hash_allocate_state
|
*@brief frees the state allocated by slow_hash_allocate_state
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void slow_hash_free_state(void)
|
void cn_slow_hash_free_state(void)
|
||||||
{
|
{
|
||||||
if(hp_state == NULL)
|
if(hp_state == NULL)
|
||||||
return;
|
return;
|
||||||
@ -760,7 +760,7 @@ void cn_slow_hash(const void *data, size_t length, char *hash, int variant, int
|
|||||||
|
|
||||||
// this isn't supposed to happen, but guard against it for now.
|
// this isn't supposed to happen, but guard against it for now.
|
||||||
if(hp_state == NULL)
|
if(hp_state == NULL)
|
||||||
slow_hash_allocate_state();
|
cn_slow_hash_allocate_state();
|
||||||
|
|
||||||
/* CryptoNight Step 1: Use Keccak1600 to initialize the 'state' (and 'text') buffers from the data. */
|
/* CryptoNight Step 1: Use Keccak1600 to initialize the 'state' (and 'text') buffers from the data. */
|
||||||
if (prehashed) {
|
if (prehashed) {
|
||||||
@ -874,13 +874,13 @@ void cn_slow_hash(const void *data, size_t length, char *hash, int variant, int
|
|||||||
}
|
}
|
||||||
|
|
||||||
#elif !defined NO_AES && (defined(__arm__) || defined(__aarch64__))
|
#elif !defined NO_AES && (defined(__arm__) || defined(__aarch64__))
|
||||||
void slow_hash_allocate_state(void)
|
void cn_slow_hash_allocate_state(void)
|
||||||
{
|
{
|
||||||
// Do nothing, this is just to maintain compatibility with the upgraded slow-hash.c
|
// Do nothing, this is just to maintain compatibility with the upgraded slow-hash.c
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void slow_hash_free_state(void)
|
void cn_slow_hash_free_state(void)
|
||||||
{
|
{
|
||||||
// As above
|
// As above
|
||||||
return;
|
return;
|
||||||
@ -1440,13 +1440,15 @@ void cn_slow_hash(const void *data, size_t length, char *hash, int variant, int
|
|||||||
#else
|
#else
|
||||||
// Portable implementation as a fallback
|
// Portable implementation as a fallback
|
||||||
|
|
||||||
void slow_hash_allocate_state(void)
|
#define hp_jitfunc ((v4_random_math_JIT_func)NULL)
|
||||||
|
|
||||||
|
void cn_slow_hash_allocate_state(void)
|
||||||
{
|
{
|
||||||
// Do nothing, this is just to maintain compatibility with the upgraded slow-hash.c
|
// Do nothing, this is just to maintain compatibility with the upgraded slow-hash.c
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void slow_hash_free_state(void)
|
void cn_slow_hash_free_state(void)
|
||||||
{
|
{
|
||||||
// As above
|
// As above
|
||||||
return;
|
return;
|
||||||
@ -1623,3 +1625,15 @@ void cn_slow_hash(const void *data, size_t length, char *hash, int variant, int
|
|||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
void slow_hash_allocate_state(void)
|
||||||
|
{
|
||||||
|
cn_slow_hash_allocate_state();
|
||||||
|
rx_slow_hash_allocate_state();
|
||||||
|
}
|
||||||
|
|
||||||
|
void slow_hash_free_state(void)
|
||||||
|
{
|
||||||
|
cn_slow_hash_free_state();
|
||||||
|
rx_slow_hash_free_state();
|
||||||
|
}
|
||||||
|
@ -1202,14 +1202,6 @@ namespace cryptonote
|
|||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
//---------------------------------------------------------------
|
//---------------------------------------------------------------
|
||||||
bool get_block_longhash(const block& b, crypto::hash& res, uint64_t height)
|
|
||||||
{
|
|
||||||
blobdata bd = get_block_hashing_blob(b);
|
|
||||||
const int cn_variant = b.major_version >= 11 ? 4 : b.major_version >= 9 && b.major_version <= 10 ? 2 : 1;
|
|
||||||
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> relative_output_offsets_to_absolute(const std::vector<uint64_t>& off)
|
||||||
{
|
{
|
||||||
std::vector<uint64_t> res = off;
|
std::vector<uint64_t> res = off;
|
||||||
@ -1230,13 +1222,6 @@ namespace cryptonote
|
|||||||
return res;
|
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)
|
bool parse_and_validate_block_from_blob(const blobdata& b_blob, block& b, crypto::hash *block_hash)
|
||||||
{
|
{
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
|
@ -117,8 +117,6 @@ namespace cryptonote
|
|||||||
bool calculate_block_hash(const block& b, crypto::hash& res, const blobdata *blob = NULL);
|
bool calculate_block_hash(const block& b, crypto::hash& res, const blobdata *blob = NULL);
|
||||||
bool get_block_hash(const block& b, crypto::hash& res);
|
bool get_block_hash(const block& b, crypto::hash& res);
|
||||||
crypto::hash get_block_hash(const block& b);
|
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, 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);
|
||||||
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, crypto::hash &block_hash);
|
||||||
|
@ -37,8 +37,10 @@
|
|||||||
#include "syncobj.h"
|
#include "syncobj.h"
|
||||||
#include "cryptonote_basic_impl.h"
|
#include "cryptonote_basic_impl.h"
|
||||||
#include "cryptonote_format_utils.h"
|
#include "cryptonote_format_utils.h"
|
||||||
|
#include "cryptonote_core/cryptonote_tx_utils.h"
|
||||||
#include "file_io_utils.h"
|
#include "file_io_utils.h"
|
||||||
#include "common/command_line.h"
|
#include "common/command_line.h"
|
||||||
|
#include "common/util.h"
|
||||||
#include "string_coding.h"
|
#include "string_coding.h"
|
||||||
#include "string_tools.h"
|
#include "string_tools.h"
|
||||||
#include "storages/portable_storage_template_helper.h"
|
#include "storages/portable_storage_template_helper.h"
|
||||||
@ -99,12 +101,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(boost::value_initialized<block>()),
|
m_template(boost::value_initialized<block>()),
|
||||||
m_template_no(0),
|
m_template_no(0),
|
||||||
m_diffic(0),
|
m_diffic(0),
|
||||||
m_thread_index(0),
|
m_thread_index(0),
|
||||||
m_phandler(phandler),
|
m_phandler(phandler),
|
||||||
|
m_pbc(pbc),
|
||||||
m_height(0),
|
m_height(0),
|
||||||
m_threads_active(0),
|
m_threads_active(0),
|
||||||
m_pausers_count(0),
|
m_pausers_count(0),
|
||||||
@ -466,12 +469,12 @@ namespace cryptonote
|
|||||||
return true;
|
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++)
|
for(; bl.nonce != std::numeric_limits<uint32_t>::max(); bl.nonce++)
|
||||||
{
|
{
|
||||||
crypto::hash h;
|
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))
|
if(check_hash(h, diffic))
|
||||||
{
|
{
|
||||||
@ -570,7 +573,7 @@ namespace cryptonote
|
|||||||
|
|
||||||
b.nonce = nonce;
|
b.nonce = nonce;
|
||||||
crypto::hash h;
|
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))
|
if(check_hash(h, local_diff))
|
||||||
{
|
{
|
||||||
|
@ -52,13 +52,15 @@ namespace cryptonote
|
|||||||
~i_miner_handler(){};
|
~i_miner_handler(){};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class Blockchain;
|
||||||
|
|
||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
/* */
|
/* */
|
||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
class miner
|
class miner
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
miner(i_miner_handler* phandler);
|
miner(i_miner_handler* phandler, Blockchain* pbc);
|
||||||
~miner();
|
~miner();
|
||||||
bool init(const boost::program_options::variables_map& vm, network_type nettype);
|
bool init(const boost::program_options::variables_map& vm, network_type nettype);
|
||||||
static void init_options(boost::program_options::options_description& desc);
|
static void init_options(boost::program_options::options_description& desc);
|
||||||
@ -74,7 +76,7 @@ namespace cryptonote
|
|||||||
bool on_idle();
|
bool on_idle();
|
||||||
void on_synchronized();
|
void on_synchronized();
|
||||||
//synchronous analog (for fast calls)
|
//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 pause();
|
||||||
void resume();
|
void resume();
|
||||||
void do_print_hashrate(bool do_hr);
|
void do_print_hashrate(bool do_hr);
|
||||||
@ -133,6 +135,7 @@ namespace cryptonote
|
|||||||
std::list<boost::thread> m_threads;
|
std::list<boost::thread> m_threads;
|
||||||
epee::critical_section m_threads_lock;
|
epee::critical_section m_threads_lock;
|
||||||
i_miner_handler* m_phandler;
|
i_miner_handler* m_phandler;
|
||||||
|
Blockchain* m_pbc;
|
||||||
account_public_address m_mine_address;
|
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<5> m_update_block_template_interval;
|
||||||
epee::math_helper::once_a_time_seconds<2> m_update_merge_hr_interval;
|
epee::math_helper::once_a_time_seconds<2> m_update_merge_hr_interval;
|
||||||
|
@ -103,6 +103,7 @@
|
|||||||
#define BLOCKS_IDS_SYNCHRONIZING_DEFAULT_COUNT 10000 //by default, blocks ids count in synchronizing
|
#define BLOCKS_IDS_SYNCHRONIZING_DEFAULT_COUNT 10000 //by default, blocks ids count in synchronizing
|
||||||
#define BLOCKS_SYNCHRONIZING_DEFAULT_COUNT_PRE_V4 100 //by default, blocks count in blocks downloading
|
#define BLOCKS_SYNCHRONIZING_DEFAULT_COUNT_PRE_V4 100 //by default, blocks count in blocks downloading
|
||||||
#define BLOCKS_SYNCHRONIZING_DEFAULT_COUNT 20 //by default, blocks count in blocks downloading
|
#define BLOCKS_SYNCHRONIZING_DEFAULT_COUNT 20 //by default, blocks count in blocks downloading
|
||||||
|
#define BLOCKS_SYNCHRONIZING_MAX_COUNT 2048 //must be a power of 2, greater than 128, equal to SEEDHASH_EPOCH_BLOCKS
|
||||||
|
|
||||||
#define CRYPTONOTE_MEMPOOL_TX_LIVETIME (86400*3) //seconds, three days
|
#define CRYPTONOTE_MEMPOOL_TX_LIVETIME (86400*3) //seconds, three days
|
||||||
#define CRYPTONOTE_MEMPOOL_TX_FROM_ALT_BLOCK_LIVETIME 604800 //seconds, one week
|
#define CRYPTONOTE_MEMPOOL_TX_FROM_ALT_BLOCK_LIVETIME 604800 //seconds, one week
|
||||||
|
@ -1093,6 +1093,7 @@ bool Blockchain::switch_to_alternative_blockchain(std::list<block_extended_info>
|
|||||||
}
|
}
|
||||||
|
|
||||||
m_hardfork->reorganize_from_chain_height(split_height);
|
m_hardfork->reorganize_from_chain_height(split_height);
|
||||||
|
get_block_longhash_reorg(split_height);
|
||||||
|
|
||||||
std::shared_ptr<tools::Notify> reorg_notify = m_reorg_notify;
|
std::shared_ptr<tools::Notify> reorg_notify = m_reorg_notify;
|
||||||
if (reorg_notify)
|
if (reorg_notify)
|
||||||
@ -1757,7 +1758,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);
|
difficulty_type current_diff = get_next_difficulty_for_alternative_chain(alt_chain, bei);
|
||||||
CHECK_AND_ASSERT_MES(current_diff, false, "!!!!!!! DIFFICULTY OVERHEAD !!!!!!!");
|
CHECK_AND_ASSERT_MES(current_diff, false, "!!!!!!! DIFFICULTY OVERHEAD !!!!!!!");
|
||||||
crypto::hash proof_of_work = null_hash;
|
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))
|
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);
|
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);
|
||||||
@ -3694,7 +3718,7 @@ leave:
|
|||||||
proof_of_work = it->second;
|
proof_of_work = it->second;
|
||||||
}
|
}
|
||||||
else
|
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
|
// validate proof_of_work versus difficulty target
|
||||||
if(!check_hash(proof_of_work, current_diffic))
|
if(!check_hash(proof_of_work, current_diffic))
|
||||||
@ -4195,7 +4219,7 @@ void Blockchain::block_longhash_worker(uint64_t height, const epee::span<const b
|
|||||||
if (m_cancel)
|
if (m_cancel)
|
||||||
break;
|
break;
|
||||||
crypto::hash id = get_block_hash(block);
|
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);
|
map.emplace(id, pow);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -218,7 +218,7 @@ namespace cryptonote
|
|||||||
core::core(i_cryptonote_protocol* pprotocol):
|
core::core(i_cryptonote_protocol* pprotocol):
|
||||||
m_mempool(m_blockchain_storage),
|
m_mempool(m_blockchain_storage),
|
||||||
m_blockchain_storage(m_mempool),
|
m_blockchain_storage(m_mempool),
|
||||||
m_miner(this),
|
m_miner(this, &m_blockchain_storage),
|
||||||
m_miner_address(boost::value_initialized<account_public_address>()),
|
m_miner_address(boost::value_initialized<account_public_address>()),
|
||||||
m_starter_message_showed(false),
|
m_starter_message_showed(false),
|
||||||
m_target_blockchain_height(0),
|
m_target_blockchain_height(0),
|
||||||
@ -654,6 +654,8 @@ namespace cryptonote
|
|||||||
CHECK_AND_ASSERT_MES(r, false, "Failed to initialize blockchain storage");
|
CHECK_AND_ASSERT_MES(r, false, "Failed to initialize blockchain storage");
|
||||||
|
|
||||||
block_sync_size = command_line::get_arg(vm, arg_block_sync_size);
|
block_sync_size = command_line::get_arg(vm, arg_block_sync_size);
|
||||||
|
if (block_sync_size > BLOCKS_SYNCHRONIZING_MAX_COUNT)
|
||||||
|
MERROR("Error --dblock-sync-size cannot be greater than " << BLOCKS_SYNCHRONIZING_MAX_COUNT);
|
||||||
|
|
||||||
MGINFO("Loading checkpoints");
|
MGINFO("Loading checkpoints");
|
||||||
|
|
||||||
|
@ -37,6 +37,7 @@ using namespace epee;
|
|||||||
#include "common/apply_permutation.h"
|
#include "common/apply_permutation.h"
|
||||||
#include "cryptonote_tx_utils.h"
|
#include "cryptonote_tx_utils.h"
|
||||||
#include "cryptonote_config.h"
|
#include "cryptonote_config.h"
|
||||||
|
#include "blockchain.h"
|
||||||
#include "cryptonote_basic/miner.h"
|
#include "cryptonote_basic/miner.h"
|
||||||
#include "cryptonote_basic/tx_extra.h"
|
#include "cryptonote_basic/tx_extra.h"
|
||||||
#include "crypto/crypto.h"
|
#include "crypto/crypto.h"
|
||||||
@ -660,9 +661,54 @@ namespace cryptonote
|
|||||||
bl.minor_version = CURRENT_BLOCK_MINOR_VERSION;
|
bl.minor_version = CURRENT_BLOCK_MINOR_VERSION;
|
||||||
bl.timestamp = 0;
|
bl.timestamp = 0;
|
||||||
bl.nonce = nonce;
|
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();
|
bl.invalidate_hashes();
|
||||||
return true;
|
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_alt_slowhash(main_height, seed_height, seed_hash.data, bd.data(), bd.size(), res.data);
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
const int pow_variant = b.major_version >= 7 ? b.major_version - 6 : 0;
|
||||||
|
if (pow_variant >= 6) {
|
||||||
|
uint64_t seed_height;
|
||||||
|
if (rx_needhash(height, &seed_height)) {
|
||||||
|
crypto::hash hash;
|
||||||
|
if (pbc != NULL)
|
||||||
|
hash = pbc->get_block_id_by_height(seed_height);
|
||||||
|
else
|
||||||
|
memset(&hash, 0, sizeof(hash)); // only happens when generating genesis block
|
||||||
|
rx_seedhash(seed_height, hash.data, miners);
|
||||||
|
}
|
||||||
|
rx_slow_hash(bd.data(), bd.size(), res.data, miners);
|
||||||
|
} else {
|
||||||
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -117,6 +117,13 @@ namespace cryptonote
|
|||||||
, uint32_t nonce
|
, 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)
|
BOOST_CLASS_VERSION(cryptonote::tx_source_entry, 1)
|
||||||
|
@ -1012,6 +1012,7 @@ namespace cryptonote
|
|||||||
case 1: res.pow_algorithm = "CNv1 (Cryptonight variant 1)"; break;
|
case 1: res.pow_algorithm = "CNv1 (Cryptonight variant 1)"; break;
|
||||||
case 2: case 3: res.pow_algorithm = "CNv2 (Cryptonight variant 2)"; break;
|
case 2: case 3: res.pow_algorithm = "CNv2 (Cryptonight variant 2)"; break;
|
||||||
case 4: case 5: res.pow_algorithm = "CNv4 (Cryptonight variant 4)"; break;
|
case 4: case 5: res.pow_algorithm = "CNv4 (Cryptonight variant 4)"; break;
|
||||||
|
case 6: res.pow_algorithm = "RandomX"; break;
|
||||||
default: res.pow_algorithm = "I'm not sure actually"; break;
|
default: res.pow_algorithm = "I'm not sure actually"; break;
|
||||||
}
|
}
|
||||||
if (res.is_background_mining_enabled)
|
if (res.is_background_mining_enabled)
|
||||||
@ -1295,6 +1296,18 @@ namespace cryptonote
|
|||||||
LOG_ERROR("Failed to create block template");
|
LOG_ERROR("Failed to create block template");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if (b.major_version >= RX_BLOCK_VERSION)
|
||||||
|
{
|
||||||
|
uint64_t seed_height, next_height;
|
||||||
|
crypto::hash seed_hash;
|
||||||
|
crypto::rx_seedheights(res.height, &seed_height, &next_height);
|
||||||
|
seed_hash = m_core.get_block_id_by_height(seed_height);
|
||||||
|
res.seed_hash = string_tools::pod_to_hex(seed_hash);
|
||||||
|
if (next_height != seed_height) {
|
||||||
|
seed_hash = m_core.get_block_id_by_height(next_height);
|
||||||
|
res.next_seed_hash = string_tools::pod_to_hex(seed_hash);
|
||||||
|
}
|
||||||
|
}
|
||||||
store_difficulty(wdiff, res.difficulty, res.wide_difficulty, res.difficulty_top64);
|
store_difficulty(wdiff, res.difficulty, res.wide_difficulty, res.difficulty_top64);
|
||||||
blobdata block_blob = t_serializable_object_to_blob(b);
|
blobdata block_blob = t_serializable_object_to_blob(b);
|
||||||
crypto::public_key tx_pub_key = cryptonote::get_tx_pub_key_from_extra(b.miner_tx);
|
crypto::public_key tx_pub_key = cryptonote::get_tx_pub_key_from_extra(b.miner_tx);
|
||||||
@ -1437,7 +1450,7 @@ namespace cryptonote
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
b.nonce = req.starting_nonce;
|
b.nonce = req.starting_nonce;
|
||||||
miner::find_nonce_for_given_block(b, template_res.difficulty, template_res.height);
|
miner::find_nonce_for_given_block(&(m_core.get_blockchain_storage()), b, template_res.difficulty, template_res.height);
|
||||||
|
|
||||||
submit_req.front() = string_tools::buff_to_hex_nodelimer(block_to_blob(b));
|
submit_req.front() = string_tools::buff_to_hex_nodelimer(block_to_blob(b));
|
||||||
r = on_submitblock(submit_req, submit_res, error_resp, ctx);
|
r = on_submitblock(submit_req, submit_res, error_resp, ctx);
|
||||||
@ -1482,7 +1495,7 @@ namespace cryptonote
|
|||||||
response.reward = get_block_reward(blk);
|
response.reward = get_block_reward(blk);
|
||||||
response.block_size = response.block_weight = m_core.get_blockchain_storage().get_db().get_block_weight(height);
|
response.block_size = response.block_weight = m_core.get_blockchain_storage().get_db().get_block_weight(height);
|
||||||
response.num_txes = blk.tx_hashes.size();
|
response.num_txes = blk.tx_hashes.size();
|
||||||
response.pow_hash = fill_pow_hash ? string_tools::pod_to_hex(get_block_longhash(blk, height)) : "";
|
response.pow_hash = fill_pow_hash ? string_tools::pod_to_hex(get_block_longhash(&(m_core.get_blockchain_storage()), blk, height, 0)) : "";
|
||||||
response.long_term_weight = m_core.get_blockchain_storage().get_db().get_block_long_term_weight(height);
|
response.long_term_weight = m_core.get_blockchain_storage().get_db().get_block_long_term_weight(height);
|
||||||
response.miner_tx_hash = string_tools::pod_to_hex(cryptonote::get_transaction_hash(blk.miner_tx));
|
response.miner_tx_hash = string_tools::pod_to_hex(cryptonote::get_transaction_hash(blk.miner_tx));
|
||||||
return true;
|
return true;
|
||||||
|
@ -84,7 +84,7 @@ namespace cryptonote
|
|||||||
// advance which version they will stop working with
|
// advance which version they will stop working with
|
||||||
// Don't go over 32767 for any of these
|
// Don't go over 32767 for any of these
|
||||||
#define CORE_RPC_VERSION_MAJOR 2
|
#define CORE_RPC_VERSION_MAJOR 2
|
||||||
#define CORE_RPC_VERSION_MINOR 6
|
#define CORE_RPC_VERSION_MINOR 7
|
||||||
#define MAKE_CORE_RPC_VERSION(major,minor) (((major)<<16)|(minor))
|
#define MAKE_CORE_RPC_VERSION(major,minor) (((major)<<16)|(minor))
|
||||||
#define CORE_RPC_VERSION MAKE_CORE_RPC_VERSION(CORE_RPC_VERSION_MAJOR, CORE_RPC_VERSION_MINOR)
|
#define CORE_RPC_VERSION MAKE_CORE_RPC_VERSION(CORE_RPC_VERSION_MAJOR, CORE_RPC_VERSION_MINOR)
|
||||||
|
|
||||||
@ -937,6 +937,8 @@ namespace cryptonote
|
|||||||
uint64_t reserved_offset;
|
uint64_t reserved_offset;
|
||||||
uint64_t expected_reward;
|
uint64_t expected_reward;
|
||||||
std::string prev_hash;
|
std::string prev_hash;
|
||||||
|
std::string seed_hash;
|
||||||
|
std::string next_seed_hash;
|
||||||
blobdata blocktemplate_blob;
|
blobdata blocktemplate_blob;
|
||||||
blobdata blockhashing_blob;
|
blobdata blockhashing_blob;
|
||||||
std::string status;
|
std::string status;
|
||||||
@ -954,6 +956,8 @@ namespace cryptonote
|
|||||||
KV_SERIALIZE(blockhashing_blob)
|
KV_SERIALIZE(blockhashing_blob)
|
||||||
KV_SERIALIZE(status)
|
KV_SERIALIZE(status)
|
||||||
KV_SERIALIZE(untrusted)
|
KV_SERIALIZE(untrusted)
|
||||||
|
KV_SERIALIZE(seed_hash)
|
||||||
|
KV_SERIALIZE(next_seed_hash)
|
||||||
END_KV_SERIALIZE_MAP()
|
END_KV_SERIALIZE_MAP()
|
||||||
};
|
};
|
||||||
typedef epee::misc_utils::struct_init<response_t> response;
|
typedef epee::misc_utils::struct_init<response_t> response;
|
||||||
|
@ -209,7 +209,7 @@ bool tests::proxy_core::handle_incoming_block(const cryptonote::blobdata& block_
|
|||||||
crypto::hash lh;
|
crypto::hash lh;
|
||||||
cout << "BLOCK" << endl << endl;
|
cout << "BLOCK" << endl << endl;
|
||||||
cout << (h = get_block_hash(b)) << endl;
|
cout << (h = get_block_hash(b)) << endl;
|
||||||
cout << (lh = get_block_longhash(b, 0)) << endl;
|
cout << (lh = get_block_longhash(NULL, b, 0, 0)) << endl;
|
||||||
cout << get_transaction_hash(b.miner_tx) << endl;
|
cout << get_transaction_hash(b.miner_tx) << endl;
|
||||||
cout << ::get_object_blobsize(b.miner_tx) << endl;
|
cout << ::get_object_blobsize(b.miner_tx) << endl;
|
||||||
//cout << string_tools::buff_to_hex_nodelimer(block_blob) << endl;
|
//cout << string_tools::buff_to_hex_nodelimer(block_blob) << endl;
|
||||||
@ -236,7 +236,7 @@ void tests::proxy_core::get_blockchain_top(uint64_t& height, crypto::hash& top_i
|
|||||||
bool tests::proxy_core::init(const boost::program_options::variables_map& /*vm*/) {
|
bool tests::proxy_core::init(const boost::program_options::variables_map& /*vm*/) {
|
||||||
generate_genesis_block(m_genesis, config::GENESIS_TX, config::GENESIS_NONCE);
|
generate_genesis_block(m_genesis, config::GENESIS_TX, config::GENESIS_NONCE);
|
||||||
crypto::hash h = get_block_hash(m_genesis);
|
crypto::hash h = get_block_hash(m_genesis);
|
||||||
add_block(h, get_block_longhash(m_genesis, 0), m_genesis, block_to_blob(m_genesis));
|
add_block(h, get_block_longhash(NULL, m_genesis, 0, 0), m_genesis, block_to_blob(m_genesis));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -186,7 +186,7 @@ bool test_generator::construct_block(cryptonote::block& blk, uint64_t height, co
|
|||||||
|
|
||||||
// Nonce search...
|
// Nonce search...
|
||||||
blk.nonce = 0;
|
blk.nonce = 0;
|
||||||
while (!miner::find_nonce_for_given_block(blk, get_test_difficulty(hf_ver), height))
|
while (!miner::find_nonce_for_given_block(NULL, blk, get_test_difficulty(hf_ver), height))
|
||||||
blk.timestamp++;
|
blk.timestamp++;
|
||||||
|
|
||||||
add_block(blk, txs_weight, block_weights, already_generated_coins, hf_ver ? hf_ver.get() : 1);
|
add_block(blk, txs_weight, block_weights, already_generated_coins, hf_ver ? hf_ver.get() : 1);
|
||||||
@ -796,7 +796,7 @@ void fill_tx_sources_and_destinations(const std::vector<test_event_entry>& event
|
|||||||
void fill_nonce(cryptonote::block& blk, const difficulty_type& diffic, uint64_t height)
|
void fill_nonce(cryptonote::block& blk, const difficulty_type& diffic, uint64_t height)
|
||||||
{
|
{
|
||||||
blk.nonce = 0;
|
blk.nonce = 0;
|
||||||
while (!miner::find_nonce_for_given_block(blk, diffic, height))
|
while (!miner::find_nonce_for_given_block(NULL, blk, diffic, height))
|
||||||
blk.timestamp++;
|
blk.timestamp++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user