From 51d617e70f90a972185917ea0096c1ecef2bfa8b Mon Sep 17 00:00:00 2001 From: Bitflash-sh Date: Fri, 24 Jul 2026 11:18:11 -0300 Subject: Bitflash: fair-launch release Satoshi's bitcoin-0.1.0 reborn with RandomX CPU proof of work, anonymous .btf addressing over Nostr with CGNAT rendezvous, automatic peer discovery, a headless Linux node, and Windows GUI wallet. Fair launch, no premine, 21M cap. --- src/randomx_pow.cpp | 143 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 143 insertions(+) create mode 100644 src/randomx_pow.cpp (limited to 'src/randomx_pow.cpp') diff --git a/src/randomx_pow.cpp b/src/randomx_pow.cpp new file mode 100644 index 0000000..17bf455 --- /dev/null +++ b/src/randomx_pow.cpp @@ -0,0 +1,143 @@ +// Copyright (c) 2026 Bitflash developers +// Distributed under the MIT/X11 software license. +// +// RandomX PoW implementation. See randomx_pow.h. + +#include "headers.h" +#include +#include +#include + +// Fixed key (seed) that determines the RandomX cache/dataset. Keeping it +// constant avoids per-epoch "reseed" logic; for the CPU+RAM fairness goal +// this is sufficient (RandomX already neutralizes GPU/ASIC by design). +static const char* RANDOMX_KEY = "Bitflash/RandomX/v1/one-cpu-one-vote"; + +static randomx_flags g_flags = RANDOMX_FLAG_DEFAULT; +static randomx_cache* g_cache = NULL; +static randomx_dataset* g_dataset = NULL; +static randomx_vm* g_vmVerify = NULL; +static CCriticalSection g_csVerify; +static bool g_fInit = false; +static bool g_fFast = false; + + +bool RandomXInit() +{ + if (g_fInit) + return true; + + // Detect the best flags for this CPU (JIT, hardware AES, Argon2). + g_flags = randomx_get_flags(); + + g_cache = randomx_alloc_cache(g_flags); + if (!g_cache) + { + // Try without JIT as a fallback + g_flags = RANDOMX_FLAG_DEFAULT; + g_cache = randomx_alloc_cache(g_flags); + if (!g_cache) + return error("RandomX: failed to allocate cache (256 MB)"); + } + randomx_init_cache(g_cache, RANDOMX_KEY, strlen(RANDOMX_KEY)); + + // Verification VM in light mode (cache only) + g_vmVerify = randomx_create_vm(g_flags, g_cache, NULL); + if (!g_vmVerify) + return error("RandomX: failed to create verification VM"); + + g_fInit = true; + printf("RandomX: initialized (cache 256 MB, flags=%d)\n", (int)g_flags); + return true; +} + + +bool RandomXInitDataset(int nThreads) +{ + if (!g_fInit && !RandomXInit()) + return false; + if (g_fFast) + return true; + + randomx_flags fastFlags = (randomx_flags)(g_flags | RANDOMX_FLAG_FULL_MEM); + g_dataset = randomx_alloc_dataset(fastFlags); + if (!g_dataset) + { + printf("RandomX: not enough memory for the 2 GB dataset, staying in light mode\n"); + return false; + } + + unsigned long total = randomx_dataset_item_count(); + if (nThreads < 1) nThreads = 1; + printf("RandomX: initializing ~2 GB dataset with %d threads...\n", nThreads); + + std::vector workers; + unsigned long per = total / nThreads; + for (int i = 0; i < nThreads; i++) + { + unsigned long start = i * per; + unsigned long count = (i == nThreads - 1) ? (total - start) : per; + workers.emplace_back([start, count]() { + randomx_init_dataset(g_dataset, g_cache, start, count); + }); + } + for (auto& w : workers) w.join(); + + g_fFast = true; + printf("RandomX: dataset ready (fast mode active)\n"); + return true; +} + + +bool RandomXFastReady() +{ + return g_fFast; +} + + +uint256 RandomXPoWHash(const void* pHeader, size_t nSize) +{ + uint256 result = 0; + if (!g_fInit && !RandomXInit()) + return result; + CRITICAL_BLOCK(g_csVerify) + { + unsigned char hash[RANDOMX_HASH_SIZE]; + randomx_calculate_hash(g_vmVerify, pHeader, nSize, hash); + memcpy(&result, hash, RANDOMX_HASH_SIZE); + } + return result; +} + + +void* RandomXCreateMinerVM() +{ + if (!g_fInit && !RandomXInit()) + return NULL; + if (g_fFast && g_dataset) + { + randomx_flags fastFlags = (randomx_flags)(g_flags | RANDOMX_FLAG_FULL_MEM); + return randomx_create_vm(fastFlags, NULL, g_dataset); + } + // Light mode: own VM sharing the cache + return randomx_create_vm(g_flags, g_cache, NULL); +} + + +void RandomXDestroyMinerVM(void* vm) +{ + if (vm) + randomx_destroy_vm((randomx_vm*)vm); +} + + +uint256 RandomXHashWithVM(void* vm, const void* pHeader, size_t nSize) +{ + uint256 result = 0; + if (!vm) + return result; + unsigned char hash[RANDOMX_HASH_SIZE]; + randomx_calculate_hash((randomx_vm*)vm, pHeader, nSize, hash); + memcpy(&result, hash, RANDOMX_HASH_SIZE); + return result; +} -- cgit v1.2.3