diff --git a/src/Makefile.am b/src/Makefile.am index 7f1c40b..e5ea940 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -750,7 +750,7 @@ vexta_cli_LDADD = \ $(LIBVEXTA_UTIL) \ $(LIBVEXTA_CRYPTO) -vexta_cli_LDADD += $(BOOST_LIBS) $(EVENT_LIBS) +vexta_cli_LDADD += $(BOOST_LIBS) $(EVENT_LIBS) $(RANDOMX_LIBS) # # digibyte-tx binary # @@ -772,7 +772,7 @@ vexta_tx_LDADD = \ $(LIBVEXTA_CRYPTO) \ $(LIBSECP256K1) -vexta_tx_LDADD += $(BOOST_LIBS) +vexta_tx_LDADD += $(BOOST_LIBS) $(RANDOMX_LIBS) # # digibyte-wallet binary # @@ -806,7 +806,7 @@ vexta_util_LDADD = \ $(LIBVEXTA_CRYPTO) \ $(LIBSECP256K1) -vexta_util_LDADD += $(BOOST_LIBS) +vexta_util_LDADD += $(BOOST_LIBS) $(RANDOMX_LIBS) # # vextaconsensus library # @@ -844,7 +844,7 @@ if GLIBC_BACK_COMPAT endif libvextaconsensus_la_LDFLAGS = $(AM_LDFLAGS) -no-undefined $(RELDFLAGS) -libvextaconsensus_la_LIBADD = $(LIBSECP256K1) +libvextaconsensus_la_LIBADD = $(LIBSECP256K1) $(RANDOMX_LIBS) libvextaconsensus_la_CPPFLAGS = $(AM_CPPFLAGS) -I$(builddir)/obj -I$(srcdir)/secp256k1/include -I$(srcdir)/crypto/pq/mldsa65 -I$(srcdir)/crypto/pq/sphincsplus -DDILITHIUM_MODE=3 -DPARAMS=sphincs-sha2-128s -DVEXTA_PQ_VERIFY_ONLY -DBUILD_VEXTA_INTERNAL libvextaconsensus_la_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) libvextaconsensus_la_CFLAGS = $(AM_CFLAGS) $(PIE_FLAGS) diff --git a/src/Makefile.bench.include b/src/Makefile.bench.include index 4c69137..3f7ff29 100644 --- a/src/Makefile.bench.include +++ b/src/Makefile.bench.include @@ -65,7 +65,8 @@ bench_bench_vexta_LDADD = \ $(LIBSECP256K1) \ $(LIBUNIVALUE) \ $(EVENT_PTHREADS_LIBS) \ - $(EVENT_LIBS) + $(EVENT_LIBS) \ + $(RANDOMX_LIBS) if ENABLE_ZMQ bench_bench_vexta_LDADD += $(LIBVEXTA_ZMQ) $(ZMQ_LIBS) diff --git a/src/Makefile.qt.include b/src/Makefile.qt.include index fe4784b..3e5a5bf 100644 --- a/src/Makefile.qt.include +++ b/src/Makefile.qt.include @@ -333,7 +333,7 @@ vexta_qt_ldadd += $(LIBVEXTA_ZMQ) $(ZMQ_LIBS) endif vexta_qt_ldadd += $(LIBVEXTA_CLI) $(LIBVEXTA_COMMON) $(LIBVEXTA_UTIL) $(LIBVEXTA_CONSENSUS) $(LIBVEXTA_PQ) $(LIBVEXTA_CRYPTO) $(LIBUNIVALUE) $(LIBLEVELDB) $(LIBLEVELDB_SSE42) $(LIBMEMENV) \ $(BOOST_LIBS) $(QT_LIBS) $(QT_DBUS_LIBS) $(QR_LIBS) $(BDB_LIBS) $(MINIUPNPC_LIBS) $(NATPMP_LIBS) $(LIBSECP256K1) \ - $(EVENT_PTHREADS_LIBS) $(EVENT_LIBS) $(SQLITE_LIBS) + $(EVENT_PTHREADS_LIBS) $(EVENT_LIBS) $(SQLITE_LIBS) $(RANDOMX_LIBS) vexta_qt_ldflags = $(RELDFLAGS) $(AM_LDFLAGS) $(QT_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) $(PTHREAD_FLAGS) vexta_qt_libtoolflags = $(AM_LIBTOOLFLAGS) --tag CXX diff --git a/src/Makefile.test.include b/src/Makefile.test.include index 63c1ba7..dc39dff 100644 --- a/src/Makefile.test.include +++ b/src/Makefile.test.include @@ -51,7 +51,8 @@ FUZZ_SUITE_LD_COMMON = \ $(LIBMEMENV) \ $(LIBSECP256K1) \ $(EVENT_LIBS) \ - $(EVENT_PTHREADS_LIBS) + $(EVENT_PTHREADS_LIBS) \ + $(RANDOMX_LIBS) if USE_UPNP FUZZ_SUITE_LD_COMMON += $(MINIUPNPC_LIBS) @@ -188,7 +189,7 @@ test_test_digibyte_LDADD += $(LIBVEXTA_SERVER) $(LIBVEXTA_CLI) $(LIBVEXTA_COMMON $(LIBLEVELDB) $(LIBLEVELDB_SSE42) $(LIBMEMENV) $(BOOST_LIBS) $(BOOST_UNIT_TEST_FRAMEWORK_LIB) $(LIBSECP256K1) $(EVENT_LIBS) $(EVENT_PTHREADS_LIBS) test_test_digibyte_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) -test_test_digibyte_LDADD += $(BDB_LIBS) $(MINIUPNPC_LIBS) $(NATPMP_LIBS) $(SQLITE_LIBS) +test_test_digibyte_LDADD += $(BDB_LIBS) $(MINIUPNPC_LIBS) $(NATPMP_LIBS) $(SQLITE_LIBS) $(RANDOMX_LIBS) test_test_digibyte_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) $(PTHREAD_FLAGS) -static if ENABLE_ZMQ diff --git a/src/primitives/block.cpp b/src/primitives/block.cpp index 714ea4e..7a19fa3 100644 --- a/src/primitives/block.cpp +++ b/src/primitives/block.cpp @@ -5,11 +5,14 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include +#include #include #include #include #include +#include #include +#include #include uint256 CBlockHeader::GetHash() const @@ -36,6 +39,25 @@ uint256 CBlockHeader::GetPoWAlgoHash(const Consensus::Params& params) const return GetHash(); } +uint256 CBlockHeader::GetRandomXPoWHash(const uint256& seed) const +{ + CDataStream stream(SER_GETHASH, PROTOCOL_VERSION); + stream << *this; + + uint256 result; + + if (!VextaRandomXHash( + stream.data(), + stream.size(), + seed.data(), + seed.size(), + result.begin())) { + result.SetNull(); + } + + return result; +} + std::string CBlock::ToString(const Consensus::Params& params) const { std::stringstream s; diff --git a/src/primitives/block.h b/src/primitives/block.h index cb863c7..6bdb9e5 100644 --- a/src/primitives/block.h +++ b/src/primitives/block.h @@ -96,6 +96,14 @@ public: uint256 GetPoWAlgoHash(const Consensus::Params& params) const; + /** + * Calculate the RandomX proof-of-work hash using an explicit seed key. + * + * The input is the canonical serialized 80-byte block header. + * The seed is supplied in raw uint256 serialization byte order. + */ + uint256 GetRandomXPoWHash(const uint256& seed) const; + int64_t GetBlockTime() const { return (int64_t)nTime; diff --git a/src/test/pow_tests.cpp b/src/test/pow_tests.cpp index 29a4ce8..7a0f6e6 100644 --- a/src/test/pow_tests.cpp +++ b/src/test/pow_tests.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #include #include @@ -558,4 +559,47 @@ BOOST_AUTO_TEST_CASE(RandomX_seed_height_test) BOOST_CHECK_EQUAL(GetRandomXSeedHeight(128, consensus), 120); } + +BOOST_AUTO_TEST_CASE(RandomX_header_hash_vector_test) +{ + CBlockHeader header; + header.nVersion = BLOCK_VERSION_DEFAULT | BLOCK_VERSION_RANDOMX; + header.hashPrevBlock = uint256S("000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"); + header.hashMerkleRoot = uint256S("f0e0d0c0b0a090807060504030201000ffeeddccbbaa99887766554433221100"); + header.nTime = 0x12345678; + header.nBits = 0x1d00ffff; + header.nNonce = 0x89abcdef; + + const uint256 seed = + uint256S("00112233445566778899aabbccddeeff102132435465768798a9bacbdcedfe0f"); + + CDataStream stream(SER_GETHASH, PROTOCOL_VERSION); + stream << header; + + BOOST_REQUIRE_EQUAL(stream.size(), 80U); + + const std::vector headerBytes(stream.begin(), stream.end()); + const std::vector seedBytes(seed.begin(), seed.end()); + + BOOST_CHECK_EQUAL( + HexStr(headerBytes), + "020400001f1e1d1c1b1a191817161514131211100f0e0d0c0b0a0908070605040302010000112233445566778899aabbccddeeff00102030405060708090a0b0c0d0e0f078563412ffff001defcdab89"); + + BOOST_CHECK_EQUAL( + HexStr(seedBytes), + "0ffeeddccbbaa9988776655443322110ffeeddccbbaa99887766554433221100"); + + const uint256 randomXHash = header.GetRandomXPoWHash(seed); + + BOOST_CHECK_EQUAL( + randomXHash.ToString(), + "a694ce64be1245187466b2027afceb32c99b57bd21164dec2913b390f68c653c"); + + const std::vector hashBytes(randomXHash.begin(), randomXHash.end()); + + BOOST_CHECK_EQUAL( + HexStr(hashBytes), + "3c658cf690b31329ec4d1621bd579bc932ebfc7a02b26674184512be64ce94a6"); +} + BOOST_AUTO_TEST_SUITE_END()