Просмотр исходного кода

Preserve floating point state when calling randomx_calculate_hash

tevador 6 лет назад
Родитель
Сommit
6a764e90d0
3 измененных файлов с 18 добавлено и 0 удалено
  1. 4 0
      src/randomx.cpp
  2. 2 0
      src/randomx.h
  3. 12 0
      src/tests/tests.cpp

+ 4 - 0
src/randomx.cpp

@@ -36,6 +36,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include "cpu.hpp"
 #include <cassert>
 #include <limits>
+#include <cfenv>
 
 extern "C" {
 
@@ -349,6 +350,8 @@ extern "C" {
 		assert(machine != nullptr);
 		assert(inputSize == 0 || input != nullptr);
 		assert(output != nullptr);
+		fenv_t fpstate;
+		fegetenv(&fpstate);
 		alignas(16) uint64_t tempHash[8];
 		int blakeResult = blake2b(tempHash, sizeof(tempHash), input, inputSize, nullptr, 0);
 		assert(blakeResult == 0);
@@ -361,6 +364,7 @@ extern "C" {
 		}
 		machine->run(&tempHash);
 		machine->getFinalResult(output, RANDOMX_HASH_SIZE);
+		fesetenv(&fpstate);
 	}
 
 	void randomx_calculate_hash_first(randomx_vm* machine, const void* input, size_t inputSize) {

+ 2 - 0
src/randomx.h

@@ -246,6 +246,8 @@ RANDOMX_EXPORT void randomx_calculate_hash(randomx_vm *machine, const void *inpu
  *                              and begin the calculation of the next hash.
  * randomx_calculate_hash_last  will output the hash value of the previous input.
  *
+ * WARNING: These functions may alter the floating point rounding mode of the calling thread.
+ *
  * @param machine is a pointer to a randomx_vm structure. Must not be NULL.
  * @param input is a pointer to memory to be hashed. Must not be NULL.
  * @param inputSize is the number of bytes to be hashed.

+ 12 - 0
src/tests/tests.cpp

@@ -4,6 +4,7 @@
 
 #include <cassert>
 #include <iomanip>
+#include <cfenv>
 #include "utility.hpp"
 #include "../bytecode_machine.hpp"
 #include "../dataset.hpp"
@@ -1051,6 +1052,10 @@ int main() {
 		assert(cacheMemory[33554431] == 0x1f47f056d05cd99b);
 	});
 
+	if (cache != nullptr)
+		randomx_release_cache(cache);
+	cache = randomx_alloc_cache(RANDOMX_FLAG_DEFAULT);
+
 	runTest("Hash batch test", RANDOMX_HAVE_COMPILER && stringsEqual(RANDOMX_ARGON_SALT, "RandomX\x03"), []() {
 		char hash1[RANDOMX_HASH_SIZE];
 		char hash2[RANDOMX_HASH_SIZE];
@@ -1070,6 +1075,13 @@ int main() {
 		assert(equalsHex(hash3, "c36d4ed4191e617309867ed66a443be4075014e2b061bcdaf9ce7b721d2b77a8"));
 	});
 
+	runTest("Preserve rounding mode", RANDOMX_FREQ_CFROUND > 0, []() {
+		fesetround(FE_TONEAREST);
+		char hash[RANDOMX_HASH_SIZE];
+		calcStringHash("test key 000", "Lorem ipsum dolor sit amet", &hash);
+		assert(fegetround() == FE_TONEAREST);
+	});
+
 	randomx_destroy_vm(vm);
 	vm = nullptr;