diff --git a/blocks/blockstore.c b/blocks/blockstore.c index 99823ae..bbe4157 100644 --- a/blocks/blockstore.c +++ b/blocks/blockstore.c @@ -40,6 +40,20 @@ unsigned char* ipfs_blockstore_cid_to_base32(const struct Cid* cid) { return buffer; } +unsigned char* ipfs_blockstore_hash_to_base32(const unsigned char* hash, size_t hash_size) { + size_t key_length = libp2p_crypto_encoding_base32_encode_size(hash_size); + unsigned char* buffer = (unsigned char*)malloc(key_length + 1); + if (buffer == NULL) + return NULL; + int retVal = ipfs_datastore_helper_ds_key_from_binary(hash, hash_size, &buffer[0], key_length, &key_length); + if (retVal == 0) { + free(buffer); + return NULL; + } + buffer[key_length] = 0; + return buffer; +} + char* ipfs_blockstore_path_get(const struct FSRepo* fs_repo, const char* filename) { int filepath_size = strlen(fs_repo->path) + 12; char filepath[filepath_size]; @@ -60,9 +74,9 @@ char* ipfs_blockstore_path_get(const struct FSRepo* fs_repo, const char* filenam * @param block where to put the data to be returned * @returns true(1) on success */ -int ipfs_blockstore_get(const struct Cid* cid, struct Block** block, const struct FSRepo* fs_repo) { +int ipfs_blockstore_get(const unsigned char* hash, size_t hash_size, struct Block** block, const struct FSRepo* fs_repo) { // get datastore key, which is a base32 key of the multihash - unsigned char* key = ipfs_blockstore_cid_to_base32(cid); + unsigned char* key = ipfs_blockstore_hash_to_base32(hash, hash_size); char* filename = ipfs_blockstore_path_get(fs_repo, (char*)key); diff --git a/cid/cid.c b/cid/cid.c index c506100..8cf2162 100644 --- a/cid/cid.c +++ b/cid/cid.c @@ -180,17 +180,18 @@ int ipfs_cid_decode_hash_from_base58(const unsigned char* incoming, size_t incom } /** - * Turn a cid into a base 58 - * @param cid the cid to work with + * Turn a cid hash into a base 58 + * @param hash the hash to work with + * @param hash_length the length of the existing hash * @param buffer where to put the results * @param max_buffer_length the maximum space reserved for the results * @returns true(1) on success */ -int ipfs_cid_hash_to_base58(struct Cid* cid, unsigned char* buffer, size_t max_buffer_length) { +int ipfs_cid_hash_to_base58(const unsigned char* hash, size_t hash_length, unsigned char* buffer, size_t max_buffer_length) { - int multihash_len = cid->hash_length + 2; + int multihash_len = hash_length + 2; unsigned char multihash[multihash_len]; - if (mh_new(multihash, MH_H_SHA2_256, cid->hash, cid->hash_length) < 0) { + if (mh_new(multihash, MH_H_SHA2_256, hash, hash_length) < 0) { return 0; } diff --git a/datastore/ds_helper.c b/datastore/ds_helper.c index c78f483..a1db92b 100644 --- a/datastore/ds_helper.c +++ b/datastore/ds_helper.c @@ -13,7 +13,7 @@ * @param results_length the length of the generated key * @returns true(1) on success */ -int ipfs_datastore_helper_ds_key_from_binary(unsigned char* binary_array, size_t array_length, +int ipfs_datastore_helper_ds_key_from_binary(const unsigned char* binary_array, size_t array_length, unsigned char* results, size_t max_results_length, size_t* results_length) { size_t encoded_length = libp2p_crypto_encoding_base32_encode_size(array_length); @@ -39,7 +39,7 @@ int ipfs_datastore_helper_ds_key_from_binary(unsigned char* binary_array, size_t * @param completed_binary_array_length the length of what was written to the binary_array * @returns true(1) on success */ -int ipfs_datastore_helper_binary_from_ds_key(unsigned char* ds_key, size_t key_length, unsigned char* binary_array, +int ipfs_datastore_helper_binary_from_ds_key(const unsigned char* ds_key, size_t key_length, unsigned char* binary_array, size_t max_binary_array_length, size_t* completed_binary_array_length) { size_t decoded_length = libp2p_crypto_encoding_base32_decode_size(key_length); diff --git a/importer/exporter.c b/importer/exporter.c index b26ece7..34fbfd7 100644 --- a/importer/exporter.c +++ b/importer/exporter.c @@ -24,7 +24,7 @@ int ipfs_exporter_to_file(const unsigned char* hash, const char* file_name, cons // find block struct Node* read_node = NULL; - if (ipfs_merkledag_get(cid, &read_node, fs_repo) == 0) { + if (ipfs_merkledag_get(cid->hash, cid->hash_length, &read_node, fs_repo) == 0) { ipfs_cid_free(cid); return 0; } @@ -47,7 +47,7 @@ int ipfs_exporter_to_file(const unsigned char* hash, const char* file_name, cons struct NodeLink* link = read_node->head_link; struct Node* link_node = NULL; while (link != NULL) { - if ( ipfs_merkledag_get(link->cid, &link_node, fs_repo) == 0) { + if ( ipfs_merkledag_get(link->hash, link->hash_size, &link_node, fs_repo) == 0) { fclose(file); ipfs_node_free(read_node); return 0; diff --git a/importer/importer.c b/importer/importer.c index f4b32c6..a8b0516 100644 --- a/importer/importer.c +++ b/importer/importer.c @@ -29,7 +29,7 @@ size_t ipfs_import_chunk(FILE* file, struct Node* node, struct FSRepo* fs_repo) ipfs_merkledag_add(new_node, fs_repo); // put link in parent node struct NodeLink* new_link = NULL; - ipfs_node_link_new("", new_node->cached->hash, new_node->cached->hash_length, &new_link); + ipfs_node_link_create("", new_node->hash, new_node->hash_size, &new_link); ipfs_node_add_link(node, new_link); ipfs_node_free(new_node); } diff --git a/include/ipfs/blocks/blockstore.h b/include/ipfs/blocks/blockstore.h index 37f2569..f209c42 100644 --- a/include/ipfs/blocks/blockstore.h +++ b/include/ipfs/blocks/blockstore.h @@ -28,7 +28,7 @@ int ipfs_blockstore_has(struct Cid* cid, struct FSRepo* fs_repo); * @param block where to put the data to be returned * @returns true(1) on success */ -int ipfs_blockstore_get(const struct Cid* cid, struct Block** block, const struct FSRepo* fs_repo); +int ipfs_blockstore_get(const unsigned char* hash, size_t hash_length, struct Block** block, const struct FSRepo* fs_repo); /*** * Put a block in the blockstore diff --git a/include/ipfs/cid/cid.h b/include/ipfs/cid/cid.h index c3c80a7..a145d7e 100644 --- a/include/ipfs/cid/cid.h +++ b/include/ipfs/cid/cid.h @@ -85,7 +85,7 @@ int ipfs_cid_decode_hash_from_base58(const unsigned char* incoming, size_t incom * @param max_buffer_length the maximum space reserved for the results * @returns true(1) on success */ -int ipfs_cid_hash_to_base58(struct Cid* cid, unsigned char* buffer, size_t max_buffer_length); +int ipfs_cid_hash_to_base58(const unsigned char* hash, size_t hash_length, unsigned char* buffer, size_t max_buffer_length); /*** * Turn a multibase decoded string of bytes into a Cid struct diff --git a/include/ipfs/datastore/ds_helper.h b/include/ipfs/datastore/ds_helper.h index f6780de..0c47358 100644 --- a/include/ipfs/datastore/ds_helper.h +++ b/include/ipfs/datastore/ds_helper.h @@ -15,7 +15,7 @@ * @param results_length the length of the generated key * @returns true(1) on success */ -int ipfs_datastore_helper_ds_key_from_binary(unsigned char* binary_array, size_t array_length, +int ipfs_datastore_helper_ds_key_from_binary(const unsigned char* binary_array, size_t array_length, unsigned char* results, size_t max_results_length, size_t* results_length); /** @@ -27,7 +27,7 @@ int ipfs_datastore_helper_ds_key_from_binary(unsigned char* binary_array, size_t * @param completed_binary_array_length the length of what was written to the binary_array * @returns true(1) on success */ -int ipfs_datastore_helper_binary_from_ds_key(unsigned char* ds_key, size_t key_length, unsigned char* binary_array, +int ipfs_datastore_helper_binary_from_ds_key(const unsigned char* ds_key, size_t key_length, unsigned char* binary_array, size_t max_binary_array_length, size_t* completed_binary_array_length); #endif diff --git a/include/ipfs/merkledag/merkledag.h b/include/ipfs/merkledag/merkledag.h index f58af38..10adcca 100644 --- a/include/ipfs/merkledag/merkledag.h +++ b/include/ipfs/merkledag/merkledag.h @@ -22,6 +22,6 @@ int ipfs_merkledag_add(struct Node* node, struct FSRepo* fs_repo); * @param fs_repo the repository * @returns true(1) on success */ -int ipfs_merkledag_get(const struct Cid* cid, struct Node** node, const struct FSRepo* fs_repo); +int ipfs_merkledag_get(const unsigned char* hash, size_t hash_size, struct Node** node, const struct FSRepo* fs_repo); #endif diff --git a/include/ipfs/merkledag/node.h b/include/ipfs/merkledag/node.h index 5973970..3a390df 100644 --- a/include/ipfs/merkledag/node.h +++ b/include/ipfs/merkledag/node.h @@ -15,18 +15,23 @@ struct NodeLink { + size_t hash_size; + unsigned char* hash; char* name; - struct Cid * cid; + size_t t_size; struct NodeLink* next; }; struct Node { - unsigned char* data; + // saved in protobuf size_t data_size; - unsigned char* encoded; - struct Cid* cached; + unsigned char* data; struct NodeLink* head_link; + // not saved in protobuf + unsigned char* encoded; + unsigned char* hash; + size_t hash_size; }; /*==================================================================================== @@ -46,7 +51,14 @@ struct Node * @param node_link a pointer to the new struct NodeLink * @returns true(1) on success */ -int ipfs_node_link_new(char * name, unsigned char * ahash, size_t hash_size, struct NodeLink** node_link); +int ipfs_node_link_create(char * name, unsigned char * ahash, size_t hash_size, struct NodeLink** node_link); + +/**** + * Allocate memory for a new NodeLink + * @param node_link a pointer to the newly allocated memory + * @returns true(1) on success + */ +int ipfs_node_link_new(struct NodeLink** node_link); /* ipfs_node_link_free * @param L: Free the link you have allocated. @@ -82,7 +94,7 @@ int ipfs_node_link_protobuf_encode(struct NodeLink* link, unsigned char* buffer, * @param bytes_read the amount of bytes read by this function * @returns true(1) on success */ -int ipfs_node_link_protobuf_decode(unsigned char* buffer, size_t buffer_length, struct NodeLink** link, size_t* bytes_read); +int ipfs_node_link_protobuf_decode(unsigned char* buffer, size_t buffer_length, struct NodeLink** link); /*** @@ -127,7 +139,7 @@ int ipfs_node_new(struct Node** node); * @param cid the cid * @returns true(1) on success */ -int ipfs_node_set_cached(struct Node* node, const struct Cid* cid); +int ipfs_node_set_hash(struct Node* node, const unsigned char* hash, size_t hash_size); /*ipfs_node_set_data * Sets the data of a node diff --git a/include/ipfs/repo/fsrepo/fs_repo.h b/include/ipfs/repo/fsrepo/fs_repo.h index 7ab6d2c..4d019e8 100644 --- a/include/ipfs/repo/fsrepo/fs_repo.h +++ b/include/ipfs/repo/fsrepo/fs_repo.h @@ -71,6 +71,6 @@ int ipfs_repo_fsrepo_init(struct FSRepo* config); * @returns true(1) on success */ int ipfs_repo_fsrepo_block_write(struct Block* block, const struct FSRepo* fs_repo); -int ipfs_repo_fsrepo_block_read(const struct Cid* cid, struct Block** block, const struct FSRepo* fs_repo); +int ipfs_repo_fsrepo_block_read(const unsigned char* hash, size_t hash_length, struct Block** block, const struct FSRepo* fs_repo); #endif /* fs_repo_h */ diff --git a/merkledag/merkledag.c b/merkledag/merkledag.c index 7e506c1..2f57aea 100644 --- a/merkledag/merkledag.c +++ b/merkledag/merkledag.c @@ -32,7 +32,7 @@ int ipfs_merkledag_add(struct Node* node, struct FSRepo* fs_repo) { return 0; } - ipfs_node_set_cached(node, block->cid); + ipfs_node_set_hash(node, block->cid->hash, block->cid->hash_length); if (block != NULL) ipfs_blocks_block_free(block); @@ -48,7 +48,7 @@ int ipfs_merkledag_add(struct Node* node, struct FSRepo* fs_repo) { * @param fs_repo the repository * @returns true(1) on success */ -int ipfs_merkledag_get(const struct Cid* cid, struct Node** node, const struct FSRepo* fs_repo) { +int ipfs_merkledag_get(const unsigned char* hash, size_t hash_size, struct Node** node, const struct FSRepo* fs_repo) { int retVal = 1; struct Block* block; size_t key_length = 100; @@ -56,12 +56,12 @@ int ipfs_merkledag_get(const struct Cid* cid, struct Node** node, const struct F // look for the node in the datastore. If it is not there, it is not a node. // If it exists, it is only a block. - retVal = fs_repo->config->datastore->datastore_get((char*)cid->hash, cid->hash_length, key, key_length, &key_length, fs_repo->config->datastore); + retVal = fs_repo->config->datastore->datastore_get((char*)hash, hash_size, key, key_length, &key_length, fs_repo->config->datastore); if (retVal == 0) return 0; // we have the record from the db. Go get the block from the blockstore - retVal = ipfs_repo_fsrepo_block_read(cid, &block, fs_repo); + retVal = ipfs_repo_fsrepo_block_read(hash, hash_size, &block, fs_repo); if (retVal == 0) { return 0; } @@ -73,7 +73,7 @@ int ipfs_merkledag_get(const struct Cid* cid, struct Node** node, const struct F } // set the cid on the node - if (ipfs_node_set_cached(*node, cid) == 0) { + if (ipfs_node_set_hash(*node, hash, hash_size) == 0) { ipfs_blocks_block_free(block); ipfs_node_free(*node); return 0; diff --git a/merkledag/node.c b/merkledag/node.c index d2e854c..ddb3e44 100644 --- a/merkledag/node.c +++ b/merkledag/node.c @@ -10,10 +10,10 @@ #include "ipfs/merkledag/node.h" -// for protobuf Node data & data_size encoded cid link_amount & links -enum WireType ipfs_node_message_fields[] = { WIRETYPE_LENGTH_DELIMITED, WIRETYPE_LENGTH_DELIMITED, WIRETYPE_LENGTH_DELIMITED, WIRETYPE_LENGTH_DELIMITED }; -// for protobuf NodeLink name cid -enum WireType ipfs_node_link_message_fields[] = { WIRETYPE_LENGTH_DELIMITED, WIRETYPE_LENGTH_DELIMITED }; +// for protobuf Node (all fields optional) links (repeated node_link) data (optional bytes) +enum WireType ipfs_node_message_fields[] = { WIRETYPE_LENGTH_DELIMITED, WIRETYPE_LENGTH_DELIMITED }; +// for protobuf NodeLink (all fields optional) hash name tsize +enum WireType ipfs_node_link_message_fields[] = { WIRETYPE_LENGTH_DELIMITED, WIRETYPE_LENGTH_DELIMITED, WIRETYPE_VARINT }; /*==================================================================================== * Link Functions @@ -24,23 +24,43 @@ enum WireType ipfs_node_link_message_fields[] = { WIRETYPE_LENGTH_DELIMITED, WIR * @Param size: Size of the link (size_t) * @Param ahash: An Qmhash */ -int ipfs_node_link_new(char * name, unsigned char * ahash, size_t hash_size, struct NodeLink** node_link) +int ipfs_node_link_create(char * name, unsigned char * ahash, size_t hash_size, struct NodeLink** node_link) { *node_link = malloc(sizeof(struct NodeLink)); if (*node_link == NULL) return 0; - (*node_link)->name = malloc(strlen(name) + 1); - if ( (*node_link)->name == NULL) { - free(*node_link); + + struct NodeLink* link = *node_link; + // hash + link->hash_size = hash_size; + link->hash = (unsigned char*)malloc(hash_size); + memcpy(link->hash, ahash, hash_size); + // name + link->name = malloc(strlen(name) + 1); + if ( link->name == NULL) { + free(link); return 0; } - strcpy((*node_link)->name, name); - (*node_link)->next = NULL; - int ver = 0; - if (ipfs_cid_new(ver, ahash, hash_size, CID_PROTOBUF, &(*node_link)->cid) == 0) { - free(*node_link); + strcpy(link->name, name); + // t_size + link->t_size = 0; + // other, non-protobuffed data + link->next = NULL; + + return 1; +} + +int ipfs_node_link_new(struct NodeLink** node_link) { + *node_link = malloc(sizeof(struct NodeLink)); + if (*node_link == NULL) return 0; - } + + struct NodeLink* link = *node_link; + link->hash = NULL; + link->hash_size = 0; + link->name = NULL; + link->next = NULL; + link->t_size = 0; return 1; } @@ -50,8 +70,8 @@ int ipfs_node_link_new(char * name, unsigned char * ahash, size_t hash_size, str int ipfs_node_link_free(struct NodeLink * node_link) { if (node_link != NULL) { - if (node_link->cid != NULL) - ipfs_cid_free(node_link->cid); + if (node_link->hash != NULL) + free(node_link->hash); if (node_link->name != NULL) free(node_link->name); free(node_link); @@ -59,49 +79,83 @@ int ipfs_node_link_free(struct NodeLink * node_link) return 1; } +/*** + * Find length of encoded version of NodeLink + * @param link the link to examine + * @returns the maximum length of the encoded NodeLink + */ size_t ipfs_node_link_protobuf_encode_size(struct NodeLink* link) { if (link == NULL) return 0; - + // hash, name, tsize size_t size = 0; - size += 11 + strlen(link->name); - size += ipfs_cid_protobuf_encode_size(link->cid); + if (link->hash_size > 0) { + size += 11 + link->hash_size; + } + if (link->name != NULL && strlen(link->name) > 0) { + size += 11 + strlen(link->name); + } + if (link->t_size > 0) { + size += 22; + } return size; } +/** + * Encode a NodeLink in protobuf format + * @param link the link to work with + * @param buffer the buffer to fill + * @param max_buffer_length the length of the buffer + * @param bytes_written the number of bytes written to buffer + * @returns true(1) on success + */ int ipfs_node_link_protobuf_encode(struct NodeLink* link, unsigned char* buffer, size_t max_buffer_length, size_t* bytes_written) { + // 3 fields, hash (length delimited), name (length delimited), tsize (varint) size_t bytes_used = 0; int retVal = 0; *bytes_written = 0; - retVal = protobuf_encode_length_delimited(1, ipfs_node_link_message_fields[0], link->name, strlen(link->name), &buffer[*bytes_written], max_buffer_length - *bytes_written, &bytes_used); - if (retVal == 0) - return 0; - *bytes_written += bytes_used; - // cid - size_t cid_size = ipfs_cid_protobuf_encode_size(link->cid); - unsigned char cid_buffer[cid_size]; - retVal = ipfs_cid_protobuf_encode(link->cid, cid_buffer, cid_size, &bytes_used); - if (retVal == 0) - return 0; - retVal = protobuf_encode_length_delimited(2, ipfs_node_link_message_fields[1], (char*)&cid_buffer[0], bytes_used, &buffer[*bytes_written], max_buffer_length - *bytes_written, &bytes_used); - if (retVal == 0) - return 0; - *bytes_written += bytes_used; + // hash + if (link->hash_size > 0) { + retVal = protobuf_encode_length_delimited(1, ipfs_node_link_message_fields[0], (char*)link->hash, link->hash_size, &buffer[*bytes_written], max_buffer_length - *bytes_written, &bytes_used); + if (retVal == 0) + return 0; + *bytes_written += bytes_used; + } + // name + if (link->name != NULL && strlen(link->name) > 0) { + retVal = protobuf_encode_string(2, ipfs_node_link_message_fields[1], link->name, &buffer[*bytes_written], max_buffer_length - *bytes_written, &bytes_used); + if (retVal == 0) + return 0; + *bytes_written += bytes_used; + } + // tsize + if (link->t_size > 0) { + retVal = protobuf_encode_varint(3, ipfs_node_link_message_fields[2], link->t_size, &buffer[*bytes_written], max_buffer_length - *bytes_written, &bytes_used); + if (retVal == 0) + return 0; + *bytes_written += bytes_used; + } return 1; } -int ipfs_node_link_protobuf_decode(unsigned char* buffer, size_t buffer_length, struct NodeLink** link, size_t* bytes_read) { +/** + * Turn a protobuf encoded byte array into a NodeLink object + * @param buffer the buffer to look in + * @param buffer_length the length of the buffer + * @param link the link to fill + * @returns true(1) on success + */ +int ipfs_node_link_protobuf_decode(unsigned char* buffer, size_t buffer_length, struct NodeLink** node_link) { size_t pos = 0; int retVal = 0; - *link = (struct NodeLink*)malloc(sizeof(struct NodeLink)); - (*link)->cid = NULL; - (*link)->name = NULL; - (*link)->next = NULL; - unsigned char* temp_buffer = NULL; - size_t temp_size; + struct NodeLink* link = NULL; - if (*link == NULL) + // allocate memory for object + if (ipfs_node_link_new(node_link) == 0) goto exit; + + link = *node_link; + while(pos < buffer_length) { size_t bytes_read = 0; int field_no; @@ -111,19 +165,24 @@ int ipfs_node_link_protobuf_decode(unsigned char* buffer, size_t buffer_length, } pos += bytes_read; switch(field_no) { - case (1): - if (protobuf_decode_string(&buffer[pos], buffer_length - pos, &((*link)->name), &bytes_read) == 0) + case (1): { // hash + if (protobuf_decode_length_delimited(&buffer[pos], buffer_length - pos, (char**)&link->hash, &link->hash_size, &bytes_read) == 0) goto exit; pos += bytes_read; break; - case (2): - if (protobuf_decode_length_delimited(&buffer[pos], buffer_length - pos, (char**)&temp_buffer, &temp_size, &bytes_read) == 0) + } + case (2): { // name + if (protobuf_decode_string(&buffer[pos], buffer_length - pos, &link->name, &bytes_read) == 0) goto exit; - ipfs_cid_protobuf_decode(temp_buffer, temp_size, &((*link)->cid)); pos += bytes_read; - free(temp_buffer); - temp_buffer = NULL; break; + } + case (3): { // t_size + if (protobuf_decode_varint(&buffer[pos], buffer_length - pos, (unsigned long long*)&link->t_size, &bytes_read) == 0) + goto exit; + pos += bytes_read; + break; + } } } @@ -132,10 +191,8 @@ int ipfs_node_link_protobuf_decode(unsigned char* buffer, size_t buffer_length, exit: if (retVal == 0) { if (link != NULL) - ipfs_node_link_free(*link); + ipfs_node_link_free(link); } - if (temp_buffer != NULL) - free(temp_buffer); return retVal; } @@ -145,21 +202,16 @@ exit: */ size_t ipfs_node_protobuf_encode_size(struct Node* node) { size_t size = 0; - // data - size += 11 + node->data_size; - // encoded - size += 11; - if (node->encoded != NULL) - size += strlen((const char*)node->encoded); - // cid (a.k.a. cached) - size += 11 + ipfs_cid_protobuf_encode_size(node->cached); // links - size += 11; struct NodeLink* current = node->head_link; while(current != NULL) { - size += 11 + strlen(current->name) + ipfs_cid_protobuf_encode_size(current->cid); + size += 11 + ipfs_node_link_protobuf_encode_size(current); current = current->next; } + // data + if (node->data_size > 0) { + size += 11 + node->data_size; + } return size; } @@ -172,44 +224,30 @@ size_t ipfs_node_protobuf_encode_size(struct Node* node) { * @returns true(1) on success */ int ipfs_node_protobuf_encode(struct Node* node, unsigned char* buffer, size_t max_buffer_length, size_t* bytes_written) { - // data & data_size size_t bytes_used = 0; *bytes_written = 0; int retVal = 0; - retVal = protobuf_encode_length_delimited(1, ipfs_node_message_fields[0], (char*)node->data, node->data_size, &buffer[*bytes_written], max_buffer_length - *bytes_written, &bytes_used); - if (retVal == 0) - return 0; - *bytes_written += bytes_used; - int sz = 0; - if (node->encoded != NULL) - sz = strlen((char*)node->encoded); - retVal = protobuf_encode_length_delimited(2, ipfs_node_message_fields[1], (char*)node->encoded, sz, &buffer[*bytes_written], max_buffer_length - *bytes_written, &bytes_used); - if (retVal == 0) - return 0; - *bytes_written += bytes_used; - // cid - size_t cid_size = ipfs_cid_protobuf_encode_size(node->cached); - unsigned char cid[cid_size]; - retVal = ipfs_cid_protobuf_encode(node->cached, cid, cid_size, &cid_size); - if (retVal == 0) - return 0; - retVal = protobuf_encode_length_delimited(3, ipfs_node_message_fields[2], (char*)cid, cid_size, &buffer[*bytes_written], max_buffer_length - *bytes_written, &bytes_used); - if (retVal == 0) - return 0; - *bytes_written += bytes_used; // links struct NodeLink* current = node->head_link; - while(current != NULL) { - // size + name + cid - size_t link_buffer_size = 11 + ipfs_node_link_protobuf_encode_size(current); - unsigned char link_buffer[link_buffer_size]; - retVal = ipfs_node_link_protobuf_encode(current, link_buffer, link_buffer_size, &link_buffer_size); + while (current != NULL) { + size_t temp_size = ipfs_node_link_protobuf_encode_size(current); + unsigned char temp[temp_size]; + retVal = ipfs_node_link_protobuf_encode(current, temp, temp_size, &bytes_used); + if (retVal == 0) + return 0; + retVal = protobuf_encode_length_delimited(1, ipfs_node_message_fields[0], (char*)temp, bytes_used, &buffer[*bytes_written], max_buffer_length - *bytes_written, &bytes_used); if (retVal == 0) return 0; - protobuf_encode_length_delimited(4, ipfs_node_message_fields[3], (char*)link_buffer, link_buffer_size, &buffer[*bytes_written], max_buffer_length - *bytes_written, &bytes_used); *bytes_written += bytes_used; current = current->next; } + // data + if (node->data_size > 0) { + retVal = protobuf_encode_length_delimited(2, ipfs_node_message_fields[1], (char*)node->data, node->data_size, &buffer[*bytes_written], max_buffer_length - *bytes_written, &bytes_used); + if (retVal == 0) + return 0; + *bytes_written += bytes_used; + } return 1; } @@ -223,10 +261,8 @@ int ipfs_node_protobuf_encode(struct Node* node, unsigned char* buffer, size_t m */ int ipfs_node_protobuf_decode(unsigned char* buffer, size_t buffer_length, struct Node** node) { /* - * Field 0: data - * Field 1: encoded - * Field 3: cid - * Field 4: links array + * Field 0: link + * Field 1: data */ size_t pos = 0; int retVal = 0; @@ -246,35 +282,23 @@ int ipfs_node_protobuf_decode(unsigned char* buffer, size_t buffer_length, struc } pos += bytes_read; switch(field_no) { - case (1): // data - if (protobuf_decode_length_delimited(&buffer[pos], buffer_length - pos, (char**)&((*node)->data), &((*node)->data_size), &bytes_read) == 0) - goto exit; - pos += bytes_read; - break; - case (2): // encoded - if (protobuf_decode_length_delimited(&buffer[pos], buffer_length - pos, (char**)&((*node)->encoded), &temp_size, &bytes_read) == 0) - goto exit; - pos += bytes_read; - break; - case (3): // cid + case (1): {// links if (protobuf_decode_length_delimited(&buffer[pos], buffer_length - pos, (char**)&temp_buffer, &temp_size, &bytes_read) == 0) goto exit; pos += bytes_read; - if (ipfs_cid_protobuf_decode(temp_buffer, temp_size, &((*node)->cached)) == 0) - goto exit; - free(temp_buffer); - temp_buffer = NULL; - break; - case (4): // links - if (protobuf_decode_length_delimited(&buffer[pos], buffer_length - pos, (char**)&temp_buffer, &temp_size, &bytes_read) == 0) - goto exit; - pos += bytes_read; - if (ipfs_node_link_protobuf_decode(temp_buffer, temp_size, &temp_link, &bytes_read) == 0) + if (ipfs_node_link_protobuf_decode(temp_buffer, temp_size, &temp_link) == 0) goto exit; free(temp_buffer); temp_buffer = NULL; ipfs_node_add_link(*node, temp_link); break; + } + case (2): { // data + if (protobuf_decode_length_delimited(&buffer[pos], buffer_length - pos, (char**)&((*node)->data), &((*node)->data_size), &bytes_read) == 0) + goto exit; + pos += bytes_read; + break; + } } } @@ -302,7 +326,8 @@ int ipfs_node_new(struct Node** node) *node = (struct Node *)malloc(sizeof(struct Node)); if (*node == NULL) return 0; - (*node)->cached = NULL; + (*node)->hash = NULL; + (*node)->hash_size = 0; (*node)->data = NULL; (*node)->data_size = 0; (*node)->encoded = NULL; @@ -316,11 +341,25 @@ int ipfs_node_new(struct Node** node) * @param cid the Cid to be copied into the Node->cached element * @returns true(1) on success */ -int ipfs_node_set_cached(struct Node* node, const struct Cid* cid) +int ipfs_node_set_hash(struct Node* node, const unsigned char* hash, size_t hash_size) { - if (node->cached != NULL) - ipfs_cid_free(node->cached); - return ipfs_cid_new(cid->version, cid->hash, cid->hash_length, cid->codec, &(node->cached)); + // don't reallocate if it is the same size + if (node->hash != NULL && hash_size != node->hash_size) { + free(node->hash); + node->hash = NULL; + node->hash_size = 0; + } + // we must reallocate + if (node->hash == NULL && hash_size > 0) { + node->hash = (unsigned char*)malloc(hash_size); + if (node->hash == NULL) + return 0; + } + if (hash_size > 0) { // don't bother if there is nothing to copy + memcpy(node->hash, hash, hash_size); + node->hash_size = hash_size; + } + return 1; } /*ipfs_node_set_data @@ -337,7 +376,8 @@ int ipfs_node_set_data(struct Node * N, unsigned char * Data, size_t data_size) return 0; } N->encoded = NULL; - N->cached = NULL; + N->hash = NULL; + N->hash_size = 0; N->data = malloc(sizeof(unsigned char) * data_size); if (N->data == NULL) return 0; @@ -425,9 +465,11 @@ int ipfs_node_free(struct Node * N) current = current->next; ipfs_node_remove_link(N, toDelete); } - if(N->cached) + if(N->hash != NULL) { - ipfs_cid_free(N->cached); + free(N->hash); + N->hash = NULL; + N->hash_size = 0; } if (N->data) { free(N->data); @@ -525,7 +567,8 @@ int ipfs_node_new_from_link(struct NodeLink * mylink, struct Node** node) return 0; (*node)->head_link = NULL; ipfs_node_add_link(*node, mylink); - (*node)->cached = NULL; + (*node)->hash = NULL; + (*node)->hash_size = 0; (*node)->data = NULL; (*node)->data_size = 0; (*node)->encoded = NULL; diff --git a/repo/fsrepo/fs_repo.c b/repo/fsrepo/fs_repo.c index 0d8ae7c..2d4d61f 100644 --- a/repo/fsrepo/fs_repo.c +++ b/repo/fsrepo/fs_repo.c @@ -554,18 +554,18 @@ int ipfs_repo_fsrepo_block_write(struct Block* block, const struct FSRepo* fs_re return 1; } -int ipfs_repo_fsrepo_block_read(const struct Cid* cid, struct Block** block, const struct FSRepo* fs_repo) { +int ipfs_repo_fsrepo_block_read(const unsigned char* hash, size_t hash_length, struct Block** block, const struct FSRepo* fs_repo) { int retVal = 0; // get the base32 hash from the database // We do this only to see if it is in the database size_t fs_key_length = 100; unsigned char fs_key[fs_key_length]; - retVal = fs_repo->config->datastore->datastore_get((char*)cid->hash, cid->hash_length, fs_key, fs_key_length, &fs_key_length, fs_repo->config->datastore); + retVal = fs_repo->config->datastore->datastore_get((const char*)hash, hash_length, fs_key, fs_key_length, &fs_key_length, fs_repo->config->datastore); if (retVal == 0) // maybe it doesn't exist? return 0; // now get the block from the blockstore - retVal = ipfs_blockstore_get(cid, block, fs_repo); + retVal = ipfs_blockstore_get(hash, hash_length, block, fs_repo); return retVal; } diff --git a/test/merkledag/test_merkledag.h b/test/merkledag/test_merkledag.h index db19787..46feb46 100644 --- a/test/merkledag/test_merkledag.h +++ b/test/merkledag/test_merkledag.h @@ -52,7 +52,7 @@ int test_merkledag_get_data() { // now retrieve it struct Node* results_node; - retVal = ipfs_merkledag_get(node1->cached, &results_node, fs_repo); + retVal = ipfs_merkledag_get(node1->hash, node1->hash_size, &results_node, fs_repo); if (retVal == 0) { ipfs_node_free(node1); ipfs_node_free(results_node); @@ -112,7 +112,7 @@ int test_merkledag_add_data() { } // make sure everything is correct - if (node1->cached == NULL) + if (node1->hash == NULL) return 0; int first_add_size = os_utils_file_size("/tmp/.ipfs/datastore/data.mdb"); @@ -132,13 +132,13 @@ int test_merkledag_add_data() { } // make sure everything is correct - if (node2->cached == NULL) { + if (node2->hash == NULL) { ipfs_node_free(node1); ipfs_node_free(node2); return 0; } - for(int i = 0; i < node1->cached->hash_length; i++) { - if (node1->cached->hash[i] != node2->cached->hash[i]) { + for(int i = 0; i < node1->hash_size; i++) { + if (node1->hash[i] != node2->hash[i]) { printf("hash of node1 does not match node2 at position %d\n", i); ipfs_node_free(node1); ipfs_node_free(node2); @@ -169,7 +169,7 @@ int test_merkledag_add_data() { } // make sure everything is correct - if (node3->cached == NULL) { + if (node3->hash == NULL) { ipfs_node_free(node1); ipfs_node_free(node2); ipfs_node_free(node3); @@ -237,7 +237,7 @@ int test_merkledag_add_node_with_links() { } // make link - retVal = ipfs_node_link_new("", (unsigned char*)"abc123", 6, &link); + retVal = ipfs_node_link_create("", (unsigned char*)"abc123", 6, &link); if (retVal == 0) { printf("Unable to make new link\n"); ipfs_repo_fsrepo_free(fs_repo); @@ -259,7 +259,7 @@ int test_merkledag_add_node_with_links() { } // now look for it - retVal = ipfs_merkledag_get(node1->cached, &node2, fs_repo); + retVal = ipfs_merkledag_get(node1->hash, node1->hash_size, &node2, fs_repo); if (retVal == 0) { ipfs_repo_fsrepo_free(fs_repo); ipfs_node_free(node1); @@ -269,16 +269,16 @@ int test_merkledag_add_node_with_links() { struct NodeLink* node1_link = node1->head_link; struct NodeLink* node2_link = node2->head_link; - if (node1_link->cid->hash_length != node2_link->cid->hash_length) { - printf("Hashes are not of the same length. Hash1: %lu, Hash2: %lu\n", node1_link->cid->hash_length, node2_link->cid->hash_length); + if (node1_link->hash_size != node2_link->hash_size) { + printf("Hashes are not of the same length. Hash1: %lu, Hash2: %lu\n", node1_link->hash_size, node2_link->hash_size); ipfs_repo_fsrepo_free(fs_repo); ipfs_node_free(node1); ipfs_node_free(node2); return 0; } while(node1_link != NULL) { - for(int i = 0; i < node1_link->cid->hash_length; i++) { - if(node1_link->cid->hash[i] != node2_link->cid->hash[i]) { + for(int i = 0; i < node1_link->hash_size; i++) { + if(node1_link->hash[i] != node2_link->hash[i]) { printf("Hashes do not match for node %s\n", node1_link->name); ipfs_repo_fsrepo_free(fs_repo); ipfs_node_free(node1); diff --git a/test/node/test_importer.h b/test/node/test_importer.h index 63097d8..f71930e 100644 --- a/test/node/test_importer.h +++ b/test/node/test_importer.h @@ -51,19 +51,18 @@ int test_import_large_file() { } // cid should be the same each time - unsigned char cid_test[10] = { 0xec ,0x79 ,0x18 ,0x4c, 0xe8, 0xb0, 0x66, 0x39, 0xaa, 0xed }; + unsigned char cid_test[10] = { 0x2c ,0x8e ,0x20 ,0x1b, 0xc7, 0xcc, 0x4d, 0x8f, 0x7e, 0x77 }; /* for (int i = 0; i < 10; i++) { - printf(" %02x ", write_node->cached->hash[i]); + printf(" %02x ", write_node->hash[i]); } printf("\n"); */ - for(int i = 0; i < 10; i++) { - if (write_node->cached->hash[i] != cid_test[i]) { - printf("Hashes should be the same each time, and do not match at position %d, should be %02x but is %02x\n", i, cid_test[i], write_node->cached->hash[i]); + if (write_node->hash[i] != cid_test[i]) { + printf("Hashes should be the same each time, and do not match at position %d, should be %02x but is %02x\n", i, cid_test[i], write_node->hash[i]); ipfs_repo_fsrepo_free(fs_repo); return 0; } @@ -71,7 +70,7 @@ int test_import_large_file() { // make sure all went okay struct Node* read_node; - if (ipfs_merkledag_get(write_node->cached, &read_node, fs_repo) == 0) { + if (ipfs_merkledag_get(write_node->hash, write_node->hash_size, &read_node, fs_repo) == 0) { ipfs_repo_fsrepo_free(fs_repo); ipfs_node_free(write_node); return 0; @@ -79,7 +78,7 @@ int test_import_large_file() { // the second block should be there struct Node* read_node2; - if (ipfs_merkledag_get(read_node->head_link->cid, &read_node2, fs_repo) == 0) { + if (ipfs_merkledag_get(read_node->head_link->hash, read_node->head_link->hash_size, &read_node2, fs_repo) == 0) { printf("Unable to find the linked node.\n"); ipfs_repo_fsrepo_free(fs_repo); ipfs_node_free(write_node); @@ -110,7 +109,7 @@ int test_import_large_file() { // convert cid to multihash size_t base58_size = 55; unsigned char base58[base58_size]; - if ( ipfs_cid_hash_to_base58(read_node->cached, base58, base58_size) == 0) { + if ( ipfs_cid_hash_to_base58(read_node->hash, read_node->hash_size, base58, base58_size) == 0) { printf("Unable to convert cid to multihash\n"); ipfs_repo_fsrepo_free(fs_repo); ipfs_node_free(write_node); @@ -199,17 +198,17 @@ int test_import_small_file() { } // cid should be the same each time - unsigned char cid_test[10] = { 0x47,0x51,0x40,0x0a, 0xdf, 0x62, 0xf9, 0xcc, 0x8d, 0xbb }; + unsigned char cid_test[10] = { 0x94, 0x4f, 0x39, 0xa0, 0x33, 0x5d, 0x7f, 0xf2, 0xcd, 0x66 }; - /** + /* for (int i = 0; i < 10; i++) { - printf("%02x\n", write_node->cached->hash[i]); + printf("%02x\n", write_node->hash[i]); } */ for(int i = 0; i < 10; i++) { - if (write_node->cached->hash[i] != cid_test[i]) { - printf("Hashes do not match at position %d, should be %02x but is %02x\n", i, cid_test[i], write_node->cached->hash[i]); + if (write_node->hash[i] != cid_test[i]) { + printf("Hashes do not match at position %d, should be %02x but is %02x\n", i, cid_test[i], write_node->hash[i]); ipfs_repo_fsrepo_free(fs_repo); return 0; } @@ -217,7 +216,7 @@ int test_import_small_file() { // make sure all went okay struct Node* read_node; - if (ipfs_merkledag_get(write_node->cached, &read_node, fs_repo) == 0) { + if (ipfs_merkledag_get(write_node->hash, write_node->hash_size, &read_node, fs_repo) == 0) { ipfs_repo_fsrepo_free(fs_repo); ipfs_node_free(write_node); return 0; diff --git a/test/node/test_node.h b/test/node/test_node.h index b65da53..8fd5b24 100644 --- a/test/node/test_node.h +++ b/test/node/test_node.h @@ -5,7 +5,7 @@ int test_node() { char * name = "Alex"; unsigned char * ahash = (unsigned char*)"QmYwAPJzv5CZsnA625s3Xf2nemtYgPpHdWEz79ojWnPbdG"; struct NodeLink * mylink; - int retVal = ipfs_node_link_new(name,ahash, strlen((char*)ahash), &mylink); + int retVal = ipfs_node_link_create(name,ahash, strlen((char*)ahash), &mylink); if (retVal == 0) return 0; @@ -13,7 +13,7 @@ int test_node() { char * name2 = "Simo"; unsigned char * ahash2 = (unsigned char*)"QmYwAPJzv5CZsnA625s3Xf2nemtYgPpHdWEz79ojWnSimo"; struct NodeLink * mylink2; - retVal = ipfs_node_link_new(name2, ahash2, strlen((char*)ahash2), &mylink2); + retVal = ipfs_node_link_create(name2, ahash2, strlen((char*)ahash2), &mylink2); //Nodes struct Node * Mynode; @@ -32,19 +32,11 @@ int compare_link(struct NodeLink* link1, struct NodeLink* link2) { printf("Link Names are different %s vs. %s\n", link1->name, link2->name); return 0; } - if (link1->cid->codec != link2->cid->codec) { - printf("Link cid codecs are different. Expected %02x but got %02x\n", link1->cid->codec, link2->cid->codec); + if (link1->hash_size != link2->hash_size) { + printf("Link cid hash lengths are different. Expected %d but got %d\n", (int)link1->hash_size, (int)link2->hash_size); return 0; } - if (link1->cid->hash_length != link2->cid->hash_length) { - printf("Link cid hash lengths are different. Expected %d but got %d\n", (int)link1->cid->hash_length, (int)link2->cid->hash_length); - return 0; - } - if (link1->cid->version != link2->cid->version) { - printf("Link cid versions are different. Expected %d but got %d\n", link1->cid->version, link2->cid->version); - return 0; - } - if (memcmp(link1->cid->hash, link2->cid->hash, link1->cid->hash_length) != 0) { + if (memcmp(link1->hash, link2->hash, link1->hash_size) != 0) { printf("compare_link: The values of the hashes are different\n"); return 0; } @@ -59,7 +51,7 @@ int test_node_link_encode_decode() { int retVal = 0; // make a NodeLink - if (ipfs_node_link_new("My Name", (unsigned char*)"QmMyHash", 8, &control) == 0) + if (ipfs_node_link_create("My Name", (unsigned char*)"QmMyHash", 8, &control) == 0) goto l_exit; // encode it @@ -72,7 +64,7 @@ int test_node_link_encode_decode() { } // decode it - if (ipfs_node_link_protobuf_decode(buffer, nl_size, &results, &nl_size) == 0) { + if (ipfs_node_link_protobuf_decode(buffer, nl_size, &results) == 0) { goto l_exit; } @@ -107,14 +99,14 @@ int test_node_encode_decode() { goto ed_exit; // first link - if (ipfs_node_link_new((char*)"Link1", (unsigned char*)"QmLink1", 7, &link1) == 0) + if (ipfs_node_link_create((char*)"Link1", (unsigned char*)"QmLink1", 7, &link1) == 0) goto ed_exit; if ( ipfs_node_add_link(control, link1) == 0) goto ed_exit; // second link - if (ipfs_node_link_new((char*)"Link2", (unsigned char*)"QmLink2", 7, &link2) == 0) + if (ipfs_node_link_create((char*)"Link2", (unsigned char*)"QmLink2", 7, &link2) == 0) goto ed_exit; if ( ipfs_node_add_link(control, link2) == 0) goto ed_exit; diff --git a/test/repo/test_repo_fsrepo.h b/test/repo/test_repo_fsrepo.h index d23c506..a3f0756 100644 --- a/test/repo/test_repo_fsrepo.h +++ b/test/repo/test_repo_fsrepo.h @@ -68,7 +68,7 @@ int test_repo_fsrepo_write_read_block() { // retrieve the block struct Block* results; - retVal = ipfs_repo_fsrepo_block_read(block->cid, &results, fs_repo); + retVal = ipfs_repo_fsrepo_block_read(block->cid->hash, block->cid->hash_length, &results, fs_repo); if (retVal == 0) { ipfs_repo_fsrepo_free(fs_repo); ipfs_blocks_block_free(block);