diff options
author | Howard Chu <highlandsun@gmail.com> | 2019-10-01 02:43:00 -0700 |
---|---|---|
committer | Howard Chu <hyc@symas.com> | 2019-10-03 20:05:17 +0100 |
commit | 1c600a492ff8670bf354b4418820950230115bfa (patch) | |
tree | 4c08bb011f3fa19405b3c4ec1b1d7bfc8b1ebf7e | |
parent | Merge pull request #5939 (diff) | |
download | monero-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.c | 40 |
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) |