...
authoralex <[email protected]>
Sun, 31 Oct 2021 23:13:47 +0000 (16:13 -0700)
committeralex <[email protected]>
Sun, 31 Oct 2021 23:13:47 +0000 (16:13 -0700)
src/block.c
test/unit/block.tests.c

index 61adb04d59c3b715b92676096338d05c3223b318..facc7151a4f83e63dc35c5590dba0f8da55cb5ad 100644 (file)
@@ -14,18 +14,23 @@ int block_append_blank(struct block *p) {
 }
 
 int block_duplicate(struct block **root, struct block *to_dup) {
-       struct block *p;
+       struct block *prev, *p;
        if(NULL==root) { return -1; }
        if(NULL==to_dup) { return -1; }
 
-       p = (*root);
-
+       prev = NULL;
        while(to_dup!=NULL) {
                if(block_init(&p)<0) { return -1; }
                
                memcpy(p->hash,to_dup->hash,crypto_hash_sha256_BYTES);
-               
-               p = p->next;
+
+               if(NULL==prev) {
+                       *root = p;
+               } else {
+                       prev->next = p;
+               }
+
+               prev = p;
                to_dup = to_dup->next;
        }
 
@@ -78,6 +83,10 @@ int block_merkle_root(struct block *root) {
 
        if(NULL==root) { return -1; }
 
+       size_t len = block_length(root);
+       if((len&(len-1))!=0) { return -1; }
+
+       p = root;
        while(p!=NULL) {
                if(NULL==p->next) { return -1; }
                if(hash_init(&state)<0) { return -1; }
@@ -88,12 +97,18 @@ int block_merkle_root(struct block *root) {
                if(hash_final(&state,p->hash,crypto_hash_sha256_BYTES)<0) { return -1; }
 
                to_free = p->next;
-               p = p->next->next;
+               p->next = p->next->next;
+               
+               to_free->next = NULL;
                block_free(to_free);
 
-               if((NULL==p)&&(p!=root)) {
+               if(NULL==p->next) {
+                       if(block_length(root)==1) { break; }
                        p = root;
+                       continue;
                }
+               
+               p = p->next;
        }
 
        return 1;
index 584b4ee0d0511d35097a351638b74060ff74d4dc..9c33de5a4d70aa27731e60146706bac78eb74bdd 100644 (file)
@@ -6,6 +6,8 @@ int main();
 static void block_append_blank_basic_test();
 static void block_duplicate_basic_test();
 static void block_init_basic_test();
+static void block_length_basic_test();
+static void block_merkle_root_basic_test();
 
 int main() {
        setup_env();
@@ -13,8 +15,8 @@ int main() {
        block_append_blank_basic_test();
        block_duplicate_basic_test();
        block_init_basic_test();
-       //block_length_basic_test();
-       //block_merkle_root_basic_test();
+       block_length_basic_test();
+       block_merkle_root_basic_test();
 
        clean_env();
 
@@ -74,10 +76,17 @@ static void block_duplicate_basic_test() {
 
 static void block_init_basic_test() {
        struct block *root, *p;
+       unsigned char expected[crypto_hash_sha256_BYTES];
+
+       memset(expected,0,crypto_hash_sha256_BYTES);
 
        assert(block_init(NULL)==-1);
        assert(block_init(&p)==1);
 
+       assert(p->data==NULL);
+       assert(p->next==NULL);
+       assert(memcmp(p->hash,expected,crypto_hash_sha256_BYTES)==0);
+
        root = p;
 
        for(int i=0;i<(rand()%100)+1;i++) {
@@ -87,3 +96,70 @@ static void block_init_basic_test() {
 
        block_free(root);
 }
+
+static void block_length_basic_test() {
+       struct block *root, *p;
+
+       assert(block_init(&root)==1);
+       p = root;
+
+       for(size_t i=0;i<10;i++) {
+               assert(block_init(&(p->next))==1);
+               p = p->next;
+       }
+
+       assert(11==block_length(root));
+
+       block_free(root);
+
+       assert(block_init(&root)==1);
+       p = root;
+       
+       size_t count = 1;
+       for(size_t i=0;i<rand()%1000;i++) {
+               assert(block_init(&(p->next))==1);
+               p = p->next;
+               count++;
+       }
+
+       assert(count==block_length(root));
+
+       block_free(root);
+}
+
+static void block_merkle_root_basic_test() {
+       struct block *root, *p;
+       unsigned char expected1[crypto_hash_sha256_BYTES] = {92,133,149,95,112,146,131,236,206,43,116,241,177,85,41,24,129,159,57,9,17,129,110,123,180,102,128,90,56,171,135,243};
+       unsigned char expected2[crypto_hash_sha256_BYTES] = {252,172,191,66,234,208,21,52,228,232,243,175,181,101,38,122,15,81,143,16,87,98,223,146,109,9,25,247,251,145,102,203};
+
+       assert(block_merkle_root(NULL)==-1);
+
+       assert(block_init(&root)==1);
+       memset(root->hash,0,crypto_hash_sha256_BYTES);
+
+       assert(block_merkle_root(root)==-1);
+
+       assert(block_init(&(root->next))==1);
+       memset(root->next->hash,1,crypto_hash_sha256_BYTES);
+
+       assert(block_merkle_root(root)==1);
+       assert(memcmp(root->hash,expected1,crypto_hash_sha256_BYTES)==0);
+       assert(root->next==NULL);
+
+       block_free(root);
+
+       assert(block_init(&root)==1);
+       memset(root->hash,0,crypto_hash_sha256_BYTES);
+       p = root;
+       
+       for(size_t i=1;i<256;i++) {
+               assert(block_init(&(p->next))==1);
+               p = p->next;
+               memset(p->hash,i,crypto_hash_sha256_BYTES);
+       }
+
+       assert(block_merkle_root(root)==1);
+       assert(memcmp(root->hash,expected2,crypto_hash_sha256_BYTES)==0);
+
+       block_free(root);
+}