aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHoward Chu <highlandsun@gmail.com>2019-10-01 02:43:00 -0700
committerHoward Chu <hyc@symas.com>2019-10-03 20:05:17 +0100
commit1c600a492ff8670bf354b4418820950230115bfa (patch)
tree4c08bb011f3fa19405b3c4ec1b1d7bfc8b1ebf7e
parentMerge pull request #5939 (diff)
downloadmonero-1c600a492ff8670bf354b4418820950230115bfa.tar.xz
Fix randomx cache selection for RPCs
Was using the wrong cache slot, and returning invalid PoW hashes to RPC clients
-rw-r--r--src/crypto/rx-slow-hash.c40
1 files changed, 28 insertions, 12 deletions
diff --git a/src/crypto/rx-slow-hash.c b/src/crypto/rx-slow-hash.c
index ada372864..6d2f50016 100644
--- a/src/crypto/rx-slow-hash.c
+++ b/src/crypto/rx-slow-hash.c
@@ -50,7 +50,7 @@
typedef struct rx_state {
CTHR_MUTEX_TYPE rs_mutex;
- char rs_hash[32];
+ char rs_hash[HASH_SIZE];
uint64_t rs_height;
randomx_cache *rs_cache;
} rx_state;
@@ -63,7 +63,8 @@ static rx_state rx_s[2] = {{CTHR_MUTEX_INIT,{0},0,0},{CTHR_MUTEX_INIT,{0},0,0}};
static randomx_dataset *rx_dataset;
static uint64_t rx_dataset_height;
static THREADV randomx_vm *rx_vm = NULL;
-static THREADV int rx_toggle;
+static THREADV int rx_toggle = -1;
+static THREADV char rx_seedhash[HASH_SIZE];
static void local_abort(const char *msg)
{
@@ -234,21 +235,25 @@ void rx_slow_hash(const uint64_t mainheight, const uint64_t seedheight, const ch
char *hash, int miners, int is_alt) {
uint64_t s_height = rx_seedheight(mainheight);
int changed = 0;
- int toggle = is_alt ? s_height : seedheight;
+ int toggle = (s_height & SEEDHASH_EPOCH_BLOCKS) != 0;
randomx_flags flags = RANDOMX_FLAG_DEFAULT;
rx_state *rx_sp;
randomx_cache *cache;
- toggle = (toggle & SEEDHASH_EPOCH_BLOCKS) != 0;
CTHR_MUTEX_LOCK(rx_mutex);
/* if alt block but with same seed as mainchain, no need for alt cache */
- if (is_alt && s_height == seedheight && !memcmp(rx_s[toggle].rs_hash, seedhash, sizeof(rx_s[toggle].rs_hash)))
- is_alt = 0;
-
+ if (is_alt) {
+ if (s_height == seedheight && !memcmp(rx_s[toggle].rs_hash, seedhash, HASH_SIZE))
+ is_alt = 0;
+ } else {
/* RPC could request an earlier block on mainchain */
- if (!is_alt && s_height > seedheight)
- is_alt = 1;
+ if (s_height > seedheight)
+ is_alt = 1;
+ /* miner can be ahead of mainchain */
+ else if (s_height < seedheight)
+ toggle ^= 1;
+ }
toggle ^= (is_alt != 0);
if (toggle != rx_toggle)
@@ -273,13 +278,16 @@ void rx_slow_hash(const uint64_t mainheight, const uint64_t seedheight, const ch
local_abort("Couldn't allocate RandomX cache");
}
}
- if (rx_sp->rs_height != seedheight || rx_sp->rs_cache == NULL || memcmp(seedhash, rx_sp->rs_hash, sizeof(rx_sp->rs_hash))) {
- randomx_init_cache(cache, seedhash, 32);
+ if (rx_sp->rs_height != seedheight || rx_sp->rs_cache == NULL || memcmp(seedhash, rx_sp->rs_hash, HASH_SIZE)) {
+ randomx_init_cache(cache, seedhash, HASH_SIZE);
rx_sp->rs_cache = cache;
rx_sp->rs_height = seedheight;
- memcpy(rx_sp->rs_hash, seedhash, sizeof(rx_sp->rs_hash));
+ memcpy(rx_sp->rs_hash, seedhash, HASH_SIZE);
changed = 1;
}
+ /* only non-miners use rx_seedhash */
+ if (!miners && !changed && memcmp(seedhash, rx_seedhash, HASH_SIZE))
+ changed = 1;
if (rx_vm == NULL) {
randomx_flags flags = RANDOMX_FLAG_DEFAULT;
if (use_rx_jit()) {
@@ -307,6 +315,9 @@ void rx_slow_hash(const uint64_t mainheight, const uint64_t seedheight, const ch
mwarning(RX_LOGCAT, "Couldn't allocate RandomX dataset for miner");
}
CTHR_MUTEX_UNLOCK(rx_dataset_mutex);
+ } else {
+ /* only non-miners use rx_seedhash */
+ memcpy(rx_seedhash, seedhash, HASH_SIZE);
}
rx_vm = randomx_create_vm(flags | RANDOMX_FLAG_LARGE_PAGES, rx_sp->rs_cache, rx_dataset);
if(rx_vm == NULL) { //large pages failed
@@ -326,6 +337,11 @@ void rx_slow_hash(const uint64_t mainheight, const uint64_t seedheight, const ch
CTHR_MUTEX_UNLOCK(rx_dataset_mutex);
} else if (changed) {
randomx_vm_set_cache(rx_vm, rx_sp->rs_cache);
+ /* remember the seedhash being used by the current VM. Other threads may set
+ * rx_sp->rs_cache to the correct value, but we still have to know if the
+ * current rx_vm has been set to use it or not.
+ */
+ memcpy(rx_seedhash, seedhash, HASH_SIZE);
}
/* mainchain users can run in parallel */
if (!is_alt)