perf(miner): optimize sha256d nonce loop with precomputed blocks
This commit is contained in:
68
miner.c
68
miner.c
@@ -8,6 +8,8 @@
|
||||
|
||||
#include "utils.h"
|
||||
|
||||
static const double RATE_INTERVAL_SEC = 5.0;
|
||||
|
||||
static int hash_meets_target(const uint8_t digest[32], const uint8_t target_be[32]) {
|
||||
int i;
|
||||
|
||||
@@ -24,6 +26,21 @@ static int hash_meets_target(const uint8_t digest[32], const uint8_t target_be[3
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void write_u32_be(uint8_t *dst, uint32_t v) {
|
||||
dst[0] = (uint8_t)((v >> 24) & 0xFF);
|
||||
dst[1] = (uint8_t)((v >> 16) & 0xFF);
|
||||
dst[2] = (uint8_t)((v >> 8) & 0xFF);
|
||||
dst[3] = (uint8_t)(v & 0xFF);
|
||||
}
|
||||
|
||||
static void sha256_ctx_to_digest(const SHA256_CTX *ctx, uint8_t out[32]) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
write_u32_be(out + i * 4, ctx->h[i]);
|
||||
}
|
||||
}
|
||||
|
||||
static int compute_hash_batch(
|
||||
const uint8_t header_76[76],
|
||||
uint32_t start_nonce,
|
||||
@@ -32,30 +49,47 @@ static int compute_hash_batch(
|
||||
uint32_t *found_nonce,
|
||||
uint8_t found_digest[32]
|
||||
) {
|
||||
SHA256_CTX base;
|
||||
uint8_t tail[16];
|
||||
SHA256_CTX init_ctx;
|
||||
SHA256_CTX first_chunk_ctx;
|
||||
uint8_t block1[64];
|
||||
uint8_t block2[64];
|
||||
uint8_t digest1[32];
|
||||
uint8_t digest2[32];
|
||||
uint32_t i;
|
||||
|
||||
SHA256_Init(&base);
|
||||
SHA256_Update(&base, header_76, 64);
|
||||
SHA256_Init(&init_ctx);
|
||||
first_chunk_ctx = init_ctx;
|
||||
SHA256_Transform(&first_chunk_ctx, header_76);
|
||||
|
||||
memcpy(tail, header_76 + 64, 12);
|
||||
memset(block1, 0, sizeof(block1));
|
||||
memcpy(block1, header_76 + 64, 12);
|
||||
block1[16] = 0x80;
|
||||
block1[62] = 0x02;
|
||||
block1[63] = 0x80;
|
||||
|
||||
memset(block2, 0, sizeof(block2));
|
||||
block2[32] = 0x80;
|
||||
block2[62] = 0x01;
|
||||
block2[63] = 0x00;
|
||||
|
||||
for (i = 0; i < batch_size; i++) {
|
||||
SHA256_CTX ctx;
|
||||
uint8_t digest1[32];
|
||||
uint8_t digest2[32];
|
||||
SHA256_CTX ctx1;
|
||||
SHA256_CTX ctx2;
|
||||
uint32_t n = start_nonce + i;
|
||||
|
||||
tail[12] = (uint8_t)(n & 0xFF);
|
||||
tail[13] = (uint8_t)((n >> 8) & 0xFF);
|
||||
tail[14] = (uint8_t)((n >> 16) & 0xFF);
|
||||
tail[15] = (uint8_t)((n >> 24) & 0xFF);
|
||||
block1[12] = (uint8_t)(n & 0xFF);
|
||||
block1[13] = (uint8_t)((n >> 8) & 0xFF);
|
||||
block1[14] = (uint8_t)((n >> 16) & 0xFF);
|
||||
block1[15] = (uint8_t)((n >> 24) & 0xFF);
|
||||
|
||||
ctx = base;
|
||||
SHA256_Update(&ctx, tail, 16);
|
||||
SHA256_Final(digest1, &ctx);
|
||||
SHA256(digest1, 32, digest2);
|
||||
ctx1 = first_chunk_ctx;
|
||||
SHA256_Transform(&ctx1, block1);
|
||||
sha256_ctx_to_digest(&ctx1, digest1);
|
||||
|
||||
memcpy(block2, digest1, 32);
|
||||
ctx2 = init_ctx;
|
||||
SHA256_Transform(&ctx2, block2);
|
||||
sha256_ctx_to_digest(&ctx2, digest2);
|
||||
|
||||
if (hash_meets_target(digest2, target_be)) {
|
||||
*found_nonce = n;
|
||||
@@ -149,7 +183,7 @@ int mine_block(
|
||||
nonce += batch_size;
|
||||
|
||||
now = (double)time(NULL);
|
||||
if ((now - last_rate_t) >= 2.0) {
|
||||
if ((now - last_rate_t) >= RATE_INTERVAL_SEC) {
|
||||
double dt = now - last_rate_t;
|
||||
if (dt <= 0.0) {
|
||||
dt = 1e-6;
|
||||
|
||||
Reference in New Issue
Block a user