diff --git a/external/randomx b/external/randomx
index 519b9cf70..298cc7709 160000
--- a/external/randomx
+++ b/external/randomx
@@ -1 +1 @@
-Subproject commit 519b9cf70540bdd996e806251cde335c8eef8aca
+Subproject commit 298cc77095c8992e30ecdd4ca0aa09a969a62bc1
diff --git a/src/crypto/rx-slow-hash.c b/src/crypto/rx-slow-hash.c
index ada372864..59bd89d13 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,6 @@ 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 void local_abort(const char *msg)
 {
@@ -162,8 +161,11 @@ 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)
+    if (split_height <= rx_s[i].rs_height) {
+      if (rx_s[i].rs_height == rx_dataset_height)
+        rx_dataset_height = 1;
       rx_s[i].rs_height = 1;	/* set to an invalid seed height */
+    }
   }
   CTHR_MUTEX_UNLOCK(rx_mutex);
 }
@@ -233,27 +235,27 @@ static void rx_initdata(randomx_cache *rs_cache, const int miners, const uint64_
 void rx_slow_hash(const uint64_t mainheight, const uint64_t seedheight, const char *seedhash, const void *data, size_t length,
   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)
-    changed = 1;
-  rx_toggle = toggle;
 
   rx_sp = &rx_s[toggle];
   CTHR_MUTEX_LOCK(rx_sp->rs_mutex);
@@ -273,12 +275,11 @@ 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));
-    changed = 1;
+    memcpy(rx_sp->rs_hash, seedhash, HASH_SIZE);
   }
   if (rx_vm == NULL) {
     randomx_flags flags = RANDOMX_FLAG_DEFAULT;
@@ -324,7 +325,8 @@ void rx_slow_hash(const uint64_t mainheight, const uint64_t seedheight, const ch
     if (rx_dataset != NULL && rx_dataset_height != seedheight)
       rx_initdata(cache, miners, seedheight);
     CTHR_MUTEX_UNLOCK(rx_dataset_mutex);
-  } else if (changed) {
+  } else {
+    /* this is a no-op if the cache hasn't changed */
     randomx_vm_set_cache(rx_vm, rx_sp->rs_cache);
   }
   /* mainchain users can run in parallel */