From 0311c2975138f3e24d328f6ef6d40e960f9a2d55 Mon Sep 17 00:00:00 2001 From: edtubbs Date: Thu, 16 Nov 2023 14:04:15 -0600 Subject: [PATCH] validation: added scrypt-sse2 and block_header_hash block: updated dogecoin_auxpow_block_new and check for chain_merkle auxpow: updated check_merkle_branch for Hash and to shift n_index hash: update Hash for uint256 and added allocation for sha2 ctx --- include/dogecoin/hash.h | 9 ++++----- src/auxpow.c | 10 +++++----- src/block.c | 21 ++++++++++++++------- src/validation.c | 13 +++++++------ 4 files changed, 30 insertions(+), 23 deletions(-) diff --git a/include/dogecoin/hash.h b/include/dogecoin/hash.h index 9632e4525..969731ece 100644 --- a/include/dogecoin/hash.h +++ b/include/dogecoin/hash.h @@ -98,7 +98,7 @@ typedef struct _chash256 { static inline chash256* dogecoin_chash256_init() { chash256* chash = dogecoin_calloc(1, sizeof(*chash)); - sha256_context* ctx = NULL; + sha256_context* ctx = dogecoin_calloc(1, sizeof(*ctx)); sha256_init(ctx); chash->sha = ctx; chash->write = sha256_write; @@ -107,13 +107,12 @@ static inline chash256* dogecoin_chash256_init() { return chash; } -static inline uint256* Hash(const uint256 p1begin, const uint256 p1end, - const uint256 p2begin, const uint256 p2end) { +static inline uint256* Hash(const uint256 p1, const uint256 p2) { static const unsigned char pblank[1]; uint256* result = dogecoin_uint256_vla(1); chash256* chash = dogecoin_chash256_init(); - chash->write(chash->sha, p1begin == p1end ? pblank : (const unsigned char*)&p1begin[0], (p1end - p1begin) * sizeof(p1begin[0])); - chash->write(chash->sha, p2begin == p2end ? pblank : (const unsigned char*)&p2begin[0], (p2end - p2begin) * sizeof(p2begin[0])); + chash->write(chash->sha, (const uint8_t*)&p1[0], sizeof(uint256)); + chash->write(chash->sha, (const uint8_t*)&p2[0], sizeof(uint256)); chash->finalize(chash->sha, (unsigned char*)result); chash->reset(chash->sha); return result; diff --git a/src/auxpow.c b/src/auxpow.c index a4eb3f9e3..1b5e9eeaa 100644 --- a/src/auxpow.c +++ b/src/auxpow.c @@ -58,15 +58,15 @@ int get_expected_index (uint32_t nNonce, int nChainId, unsigned h) uint256* check_merkle_branch(uint256 hash, const vector* parent_coinbase_merkle, unsigned int n_index) { if (n_index == (unsigned int)-1) return dogecoin_uint256_vla(1); - unsigned int i = n_index; + unsigned int i = 0; for (; i < parent_coinbase_merkle->len; ++i) { uint256 pcm; memcpy(pcm, vector_idx(parent_coinbase_merkle, i), 32); - if (i & 1) - hash = (uint8_t *)Hash(UBEGIN(*pcm), UEND(*pcm), UBEGIN(hash), UEND(hash)); + if (n_index & 1) + hash = (uint8_t *)Hash(&pcm[0], &hash[0]); else - hash = (uint8_t *)Hash(UBEGIN(hash), UEND(hash), UBEGIN(*pcm), UEND(*pcm)); - i >>= 1; + hash = (uint8_t *)Hash(&hash[0], &pcm[0]); + n_index >>= 1; } return (uint256*)*&hash; } diff --git a/src/block.c b/src/block.c index 3b57220ec..cd05a916a 100644 --- a/src/block.c +++ b/src/block.c @@ -57,21 +57,22 @@ dogecoin_bool check(void *ctx, uint256* hash, uint32_t chainid, dogecoin_chainpa return false; } - vector* parent_merkle = vector_new(8, NULL); + vector* chain_merkle = vector_new(8, NULL); size_t p = 0; - for (; p < block->parent_merkle_count; p++) { - vector_add(parent_merkle, block->parent_coinbase_merkle[p]); + for (; p < block->aux_merkle_count; p++) { + vector_add(chain_merkle, block->aux_merkle_branch[p]); } - if (parent_merkle->len > 30) { + if (chain_merkle->len > 30) { printf("Aux POW chain merkle branch too long\n"); return false; } // Check that the chain merkle root is in the coinbase - uint256* n_roothash = check_merkle_branch((uint8_t*)hash, parent_merkle, parent_merkle->len); - const unsigned char* vch_roothash = (unsigned char*)hash_to_string((uint8_t*)n_roothash); // correct endian - vector_free(parent_merkle, true); + uint256* n_roothash = check_merkle_branch((uint8_t*)hash, chain_merkle, block->aux_merkle_index); + unsigned char vch_roothash[64]; // Make sure it's large enough to hold the hash + memcpy(vch_roothash, hash_to_string((uint8_t*)n_roothash), 64); // Copy the data + vector_free(chain_merkle, true); dogecoin_tx_in *tx_in = vector_idx(block->parent_coinbase->vin, 0); size_t idx = 0, count = 0; @@ -146,6 +147,12 @@ dogecoin_auxpow_block* dogecoin_auxpow_block_new() { dogecoin_auxpow_block* block = dogecoin_calloc(1, sizeof(*block)); block->header = dogecoin_block_header_new(); block->parent_coinbase = dogecoin_tx_new(); + block->parent_merkle_count = 0; + block->parent_coinbase_merkle = dogecoin_calloc(1, sizeof(uint256)); + block->parent_merkle_index = 0; + block->aux_merkle_count = 0; + block->aux_merkle_branch = dogecoin_calloc(1, sizeof(uint256)); + block->aux_merkle_index = 0; block->parent_header = dogecoin_block_header_new(); block->header->auxpow->check = check; block->header->auxpow->ctx = block; diff --git a/src/validation.c b/src/validation.c index e662e6ec8..f2c9a7814 100644 --- a/src/validation.c +++ b/src/validation.c @@ -42,9 +42,13 @@ */ dogecoin_bool dogecoin_block_header_scrypt_hash(cstring* s, uint256* hash) { char scratchpad[SCRYPT_SCRATCHPAD_SIZE]; +#if defined(USE_SSE2) + scrypt_1024_1_1_256_sp_sse2((const char*)s->str, (char *) hash, scratchpad); +#else scrypt_1024_1_1_256_sp_generic((const char*)s->str, (char *) hash, scratchpad); +#endif return true; - } +} uint32_t get_chainid(uint32_t version) { return version >> 16; @@ -92,10 +96,7 @@ dogecoin_bool check_auxpow(dogecoin_auxpow_block block, dogecoin_chainparams* pa /* We have auxpow. Check it. */ uint256 block_header_hash; - cstring* s = cstr_new_sz(64); - dogecoin_block_header_serialize(s, block.header); - dogecoin_block_header_scrypt_hash(s, &block_header_hash); - cstr_free(s, true); + dogecoin_block_header_hash(block.header, (uint8_t *) &block_header_hash); uint32_t chainid = get_chainid(block.header->version); if (!block.header->auxpow->check(&block, &block_header_hash, chainid, params)) { printf("%s:%d:%s : AUX POW is not valid : %s\n", __FILE__, __LINE__, __func__, strerror(errno)); @@ -108,7 +109,7 @@ dogecoin_bool check_auxpow(dogecoin_auxpow_block block, dogecoin_chainparams* pa dogecoin_block_header_scrypt_hash(s2, &parent_hash); cstr_free(s2, true); if (!check_pow(&parent_hash, block.header->bits, params)) { - printf("%s:%d:%s : check_pow failure : %s\n", __FILE__, __LINE__, __func__, strerror(errno)); + printf("%s:%d:%s : AUX proof of work failed: %s\n", __FILE__, __LINE__, __func__, strerror(errno)); return false; }