Skip to content

Commit

Permalink
headersdb_file: updated dogecoin_headers_db_connect_hdr to reorg
Browse files Browse the repository at this point in the history
arith_uint256: added negate, arithmetic and comparisions from xanimo
arith_uint256: updated div_arith_uint256 for long division
arith_uint256: updated get_low62 byte order
block: updated dogecoin_block_header with chainwork
block: updated dogecoin_block_header_copy to copy chainwork
block: updated dogecoin_block_header_new to initialize chainwork
block: updated dogecoin_block_header_new to initialize auxpow flag
block: removed duplicate initialization from dogecoin_auxpow_block_new
headersdb_file: updated dogecoin_headers_db_free check for genesis
pow: added nhashes_done to check_pow for chainwork
validation: updated check_pow for chainwork
spv: added escape characters to dogecoin_net_spv_post_cmd for shutdown
spvnode: moved "done" print after dogecoin_spv_client_free
test: updated block_test to check chainwork of genesis
test: added test_reorg to spv_test
test: updated unittester to test_reorg
  • Loading branch information
edtubbs committed Dec 21, 2023
1 parent 6759b39 commit 0de7b56
Show file tree
Hide file tree
Showing 13 changed files with 582 additions and 45 deletions.
12 changes: 11 additions & 1 deletion include/dogecoin/arith_uint256.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,21 @@ typedef struct base_uint_ {

typedef base_uint_ arith_uint256;

void arith_negate(arith_uint256* input);
arith_uint256* init_arith_uint256();
arith_uint256* set_compact(arith_uint256* hash, uint32_t compact, dogecoin_bool *pf_negative, dogecoin_bool *pf_overflow);
uint8_t* arith_to_uint256(const arith_uint256* a);
arith_uint256* uint_to_arith(const uint256* a);
uint64_t get_low64(arith_uint256 pn);
uint64_t get_low64(arith_uint256* a);
arith_uint256* div_arith_uint256(arith_uint256* a, arith_uint256* b);
arith_uint256* add_arith_uint256(arith_uint256* a, arith_uint256* b);
arith_uint256* sub_arith_uint256(arith_uint256* a, arith_uint256* b);
dogecoin_bool arith_uint256_is_zero(const arith_uint256* a);
dogecoin_bool arith_uint256_equal(const arith_uint256* a, const arith_uint256* b);
dogecoin_bool arith_uint256_greater_than(const arith_uint256* a, const arith_uint256* b);
dogecoin_bool arith_uint256_greater_than_or_equal(const arith_uint256* a, const arith_uint256* b);
dogecoin_bool arith_uint256_less_than(const arith_uint256* a, const arith_uint256* b);
dogecoin_bool arith_uint256_less_than_or_equal(const arith_uint256* a, const arith_uint256* b);

LIBDOGECOIN_END_DECL

Expand Down
1 change: 1 addition & 0 deletions include/dogecoin/block.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ typedef struct dogecoin_block_header_ {
uint32_t bits;
uint32_t nonce;
auxpow auxpow[1];
uint256 chainwork;
} dogecoin_block_header;

typedef struct dogecoin_auxpow_block_ {
Expand Down
2 changes: 1 addition & 1 deletion include/dogecoin/pow.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@

LIBDOGECOIN_BEGIN_DECL

dogecoin_bool check_pow(uint256* hash, unsigned int nbits, const dogecoin_chainparams *params);
dogecoin_bool check_pow(uint256* hash, unsigned int nbits, const dogecoin_chainparams *params, uint256* nhashes_done);

LIBDOGECOIN_END_DECL

Expand Down
123 changes: 116 additions & 7 deletions src/arith_uint256.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,13 @@

#include <dogecoin/arith_uint256.h>

void arith_negate(arith_uint256* input) {
// Inverting all bits (one's complement)
for (int i = 0; i < WIDTH; i++) {
input->pn[i] = ~input->pn[i];
}
}

arith_uint256* init_arith_uint256() {
arith_uint256* x = dogecoin_calloc(8, sizeof(uint32_t));
int i = 0;
Expand Down Expand Up @@ -95,17 +102,119 @@ arith_uint256* set_compact(arith_uint256* hash, uint32_t compact, dogecoin_bool

arith_uint256* uint_to_arith(const uint256* a)
{
static arith_uint256 b;
memcpy_safe(b.pn, a, sizeof(b.pn));
return &b;
arith_uint256* b = (arith_uint256*)calloc(1, sizeof(arith_uint256));
if (!b) {
return NULL;
}
memcpy_safe(b->pn, a, sizeof(b->pn));
return b;
}

uint8_t* arith_to_uint256(const arith_uint256* a) {
static uint256 b = {0};
uint8_t* b = (uint8_t*)calloc(1, sizeof(uint256));
if (!b) {
return NULL;
}
memcpy_safe(b, a->pn, sizeof(uint256));
return &b[0];
return b;
}

arith_uint256* div_arith_uint256(arith_uint256* a, arith_uint256* b) {
if (arith_uint256_is_zero(b)) {
// Handle division by zero if necessary
return NULL;
}

arith_uint256* quotient = init_arith_uint256();
arith_uint256* remainder = init_arith_uint256();

for (int i = WIDTH * 32 - 1; i >= 0; i--) {
// Left shift remainder by 1 bit
arith_shift_left(remainder, 1);

// Set the least significant bit of remainder to bit i of a
int word_idx = i / 32;
int bit_idx = i % 32;
if ((a->pn[word_idx] & (1 << bit_idx)) != 0) {
remainder->pn[0] |= 1;
}

// Compare remainder with b
if (arith_uint256_greater_than_or_equal(remainder, b)) {
// Subtract b from remainder
arith_uint256* temp = sub_arith_uint256(remainder, b);
memcpy(remainder, temp, sizeof(arith_uint256));
free(temp);

// Set bit i of quotient
quotient->pn[word_idx] |= (1 << bit_idx);
}
}

free(remainder);
return quotient;
}

arith_uint256* add_arith_uint256(arith_uint256* a, arith_uint256* b) {
arith_uint256* result = init_arith_uint256();
uint64_t carry = 0;
for (int i = WIDTH - 1; i >= 0; i--) {
uint64_t sum = (uint64_t)a->pn[i] + b->pn[i] + carry;
result->pn[i] = sum; // This will only keep the lower 32 bits
carry = sum >> 32; // This will keep the upper 32 bits (carry)
}
return result;
}

arith_uint256* sub_arith_uint256(arith_uint256* a, arith_uint256* b) {
arith_uint256* result = init_arith_uint256();
int64_t carry = 0;
for (int i = WIDTH - 1; i >= 0; i--) {
int64_t diff = (uint64_t)a->pn[i] - b->pn[i] - carry;
result->pn[i] = diff; // This will only keep the lower 32 bits
carry = (diff < 0) ? 1 : 0; // If diff is negative, there's a borrow
}
return result;
}

dogecoin_bool arith_uint256_is_zero(const arith_uint256* a) {
for (int i = 0; i < WIDTH; i++) {
if (a->pn[i] != 0) return false;
}
return true;
}

dogecoin_bool arith_uint256_less_than(const arith_uint256* a, const arith_uint256* b) {
for (int i = WIDTH - 1; i >= 0; i--) {
if (a->pn[i] < b->pn[i]) return true;
else if (a->pn[i] > b->pn[i]) return false;
}
return false;
}

dogecoin_bool arith_uint256_equal(const arith_uint256* a, const arith_uint256* b) {
for (int i = 0; i < WIDTH; i++) {
if (a->pn[i] != b->pn[i]) return false;
}
return true;
}

dogecoin_bool arith_uint256_less_than_or_equal(const arith_uint256* a, const arith_uint256* b) {
return arith_uint256_less_than(a, b) || arith_uint256_equal(a, b);
}

dogecoin_bool arith_uint256_greater_than(const arith_uint256* a, const arith_uint256* b) {
for (int i = 0; i < WIDTH; i++) {
if (a->pn[i] > b->pn[i]) return true;
else if (a->pn[i] < b->pn[i]) return false;
}
return false;
}

dogecoin_bool arith_uint256_greater_than_or_equal(const arith_uint256* a, const arith_uint256* b) {
return !arith_uint256_less_than(a, b);
}

uint64_t get_low64(arith_uint256 a) {
return a.pn[0] | (uint64_t)a.pn[1] << 32;
uint64_t get_low64(arith_uint256* a) {
return ((uint64_t)a->pn[WIDTH - 2]) | (((uint64_t)a->pn[WIDTH - 1]) << 32);
}
6 changes: 5 additions & 1 deletion src/block.c
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,8 @@ dogecoin_block_header* dogecoin_block_header_new() {
header->nonce = 0;
header->auxpow->check = check;
header->auxpow->ctx = header;
header->auxpow->is = false;
dogecoin_mem_zero(&header->chainwork, DOGECOIN_HASH_LENGTH);
return header;
}

Expand All @@ -187,7 +189,6 @@ dogecoin_auxpow_block* dogecoin_auxpow_block_new() {
block->aux_merkle_branch = NULL;
block->aux_merkle_index = 0;
block->parent_header = dogecoin_block_header_new();
block->header->auxpow->check = check;
block->header->auxpow->ctx = block;
return block;
}
Expand Down Expand Up @@ -332,6 +333,7 @@ int dogecoin_block_header_deserialize(dogecoin_block_header* header, struct cons
printf("%s:%d:%s:%s\n", __FILE__, __LINE__, __func__, strerror(errno));
return false;
}
dogecoin_block_header_copy(header, block->header);
}
dogecoin_auxpow_block_free(block);
return true;
Expand Down Expand Up @@ -470,6 +472,8 @@ void dogecoin_block_header_copy(dogecoin_block_header* dest, const dogecoin_bloc
dest->nonce = src->nonce;
dest->auxpow->check = src->auxpow->check;
dest->auxpow->ctx = src->auxpow->ctx;
dest->auxpow->is = src->auxpow->is;
memcpy_safe(&dest->chainwork, &src->chainwork, sizeof(src->chainwork));
}

/**
Expand Down
1 change: 1 addition & 0 deletions src/cli/spvnode.c
Original file line number Diff line number Diff line change
Expand Up @@ -462,6 +462,7 @@ int main(int argc, char* argv[]) {
printf("Connecting to the p2p network...\n");
dogecoin_spv_client_runloop(client);
dogecoin_spv_client_free(client);
printf("done\n");
ret = EXIT_SUCCESS;
#if WITH_WALLET
dogecoin_wallet_free(wallet);
Expand Down
Loading

0 comments on commit 0de7b56

Please sign in to comment.