Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions components/asic/bm1366.c
Original file line number Diff line number Diff line change
Expand Up @@ -289,8 +289,8 @@ void BM1366_send_work(void * pvParameters, bm_job * next_bm_job)
memcpy(&job.starting_nonce, &next_bm_job->starting_nonce, 4);
memcpy(&job.nbits, &next_bm_job->target, 4);
memcpy(&job.ntime, &next_bm_job->ntime, 4);
memcpy(job.merkle_root, next_bm_job->merkle_root_be, 32);
memcpy(job.prev_block_hash, next_bm_job->prev_block_hash_be, 32);
memcpy(job.merkle_root, next_bm_job->merkle_root, 32);
memcpy(job.prev_block_hash, next_bm_job->prev_block_hash, 32);
memcpy(&job.version, &next_bm_job->version, 4);

if (GLOBAL_STATE->ASIC_TASK_MODULE.active_jobs[job.job_id] != NULL) {
Expand Down
4 changes: 2 additions & 2 deletions components/asic/bm1368.c
Original file line number Diff line number Diff line change
Expand Up @@ -233,8 +233,8 @@ void BM1368_send_work(void * pvParameters, bm_job * next_bm_job)
memcpy(&job.starting_nonce, &next_bm_job->starting_nonce, 4);
memcpy(&job.nbits, &next_bm_job->target, 4);
memcpy(&job.ntime, &next_bm_job->ntime, 4);
memcpy(job.merkle_root, next_bm_job->merkle_root_be, 32);
memcpy(job.prev_block_hash, next_bm_job->prev_block_hash_be, 32);
memcpy(job.merkle_root, next_bm_job->merkle_root, 32);
memcpy(job.prev_block_hash, next_bm_job->prev_block_hash, 32);
memcpy(&job.version, &next_bm_job->version, 4);

if (GLOBAL_STATE->ASIC_TASK_MODULE.active_jobs[job.job_id] != NULL) {
Expand Down
4 changes: 2 additions & 2 deletions components/asic/bm1370.c
Original file line number Diff line number Diff line change
Expand Up @@ -309,8 +309,8 @@ void BM1370_send_work(void * pvParameters, bm_job * next_bm_job)
memcpy(&job.starting_nonce, &next_bm_job->starting_nonce, 4);
memcpy(&job.nbits, &next_bm_job->target, 4);
memcpy(&job.ntime, &next_bm_job->ntime, 4);
memcpy(job.merkle_root, next_bm_job->merkle_root_be, 32);
memcpy(job.prev_block_hash, next_bm_job->prev_block_hash_be, 32);
memcpy(job.merkle_root, next_bm_job->merkle_root, 32);
memcpy(job.prev_block_hash, next_bm_job->prev_block_hash, 32);
memcpy(&job.version, &next_bm_job->version, 4);

if (GLOBAL_STATE->ASIC_TASK_MODULE.active_jobs[job.job_id] != NULL) {
Expand Down
2 changes: 1 addition & 1 deletion components/asic/bm1397.c
Original file line number Diff line number Diff line change
Expand Up @@ -332,7 +332,7 @@ void BM1397_send_work(void *pvParameters, bm_job *next_bm_job)
memcpy(&job.starting_nonce, &next_bm_job->starting_nonce, 4);
memcpy(&job.nbits, &next_bm_job->target, 4);
memcpy(&job.ntime, &next_bm_job->ntime, 4);
memcpy(&job.merkle4, next_bm_job->merkle_root + 28, 4);
memcpy(&job.merkle4, next_bm_job->merkle_root, 4);
memcpy(job.midstate, next_bm_job->midstate, 32);

if (job.num_midstates == 4)
Expand Down
10 changes: 4 additions & 6 deletions components/stratum/include/mining.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,7 @@ typedef struct
uint32_t version;
uint32_t version_mask;
uint8_t prev_block_hash[32];
uint8_t prev_block_hash_be[32];
uint8_t merkle_root[32];
uint8_t merkle_root_be[32];
uint32_t ntime;
uint32_t target; // aka difficulty, aka nbits
uint32_t starting_nonce;
Expand All @@ -27,12 +25,12 @@ typedef struct

void free_bm_job(bm_job *job);

char *construct_coinbase_tx(const char *coinbase_1, const char *coinbase_2,
const char *extranonce, const char *extranonce_2);
void calculate_coinbase_tx_hash(const char *coinbase_1, const char *coinbase_2,
const char *extranonce, const char *extranonce_2, uint8_t dest[32]);

void calculate_merkle_root_hash(const char *coinbase_tx, const uint8_t merkle_branches[][32], const int num_merkle_branches, char dest[65]);
void calculate_merkle_root_hash(const uint8_t coinbase_tx_hash[32], const uint8_t merkle_branches[][32], const int num_merkle_branches, uint8_t dest[32]);

bm_job construct_bm_job(mining_notify *params, const char *merkle_root, const uint32_t version_mask, uint32_t difficulty);
void construct_bm_job(mining_notify *params, const uint8_t merkle_root[32], const uint32_t version_mask, const uint32_t difficulty, bm_job* new_job);

double test_nonce_value(const bm_job *job, const uint32_t nonce, const uint32_t rolled_version);

Expand Down
12 changes: 2 additions & 10 deletions components/stratum/include/utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,31 +6,23 @@

size_t bin2hex(const uint8_t *buf, size_t buflen, char *hex, size_t hexlen);

void flip80bytes(void *dest_p, const void *src_p);
void flip32bytes(void *dest_p, const void *src_p);

size_t hex2bin(const char *hex, uint8_t *bin, size_t bin_len);

void print_hex(const uint8_t *b, size_t len,
const size_t in_line, const char *prefix);

char *double_sha256(const char *hex_string);

void double_sha256_bin(const uint8_t *data, const size_t data_len, uint8_t dest[32]);

void single_sha256_bin(const uint8_t *data, const size_t data_len, uint8_t dest[32]);
void midstate_sha256_bin(const uint8_t *data, const size_t data_len, uint8_t dest[32]);

void swap_endian_words(const char *hex, uint8_t *output);
void reverse_32bit_words(const uint8_t src[32], uint8_t dest[32]);

void reverse_bytes(uint8_t *data, size_t len);
void reverse_endianness_per_word(uint8_t data[32]);

double le256todouble(const void *target);

void prettyHex(unsigned char *buf, int len);

uint32_t flip32(uint32_t val);

double networkDifficulty(uint32_t nBits);

void suffixString(uint64_t val, char * buf, size_t bufsiz, int sigdigits);
Expand Down
124 changes: 55 additions & 69 deletions components/stratum/mining.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,94 +13,87 @@ void free_bm_job(bm_job *job)
free(job);
}

char *construct_coinbase_tx(const char *coinbase_1, const char *coinbase_2,
const char *extranonce, const char *extranonce_2)
void calculate_coinbase_tx_hash(const char *coinbase_1, const char *coinbase_2, const char *extranonce, const char *extranonce_2, uint8_t dest[32])
{
int coinbase_tx_len = strlen(coinbase_1) + strlen(coinbase_2) + strlen(extranonce) + strlen(extranonce_2) + 1;
size_t len1 = strlen(coinbase_1);
size_t len2 = strlen(extranonce);
size_t len3 = strlen(extranonce_2);
size_t len4 = strlen(coinbase_2);

char *coinbase_tx = malloc(coinbase_tx_len);
strcpy(coinbase_tx, coinbase_1);
strcat(coinbase_tx, extranonce);
strcat(coinbase_tx, extranonce_2);
strcat(coinbase_tx, coinbase_2);
coinbase_tx[coinbase_tx_len - 1] = '\0';
size_t coinbase_tx_bin_len = (len1 + len2 + len3 + len4) / 2;

return coinbase_tx;
uint8_t coinbase_tx_bin[coinbase_tx_bin_len];

size_t bin_offset = 0;
bin_offset += hex2bin(coinbase_1, coinbase_tx_bin + bin_offset, coinbase_tx_bin_len - bin_offset);
bin_offset += hex2bin(extranonce, coinbase_tx_bin + bin_offset, coinbase_tx_bin_len - bin_offset);
bin_offset += hex2bin(extranonce_2, coinbase_tx_bin + bin_offset, coinbase_tx_bin_len - bin_offset);
bin_offset += hex2bin(coinbase_2, coinbase_tx_bin + bin_offset, coinbase_tx_bin_len - bin_offset);

double_sha256_bin(coinbase_tx_bin, coinbase_tx_bin_len, dest);
}

void calculate_merkle_root_hash(const char *coinbase_tx, const uint8_t merkle_branches[][32], const int num_merkle_branches, char dest[65])
void calculate_merkle_root_hash(const uint8_t coinbase_tx_hash[32], const uint8_t merkle_branches[][32], const int num_merkle_branches, uint8_t dest[32])
{
size_t coinbase_tx_bin_len = strlen(coinbase_tx) / 2;
uint8_t coinbase_tx_bin[coinbase_tx_bin_len];
hex2bin(coinbase_tx, coinbase_tx_bin, coinbase_tx_bin_len);

uint8_t both_merkles[64];
double_sha256_bin(coinbase_tx_bin, coinbase_tx_bin_len, both_merkles);
memcpy(both_merkles, coinbase_tx_hash, 32);
for (int i = 0; i < num_merkle_branches; i++) {
memcpy(both_merkles + 32, merkle_branches[i], 32);
double_sha256_bin(both_merkles, 64, both_merkles);
}

bin2hex(both_merkles, 32, dest, 65);
memcpy(dest, both_merkles, 32);
}

// take a mining_notify struct with ascii hex strings and convert it to a bm_job struct
bm_job construct_bm_job(mining_notify *params, const char *merkle_root, const uint32_t version_mask, const uint32_t difficulty)
void construct_bm_job(mining_notify *params, const uint8_t merkle_root[32], const uint32_t version_mask, const uint32_t difficulty, bm_job *new_job)
{
bm_job new_job;

new_job.version = params->version;
new_job.target = params->target;
new_job.ntime = params->ntime;
new_job.starting_nonce = 0;
new_job.pool_diff = difficulty;

hex2bin(merkle_root, new_job.merkle_root, 32);

// hex2bin(merkle_root, new_job.merkle_root_be, 32);
swap_endian_words(merkle_root, new_job.merkle_root_be);
reverse_bytes(new_job.merkle_root_be, 32);

swap_endian_words(params->prev_block_hash, new_job.prev_block_hash);

hex2bin(params->prev_block_hash, new_job.prev_block_hash_be, 32);
reverse_bytes(new_job.prev_block_hash_be, 32);

////make the midstate hash
new_job->version = params->version;
new_job->target = params->target;
new_job->ntime = params->ntime;
new_job->starting_nonce = 0;
new_job->pool_diff = difficulty;
reverse_32bit_words(merkle_root, new_job->merkle_root);

uint8_t prev_block_hash[32];
hex2bin(params->prev_block_hash, prev_block_hash, 32);
reverse_endianness_per_word(prev_block_hash);
reverse_32bit_words(prev_block_hash, new_job->prev_block_hash);

// make the midstate hash
uint8_t midstate_data[64];

// copy 68 bytes header data into midstate (and deal with endianess)
memcpy(midstate_data, &new_job.version, 4); // copy version
memcpy(midstate_data + 4, new_job.prev_block_hash, 32); // copy prev_block_hash
memcpy(midstate_data + 36, new_job.merkle_root, 28); // copy merkle_root
memcpy(midstate_data, &new_job->version, 4); // copy version
memcpy(midstate_data + 4, prev_block_hash, 32); // copy prev_block_hash
memcpy(midstate_data + 36, merkle_root, 28); // copy merkle_root

midstate_sha256_bin(midstate_data, 64, new_job.midstate); // make the midstate hash
reverse_bytes(new_job.midstate, 32); // reverse the midstate bytes for the BM job packet
uint8_t midstate[32];
midstate_sha256_bin(midstate_data, 64, midstate); // make the midstate hash
reverse_32bit_words(midstate, new_job->midstate); // reverse the midstate words for the BM job packet

if (version_mask != 0)
{
uint32_t rolled_version = increment_bitmask(new_job.version, version_mask);
uint32_t rolled_version = increment_bitmask(new_job->version, version_mask);
memcpy(midstate_data, &rolled_version, 4);
midstate_sha256_bin(midstate_data, 64, new_job.midstate1);
reverse_bytes(new_job.midstate1, 32);
midstate_sha256_bin(midstate_data, 64, midstate);
reverse_32bit_words(midstate, new_job->midstate1);

rolled_version = increment_bitmask(rolled_version, version_mask);
memcpy(midstate_data, &rolled_version, 4);
midstate_sha256_bin(midstate_data, 64, new_job.midstate2);
reverse_bytes(new_job.midstate2, 32);
midstate_sha256_bin(midstate_data, 64, midstate);
reverse_32bit_words(midstate, new_job->midstate2);

rolled_version = increment_bitmask(rolled_version, version_mask);
memcpy(midstate_data, &rolled_version, 4);
midstate_sha256_bin(midstate_data, 64, new_job.midstate3);
reverse_bytes(new_job.midstate3, 32);
new_job.num_midstates = 4;
midstate_sha256_bin(midstate_data, 64, midstate);
reverse_32bit_words(midstate, new_job->midstate3);
new_job->num_midstates = 4;
}
else
{
new_job.num_midstates = 1;
new_job->num_midstates = 1;
}

return new_job;
}

void extranonce_2_generate(uint64_t extranonce_2, uint32_t length, char dest[static length * 2 + 1])
Expand All @@ -126,8 +119,7 @@ static const double truediffone = 2695953529101130949315647634472399133601089873
/* testing a nonce and return the diff - 0 means invalid */
double test_nonce_value(const bm_job *job, const uint32_t nonce, const uint32_t rolled_version)
{
double d64, s64, ds;
unsigned char header[80];
uint8_t header[80];

// // TODO: use the midstate hash instead of hashing the whole header
// uint32_t rolled_version = job->version;
Expand All @@ -137,24 +129,18 @@ double test_nonce_value(const bm_job *job, const uint32_t nonce, const uint32_t

// copy data from job to header
memcpy(header, &rolled_version, 4);
memcpy(header + 4, job->prev_block_hash, 32);
memcpy(header + 36, job->merkle_root, 32);
reverse_32bit_words(job->prev_block_hash, header + 4);
reverse_32bit_words(job->merkle_root, header + 36);
memcpy(header + 68, &job->ntime, 4);
memcpy(header + 72, &job->target, 4);
memcpy(header + 76, &nonce, 4);

unsigned char hash_buffer[32];
unsigned char hash_result[32];

// double hash the header
mbedtls_sha256(header, 80, hash_buffer, 0);
mbedtls_sha256(hash_buffer, 32, hash_result, 0);

d64 = truediffone;
s64 = le256todouble(hash_result);
ds = d64 / s64;
uint8_t hash_result[32];
double_sha256_bin(header, 80, hash_result);

return ds;
double d64 = truediffone;
double s64 = le256todouble(hash_result);
return d64 / s64;
}

uint32_t increment_bitmask(const uint32_t value, const uint32_t mask)
Expand Down
Loading
Loading