size_t block_length(struct block*);
int block_merkle_layer(struct block*);
int block_merkle_root(struct block*);
+int block_pad(struct block*);
#endif
return 1;
}
-int block_pad(struct block *root) {
- return -1;
+int block_pad(struct block *p) {
+ if(NULL==p) { return -1; }
+
+ size_t i = 1;
+ while(p->next!=NULL) {
+ i++;
+ p = p->next;
+ }
+
+ while(i&&(i&(i-1))) {
+ if(block_init(&(p->next))<0) { return -1; }
+ memset(p->next->hash,0,crypto_hash_sha256_BYTES);
+ p = p->next;
+ i++;
+ }
+
+ return 1;
}
int file_hash(struct file *file_p, int piece_length) {
uint8_t data[BLOCK_SIZE];
- struct block *p, *next;
+ struct block *p, *next, *layer_p;
FILE *fp;
+ size_t blocks;
+ int ratio;
if(NULL==file_p) { return -1; }
return -1;
}
+ blocks = 0;
+ ratio = piece_length / BLOCK_SIZE;
+
/* generate piece_layers
* 1. grab all data and hash
* 2. generate piece layer merkle trees (padding to piece layer boundary)
if(NULL==p) {
file_p->piece_layers = next;
p = next;
+ layer_p = next;
} else {
p->next = next;
p = p->next;
}
+
+ if(blocks%ratio==0) {
+ layer_p = p;
+ }
+
+ blocks++;
}
fclose(fp);
// pad to appropiate piece layer size
// i.e. so each piece layer tree is balanced
+ if(block_pad(layer_p)<0) { return -1; }
- int ratio = piece_length / BLOCK_SIZE;
while(ratio>1) {
if(block_merkle_layer(file_p->piece_layers)<0) { return -1; }
ratio>>=1;
static void block_length_basic_test();
static void block_merkle_layer_basic_test();
static void block_merkle_root_basic_test();
+static void block_pad_basic_test();
int main() {
setup_env();
block_length_basic_test();
block_merkle_layer_basic_test();
block_merkle_root_basic_test();
+ block_pad_basic_test();
clean_env();
block_free(root);
}
+
+static void block_pad_basic_test() {
+ struct block *root, *p;
+
+ assert(-1==block_pad(NULL));
+
+ assert(block_init(&root)==1);
+ assert(block_pad(root)==1);
+ assert(block_length(root)==1);
+
+ assert(block_init(&(root->next))==1);
+ assert(block_pad(root)==1);
+ assert(block_length(root)==2);
+
+ p = root->next;
+ for(size_t i=2;i<7;i++) {
+ assert(block_init(&(p->next))==1);
+ p = p->next;
+ }
+
+ assert(block_length(root)==7);
+ for(size_t i=8;i<=1024;i<<=1) {
+ assert(block_pad(root)==1);
+ assert(block_length(root)==i);
+
+ assert(block_pad(root->next)==1);
+ assert(block_length(root)==i+1);
+ }
+
+ block_free(root);
+}