}
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;
}
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; }
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;
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();
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();
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++) {
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);
+}