perf(miner): route nonce scanning through sha256d80_scan_4way
This commit is contained in:
145
miner.c
145
miner.c
@@ -1,99 +1,103 @@
|
||||
#include "miner.h"
|
||||
|
||||
#include <openssl/sha.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "sha256/sha256_backend.h"
|
||||
#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;
|
||||
|
||||
for (i = 0; i < 32; i++) {
|
||||
uint8_t hb = digest[31 - i];
|
||||
if (hb < target_be[i]) {
|
||||
return 1;
|
||||
}
|
||||
if (hb > target_be[i]) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
static inline uint32_t load_u32_be(const uint8_t *p) {
|
||||
return ((uint32_t)p[0] << 24) |
|
||||
((uint32_t)p[1] << 16) |
|
||||
((uint32_t)p[2] << 8) |
|
||||
(uint32_t)p[3];
|
||||
}
|
||||
|
||||
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]) {
|
||||
static void target_words_from_be(const uint8_t target_be[32], uint32_t out[8]) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
write_u32_be(out + i * 4, ctx->h[i]);
|
||||
out[i] = load_u32_be(target_be + i * 4);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void write_u32_le(uint8_t *dst, uint32_t v) {
|
||||
dst[0] = (uint8_t)(v & 0xFFU);
|
||||
dst[1] = (uint8_t)((v >> 8) & 0xFFU);
|
||||
dst[2] = (uint8_t)((v >> 16) & 0xFFU);
|
||||
dst[3] = (uint8_t)((v >> 24) & 0xFFU);
|
||||
}
|
||||
|
||||
static int compute_hash_batch(
|
||||
const uint8_t header_76[76],
|
||||
uint32_t start_nonce,
|
||||
uint32_t batch_size,
|
||||
const uint8_t target_be[32],
|
||||
const uint32_t target_words[8],
|
||||
uint32_t *found_nonce,
|
||||
uint8_t found_digest[32]
|
||||
) {
|
||||
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;
|
||||
sha256d80_midstate_t mid;
|
||||
uint32_t i = 0;
|
||||
sha256d80_midstate_init(&mid, header_76);
|
||||
|
||||
SHA256_Init(&init_ctx);
|
||||
first_chunk_ctx = init_ctx;
|
||||
SHA256_Transform(&first_chunk_ctx, header_76);
|
||||
while ((batch_size - i) >= 4U) {
|
||||
uint32_t n0 = start_nonce + i;
|
||||
sha256_state_t st1[4];
|
||||
uint32_t mask = sha256d80_scan_4way(&mid, n0, target_words, st1);
|
||||
|
||||
memset(block1, 0, sizeof(block1));
|
||||
memcpy(block1, header_76 + 64, 12);
|
||||
block1[16] = 0x80;
|
||||
block1[62] = 0x02;
|
||||
block1[63] = 0x80;
|
||||
if (mask & 1U) {
|
||||
*found_nonce = n0;
|
||||
sha256_state_to_digest(&st1[0], found_digest);
|
||||
return 1;
|
||||
}
|
||||
if (mask & 2U) {
|
||||
*found_nonce = n0 + 1U;
|
||||
sha256_state_to_digest(&st1[1], found_digest);
|
||||
return 1;
|
||||
}
|
||||
if (mask & 4U) {
|
||||
*found_nonce = n0 + 2U;
|
||||
sha256_state_to_digest(&st1[2], found_digest);
|
||||
return 1;
|
||||
}
|
||||
if (mask & 8U) {
|
||||
*found_nonce = n0 + 3U;
|
||||
sha256_state_to_digest(&st1[3], found_digest);
|
||||
return 1;
|
||||
}
|
||||
|
||||
memset(block2, 0, sizeof(block2));
|
||||
block2[32] = 0x80;
|
||||
block2[62] = 0x01;
|
||||
block2[63] = 0x00;
|
||||
i += 4U;
|
||||
}
|
||||
|
||||
for (i = 0; i < batch_size; i++) {
|
||||
SHA256_CTX ctx1;
|
||||
SHA256_CTX ctx2;
|
||||
uint32_t n = start_nonce + i;
|
||||
if (i < batch_size) {
|
||||
uint32_t n0 = start_nonce + i;
|
||||
uint32_t remain = batch_size - i;
|
||||
uint32_t valid_mask = (1U << remain) - 1U;
|
||||
sha256_state_t st1[4];
|
||||
uint32_t mask = sha256d80_scan_4way(&mid, n0, target_words, st1) & valid_mask;
|
||||
|
||||
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);
|
||||
|
||||
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;
|
||||
memcpy(found_digest, digest2, 32);
|
||||
if (mask & 1U) {
|
||||
*found_nonce = n0;
|
||||
sha256_state_to_digest(&st1[0], found_digest);
|
||||
return 1;
|
||||
}
|
||||
if (mask & 2U) {
|
||||
*found_nonce = n0 + 1U;
|
||||
sha256_state_to_digest(&st1[1], found_digest);
|
||||
return 1;
|
||||
}
|
||||
if (mask & 4U) {
|
||||
*found_nonce = n0 + 2U;
|
||||
sha256_state_to_digest(&st1[2], found_digest);
|
||||
return 1;
|
||||
}
|
||||
if (mask & 8U) {
|
||||
*found_nonce = n0 + 3U;
|
||||
sha256_state_to_digest(&st1[3], found_digest);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@@ -101,13 +105,6 @@ static int compute_hash_batch(
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void write_u32_le(uint8_t *dst, uint32_t v) {
|
||||
dst[0] = (uint8_t)(v & 0xFF);
|
||||
dst[1] = (uint8_t)((v >> 8) & 0xFF);
|
||||
dst[2] = (uint8_t)((v >> 16) & 0xFF);
|
||||
dst[3] = (uint8_t)((v >> 24) & 0xFF);
|
||||
}
|
||||
|
||||
int mine_block(
|
||||
uint8_t header_76[76],
|
||||
const char *target_hex,
|
||||
@@ -120,6 +117,7 @@ int mine_block(
|
||||
MineResult *out
|
||||
) {
|
||||
uint8_t target_be[32];
|
||||
uint32_t target_words[8];
|
||||
uint32_t nonce;
|
||||
long long attempts = 0;
|
||||
time_t t_start;
|
||||
@@ -133,6 +131,7 @@ int mine_block(
|
||||
fprintf(stderr, "[miner] target hex non valido\n");
|
||||
return 0;
|
||||
}
|
||||
target_words_from_be(target_be, target_words);
|
||||
|
||||
if (strcmp(nonce_mode, "incremental") == 0) {
|
||||
nonce = 0;
|
||||
@@ -162,7 +161,7 @@ int mine_block(
|
||||
last_tsu = now;
|
||||
}
|
||||
|
||||
if (compute_hash_batch(header_76, nonce, batch_size, target_be, &found_nonce, found_digest)) {
|
||||
if (compute_hash_batch(header_76, nonce, batch_size, target_words, &found_nonce, found_digest)) {
|
||||
double total = now - (double)t_start;
|
||||
if (total <= 0.0) {
|
||||
total = 1e-6;
|
||||
|
||||
Reference in New Issue
Block a user