diff --git a/blocks/blockstore.c b/blocks/blockstore.c index a63ea92..93b68f4 100644 --- a/blocks/blockstore.c +++ b/blocks/blockstore.c @@ -235,7 +235,7 @@ int ipfs_blockstore_get_unixfs(const unsigned char* hash, size_t hash_length, st * @param bytes_written the number of bytes written to the blockstore * @returns true(1) on success */ -int ipfs_blockstore_put_node(const struct Node* node, const struct FSRepo* fs_repo, size_t* bytes_written) { +int ipfs_blockstore_put_node(const struct HashtableNode* node, const struct FSRepo* fs_repo, size_t* bytes_written) { // from blockstore.go line 118 int retVal = 0; @@ -249,9 +249,9 @@ int ipfs_blockstore_put_node(const struct Node* node, const struct FSRepo* fs_re //TODO: put this in subdirectories // turn the block into a binary array - size_t protobuf_len = ipfs_node_protobuf_encode_size(node); + size_t protobuf_len = ipfs_hashtable_node_protobuf_encode_size(node); unsigned char protobuf[protobuf_len]; - retVal = ipfs_node_protobuf_encode(node, protobuf, protobuf_len, &protobuf_len); + retVal = ipfs_hashtable_node_protobuf_encode(node, protobuf, protobuf_len, &protobuf_len); if (retVal == 0) { free(key); return 0; @@ -286,7 +286,7 @@ int ipfs_blockstore_put_node(const struct Node* node, const struct FSRepo* fs_re * @param fs_repo where to look for the data * @returns true(1) on success */ -int ipfs_blockstore_get_node(const unsigned char* hash, size_t hash_length, struct Node** node, const struct FSRepo* fs_repo) { +int ipfs_blockstore_get_node(const unsigned char* hash, size_t hash_length, struct HashtableNode** node, const struct FSRepo* fs_repo) { // get datastore key, which is a base32 key of the multihash unsigned char* key = ipfs_blockstore_hash_to_base32(hash, hash_length); @@ -299,7 +299,7 @@ int ipfs_blockstore_get_node(const unsigned char* hash, size_t hash_length, stru size_t bytes_read = fread(buffer, 1, file_size, file); fclose(file); - int retVal = ipfs_node_protobuf_decode(buffer, bytes_read, node); + int retVal = ipfs_hashtable_node_protobuf_decode(buffer, bytes_read, node); free(key); free(filename); diff --git a/core/Makefile b/core/Makefile index e88d7ac..0fde7d7 100644 --- a/core/Makefile +++ b/core/Makefile @@ -7,7 +7,7 @@ endif LFLAGS = DEPS = builder.h ipfs_node.h -OBJS = builder.o daemon.o null.o ping.o bootstrap.o +OBJS = builder.o daemon.o null.o ping.o bootstrap.o ipfs_node.o %.o: %.c $(DEPS) $(CC) -c -o $@ $< $(CFLAGS) diff --git a/core/bootstrap.c b/core/bootstrap.c index 195bc6f..997c405 100644 --- a/core/bootstrap.c +++ b/core/bootstrap.c @@ -47,7 +47,7 @@ void ipfs_bootstrap_announce_files(struct IpfsNode* local_node) { enum DatastoreCursorOp op = CURSOR_FIRST; while (db->datastore_cursor_get(&key, &key_size, NULL, 0, op, db)) { libp2p_logger_debug("bootstrap", "Announcing a file to the world.\n"); - local_node->routing->Provide(local_node->routing, (char*)key, key_size); + local_node->routing->Provide(local_node->routing, key, key_size); op = CURSOR_NEXT; free(key); } @@ -66,7 +66,6 @@ void ipfs_bootstrap_announce_files(struct IpfsNode* local_node) { * @returns nothing useful */ void *ipfs_bootstrap_routing(void* param) { - libp2p_logger_add_class("bootstrap"); struct IpfsNode* local_node = (struct IpfsNode*)param; local_node->routing = ipfs_routing_new_online(local_node, &local_node->identity->private_key, NULL); local_node->routing->Bootstrap(local_node->routing); diff --git a/core/daemon.c b/core/daemon.c index 4eb9213..c6481d4 100644 --- a/core/daemon.c +++ b/core/daemon.c @@ -20,29 +20,15 @@ int ipfs_daemon_start(char* repo_path) { libp2p_logger_info("daemon", "Initializing daemon...\n"); - // read the configuration - struct FSRepo* fs_repo = NULL; - if (!ipfs_repo_fsrepo_new(repo_path, NULL, &fs_repo)) - goto exit; - - // open the repository and read the file - if (!ipfs_repo_fsrepo_open(fs_repo)) { - goto exit; - } - - // create a new IpfsNode - struct IpfsNode local_node; - local_node.mode = MODE_ONLINE; - local_node.peerstore = libp2p_peerstore_new(); - local_node.providerstore = libp2p_providerstore_new(); - local_node.repo = fs_repo; - local_node.identity = fs_repo->config->identity; + struct IpfsNode* local_node = NULL; + if (!ipfs_node_online_new(repo_path, &local_node)) + goto exit; // Set null router param - ma = multiaddress_new_from_string(fs_repo->config->addresses->swarm_head->item); + ma = multiaddress_new_from_string(local_node->repo->config->addresses->swarm_head->item); listen_param.port = multiaddress_get_ip_port(ma); listen_param.ipv4 = 0; // ip 0.0.0.0, all interfaces - listen_param.local_node = &local_node; + listen_param.local_node = local_node; // Create pthread for swarm listener. if (pthread_create(&work_pths[count_pths++], NULL, ipfs_null_listen, &listen_param)) { @@ -50,7 +36,7 @@ int ipfs_daemon_start(char* repo_path) { goto exit; } - ipfs_bootstrap_routing(&local_node); + //ipfs_bootstrap_routing(local_node); libp2p_logger_info("daemon", "Daemon is ready\n"); @@ -64,18 +50,12 @@ int ipfs_daemon_start(char* repo_path) { retVal = 1; exit: - fprintf(stderr, "Cleaning up daemon processes\n"); + libp2p_logger_debug("daemon", "Cleaning up daemon processes\n"); // clean up - if (fs_repo != NULL) - ipfs_repo_fsrepo_free(fs_repo); - if (local_node.peerstore != NULL) - libp2p_peerstore_free(local_node.peerstore); - if (local_node.providerstore != NULL) - libp2p_providerstore_free(local_node.providerstore); if (ma != NULL) multiaddress_free(ma); - if (local_node.routing != NULL) { - ipfs_routing_online_free(local_node.routing); + if (local_node != NULL) { + ipfs_node_free(local_node); } return retVal; @@ -94,10 +74,5 @@ int ipfs_daemon (int argc, char **argv) return 0; } - libp2p_logger_add_class("peerstore"); - libp2p_logger_add_class("providerstore"); - libp2p_logger_add_class("daemon"); - libp2p_logger_add_class("online"); - return ipfs_daemon_start(repo_path); } diff --git a/core/ipfs_node.c b/core/ipfs_node.c new file mode 100644 index 0000000..07dcffe --- /dev/null +++ b/core/ipfs_node.c @@ -0,0 +1,61 @@ +#include + +#include "ipfs/core/ipfs_node.h" + +/*** + * build an online IpfsNode + * @param repo_path where the IPFS repository directory is + * @param node the completed IpfsNode struct + * @returns true(1) on success + */ +int ipfs_node_online_new(const char* repo_path, struct IpfsNode** node) { + struct FSRepo* fs_repo = NULL; + + *node = (struct IpfsNode*)malloc(sizeof(struct IpfsNode)); + if(*node == NULL) + return 0; + + struct IpfsNode* local_node = *node; + + // build the struct + if (!ipfs_repo_fsrepo_new(repo_path, NULL, &fs_repo)) { + free(local_node); + return 0; + } + // open the repo + if (!ipfs_repo_fsrepo_open(fs_repo)) { + free(local_node); + return 0; + } + + // fill in the node + local_node->repo = fs_repo; + local_node->identity = fs_repo->config->identity; + local_node->peerstore = libp2p_peerstore_new(); + local_node->providerstore = libp2p_providerstore_new(); + local_node->mode = MODE_OFFLINE; + local_node->routing = ipfs_routing_new_online(local_node, &fs_repo->config->identity->private_key, NULL); + + return 1; +} + +/*** + * Free resources from the creation of an IpfsNode + * @param node the node to free + * @returns true(1) + */ +int ipfs_node_free(struct IpfsNode* node) { + if (node != NULL) { + if (node->providerstore != NULL) + libp2p_providerstore_free(node->providerstore); + if (node->peerstore != NULL) + libp2p_peerstore_free(node->peerstore); + if (node->repo != NULL) + ipfs_repo_fsrepo_free(node->repo); + if (node->mode == MODE_ONLINE) { + ipfs_routing_online_free(node->routing); + } + free(node); + } + return 1; +} diff --git a/core/null.c b/core/null.c index 8fd63c8..b15b99f 100644 --- a/core/null.c +++ b/core/null.c @@ -54,6 +54,7 @@ void ipfs_null_connection (void *ptr) session.insecure_stream = libp2p_net_multistream_stream_new(connection_param->file_descriptor, connection_param->ip, connection_param->port); session.default_stream = session.insecure_stream; session.datastore = connection_param->local_node->repo->config->datastore; + session.filestore = connection_param->local_node->repo->config->filestore; libp2p_logger_log("null", LOGLEVEL_INFO, "Connection %d, count %d\n", connection_param->file_descriptor, *(connection_param->count)); @@ -100,14 +101,14 @@ void ipfs_null_connection (void *ptr) } else { // try to get the Node - struct Node* node = NULL; + struct HashtableNode* node = NULL; if (!ipfs_merkledag_get(hash, hash_length, &node, connection_param->local_node->repo)) { _continue = 0; continue; } - size_t results_size = ipfs_node_protobuf_encode_size(node); + size_t results_size = ipfs_hashtable_node_protobuf_encode_size(node); unsigned char results[results_size]; - if (!ipfs_node_protobuf_encode(node, results, results_size, &results_size)) { + if (!ipfs_hashtable_node_protobuf_encode(node, results, results_size, &results_size)) { _continue = 0; continue; } diff --git a/importer/exporter.c b/importer/exporter.c index 9517d30..255d7de 100644 --- a/importer/exporter.c +++ b/importer/exporter.c @@ -6,18 +6,62 @@ #include "ipfs/merkledag/node.h" #include "ipfs/repo/fsrepo/fs_repo.h" #include "ipfs/repo/init.h" +#include "ipfs/core/ipfs_node.h" +#include "libp2p/utils/logger.h" + /** * pull objects from ipfs */ +/*** + * Helper method to retrieve a protobuf'd Node from the router + * @param local_node the context + * @param hash the hash to retrieve + * @param hash_size the length of the hash + * @param result a place to store the Node + * @returns true(1) on success, otherwise false(0) + */ +int ipfs_exporter_get_node(struct IpfsNode* local_node, const unsigned char* hash, const size_t hash_size, + struct HashtableNode** result) { + unsigned char *buffer = NULL; + size_t buffer_size = 0; + int retVal = 0; + struct Libp2pMessage* msg = NULL; + + if (local_node->routing->GetValue(local_node->routing, hash, hash_size, (void**)&buffer, &buffer_size)) { + libp2p_logger_debug("exporter", "get_node got a value. Converting it to a HashtableNode\n"); + // unprotobuf + if (ipfs_hashtable_node_protobuf_decode(buffer, buffer_size, result)) { + libp2p_logger_debug("exporter", "Conversion to HashtableNode successful\n"); + } + } else { + libp2p_logger_debug("exporter", "get_node got no value. Returning false.\n"); + goto exit; + } + + // copy in the hash + (*result)->hash_size = hash_size; + (*result)->hash = malloc(hash_size); + memcpy((*result)->hash, hash, hash_size); + + retVal = 1; + exit: + if (buffer != NULL) + free(buffer); + if (msg != NULL) + libp2p_message_free(msg); + + return retVal; +} /*** * Get a file by its hash, and write the data to a filestream * @param hash the base58 multihash of the cid * @param file_descriptor where to write - * @param fs_repo the repo + * @param local_node the context */ -int ipfs_exporter_to_filestream(const unsigned char* hash, FILE* file_descriptor, const struct FSRepo* fs_repo) { +int ipfs_exporter_to_filestream(const unsigned char* hash, FILE* file_descriptor, struct IpfsNode* local_node) { + // convert hash to cid struct Cid* cid = NULL; if ( ipfs_cid_decode_hash_from_base58(hash, strlen((char*)hash), &cid) == 0) { @@ -25,8 +69,8 @@ int ipfs_exporter_to_filestream(const unsigned char* hash, FILE* file_descriptor } // find block - struct Node* read_node = NULL; - if (ipfs_merkledag_get(cid->hash, cid->hash_length, &read_node, fs_repo) == 0) { + struct HashtableNode* read_node = NULL; + if (!ipfs_exporter_get_node(local_node, cid->hash, cid->hash_length, &read_node)) { ipfs_cid_free(cid); return 0; } @@ -41,31 +85,31 @@ int ipfs_exporter_to_filestream(const unsigned char* hash, FILE* file_descriptor size_t bytes_written = fwrite(unix_fs->bytes, 1, unix_fs->bytes_size, file_descriptor); if (bytes_written != unix_fs->bytes_size) { fclose(file_descriptor); - ipfs_node_free(read_node); + ipfs_hashtable_node_free(read_node); ipfs_unixfs_free(unix_fs); return 0; } ipfs_unixfs_free(unix_fs); } else { struct NodeLink* link = read_node->head_link; - struct Node* link_node = NULL; + struct HashtableNode* link_node = NULL; while (link != NULL) { - if ( ipfs_merkledag_get(link->hash, link->hash_size, &link_node, fs_repo) == 0) { + if ( !ipfs_exporter_get_node(local_node, link->hash, link->hash_size, &link_node)) { fclose(file_descriptor); - ipfs_node_free(read_node); + ipfs_hashtable_node_free(read_node); return 0; } struct UnixFS* unix_fs; ipfs_unixfs_protobuf_decode(link_node->data, link_node->data_size, &unix_fs); size_t bytes_written = fwrite(unix_fs->bytes, 1, unix_fs->bytes_size, file_descriptor); if (bytes_written != unix_fs->bytes_size) { - ipfs_node_free(link_node); + ipfs_hashtable_node_free(link_node); fclose(file_descriptor); - ipfs_node_free(read_node); + ipfs_hashtable_node_free(read_node); ipfs_unixfs_free(unix_fs); return 0; } - ipfs_node_free(link_node); + ipfs_hashtable_node_free(link_node); ipfs_unixfs_free(unix_fs); link = link->next; } @@ -73,7 +117,7 @@ int ipfs_exporter_to_filestream(const unsigned char* hash, FILE* file_descriptor fclose(file_descriptor); if (read_node != NULL) - ipfs_node_free(read_node); + ipfs_hashtable_node_free(read_node); return 1; } @@ -85,13 +129,13 @@ int ipfs_exporter_to_filestream(const unsigned char* hash, FILE* file_descriptor * @param file_name the file name to write to * @returns true(1) on success */ -int ipfs_exporter_to_file(const unsigned char* hash, const char* file_name, const struct FSRepo* fs_repo) { +int ipfs_exporter_to_file(const unsigned char* hash, const char* file_name, struct IpfsNode *local_node) { // process blocks FILE* file = fopen(file_name, "wb"); if (file == NULL) { return 0; } - return ipfs_exporter_to_filestream(hash, file, fs_repo); + return ipfs_exporter_to_filestream(hash, file, local_node); } /** @@ -100,7 +144,7 @@ int ipfs_exporter_to_file(const unsigned char* hash, const char* file_name, cons * @param file_name the file name to write to * @returns true(1) on success */ -int ipfs_exporter_to_console(const unsigned char* hash, const struct FSRepo* fs_repo) { +int ipfs_exporter_to_console(const unsigned char* hash, struct IpfsNode *local_node) { // convert hash to cid struct Cid* cid = NULL; if ( ipfs_cid_decode_hash_from_base58(hash, strlen((char*)hash), &cid) == 0) { @@ -108,8 +152,8 @@ int ipfs_exporter_to_console(const unsigned char* hash, const struct FSRepo* fs_ } // find block - struct Node* read_node = NULL; - if (ipfs_merkledag_get(cid->hash, cid->hash_length, &read_node, fs_repo) == 0) { + struct HashtableNode* read_node = NULL; + if (!ipfs_exporter_get_node(local_node, cid->hash, cid->hash_length, &read_node)) { ipfs_cid_free(cid); return 0; } @@ -133,7 +177,7 @@ int ipfs_exporter_to_console(const unsigned char* hash, const struct FSRepo* fs_ printf("\"}\n"); if (read_node != NULL) - ipfs_node_free(read_node); + ipfs_hashtable_node_free(read_node); return 1; } @@ -147,7 +191,6 @@ int ipfs_exporter_to_console(const unsigned char* hash, const struct FSRepo* fs_ * @returns true(1) on success */ int ipfs_exporter_object_get(int argc, char** argv) { - struct FSRepo* fs_repo = NULL; char* repo_path = NULL; if (!ipfs_repo_get_directory(argc, argv, &repo_path)) { @@ -155,22 +198,19 @@ int ipfs_exporter_object_get(int argc, char** argv) { return 0; } - // build the struct - int retVal = ipfs_repo_fsrepo_new(repo_path, NULL, &fs_repo); - if (retVal == 0) { + struct IpfsNode* local_node = NULL; + if (!ipfs_node_online_new(repo_path, &local_node)) return 0; - } - // open the repo - retVal = ipfs_repo_fsrepo_open(fs_repo); - if (retVal == 0) { - return 0; - } + // find hash - retVal = ipfs_exporter_to_console((unsigned char*)argv[3], fs_repo); + int retVal = ipfs_exporter_to_console((unsigned char*)argv[3], local_node); + + ipfs_node_free(local_node); + return retVal; } -int ipfs_exporter_cat_node(struct Node* node, const struct FSRepo* fs_repo) { +int ipfs_exporter_cat_node(struct HashtableNode* node, struct IpfsNode* local_node) { // process this node, then move on to the links // build the unixfs @@ -183,12 +223,12 @@ int ipfs_exporter_cat_node(struct Node* node, const struct FSRepo* fs_repo) { struct NodeLink* current = node->head_link; while (current != NULL) { // find the node - struct Node* child_node = NULL; - if (ipfs_merkledag_get(current->hash, current->hash_size, &child_node, fs_repo) == 0) { + struct HashtableNode* child_node = NULL; + if (!ipfs_exporter_get_node(local_node, current->hash, current->hash_size, &child_node)) { return 0; } - ipfs_exporter_cat_node(child_node, fs_repo); - ipfs_node_free(child_node); + ipfs_exporter_cat_node(child_node, local_node); + ipfs_hashtable_node_free(child_node); current = current->next; } @@ -202,7 +242,7 @@ int ipfs_exporter_cat_node(struct Node* node, const struct FSRepo* fs_repo) { * @returns true(1) on success */ int ipfs_exporter_object_cat(int argc, char** argv) { - struct FSRepo* fs_repo = NULL; + struct IpfsNode *local_node = NULL; char* repo_dir = NULL; if (!ipfs_repo_get_directory(argc, argv, &repo_dir)) { @@ -210,15 +250,9 @@ int ipfs_exporter_object_cat(int argc, char** argv) { return 0; } - // open the repo - int retVal = ipfs_repo_fsrepo_new(repo_dir, NULL, &fs_repo); - if (retVal == 0) { + if (!ipfs_node_online_new(repo_dir, &local_node)) return 0; - } - retVal = ipfs_repo_fsrepo_open(fs_repo); - if (retVal == 0) { - return 0; - } + // find hash // convert hash to cid struct Cid* cid = NULL; @@ -227,16 +261,16 @@ int ipfs_exporter_object_cat(int argc, char** argv) { } // find block - struct Node* read_node = NULL; - if (ipfs_merkledag_get(cid->hash, cid->hash_length, &read_node, fs_repo) == 0) { + struct HashtableNode* read_node = NULL; + if (ipfs_exporter_get_node(local_node, cid->hash, cid->hash_length, &read_node)) { ipfs_cid_free(cid); return 0; } // no longer need the cid ipfs_cid_free(cid); - ipfs_exporter_cat_node(read_node, fs_repo); - ipfs_node_free(read_node); + int retVal = ipfs_exporter_cat_node(read_node, local_node); + ipfs_hashtable_node_free(read_node); return retVal; diff --git a/importer/importer.c b/importer/importer.c index 0f369ad..03339fa 100644 --- a/importer/importer.c +++ b/importer/importer.c @@ -5,6 +5,7 @@ #include "ipfs/importer/importer.h" #include "ipfs/merkledag/merkledag.h" #include "libp2p/os/utils.h" +#include "ipfs/core/ipfs_node.h" #include "ipfs/repo/fsrepo/fs_repo.h" #include "ipfs/repo/init.h" #include "ipfs/unixfs/unixfs.h" @@ -22,7 +23,7 @@ * @param blocksize the blocksize to add * @returns true(1) on success */ -int ipfs_importer_add_filesize_to_data_section(struct Node* node, size_t bytes_read) { +int ipfs_importer_add_filesize_to_data_section(struct HashtableNode* node, size_t bytes_read) { // now add to the data section struct UnixFS* data_section = NULL; if (node->data == NULL) { @@ -41,7 +42,7 @@ int ipfs_importer_add_filesize_to_data_section(struct Node* node, size_t bytes_r unsigned char protobuf[protobuf_size]; ipfs_unixfs_protobuf_encode(data_section, protobuf, protobuf_size, &protobuf_size); ipfs_unixfs_free(data_section); - ipfs_node_set_data(node, protobuf, protobuf_size); + ipfs_hashtable_node_set_data(node, protobuf, protobuf_size); return 1; } @@ -51,13 +52,13 @@ int ipfs_importer_add_filesize_to_data_section(struct Node* node, size_t bytes_r * @param node the node to add to * @returns number of bytes read */ -size_t ipfs_import_chunk(FILE* file, struct Node* parent_node, struct FSRepo* fs_repo, size_t* total_size, size_t* bytes_written) { +size_t ipfs_import_chunk(FILE* file, struct HashtableNode* parent_node, struct FSRepo* fs_repo, size_t* total_size, size_t* bytes_written) { unsigned char buffer[MAX_DATA_SIZE]; size_t bytes_read = fread(buffer, 1, MAX_DATA_SIZE, file); // structs used by this method struct UnixFS* new_unixfs = NULL; - struct Node* new_node = NULL; + struct HashtableNode* new_node = NULL; struct NodeLink* new_link = NULL; // put the file bits into a new UnixFS file @@ -90,63 +91,63 @@ size_t ipfs_import_chunk(FILE* file, struct Node* parent_node, struct FSRepo* fs // if there is more to read, create a new node. if (bytes_read == MAX_DATA_SIZE) { // create a new node - if (ipfs_node_new_from_data(protobuf, *bytes_written, &new_node) == 0) { + if (ipfs_hashtable_node_new_from_data(protobuf, *bytes_written, &new_node) == 0) { return 0; } // persist size_t size_of_node = 0; if (ipfs_merkledag_add(new_node, fs_repo, &size_of_node) == 0) { - ipfs_node_free(new_node); + ipfs_hashtable_node_free(new_node); return 0; } // put link in parent node if (ipfs_node_link_create(NULL, new_node->hash, new_node->hash_size, &new_link) == 0) { - ipfs_node_free(new_node); + ipfs_hashtable_node_free(new_node); return 0; } new_link->t_size = size_of_node; *total_size += new_link->t_size; // NOTE: disposal of this link object happens when the parent is disposed - if (ipfs_node_add_link(parent_node, new_link) == 0) { - ipfs_node_free(new_node); + if (ipfs_hashtable_node_add_link(parent_node, new_link) == 0) { + ipfs_hashtable_node_free(new_node); return 0; } ipfs_importer_add_filesize_to_data_section(parent_node, bytes_read); - ipfs_node_free(new_node); + ipfs_hashtable_node_free(new_node); *bytes_written = size_of_node; size_of_node = 0; } else { // if there are no existing links, put what we pulled from the file into parent_node // otherwise, add it as a link if (parent_node->head_link == NULL) { - ipfs_node_set_data(parent_node, protobuf, *bytes_written); + ipfs_hashtable_node_set_data(parent_node, protobuf, *bytes_written); } else { // there are existing links. put the data in a new node, save it, then put the link in parent_node // create a new node - if (ipfs_node_new_from_data(protobuf, *bytes_written, &new_node) == 0) { + if (ipfs_hashtable_node_new_from_data(protobuf, *bytes_written, &new_node) == 0) { return 0; } // persist if (ipfs_merkledag_add(new_node, fs_repo, &size_of_node) == 0) { - ipfs_node_free(new_node); + ipfs_hashtable_node_free(new_node); return 0; } // put link in parent node if (ipfs_node_link_create(NULL, new_node->hash, new_node->hash_size, &new_link) == 0) { - ipfs_node_free(new_node); + ipfs_hashtable_node_free(new_node); return 0; } new_link->t_size = size_of_node; *total_size += new_link->t_size; // NOTE: disposal of this link object happens when the parent is disposed - if (ipfs_node_add_link(parent_node, new_link) == 0) { - ipfs_node_free(new_node); + if (ipfs_hashtable_node_add_link(parent_node, new_link) == 0) { + ipfs_hashtable_node_free(new_node); return 0; } ipfs_importer_add_filesize_to_data_section(parent_node, bytes_read); - ipfs_node_free(new_node); + ipfs_hashtable_node_free(new_node); } // persist the main node ipfs_merkledag_add(parent_node, fs_repo, bytes_written); @@ -162,7 +163,7 @@ size_t ipfs_import_chunk(FILE* file, struct Node* parent_node, struct FSRepo* fs * @param file_name the name of the file * @returns true(1) if successful, false(0) if couldn't generate the MultiHash to be displayed */ -int ipfs_import_print_node_results(const struct Node* node, const char* file_name) { +int ipfs_import_print_node_results(const struct HashtableNode* node, const char* file_name) { // give some results to the user //TODO: if directory_entry is itself a directory, traverse and report files int buffer_len = 100; @@ -191,7 +192,7 @@ int ipfs_import_print_node_results(const struct Node* node, const char* file_nam * @param recursive true if we should navigate directories * @returns true(1) on success */ -int ipfs_import_file(const char* root_dir, const char* fileName, struct Node** parent_node, struct FSRepo* fs_repo, size_t* bytes_written, int recursive) { +int ipfs_import_file(const char* root_dir, const char* fileName, struct HashtableNode** parent_node, struct IpfsNode* local_node, size_t* bytes_written, int recursive) { /** * NOTE: When this function completes, parent_node will be either: * 1) the complete file, in the case of a small file (<256k-ish) @@ -217,7 +218,7 @@ int ipfs_import_file(const char* root_dir, const char* fileName, struct Node** p new_root_dir = path; } // initialize parent_node as a directory - if (ipfs_node_create_directory(parent_node) == 0) { + if (ipfs_hashtable_node_create_directory(parent_node) == 0) { if (path != NULL) free(path); if (file != NULL) @@ -231,7 +232,7 @@ int ipfs_import_file(const char* root_dir, const char* fileName, struct Node** p while (next != NULL) { // process each file. NOTE: could be an embedded directory *bytes_written = 0; - struct Node* file_node; + struct HashtableNode* file_node; // put the filename together from fileName, which is the directory, and next->file_name // which is a file (or a directory) within the directory we just found. size_t filename_len = strlen(fileName) + strlen(next->file_name) + 2; @@ -239,8 +240,8 @@ int ipfs_import_file(const char* root_dir, const char* fileName, struct Node** p os_utils_filepath_join(fileName, next->file_name, full_file_name, filename_len); // adjust root directory - if (ipfs_import_file(new_root_dir, full_file_name, &file_node, fs_repo, bytes_written, recursive) == 0) { - ipfs_node_free(*parent_node); + if (ipfs_import_file(new_root_dir, full_file_name, &file_node, local_node, bytes_written, recursive) == 0) { + ipfs_hashtable_node_free(*parent_node); os_utils_free_file_list(first); if (file != NULL) free(file); @@ -259,16 +260,16 @@ int ipfs_import_file(const char* root_dir, const char* fileName, struct Node** p ipfs_node_link_create(next->file_name, file_node->hash, file_node->hash_size, &file_node_link); file_node_link->t_size = *bytes_written; // add file_node as link to parent_node - ipfs_node_add_link(*parent_node, file_node_link); + ipfs_hashtable_node_add_link(*parent_node, file_node_link); // clean up file_node - ipfs_node_free(file_node); + ipfs_hashtable_node_free(file_node); // move to next file in list next = next->next; } // while going through files } // save the parent_node (the directory) size_t bytes_written; - ipfs_merkledag_add(*parent_node, fs_repo, &bytes_written); + ipfs_merkledag_add(*parent_node, local_node->repo, &bytes_written); if (file != NULL) free(file); if (path != NULL) @@ -277,7 +278,7 @@ int ipfs_import_file(const char* root_dir, const char* fileName, struct Node** p } else { // process this file FILE* file = fopen(fileName, "rb"); - retVal = ipfs_node_new(parent_node); + retVal = ipfs_hashtable_node_new(parent_node); if (retVal == 0) { return 0; } @@ -285,12 +286,15 @@ int ipfs_import_file(const char* root_dir, const char* fileName, struct Node** p // add all nodes (will be called multiple times for large files) while ( bytes_read == MAX_DATA_SIZE) { size_t written = 0; - bytes_read = ipfs_import_chunk(file, *parent_node, fs_repo, &total_size, &written); + bytes_read = ipfs_import_chunk(file, *parent_node, local_node->repo, &total_size, &written); *bytes_written += written; } fclose(file); } + // notify the network + local_node->routing->Provide(local_node->routing, (*parent_node)->hash, (*parent_node)->hash_size); + return 1; } @@ -359,51 +363,45 @@ int ipfs_import_files(int argc, char** argv) { * param 2: -r (optional) * param 3: directoryname */ - struct FSRepo* fs_repo = NULL; + struct IpfsNode* local_node = NULL; + char* repo_path = NULL; + int retVal = 0; + int recursive = ipfs_import_is_recursive(argc, argv); // parse the command line struct FileList* first = ipfs_import_get_filelist(argc, argv); // open the repo - char* repo_path = NULL; if (!ipfs_repo_get_directory(argc, argv, &repo_path)) { // dir doesn't exist fprintf(stderr, "Repo does not exist: %s\n", repo_path); return 0; } - if (!ipfs_repo_fsrepo_new(repo_path, NULL, &fs_repo)) { - fprintf(stderr, "Unable to build the repo struct: %s\n", repo_path); - return 0; - } - if (!ipfs_repo_fsrepo_open(fs_repo)) { - fprintf(stderr, "Unable to open repository: %s\n", repo_path); - return 0; - } + ipfs_node_online_new(repo_path, &local_node); - int retVal = 0; // import the file(s) struct FileList* current = first; while (current != NULL) { - struct Node* directory_entry = NULL; + struct HashtableNode* directory_entry = NULL; char* path = NULL; char* filename = NULL; os_utils_split_filename(current->file_name, &path, &filename); size_t bytes_written = 0; - retVal = ipfs_import_file(NULL, current->file_name, &directory_entry, fs_repo, &bytes_written, recursive); + retVal = ipfs_import_file(NULL, current->file_name, &directory_entry, local_node, &bytes_written, recursive); ipfs_import_print_node_results(directory_entry, filename); // cleanup - ipfs_node_free(directory_entry); + ipfs_hashtable_node_free(directory_entry); if (path != NULL) free(path); free(filename); current = current->next; } - if (fs_repo != NULL) - ipfs_repo_fsrepo_free(fs_repo); + if (local_node!= NULL) + ipfs_node_free(local_node); // free file list current = first; while (current != NULL) { diff --git a/importer/resolver.c b/importer/resolver.c index 6d18ac0..c395368 100644 --- a/importer/resolver.c +++ b/importer/resolver.c @@ -106,7 +106,7 @@ int ipfs_resolver_is_remote(const char* path, const struct FSRepo* fs_repo) { * @param fs_repo the local repo * @returns the node, or NULL if not found */ -struct Node* ipfs_resolver_remote_get(const char* path, struct Node* from, const struct IpfsNode* ipfs_node) { +struct HashtableNode* ipfs_resolver_remote_get(const char* path, struct HashtableNode* from, const struct IpfsNode* ipfs_node) { // parse the path const char* temp = ipfs_resolver_remove_path_prefix(path, ipfs_node->repo); if (temp == NULL) @@ -158,8 +158,8 @@ struct Node* ipfs_resolver_remote_get(const char* path, struct Node* from, const if (response_size == 1) return NULL; // turn the protobuf into a Node - struct Node* node; - ipfs_node_protobuf_decode(response, response_size, &node); + struct HashtableNode* node; + ipfs_hashtable_node_protobuf_decode(response, response_size, &node); return node; } @@ -170,7 +170,7 @@ struct Node* ipfs_resolver_remote_get(const char* path, struct Node* from, const * @param from the current node (or NULL if it is the first call) * @returns what we are looking for, or NULL if it wasn't found */ -struct Node* ipfs_resolver_get(const char* path, struct Node* from, const struct IpfsNode* ipfs_node) { +struct HashtableNode* ipfs_resolver_get(const char* path, struct HashtableNode* from, const struct IpfsNode* ipfs_node) { struct FSRepo* fs_repo = ipfs_node->repo; @@ -191,7 +191,7 @@ struct Node* ipfs_resolver_get(const char* path, struct Node* from, const struct char* path_section; if (ipfs_resolver_next_path(path, &path_section) == 0) return NULL; - struct Node* current_node = NULL; + struct HashtableNode* current_node = NULL; if (from == NULL) { // this is the first time around. Grab the root node if (path_section[0] == 'Q' && path_section[1] == 'm') { @@ -215,7 +215,7 @@ struct Node* ipfs_resolver_get(const char* path, struct Node* from, const struct } else { // look on... free(path_section); - struct Node* newNode = ipfs_resolver_get(&path[pos+1], current_node, ipfs_node); // the +1 is the slash + struct HashtableNode* newNode = ipfs_resolver_get(&path[pos+1], current_node, ipfs_node); // the +1 is the slash return newNode; } } else { @@ -225,7 +225,7 @@ struct Node* ipfs_resolver_get(const char* path, struct Node* from, const struct } } else { // we were passed a node. If it is a directory, see if what we're looking for is in it - if (ipfs_node_is_directory(from)) { + if (ipfs_hashtable_node_is_directory(from)) { struct NodeLink* curr_link = from->head_link; while (curr_link != NULL) { // if it matches the name, we found what we're looking for. @@ -237,7 +237,7 @@ struct Node* ipfs_resolver_get(const char* path, struct Node* from, const struct } if (strlen(path_section) == strlen(path)) { // we are at the end of our search - ipfs_node_free(from); + ipfs_hashtable_node_free(from); free(path_section); return current_node; } else { @@ -246,8 +246,8 @@ struct Node* ipfs_resolver_get(const char* path, struct Node* from, const struct free(path_section); // if we're at the end of the path, return the node // continue looking for the next part of the path - ipfs_node_free(from); - struct Node* newNode = ipfs_resolver_get(next_path_section, current_node, ipfs_node); + ipfs_hashtable_node_free(from); + struct HashtableNode* newNode = ipfs_resolver_get(next_path_section, current_node, ipfs_node); return newNode; } } @@ -262,7 +262,7 @@ struct Node* ipfs_resolver_get(const char* path, struct Node* from, const struct // it should never get here free(path_section); if (from != NULL) - ipfs_node_free(from); + ipfs_hashtable_node_free(from); return NULL; } @@ -298,7 +298,7 @@ struct Libp2pPeer* ipfs_resolver_find_peer(const char* path, const struct IpfsNo // ask the swarm for the peer const char* address_string = ipfs_resolver_remove_path_prefix(path, fs_repo); - ipfs_node->routing->FindPeer(ipfs_node->routing, address_string, strlen(address_string), &peer); + ipfs_node->routing->FindPeer(ipfs_node->routing, (const unsigned char*)address_string, strlen(address_string), &peer); return peer; } diff --git a/include/ipfs/blocks/blockstore.h b/include/ipfs/blocks/blockstore.h index 28f8a2f..5581758 100644 --- a/include/ipfs/blocks/blockstore.h +++ b/include/ipfs/blocks/blockstore.h @@ -59,7 +59,7 @@ int ipfs_blockstore_get_unixfs(const unsigned char* hash, size_t hash_length, st /** * Put a struct Node in the blockstore */ -int ipfs_blockstore_put_node(const struct Node* node, const struct FSRepo* fs_repo, size_t* bytes_written); -int ipfs_blockstore_get_node(const unsigned char* hash, size_t hash_length, struct Node** node, const struct FSRepo* fs_repo); +int ipfs_blockstore_put_node(const struct HashtableNode* node, const struct FSRepo* fs_repo, size_t* bytes_written); +int ipfs_blockstore_get_node(const unsigned char* hash, size_t hash_length, struct HashtableNode** node, const struct FSRepo* fs_repo); #endif diff --git a/include/ipfs/core/builder.h b/include/ipfs/core/builder.h index e698a66..405bbf8 100644 --- a/include/ipfs/core/builder.h +++ b/include/ipfs/core/builder.h @@ -5,6 +5,7 @@ #include "ipfs/commands/context.h" #include "ipfs/repo/config/config.h" +#include "ipfs/core/ipfs_node.h" struct BuildCfg { int online; diff --git a/include/ipfs/core/ipfs_node.h b/include/ipfs/core/ipfs_node.h index ece1e5e..ebcb138 100644 --- a/include/ipfs/core/ipfs_node.h +++ b/include/ipfs/core/ipfs_node.h @@ -19,3 +19,17 @@ struct IpfsNode { //struct Mount** mounts; // TODO: Add more here }; + +/*** + * build an online IpfsNode + * @param repo_path where the IPFS repository directory is + * @param node the completed IpfsNode struct + * @returns true(1) on success + */ +int ipfs_node_online_new(const char* repo_path, struct IpfsNode** node); +/*** + * Free resources from the creation of an IpfsNode + * @param node the node to free + * @returns true(1) + */ +int ipfs_node_free(struct IpfsNode* node); diff --git a/include/ipfs/importer/exporter.h b/include/ipfs/importer/exporter.h index da3f650..5b00645 100644 --- a/include/ipfs/importer/exporter.h +++ b/include/ipfs/importer/exporter.h @@ -1,5 +1,11 @@ #pragma once +#include "ipfs/core/ipfs_node.h" + +/** + * Pull bytes from the hashtable + */ + /** * get a file by its hash, and write the data to a file * @param hash the base58 multihash of the cid @@ -8,6 +14,16 @@ */ int ipfs_exporter_to_file(const unsigned char* hash, const char* file_name, const struct FSRepo* fs_repo); +/*** + * Retrieve a protobuf'd Node from the router + * @param local_node the context + * @param hash the hash to retrieve + * @param hash_size the length of the hash + * @param result a place to store the Node + * @returns true(1) on success, otherwise false(0) + */ +int ipfs_exporter_get_node(struct IpfsNode* local_node, const unsigned char* hash, const size_t hash_size, struct HashtableNode** result); + int ipfs_exporter_object_get(int argc, char** argv); /*** diff --git a/include/ipfs/importer/importer.h b/include/ipfs/importer/importer.h index 6dc06f0..18decd6 100644 --- a/include/ipfs/importer/importer.h +++ b/include/ipfs/importer/importer.h @@ -2,7 +2,7 @@ #define __IPFS_IMPORTER_IMPORTER_H__ #include "ipfs/merkledag/node.h" -#include "ipfs/repo/fsrepo/fs_repo.h" +#include "ipfs/core/ipfs_node.h" /** * Creates a node based on an incoming file or directory @@ -19,7 +19,7 @@ * @param recursive true if we should navigate directories * @returns true(1) on success */ -int ipfs_import_file(const char* root, const char* fileName, struct Node** parent_node, struct FSRepo* fs_repo, size_t* bytes_written, int recursive); +int ipfs_import_file(const char* root, const char* fileName, struct HashtableNode** parent_node, struct IpfsNode *local_node, size_t* bytes_written, int recursive); /** * called from the command line diff --git a/include/ipfs/importer/resolver.h b/include/ipfs/importer/resolver.h index 1c7d568..75f555e 100644 --- a/include/ipfs/importer/resolver.h +++ b/include/ipfs/importer/resolver.h @@ -14,7 +14,7 @@ * @param from the current node (or NULL if it is the first call) * @returns what we are looking for, or NULL if it wasn't found */ -struct Node* ipfs_resolver_get(const char* path, struct Node* from, const struct IpfsNode* ipfs_node); +struct HashtableNode* ipfs_resolver_get(const char* path, struct HashtableNode* from, const struct IpfsNode* ipfs_node); /** * Interrogate the path, looking for the peer diff --git a/include/ipfs/merkledag/Example for node.c b/include/ipfs/merkledag/Example for node.c index 1ec8f98..4098dfd 100644 --- a/include/ipfs/merkledag/Example for node.c +++ b/include/ipfs/merkledag/Example for node.c @@ -43,7 +43,7 @@ int main(int argc, char** argv) ////Nodes///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //N_Create_From_Link - struct Node * Mynode; + struct HashtableNode * Mynode; Mynode = N_Create_From_Link(mylink); mylink->name = "HAHA";//Testing for valid node creation printf("Node Link[0] Name: %s\nHash: %s\n",Mynode->head_link[0]->name, Mynode->head_link[0]->Lcid->hash); @@ -72,7 +72,7 @@ int main(int argc, char** argv) printf("Outlinkamt: %d\n", Mynode->link_ammount); //Node Copy - struct Node * Node2; + struct HashtableNode * Node2; Node2 = Node_Copy(Mynode); printf("NODE COPY TEST: [0]: %s\n", Node2->head_link[0]->Lcid->hash); Node_Delete(Node2); diff --git a/include/ipfs/merkledag/merkledag.h b/include/ipfs/merkledag/merkledag.h index e2f7ecd..0a23fb2 100644 --- a/include/ipfs/merkledag/merkledag.h +++ b/include/ipfs/merkledag/merkledag.h @@ -14,7 +14,7 @@ * @param bytes_written the number of bytes written * @returns true(1) on success */ -int ipfs_merkledag_add(struct Node* node, struct FSRepo* fs_repo, size_t* bytes_written); +int ipfs_merkledag_add(struct HashtableNode* node, struct FSRepo* fs_repo, size_t* bytes_written); /*** * Retrieves a node from the datastore based on the cid @@ -23,7 +23,7 @@ int ipfs_merkledag_add(struct Node* node, struct FSRepo* fs_repo, size_t* bytes_ * @param fs_repo the repository * @returns true(1) on success */ -int ipfs_merkledag_get(const unsigned char* hash, size_t hash_size, struct Node** node, const struct FSRepo* fs_repo); +int ipfs_merkledag_get(const unsigned char* hash, size_t hash_size, struct HashtableNode** node, const struct FSRepo* fs_repo); /*** * Retrieves a node from the datastore based on the multihash @@ -32,6 +32,6 @@ int ipfs_merkledag_get(const unsigned char* hash, size_t hash_size, struct Node* * @param fs_repo the repository * @returns true(1) on success */ -int ipfs_merkledag_get_by_multihash(const unsigned char* multihash, size_t multihash_length, struct Node** node, const struct FSRepo* fs_repo); +int ipfs_merkledag_get_by_multihash(const unsigned char* multihash, size_t multihash_length, struct HashtableNode** node, const struct FSRepo* fs_repo); #endif diff --git a/include/ipfs/merkledag/node.h b/include/ipfs/merkledag/node.h index a1a3d22..9861e60 100644 --- a/include/ipfs/merkledag/node.h +++ b/include/ipfs/merkledag/node.h @@ -22,7 +22,7 @@ struct NodeLink struct NodeLink* next; }; -struct Node +struct HashtableNode { // saved in protobuf size_t data_size; @@ -103,7 +103,7 @@ int ipfs_node_link_protobuf_decode(unsigned char* buffer, size_t buffer_length, * @param node the node to examine * @returns the max size of an encoded stream of bytes, if it were encoded */ -size_t ipfs_node_protobuf_encode_size(const struct Node* node); +size_t ipfs_hashtable_node_protobuf_encode_size(const struct HashtableNode* node); /*** * Encode a node into a protobuf byte stream @@ -113,7 +113,7 @@ size_t ipfs_node_protobuf_encode_size(const struct Node* node); * @param bytes_written how much of buffer was used * @returns true(1) on success */ -int ipfs_node_protobuf_encode(const struct Node* node, unsigned char* buffer, size_t max_buffer_length, size_t* bytes_written); +int ipfs_hashtable_node_protobuf_encode(const struct HashtableNode* node, unsigned char* buffer, size_t max_buffer_length, size_t* bytes_written); /*** * Decode a stream of bytes into a Node structure @@ -122,7 +122,7 @@ int ipfs_node_protobuf_encode(const struct Node* node, unsigned char* buffer, si * @param node pointer to the Node to be created * @returns true(1) on success */ -int ipfs_node_protobuf_decode(unsigned char* buffer, size_t buffer_length, struct Node** node); +int ipfs_hashtable_node_protobuf_decode(unsigned char* buffer, size_t buffer_length, struct HashtableNode** node); /*==================================================================================== * Node Functions @@ -133,7 +133,7 @@ int ipfs_node_protobuf_decode(unsigned char* buffer, size_t buffer_length, struc * @param node the pointer to the memory allocated * @returns true(1) on success, otherwise false(0) */ -int ipfs_node_new(struct Node** node); +int ipfs_hashtable_node_new(struct HashtableNode** node); /*** * Allocates memory for a node, and sets the data section to indicate @@ -141,14 +141,14 @@ int ipfs_node_new(struct Node** node); * @param node the node to initialize * @returns true(1) on success, otherwise false(0) */ -int ipfs_node_create_directory(struct Node** node); +int ipfs_hashtable_node_create_directory(struct HashtableNode** node); /*** * Determine if this node is actually a directory * @param node the node to examine * @returns true(1) if this node is a directory. Otherwise, false(0) */ -int ipfs_node_is_directory(struct Node* node); +int ipfs_hashtable_node_is_directory(struct HashtableNode* node); /** * sets the Cid into the struct element titled cached @@ -156,7 +156,7 @@ int ipfs_node_is_directory(struct Node* node); * @param cid the cid * @returns true(1) on success */ -int ipfs_node_set_hash(struct Node* node, const unsigned char* hash, size_t hash_size); +int ipfs_hashtable_node_set_hash(struct HashtableNode* node, const unsigned char* hash, size_t hash_size); /*ipfs_node_set_data * Sets the data of a node @@ -165,42 +165,42 @@ int ipfs_node_set_hash(struct Node* node, const unsigned char* hash, size_t hash * Sets pointers of encoded & cached to NULL /following go method * returns 1 on success 0 on failure */ -int ipfs_node_set_data(struct Node * N, unsigned char * Data, size_t data_size); +int ipfs_hashtable_node_set_data(struct HashtableNode * N, unsigned char * Data, size_t data_size); /*ipfs_node_set_encoded * @param NODE: the node you wish to alter (struct Node *) * @param Data: The data you wish to set in encoded.(unsigned char *) * returns 1 on success 0 on failure */ -int ipfs_node_set_encoded(struct Node * N, unsigned char * Data); +int ipfs_hashtable_node_set_encoded(struct HashtableNode * N, unsigned char * Data); /*ipfs_node_get_data * Gets data from a node * @param Node: = The node you want to get data from. (unsigned char *) * Returns data of node. */ -unsigned char * ipfs_node_get_data(struct Node * N); +unsigned char * ipfs_hashtable_node_get_data(struct HashtableNode * N); /*ipfs_node_free * Once you are finished using a node, always delete it using this. * It will take care of the links inside it. * @param N: the node you want to free. (struct Node *) */ -int ipfs_node_free(struct Node * N); +int ipfs_hashtable_node_free(struct HashtableNode * N); /*ipfs_node_get_link_by_name * Returns a copy of the link with given name * @param Name: (char * name) searches for link with this name * Returns the link struct if it's found otherwise returns NULL */ -struct NodeLink * ipfs_node_get_link_by_name(struct Node * N, char * Name); +struct NodeLink * ipfs_hashtable_node_get_link_by_name(struct HashtableNode * N, char * Name); /*ipfs_node_remove_link_by_name * Removes a link from node if found by name. * @param name: Name of link (char * name) * returns 1 on success, 0 on failure. */ -int ipfs_node_remove_link_by_name(char * Name, struct Node * mynode); +int ipfs_hashtable_node_remove_link_by_name(char * Name, struct HashtableNode * mynode); /* ipfs_node_add_link * Adds a link to your node @@ -209,7 +209,7 @@ int ipfs_node_remove_link_by_name(char * Name, struct Node * mynode); * @param linksz: sizeof(your cid here) * Returns your node with the newly added link */ -int ipfs_node_add_link(struct Node * mynode, struct NodeLink * mylink); +int ipfs_hashtable_node_add_link(struct HashtableNode * mynode, struct NodeLink * mylink); /*ipfs_node_new_from_link * Create a node from a link @@ -217,7 +217,7 @@ int ipfs_node_add_link(struct Node * mynode, struct NodeLink * mylink); * @param node the pointer to the new node * @returns true(1) on success */ -int ipfs_node_new_from_link(struct NodeLink * mylink, struct Node** node); +int ipfs_hashtable_node_new_from_link(struct NodeLink * mylink, struct HashtableNode** node); /*ipfs_node_new_from_data * @param data: bytes buffer you want to create the node from @@ -225,7 +225,7 @@ int ipfs_node_new_from_link(struct NodeLink * mylink, struct Node** node); * @param node the pointer to the new node * @returns true(1) on success */ -int ipfs_node_new_from_data(unsigned char * data, size_t data_size, struct Node** node); +int ipfs_hashtable_node_new_from_data(unsigned char * data, size_t data_size, struct HashtableNode** node); /*** * create a Node struct from encoded data @@ -233,7 +233,7 @@ int ipfs_node_new_from_data(unsigned char * data, size_t data_size, struct Node* * @param node a pointer to the node that will be created * @returns true(1) on success */ -int ipfs_node_new_from_encoded(unsigned char * data, struct Node** node); +int ipfs_hashtable_node_new_from_encoded(unsigned char * data, struct HashtableNode** node); /*Node_Resolve_Max_Size * !!!This shouldn't concern you! @@ -278,7 +278,7 @@ struct Link_Proc * @param N: The node you want to get links from * @param path: The "foo/bar/bin" path */ -struct Link_Proc * Node_Resolve_Links(struct Node * N, char * path); +struct Link_Proc * Node_Resolve_Links(struct HashtableNode * N, char * path); /*Free_link_Proc * frees the Link_Proc struct you created. diff --git a/include/ipfs/repo/config/config.h b/include/ipfs/repo/config/config.h index 35d0f36..d51f758 100644 --- a/include/ipfs/repo/config/config.h +++ b/include/ipfs/repo/config/config.h @@ -33,6 +33,7 @@ struct Reprovider { struct RepoConfig { struct Identity* identity; struct Datastore* datastore; + struct Filestore* filestore; struct Addresses* addresses; struct Mounts mounts; struct Discovery discovery; diff --git a/include/ipfs/repo/fsrepo/fs_repo.h b/include/ipfs/repo/fsrepo/fs_repo.h index 49178f3..8b9e46d 100644 --- a/include/ipfs/repo/fsrepo/fs_repo.h +++ b/include/ipfs/repo/fsrepo/fs_repo.h @@ -91,8 +91,8 @@ int ipfs_repo_fsrepo_unixfs_read(const unsigned char* hash, size_t hash_length, * @param fs_repo the repo to write to * @returns true(1) on success */ -int ipfs_repo_fsrepo_node_write(const struct Node* unix_fs, const struct FSRepo* fs_repo, size_t* bytes_written); -int ipfs_repo_fsrepo_node_read(const unsigned char* hash, size_t hash_length, struct Node** node, const struct FSRepo* fs_repo); +int ipfs_repo_fsrepo_node_write(const struct HashtableNode* unix_fs, const struct FSRepo* fs_repo, size_t* bytes_written); +int ipfs_repo_fsrepo_node_read(const unsigned char* hash, size_t hash_length, struct HashtableNode** node, const struct FSRepo* fs_repo); #endif /* fs_repo_h */ diff --git a/include/ipfs/routing/routing.h b/include/ipfs/routing/routing.h index ab69659..8a8fe91 100644 --- a/include/ipfs/routing/routing.h +++ b/include/ipfs/routing/routing.h @@ -23,16 +23,16 @@ struct IpfsRouting { * @param 5 the size of the value * @returns 0 on success, otherwise -1 */ - int (*PutValue) (struct IpfsRouting*, char*, size_t, void*, size_t); + int (*PutValue) (struct IpfsRouting*, const unsigned char*, size_t, const void*, size_t); /** - * Get a value from the datastore + * Get a value from the filestore * @param 1 the struct that contains the connection information * @param 2 the key to look for * @param 3 the size of the key * @param 4 a place to store the value * @param 5 the size of the value */ - int (*GetValue) (struct IpfsRouting*, char*, size_t, void**, size_t*); + int (*GetValue) (struct IpfsRouting*, const unsigned char*, size_t, void**, size_t*); /** * Find a provider * @param routing the context @@ -41,7 +41,7 @@ struct IpfsRouting { * @param peers a vector of peers found that can provide the value for the key * @returns true(1) on success, otherwise false(0) */ - int (*FindProviders) (struct IpfsRouting* routing, unsigned char* key, size_t key_size, struct Libp2pVector** peers); + int (*FindProviders) (struct IpfsRouting* routing, const unsigned char* key, size_t key_size, struct Libp2pVector** peers); /** * Find a peer * @param 1 the context @@ -51,7 +51,7 @@ struct IpfsRouting { * @param 5 the size of the results * @returns 0 or error code */ - int (*FindPeer) (struct IpfsRouting*, const char*, size_t, struct Libp2pPeer** result); + int (*FindPeer) (struct IpfsRouting*, const unsigned char*, size_t, struct Libp2pPeer** result); /** * Announce to the network that this host can provide this key * @param 1 the context @@ -59,7 +59,7 @@ struct IpfsRouting { * @param 3 the key size * @returns true(1) on success, otherwise false(0) */ - int (*Provide) (struct IpfsRouting*, char*, size_t); + int (*Provide) (struct IpfsRouting*, const unsigned char*, size_t); /** * Ping * @param routing the context @@ -84,8 +84,8 @@ int ipfs_routing_online_free(ipfs_routing*); // online using DHT/kademlia, the recommended router ipfs_routing* ipfs_routing_new_kademlia(struct IpfsNode* local_node, struct RsaPrivateKey* private_key, struct Stream* stream); // generic routines -int ipfs_routing_generic_put_value (ipfs_routing* offlineRouting, char *key, size_t key_size, void *val, size_t vlen); -int ipfs_routing_generic_get_value (ipfs_routing* offlineRouting, char *key, size_t key_size, void **val, size_t *vlen); +int ipfs_routing_generic_put_value (ipfs_routing* offlineRouting, const unsigned char *key, size_t key_size, const void *val, size_t vlen); +int ipfs_routing_generic_get_value (ipfs_routing* offlineRouting, const unsigned char *key, size_t key_size, void **val, size_t *vlen); // supernode int ipfs_routing_supernode_parse_provider(const unsigned char* in, size_t in_size, struct Libp2pLinkedList** multiaddresses); diff --git a/main/Makefile b/main/Makefile index 3a666aa..2b04111 100644 --- a/main/Makefile +++ b/main/Makefile @@ -7,7 +7,7 @@ OBJS = main.o \ ../cid/cid.o \ ../cmd/ipfs/init.o \ ../commands/argument.o ../commands/command_option.o ../commands/command.o ../commands/cli/parse.o \ - ../core/builder.o ../core/daemon.o ../core/null.o ../core/ping.o ../core/bootstrap.o \ + ../core/builder.o ../core/daemon.o ../core/null.o ../core/ping.o ../core/bootstrap.o ../core/ipfs_node.o \ ../datastore/ds_helper.o \ ../datastore/key.o \ ../dnslink/*.o \ diff --git a/merkledag/merkledag.c b/merkledag/merkledag.c index fd2fdec..5a84835 100644 --- a/merkledag/merkledag.c +++ b/merkledag/merkledag.c @@ -19,16 +19,16 @@ * @param bytes_written the number of bytes written * @returns true(1) on success */ -int ipfs_merkledag_add(struct Node* node, struct FSRepo* fs_repo, size_t* bytes_written) { +int ipfs_merkledag_add(struct HashtableNode* node, struct FSRepo* fs_repo, size_t* bytes_written) { // taken from merkledag.go line 59 int retVal = 0; // compute the hash if necessary if (node->hash == NULL) { - size_t protobuf_size = ipfs_node_protobuf_encode_size(node); + size_t protobuf_size = ipfs_hashtable_node_protobuf_encode_size(node); unsigned char protobuf[protobuf_size]; size_t bytes_encoded; - retVal = ipfs_node_protobuf_encode(node, protobuf, protobuf_size, &bytes_encoded); + retVal = ipfs_hashtable_node_protobuf_encode(node, protobuf, protobuf_size, &bytes_encoded); node->hash_size = 32; node->hash = (unsigned char*)malloc(node->hash_size); @@ -59,7 +59,7 @@ int ipfs_merkledag_add(struct Node* node, struct FSRepo* fs_repo, size_t* bytes_ * @param fs_repo the repository * @returns true(1) on success */ -int ipfs_merkledag_get(const unsigned char* hash, size_t hash_size, struct Node** node, const struct FSRepo* fs_repo) { +int ipfs_merkledag_get(const unsigned char* hash, size_t hash_size, struct HashtableNode** node, const struct FSRepo* fs_repo) { int retVal = 1; size_t key_length = 100; unsigned char key[key_length]; @@ -77,12 +77,12 @@ int ipfs_merkledag_get(const unsigned char* hash, size_t hash_size, struct Node* } // set the hash - ipfs_node_set_hash(*node, hash, hash_size); + ipfs_hashtable_node_set_hash(*node, hash, hash_size); return 1; } -int ipfs_merkledag_get_by_multihash(const unsigned char* multihash, size_t multihash_length, struct Node** node, const struct FSRepo* fs_repo) { +int ipfs_merkledag_get_by_multihash(const unsigned char* multihash, size_t multihash_length, struct HashtableNode** node, const struct FSRepo* fs_repo) { // convert to hash size_t hash_size = 0; unsigned char* hash = NULL; diff --git a/merkledag/node.c b/merkledag/node.c index b85c794..57bdd42 100644 --- a/merkledag/node.c +++ b/merkledag/node.c @@ -223,7 +223,7 @@ exit: /*** * return an approximate size of the encoded node */ -size_t ipfs_node_protobuf_encode_size(const struct Node* node) { +size_t ipfs_hashtable_node_protobuf_encode_size(const struct HashtableNode* node) { size_t size = 0; // links struct NodeLink* current = node->head_link; @@ -246,7 +246,7 @@ size_t ipfs_node_protobuf_encode_size(const struct Node* node) { * @param bytes_written how much of buffer was used * @returns true(1) on success */ -int ipfs_node_protobuf_encode(const struct Node* node, unsigned char* buffer, size_t max_buffer_length, size_t* bytes_written) { +int ipfs_hashtable_node_protobuf_encode(const struct HashtableNode* node, unsigned char* buffer, size_t max_buffer_length, size_t* bytes_written) { size_t bytes_used = 0; *bytes_written = 0; int retVal = 0; @@ -282,7 +282,7 @@ int ipfs_node_protobuf_encode(const struct Node* node, unsigned char* buffer, si * @param node pointer to the Node to be created * @returns true(1) on success */ -int ipfs_node_protobuf_decode(unsigned char* buffer, size_t buffer_length, struct Node** node) { +int ipfs_hashtable_node_protobuf_decode(unsigned char* buffer, size_t buffer_length, struct HashtableNode** node) { /* * Field 1: data * Field 2: link @@ -293,7 +293,7 @@ int ipfs_node_protobuf_decode(unsigned char* buffer, size_t buffer_length, struc size_t temp_size; struct NodeLink* temp_link = NULL; - if (ipfs_node_new(node) == 0) + if (ipfs_hashtable_node_new(node) == 0) goto exit; while(pos < buffer_length) { @@ -319,7 +319,7 @@ int ipfs_node_protobuf_decode(unsigned char* buffer, size_t buffer_length, struc goto exit; free(temp_buffer); temp_buffer = NULL; - ipfs_node_add_link(*node, temp_link); + ipfs_hashtable_node_add_link(*node, temp_link); break; } } @@ -329,7 +329,7 @@ int ipfs_node_protobuf_decode(unsigned char* buffer, size_t buffer_length, struc exit: if (retVal == 0) { - ipfs_node_free(*node); + ipfs_hashtable_node_free(*node); } if (temp_buffer != NULL) free(temp_buffer); @@ -344,9 +344,9 @@ exit: * Creates an empty node, allocates the required memory * Returns a fresh new node with no data set in it. */ -int ipfs_node_new(struct Node** node) +int ipfs_hashtable_node_new(struct HashtableNode** node) { - *node = (struct Node *)malloc(sizeof(struct Node)); + *node = (struct HashtableNode *)malloc(sizeof(struct HashtableNode)); if (*node == NULL) return 0; (*node)->hash = NULL; @@ -364,30 +364,30 @@ int ipfs_node_new(struct Node** node) * @param node the node to initialize * @returns true(1) on success, otherwise false(0) */ -int ipfs_node_create_directory(struct Node** node) { +int ipfs_hashtable_node_create_directory(struct HashtableNode** node) { // initialize parent_node - if (ipfs_node_new(node) == 0) + if (ipfs_hashtable_node_new(node) == 0) return 0; // put a UnixFS protobuf in the data section struct UnixFS* unix_fs; if (ipfs_unixfs_new(&unix_fs) == 0) { - ipfs_node_free(*node); + ipfs_hashtable_node_free(*node); return 0; } unix_fs->data_type = UNIXFS_DIRECTORY; size_t protobuf_len = ipfs_unixfs_protobuf_encode_size(unix_fs); unsigned char protobuf[protobuf_len]; if (ipfs_unixfs_protobuf_encode(unix_fs, protobuf, protobuf_len, &protobuf_len) == 0) { - ipfs_node_free(*node); + ipfs_hashtable_node_free(*node); ipfs_unixfs_free(unix_fs); return 0; } ipfs_unixfs_free(unix_fs); - ipfs_node_set_data(*node, protobuf, protobuf_len); + ipfs_hashtable_node_set_data(*node, protobuf, protobuf_len); return 1; } -int ipfs_node_is_directory(struct Node* node) { +int ipfs_hashtable_node_is_directory(struct HashtableNode* node) { if (node->data_size < 2) { return 0; } @@ -406,7 +406,7 @@ int ipfs_node_is_directory(struct Node* node) { * @param cid the Cid to be copied into the Node->cached element * @returns true(1) on success */ -int ipfs_node_set_hash(struct Node* node, const unsigned char* hash, size_t hash_size) +int ipfs_hashtable_node_set_hash(struct HashtableNode* node, const unsigned char* hash, size_t hash_size) { // don't reallocate if it is the same size if (node->hash != NULL && hash_size != node->hash_size) { @@ -434,7 +434,7 @@ int ipfs_node_set_hash(struct Node* node, const unsigned char* hash, size_t hash * Sets pointers of encoded & cached to NULL /following go method * returns 1 on success 0 on failure */ -int ipfs_node_set_data(struct Node* node, unsigned char * Data, size_t data_size) +int ipfs_hashtable_node_set_data(struct HashtableNode* node, unsigned char * Data, size_t data_size) { if(!node || !Data) { @@ -457,7 +457,7 @@ int ipfs_node_set_data(struct Node* node, unsigned char * Data, size_t data_size * @param Data: The data you wish to set in encoded.(unsigned char *) * returns 1 on success 0 on failure */ -int ipfs_node_set_encoded(struct Node * N, unsigned char * Data) +int ipfs_hashtable_node_set_encoded(struct HashtableNode * N, unsigned char * Data) { if(!N || !Data) { @@ -474,14 +474,14 @@ int ipfs_node_set_encoded(struct Node * N, unsigned char * Data) * @param Node: = The node you want to get data from. (unsigned char *) * Returns data of node. */ -unsigned char * ipfs_node_get_data(struct Node * N) +unsigned char * ipfs_hashtable_node_get_data(struct HashtableNode * N) { unsigned char * DATA; DATA = N->data; return DATA; } -struct NodeLink* ipfs_node_link_last(struct Node* node) { +struct NodeLink* ipfs_node_link_last(struct HashtableNode* node) { struct NodeLink* current = node->head_link; while(current != NULL) { if (current->next == NULL) @@ -491,7 +491,7 @@ struct NodeLink* ipfs_node_link_last(struct Node* node) { return current; } -int ipfs_node_remove_link(struct Node* node, struct NodeLink* toRemove) { +int ipfs_node_remove_link(struct HashtableNode* node, struct NodeLink* toRemove) { struct NodeLink* current = node->head_link; struct NodeLink* previous = NULL; while(current != NULL && current != toRemove) { @@ -519,7 +519,7 @@ int ipfs_node_remove_link(struct Node* node, struct NodeLink* toRemove) { * It will take care of the links inside it. * @param N: the node you want to free. (struct Node *) */ -int ipfs_node_free(struct Node * N) +int ipfs_hashtable_node_free(struct HashtableNode * N) { if(N != NULL) { @@ -552,7 +552,7 @@ int ipfs_node_free(struct Node * N) * @param Name: (char * name) searches for link with this name * Returns the link struct if it's found otherwise returns NULL */ -struct NodeLink * ipfs_node_get_link_by_name(struct Node * N, char * Name) +struct NodeLink * ipfs_hashtable_node_get_link_by_name(struct HashtableNode * N, char * Name) { struct NodeLink* current = N->head_link; while(current != NULL && strcmp(Name, current->name) != 0) { @@ -566,7 +566,7 @@ struct NodeLink * ipfs_node_get_link_by_name(struct Node * N, char * Name) * @param name: Name of link (char * name) * returns 1 on success, 0 on failure. */ -int ipfs_node_remove_link_by_name(char * Name, struct Node * mynode) +int ipfs_hashtable_node_remove_link_by_name(char * Name, struct HashtableNode * mynode) { struct NodeLink* current = mynode->head_link; struct NodeLink* previous = NULL; @@ -600,7 +600,7 @@ int ipfs_node_remove_link_by_name(char * Name, struct Node * mynode) * @param mylink: the link to add * @returns true(1) on success */ -int ipfs_node_add_link(struct Node* node, struct NodeLink * mylink) +int ipfs_hashtable_node_add_link(struct HashtableNode* node, struct NodeLink * mylink) { if(node->head_link != NULL) { // add to existing by finding last one @@ -624,13 +624,13 @@ int ipfs_node_add_link(struct Node* node, struct NodeLink * mylink) * @param linksize: sizeof(the link in mylink) (size_T) * Returns a fresh new node with the link you specified. Has to be freed with Node_Free preferably. */ -int ipfs_node_new_from_link(struct NodeLink * mylink, struct Node** node) +int ipfs_hashtable_node_new_from_link(struct NodeLink * mylink, struct HashtableNode** node) { - *node = (struct Node *) malloc(sizeof(struct Node)); + *node = (struct HashtableNode *) malloc(sizeof(struct HashtableNode)); if (*node == NULL) return 0; (*node)->head_link = NULL; - ipfs_node_add_link(*node, mylink); + ipfs_hashtable_node_add_link(*node, mylink); (*node)->hash = NULL; (*node)->hash_size = 0; (*node)->data = NULL; @@ -646,13 +646,13 @@ int ipfs_node_new_from_link(struct NodeLink * mylink, struct Node** node) * @param node a pointer to the node to be created * returns a node with the data you inputted. */ -int ipfs_node_new_from_data(unsigned char * data, size_t data_size, struct Node** node) +int ipfs_hashtable_node_new_from_data(unsigned char * data, size_t data_size, struct HashtableNode** node) { if(data) { - if (ipfs_node_new(node) == 0) + if (ipfs_hashtable_node_new(node) == 0) return 0; - return ipfs_node_set_data(*node, data, data_size); + return ipfs_hashtable_node_set_data(*node, data, data_size); } return 0; } @@ -663,11 +663,11 @@ int ipfs_node_new_from_data(unsigned char * data, size_t data_size, struct Node* * @param node a pointer to the node that will be created * @returns true(1) on success */ -int ipfs_node_new_from_encoded(unsigned char * data, struct Node** node) +int ipfs_hashtable_node_new_from_encoded(unsigned char * data, struct HashtableNode** node) { if(data) { - if (ipfs_node_new(node) == 0) + if (ipfs_hashtable_node_new(node) == 0) return 0; (*node)->encoded = data; return 1; @@ -734,7 +734,7 @@ int Node_Resolve(char ** result, char * input1) * @param N: The node you want to get links from * @param path: The "foo/bar/bin" path */ -struct Link_Proc * Node_Resolve_Links(struct Node * N, char * path) +struct Link_Proc * Node_Resolve_Links(struct HashtableNode * N, char * path) { if(!N || !path) { @@ -748,7 +748,7 @@ struct Link_Proc * Node_Resolve_Links(struct Node * N, char * path) for(int i=0;ilinks[i] = (struct NodeLink *)malloc(sizeof(struct NodeLink)); diff --git a/pin/pin.c b/pin/pin.c index 8fe507b..571c871 100644 --- a/pin/pin.c +++ b/pin/pin.c @@ -119,7 +119,7 @@ int ipfs_pin_has_child (struct FSRepo *ds, unsigned char *hash, size_t hash_size, unsigned char *child, size_t child_size) { - struct Node *node; + struct HashtableNode *node; struct NodeLink *node_link; if (ipfs_merkledag_get (hash, hash_size, &node, ds)) { diff --git a/repo/config/config.c b/repo/config/config.c index c594467..e6df0bb 100644 --- a/repo/config/config.c +++ b/repo/config/config.c @@ -7,6 +7,7 @@ #include "libp2p/os/utils.h" #include "ipfs/repo/config/bootstrap_peers.h" #include "ipfs/repo/config/swarm.h" +#include "libp2p/db/filestore.h" /*** * public @@ -172,6 +173,8 @@ int ipfs_repo_config_new(struct RepoConfig** config) { if (retVal == 0) return 0; + (*config)->filestore = libp2p_filestore_new(); + retVal = repo_config_addresses_new(&((*config)->addresses)); if (retVal == 0) return 0; @@ -196,6 +199,8 @@ int ipfs_repo_config_free(struct RepoConfig* config) { repo_config_bootstrap_peers_free(config->bootstrap_peers); if (config->datastore != NULL) libp2p_datastore_free(config->datastore); + if (config->filestore != NULL) + libp2p_filestore_free(config->filestore); if (config->addresses != NULL) repo_config_addresses_free(config->addresses); if (config->gateway != NULL) diff --git a/repo/fsrepo/fs_repo.c b/repo/fsrepo/fs_repo.c index 4cbe0b7..1501d1c 100644 --- a/repo/fsrepo/fs_repo.c +++ b/repo/fsrepo/fs_repo.c @@ -7,6 +7,7 @@ #include "ipfs/blocks/blockstore.h" #include "ipfs/datastore/ds_helper.h" #include "libp2p/db/datastore.h" +#include "libp2p/db/filestore.h" #include "ipfs/repo/fsrepo/fs_repo.h" #include "libp2p/os/utils.h" #include "ipfs/repo/fsrepo/lmdb_datastore.h" @@ -511,6 +512,28 @@ int fs_repo_open_datastore(struct FSRepo* repo) { return retVal; } +/** + * For interface of Filestore. Retrieves a node from the filestore + * @param hash the hash to pull + * @param hash_length the length of the hash + * @param node_obj where to put the results + * @param filestore a reference to the filestore struct + * @returns true(1) on success, false(0) otherwise + */ +int ipfs_repo_fsrepo_node_get(const unsigned char* hash, size_t hash_length, void** node_obj, size_t *node_size, const struct Filestore* filestore) { + struct FSRepo* fs_repo = (struct FSRepo*)filestore->handle; + struct HashtableNode* node = NULL; + int retVal = ipfs_repo_fsrepo_node_read(hash, hash_length, &node, fs_repo); + if (retVal == 1) { + *node_size = ipfs_hashtable_node_protobuf_encode_size(node); + *node_obj = malloc(*node_size); + retVal = ipfs_hashtable_node_protobuf_encode(node, *node_obj, *node_size, node_size); + } + if (node != NULL) + ipfs_hashtable_node_free(node); + return retVal; +} + /** * public methods */ @@ -539,6 +562,10 @@ int ipfs_repo_fsrepo_open(struct FSRepo* repo) { return 0; } + // init the filestore + repo->config->filestore->handle = repo; + repo->config->filestore->node_get = ipfs_repo_fsrepo_node_get; + return 1; } @@ -693,7 +720,7 @@ int ipfs_repo_fsrepo_unixfs_write(const struct UnixFS* unix_fs, const struct FSR * @param bytes_written number of bytes written to the repo * @returns true(1) on success */ -int ipfs_repo_fsrepo_node_write(const struct Node* node, const struct FSRepo* fs_repo, size_t* bytes_written) { +int ipfs_repo_fsrepo_node_write(const struct HashtableNode* node, const struct FSRepo* fs_repo, size_t* bytes_written) { /** * What is put in the blockstore is the node. * What is put in the datastore is the multihash as the key, @@ -715,7 +742,7 @@ int ipfs_repo_fsrepo_node_write(const struct Node* node, const struct FSRepo* fs return 1; } -int ipfs_repo_fsrepo_node_read(const unsigned char* hash, size_t hash_length, struct Node** node, const struct FSRepo* fs_repo) { +int ipfs_repo_fsrepo_node_read(const unsigned char* hash, size_t hash_length, struct HashtableNode** node, const struct FSRepo* fs_repo) { int retVal = 0; // get the base32 hash from the database @@ -731,6 +758,7 @@ int ipfs_repo_fsrepo_node_read(const unsigned char* hash, size_t hash_length, st } + 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; diff --git a/routing/k_routing.c b/routing/k_routing.c index 1789ede..8335264 100644 --- a/routing/k_routing.c +++ b/routing/k_routing.c @@ -18,7 +18,7 @@ * @param value_size the size of the value * @returns 0 on success, otherwise -1 */ -int ipfs_routing_kademlia_put_value(struct IpfsRouting* routing, char* key, size_t key_size, void* value, size_t value_size) { +int ipfs_routing_kademlia_put_value(struct IpfsRouting* routing, const unsigned char* key, size_t key_size, const void* value, size_t value_size) { return 0; } @@ -30,7 +30,7 @@ int ipfs_routing_kademlia_put_value(struct IpfsRouting* routing, char* key, size * @param 4 a place to store the value * @param 5 the size of the value */ -int ipfs_routing_kademlia_get_value(struct IpfsRouting* routing, char* key, size_t key_size, void** value, size_t* value_size) { +int ipfs_routing_kademlia_get_value(struct IpfsRouting* routing, const unsigned char* key, size_t key_size, void** value, size_t* value_size) { return 0; } @@ -46,7 +46,7 @@ int ipfs_routing_kademlia_get_value(struct IpfsRouting* routing, char* key, size * @param results_size the size of the results buffer * @returns true(1) on success, otherwise false(0) */ -int ipfs_routing_kademlia_find_providers(struct IpfsRouting* routing, unsigned char* key, size_t key_size, struct Libp2pVector** results) { +int ipfs_routing_kademlia_find_providers(struct IpfsRouting* routing, const unsigned char* key, size_t key_size, struct Libp2pVector** results) { *results = libp2p_utils_vector_new(1); struct Libp2pVector* vector = *results; // see if I can provide it @@ -92,7 +92,7 @@ int ipfs_routing_kademlia_find_providers(struct IpfsRouting* routing, unsigned c /** * Find a peer */ -int ipfs_routing_kademlia_find_peer(struct IpfsRouting* routing, const char* param1, size_t param2, struct Libp2pPeer **result) { +int ipfs_routing_kademlia_find_peer(struct IpfsRouting* routing, const unsigned char* param1, size_t param2, struct Libp2pPeer **result) { return 0; } @@ -103,7 +103,7 @@ int ipfs_routing_kademlia_find_peer(struct IpfsRouting* routing, const char* par * @param key_size the size of the key * @returns true(1) on success, otherwise false(0) */ -int ipfs_routing_kademlia_provide(struct IpfsRouting* routing, char* key, size_t key_size) { +int ipfs_routing_kademlia_provide(struct IpfsRouting* routing, const unsigned char* key, size_t key_size) { //TODO: Announce to the network that I can provide this file // save in a cache // store key and address in cache. Key is the hash, peer id is the value diff --git a/routing/offline.c b/routing/offline.c index bbba7e3..4a5c58a 100644 --- a/routing/offline.c +++ b/routing/offline.c @@ -8,13 +8,13 @@ #include "ipfs/routing/routing.h" #include "ipfs/importer/resolver.h" -int ipfs_routing_generic_put_value (ipfs_routing* offlineRouting, char *key, size_t key_size, void *val, size_t vlen) +int ipfs_routing_generic_put_value (ipfs_routing* offlineRouting, const unsigned char *key, size_t key_size, const void *val, size_t vlen) { int err; char *record, *nkey; size_t len, nkey_len; - err = libp2p_record_make_put_record (&record, &len, offlineRouting->sk, key, val, vlen, 0); + err = libp2p_record_make_put_record (&record, &len, offlineRouting->sk, (const char*)key, val, vlen, 0); if (err) { return err; @@ -26,7 +26,7 @@ int ipfs_routing_generic_put_value (ipfs_routing* offlineRouting, char *key, siz return -1; } - if (!ipfs_datastore_helper_ds_key_from_binary((unsigned char*)key, key_size, (unsigned char*)nkey, key_size+1, &nkey_len)) { + if (!ipfs_datastore_helper_ds_key_from_binary(key, key_size, (unsigned char*)nkey, key_size+1, &nkey_len)) { free (nkey); free (record); return -1; @@ -37,34 +37,34 @@ int ipfs_routing_generic_put_value (ipfs_routing* offlineRouting, char *key, siz return 0; // success. } -int ipfs_routing_generic_get_value (ipfs_routing* routing, char *key, size_t key_size, void **val, size_t *vlen) +int ipfs_routing_generic_get_value (ipfs_routing* routing, const unsigned char *key, size_t key_size, void **val, size_t *vlen) { char key_str[key_size + 1]; - strncpy(key_str, key, key_size); + strncpy(key_str, (const char*)key, key_size); key_str[key_size] = 0; - struct Node* node = ipfs_resolver_get(key_str, NULL, routing->local_node); + struct HashtableNode* node = ipfs_resolver_get(key_str, NULL, routing->local_node); if (node == NULL) return -1; // protobuf the node - int protobuf_size = ipfs_node_protobuf_encode_size(node); + int protobuf_size = ipfs_hashtable_node_protobuf_encode_size(node); *val = malloc(protobuf_size); - if (ipfs_node_protobuf_encode(node, *val, protobuf_size, vlen) == 0) + if (ipfs_hashtable_node_protobuf_encode(node, *val, protobuf_size, vlen) == 0) return -1; return 0; } -int ipfs_routing_offline_find_providers (ipfs_routing* offlineRouting, unsigned char *key, size_t key_size, struct Libp2pVector** peers) +int ipfs_routing_offline_find_providers (ipfs_routing* offlineRouting, const unsigned char *key, size_t key_size, struct Libp2pVector** peers) { return ErrOffline; } -int ipfs_routing_offline_find_peer (ipfs_routing* offlineRouting, const char *peer_id, size_t pid_size, struct Libp2pPeer **result) +int ipfs_routing_offline_find_peer (ipfs_routing* offlineRouting, const unsigned char *peer_id, size_t pid_size, struct Libp2pPeer **result) { return ErrOffline; } -int ipfs_routing_offline_provide (ipfs_routing* offlineRouting, char *cid, size_t cid_size) +int ipfs_routing_offline_provide (ipfs_routing* offlineRouting, const unsigned char *cid, size_t cid_size) { return ErrOffline; } diff --git a/routing/online.c b/routing/online.c index 3e04d57..6ca677e 100644 --- a/routing/online.c +++ b/routing/online.c @@ -61,7 +61,7 @@ struct Libp2pMessage* ipfs_routing_online_send_receive_message(struct Stream* st * @param peers an array of Peer structs that can provide the hash * @returns true(1) on success, otherwise false(0) */ -int ipfs_routing_online_find_remote_providers(struct IpfsRouting* routing, unsigned char* key, size_t key_size, struct Libp2pVector** peers) { +int ipfs_routing_online_find_remote_providers(struct IpfsRouting* routing, const unsigned char* key, size_t key_size, struct Libp2pVector** peers) { int found = 0; // build the message to be transmitted struct Libp2pMessage* message = libp2p_message_new(); @@ -75,8 +75,10 @@ int ipfs_routing_online_find_remote_providers(struct IpfsRouting* routing, unsig struct Libp2pPeer* peer = ((struct PeerEntry*)current_entry->item)->peer; if (peer->connection_type == CONNECTION_TYPE_CONNECTED) { // Ask for hash, if it has it, break out of the loop and stop looking + libp2p_logger_debug("online", "FindRemoteProviders: Asking for who can provide\n"); struct Libp2pMessage* return_message = ipfs_routing_online_send_receive_message(peer->connection, message); if (return_message != NULL && return_message->provider_peer_head != NULL) { + libp2p_logger_debug("online", "FindRemoteProviders: Return value is not null\n"); found = 1; *peers = libp2p_utils_vector_new(1); struct Libp2pLinkedList * current_provider_peer_list_item = return_message->provider_peer_head; @@ -87,7 +89,10 @@ int ipfs_routing_online_find_remote_providers(struct IpfsRouting* routing, unsig } libp2p_message_free(return_message); break; + } else { + libp2p_logger_debug("online", "FindRemoteProviders: Return value is null or providers are empty.\n"); } + libp2p_message_free(return_message); // TODO: Make this multithreaded } if (found) @@ -108,17 +113,19 @@ int ipfs_routing_online_find_remote_providers(struct IpfsRouting* routing, unsig * @param multiaddresses the results * @returns true(1) on success, otherwise false(0) */ -int ipfs_routing_online_find_providers(struct IpfsRouting* routing, unsigned char* key, size_t key_size, struct Libp2pVector** peers) { +int ipfs_routing_online_find_providers(struct IpfsRouting* routing, const unsigned char* key, size_t key_size, struct Libp2pVector** peers) { unsigned char* peer_id; int peer_id_size; struct Libp2pPeer *peer; // see if we can find the key, and retrieve the peer who has it if (!libp2p_providerstore_get(routing->local_node->providerstore, key, key_size, &peer_id, &peer_id_size)) { + libp2p_logger_debug("online", "Unable to find provider locally... Asking network\n"); // we need to look remotely return ipfs_routing_online_find_remote_providers(routing, key, key_size, peers); } + libp2p_logger_debug("online", "FindProviders: Found provider locally. Searching for peer.\n"); // now translate the peer id into a peer to get the multiaddresses peer = libp2p_peerstore_get_peer(routing->local_node->peerstore, peer_id, peer_id_size); if (peer == NULL) @@ -133,7 +140,7 @@ int ipfs_routing_online_find_providers(struct IpfsRouting* routing, unsigned cha * helper method. Connect to a peer and ask it for information * about another peer */ -int ipfs_routing_online_ask_peer_for_peer(struct Libp2pPeer* whoToAsk, const char* peer_id, size_t peer_id_size, struct Libp2pPeer **result) { +int ipfs_routing_online_ask_peer_for_peer(struct Libp2pPeer* whoToAsk, const unsigned char* peer_id, size_t peer_id_size, struct Libp2pPeer **result) { if (whoToAsk->connection_type == CONNECTION_TYPE_CONNECTED) { struct Libp2pMessage *message = libp2p_message_new(); if (message == NULL) @@ -160,7 +167,7 @@ int ipfs_routing_online_ask_peer_for_peer(struct Libp2pPeer* whoToAsk, const cha * @param peer the result of the search * @returns true(1) on success, otherwise false(0) */ -int ipfs_routing_online_find_peer(struct IpfsRouting* routing, const char* peer_id, size_t peer_id_size, struct Libp2pPeer **result) { +int ipfs_routing_online_find_peer(struct IpfsRouting* routing, const unsigned char* peer_id, size_t peer_id_size, struct Libp2pPeer **result) { // first look to see if we have it in the peerstore struct Peerstore* peerstore = routing->local_node->peerstore; *result = libp2p_peerstore_get_peer(peerstore, (unsigned char*)peer_id, peer_id_size); @@ -187,7 +194,7 @@ int ipfs_routing_online_find_peer(struct IpfsRouting* routing, const char* peer_ * @param key_size the length of the key * @returns true(1) on success, otherwise false */ -int ipfs_routing_online_provide(struct IpfsRouting* routing, char* key, size_t key_size) { +int ipfs_routing_online_provide(struct IpfsRouting* routing, const unsigned char* key, size_t key_size) { struct Libp2pPeer* local_peer = libp2p_peer_new(); local_peer->id_size = strlen(routing->local_node->identity->peer_id); local_peer->id = malloc(local_peer->id_size); @@ -203,6 +210,7 @@ int ipfs_routing_online_provide(struct IpfsRouting* routing, char* key, size_t k libp2p_logger_debug("online", "Adding local MultiAddress %s to peer.\n", ma->string); local_peer->addr_head->item = ma; + // create the message struct Libp2pMessage* msg = libp2p_message_new(); msg->key_size = key_size; msg->key = malloc(msg->key_size); @@ -211,6 +219,7 @@ int ipfs_routing_online_provide(struct IpfsRouting* routing, char* key, size_t k msg->provider_peer_head = libp2p_utils_linked_list_new(); msg->provider_peer_head->item = local_peer; + // loop through all peers in peerstre, and let them know (if we're still connected) struct Libp2pLinkedList *current = routing->local_node->peerstore->head_entry; while (current != NULL) { struct PeerEntry* current_peer_entry = (struct PeerEntry*)current->item; @@ -263,6 +272,120 @@ int ipfs_routing_online_ping(struct IpfsRouting* routing, struct Libp2pPeer* pee return retVal; } +/*** + * Ask a peer for a value + * @param routing the context + * @param peer the peer to ask + * @param key the key to ask for + * @param key_size the size of the key + * @param buffer where to put the results + * @param buffer_length the size of the buffer + * @returns true(1) on success + */ +int ipfs_routing_online_get_peer_value(ipfs_routing* routing, const struct Libp2pPeer* peer, const unsigned char* key, size_t key_size, void** buffer, size_t *buffer_size) { + // build message + struct Libp2pMessage* msg = libp2p_message_new(); + msg->key_size = key_size; + msg->key = malloc(msg->key_size); + memcpy(msg->key, key, msg->key_size); + msg->message_type = MESSAGE_TYPE_GET_VALUE; + + // send message and receive results + struct Libp2pMessage* ret_msg = ipfs_routing_online_send_receive_message(peer->connection, msg); + libp2p_message_free(msg); + + if (ret_msg == NULL) + return 0; + if (ret_msg->record == NULL || ret_msg->record->value_size <= 0) { + libp2p_message_free(ret_msg); + return 0; + } + // put message results into buffer + *buffer_size = ret_msg->record->value_size; + *buffer = malloc(*buffer_size); + if (*buffer == NULL) { + *buffer_size = 0; + libp2p_message_free(ret_msg); + return 0; + } + memcpy(*buffer, ret_msg->record->value, *buffer_size); + libp2p_message_free(ret_msg); + return 1; +} + +/** + * Retrieve a value from the dht + * @param routing the context + * @param key the key + * @param key_size the size of the key + * @param buffer where to put the results + * @param buffer_size the length of the buffer + */ +int ipfs_routing_online_get_value (ipfs_routing* routing, const unsigned char *key, size_t key_size, void **buffer, size_t *buffer_size) +{ + struct Libp2pVector *peers = NULL; + int retVal = 0; + + // find a provider + routing->FindProviders(routing, key, key_size, &peers); + if (peers == NULL) { + libp2p_logger_debug("online", "online_get_value returned no providers\n"); + goto exit; + } + + libp2p_logger_debug("online", "FindProviders returned %d providers\n", peers->total); + + for(int i = 0; i < peers->total; i++) { + struct Libp2pPeer* current_peer = libp2p_peerstore_get_or_add_peer(routing->local_node->peerstore, libp2p_utils_vector_get(peers, i)); + if (libp2p_peer_matches_id(current_peer, (unsigned char*)routing->local_node->identity->peer_id)) { + // it's a local fetch. Retrieve it + if (!ipfs_routing_generic_get_value(routing, key, key_size, buffer, buffer_size)) + continue; + } + if (libp2p_peer_is_connected(current_peer)) { + // ask a connected peer for the file. If unsuccessful, continue in the loop. + if (ipfs_routing_online_get_peer_value(routing, current_peer, key, key_size, buffer, buffer_size)) { + retVal = 1; + goto exit; + } + } + } + // we didn't get the file. Try to connect to the peers we're not connected to, and ask for the file + for(int i = 0; i < peers->total; i++) { + struct Libp2pPeer* current_peer = libp2p_utils_vector_get(peers, i); + if (libp2p_peer_matches_id(current_peer, (unsigned char*)routing->local_node->identity->peer_id)) { + // we tried this once, it didn't work. Skip it. + continue; + } + if (!libp2p_peer_is_connected(current_peer)) { + // attempt to connect. If unsuccessful, continue in the loop. + libp2p_logger_debug("online", "Attempting to connect to peer to retrieve file\n"); + if (libp2p_peer_connect(current_peer)) { + libp2p_logger_debug("online", "Peer connected\n"); + if (ipfs_routing_online_get_peer_value(routing, current_peer, key, key_size, buffer, buffer_size)) { + libp2p_logger_debug("online", "Retrieved a value\n"); + retVal = 1; + goto exit; + } else { + libp2p_logger_debug("online", "Did not retrieve a value\n"); + } + } + } + } + + retVal = 0; + exit: + if (peers != NULL) { + for (int i = 0; i < peers->total; i++) { + struct Libp2pPeer* current = libp2p_utils_vector_get(peers, i); + libp2p_peer_free(current); + } + libp2p_utils_vector_free(peers); + } + return retVal; +} + + /** * Connects to swarm * @param routing the routing struct @@ -331,7 +454,7 @@ ipfs_routing* ipfs_routing_new_online (struct IpfsNode* local_node, struct RsaPr onlineRouting->stream = stream; onlineRouting->PutValue = ipfs_routing_generic_put_value; - onlineRouting->GetValue = ipfs_routing_generic_get_value; + onlineRouting->GetValue = ipfs_routing_online_get_value; onlineRouting->FindProviders = ipfs_routing_online_find_providers; onlineRouting->FindPeer = ipfs_routing_online_find_peer; onlineRouting->Provide = ipfs_routing_online_provide; @@ -339,6 +462,8 @@ ipfs_routing* ipfs_routing_new_online (struct IpfsNode* local_node, struct RsaPr onlineRouting->Bootstrap = ipfs_routing_online_bootstrap; } + onlineRouting->local_node->mode = MODE_ONLINE; + return onlineRouting; } diff --git a/test/Makefile b/test/Makefile index 66f2513..e13b5aa 100644 --- a/test/Makefile +++ b/test/Makefile @@ -12,6 +12,7 @@ OBJS = testit.o test_helper.o \ ../core/null.o \ ../core/bootstrap.o \ ../core/ping.o \ + ../core/ipfs_node.o \ ../datastore/ds_helper.o \ ../flatfs/flatfs.o \ ../importer/importer.o ../importer/exporter.o ../importer/resolver.o \ diff --git a/test/core/test_node.h b/test/core/test_node.h new file mode 100644 index 0000000..3d272b7 --- /dev/null +++ b/test/core/test_node.h @@ -0,0 +1,53 @@ +#include + +#include "../test_helper.h" +#include "ipfs/core/ipfs_node.h" + +int test_node_peerstore() { + int retVal = 0; + const char *repo_path = "/tmp/test1"; + char* peer_id = NULL; + struct IpfsNode *local_node = NULL; + struct Libp2pPeer* peer = NULL; + + if (!drop_and_build_repository(repo_path, 4001, NULL, &peer_id)) + goto exit; + + if (!ipfs_node_online_new(repo_path, &local_node)) + goto exit; + + // add a peer to the peerstore + peer = libp2p_peer_new(); + if (peer == NULL) + goto exit; + + peer->id_size = strlen(peer_id); + peer->id = malloc(peer->id_size); + memcpy(peer->id, peer_id, peer->id_size); + + if (!libp2p_peerstore_add_peer(local_node->peerstore, peer)) + goto exit; + + // add a second peer by changing the id a bit + char tmp = peer->id[3]; + char tmp2 = peer->id[4]; + char tmp3 = peer->id[5]; + peer->id[3] = tmp2; + peer->id[4] = tmp3; + peer->id[5] = tmp; + + if (!libp2p_peerstore_add_peer(local_node->peerstore, peer)) + goto exit; + + + retVal = 1; + exit: + if (peer_id != NULL) + free(peer_id); + if (peer != NULL) + libp2p_peer_free(peer); + if (local_node != NULL) + ipfs_node_free(local_node); + + return retVal; +} diff --git a/test/core/test_null.h b/test/core/test_null.h index 0203b0a..b627be7 100644 --- a/test/core/test_null.h +++ b/test/core/test_null.h @@ -4,7 +4,7 @@ int test_null_add_provider() { int retVal = 0; char* peer_id_1; char* peer_id_2; - struct FSRepo *fs_repo_2 = NULL; + struct IpfsNode *local_node2 = NULL; pthread_t thread1; pthread_t thread2; struct MultiAddress* ma_peer1; @@ -29,11 +29,10 @@ int test_null_add_provider() { // add a file, to prime the connection to peer 1 //TODO: Find a better way to do this... size_t bytes_written = 0; - ipfs_repo_fsrepo_new(ipfs_path, NULL, &fs_repo_2); - ipfs_repo_fsrepo_open(fs_repo_2); - struct Node* node = NULL; - ipfs_import_file(NULL, "/home/parallels/ipfstest/hello_world.txt", &node, fs_repo_2, &bytes_written, 0); - ipfs_repo_fsrepo_free(fs_repo_2); + ipfs_node_online_new(ipfs_path, &local_node2); + struct HashtableNode* node = NULL; + ipfs_import_file(NULL, "/home/parallels/ipfstest/hello_world.txt", &node, local_node2, &bytes_written, 0); + ipfs_node_free(local_node2); // start the daemon in a separate thread if (pthread_create(&thread2, NULL, test_routing_daemon_start, (void*)ipfs_path) < 0) goto exit; @@ -46,8 +45,8 @@ int test_null_add_provider() { retVal = 1; exit: - if (fs_repo_2 != NULL) - ipfs_repo_fsrepo_free(fs_repo_2); + if (local_node2 != NULL) + ipfs_node_free(local_node2); if (ma_peer1 != NULL) multiaddress_free(ma_peer1); pthread_cancel(thread1); diff --git a/test/merkledag/test_merkledag.h b/test/merkledag/test_merkledag.h index 8d20fde..5012ee0 100644 --- a/test/merkledag/test_merkledag.h +++ b/test/merkledag/test_merkledag.h @@ -40,29 +40,29 @@ int test_merkledag_get_data() { } // create a node - struct Node* node1; - retVal = ipfs_node_new_from_data(binary_data, binary_data_size, &node1); + struct HashtableNode* node1; + retVal = ipfs_hashtable_node_new_from_data(binary_data, binary_data_size, &node1); size_t bytes_written = 0; retVal = ipfs_merkledag_add(node1, fs_repo, &bytes_written); if (retVal == 0) { - ipfs_node_free(node1); + ipfs_hashtable_node_free(node1); ipfs_repo_fsrepo_free(fs_repo); return 0; } // now retrieve it - struct Node* results_node; + struct HashtableNode* results_node; 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); + ipfs_hashtable_node_free(node1); + ipfs_hashtable_node_free(results_node); ipfs_repo_fsrepo_free(fs_repo); return 0; } if (results_node->data_size != 256) { - ipfs_node_free(node1); - ipfs_node_free(results_node); + ipfs_hashtable_node_free(node1); + ipfs_hashtable_node_free(results_node); ipfs_repo_fsrepo_free(fs_repo); return 0; } @@ -70,15 +70,15 @@ int test_merkledag_get_data() { // the data should be the same for(int i = 0; i < results_node->data_size; i++) { if (results_node->data[i] != node1->data[i]) { - ipfs_node_free(node1); - ipfs_node_free(results_node); + ipfs_hashtable_node_free(node1); + ipfs_hashtable_node_free(results_node); ipfs_repo_fsrepo_free(fs_repo); return 0; } } - ipfs_node_free(node1); - ipfs_node_free(results_node); + ipfs_hashtable_node_free(node1); + ipfs_hashtable_node_free(results_node); ipfs_repo_fsrepo_free(fs_repo); return retVal; @@ -102,13 +102,13 @@ int test_merkledag_add_data() { } // create a node - struct Node* node1; - retVal = ipfs_node_new_from_data(binary_data, binary_data_size, &node1); + struct HashtableNode* node1; + retVal = ipfs_hashtable_node_new_from_data(binary_data, binary_data_size, &node1); size_t bytes_written = 0; retVal = ipfs_merkledag_add(node1, fs_repo, &bytes_written); if (retVal == 0) { - ipfs_node_free(node1); + ipfs_hashtable_node_free(node1); return 0; } @@ -118,31 +118,31 @@ int test_merkledag_add_data() { int first_add_size = os_utils_file_size("/tmp/.ipfs/datastore/data.mdb"); if (first_add_size == start_file_size) { // uh oh, database should have increased in size - ipfs_node_free(node1); + ipfs_hashtable_node_free(node1); return 0; } // adding the same binary again should do nothing (the hash should be the same) - struct Node* node2; - retVal = ipfs_node_new_from_data(binary_data, binary_data_size, &node2); + struct HashtableNode* node2; + retVal = ipfs_hashtable_node_new_from_data(binary_data, binary_data_size, &node2); retVal = ipfs_merkledag_add(node2, fs_repo, &bytes_written); if (retVal == 0) { - ipfs_node_free(node1); - ipfs_node_free(node2); + ipfs_hashtable_node_free(node1); + ipfs_hashtable_node_free(node2); return 0; } // make sure everything is correct if (node2->hash == NULL) { - ipfs_node_free(node1); - ipfs_node_free(node2); + ipfs_hashtable_node_free(node1); + ipfs_hashtable_node_free(node2); return 0; } 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); + ipfs_hashtable_node_free(node1); + ipfs_hashtable_node_free(node2); return 0; } } @@ -150,36 +150,36 @@ int test_merkledag_add_data() { int second_add_size = os_utils_file_size("/tmp/.ipfs/datastore/data.mdb"); if (first_add_size != second_add_size) { // uh oh, the database shouldn't have changed size printf("looks as if a new record was added when it shouldn't have. Old file size: %d, new file size: %d\n", first_add_size, second_add_size); - ipfs_node_free(node1); - ipfs_node_free(node2); + ipfs_hashtable_node_free(node1); + ipfs_hashtable_node_free(node2); return 0; } // now change 1 byte, which should change the hash binary_data[10] = 0; // create a node - struct Node* node3; - retVal = ipfs_node_new_from_data(binary_data, binary_data_size, &node3); + struct HashtableNode* node3; + retVal = ipfs_hashtable_node_new_from_data(binary_data, binary_data_size, &node3); retVal = ipfs_merkledag_add(node3, fs_repo, &bytes_written); if (retVal == 0) { - ipfs_node_free(node1); - ipfs_node_free(node2); - ipfs_node_free(node3); + ipfs_hashtable_node_free(node1); + ipfs_hashtable_node_free(node2); + ipfs_hashtable_node_free(node3); return 0; } // make sure everything is correct if (node3->hash == NULL) { - ipfs_node_free(node1); - ipfs_node_free(node2); - ipfs_node_free(node3); + ipfs_hashtable_node_free(node1); + ipfs_hashtable_node_free(node2); + ipfs_hashtable_node_free(node3); return 0; } - ipfs_node_free(node1); - ipfs_node_free(node2); - ipfs_node_free(node3); + ipfs_hashtable_node_free(node1); + ipfs_hashtable_node_free(node2); + ipfs_hashtable_node_free(node3); int third_add_size = os_utils_file_size("/tmp/.ipfs/datastore/data.mdb"); if (third_add_size == second_add_size || third_add_size < second_add_size) {// uh oh, it didn't add it printf("Node 3 should have been added, but the file size did not change from %d.\n", third_add_size); @@ -193,7 +193,7 @@ int test_merkledag_add_data() { int test_merkledag_add_node() { int retVal = 0; - struct Node* node1 = NULL; + struct HashtableNode* node1 = NULL; struct FSRepo* fs_repo = createAndOpenRepo("/tmp/.ipfs"); if (fs_repo == NULL) { @@ -201,7 +201,7 @@ int test_merkledag_add_node() { return 0; } - retVal = ipfs_node_new(&node1); + retVal = ipfs_hashtable_node_new(&node1); if (retVal == 0) { printf("Unable to make node\n"); ipfs_repo_fsrepo_free(fs_repo); @@ -212,12 +212,12 @@ int test_merkledag_add_node() { retVal = ipfs_merkledag_add(node1, fs_repo, &bytes_written); if (retVal == 0) { ipfs_repo_fsrepo_free(fs_repo); - ipfs_node_free(node1); + ipfs_hashtable_node_free(node1); printf("Unable to add node\n"); return 0; } - ipfs_node_free(node1); + ipfs_hashtable_node_free(node1); ipfs_repo_fsrepo_free(fs_repo); return 1; @@ -229,8 +229,8 @@ int test_merkledag_add_node() { int test_merkledag_add_node_with_links() { int retVal = 0; struct NodeLink* link = NULL; - struct Node* node1 = NULL; - struct Node* node2 = NULL; + struct HashtableNode* node1 = NULL; + struct HashtableNode* node2 = NULL; struct FSRepo* fs_repo = createAndOpenRepo("/tmp/.ipfs"); if (fs_repo == NULL) { @@ -245,7 +245,7 @@ int test_merkledag_add_node_with_links() { ipfs_repo_fsrepo_free(fs_repo); return 0; } - retVal = ipfs_node_new_from_link(link, &node1); + retVal = ipfs_hashtable_node_new_from_link(link, &node1); if (retVal == 0) { printf("Unable to make node\n"); ipfs_repo_fsrepo_free(fs_repo); @@ -256,7 +256,7 @@ int test_merkledag_add_node_with_links() { retVal = ipfs_merkledag_add(node1, fs_repo, &bytes_written); if (retVal == 0) { ipfs_repo_fsrepo_free(fs_repo); - ipfs_node_free(node1); + ipfs_hashtable_node_free(node1); printf("Unable to add node\n"); return 0; } @@ -265,7 +265,7 @@ int test_merkledag_add_node_with_links() { 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); + ipfs_hashtable_node_free(node1); return 0; } @@ -275,8 +275,8 @@ int test_merkledag_add_node_with_links() { 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); + ipfs_hashtable_node_free(node1); + ipfs_hashtable_node_free(node2); return 0; } while(node1_link != NULL) { @@ -284,8 +284,8 @@ int test_merkledag_add_node_with_links() { 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); - ipfs_node_free(node2); + ipfs_hashtable_node_free(node1); + ipfs_hashtable_node_free(node2); return 0; } } @@ -293,8 +293,8 @@ int test_merkledag_add_node_with_links() { node2_link = node2_link->next; } - ipfs_node_free(node1); - ipfs_node_free(node2); + ipfs_hashtable_node_free(node1); + ipfs_hashtable_node_free(node2); ipfs_repo_fsrepo_free(fs_repo); return 1; diff --git a/test/node/test_importer.h b/test/node/test_importer.h index 1d8691e..fbbf34c 100644 --- a/test/node/test_importer.h +++ b/test/node/test_importer.h @@ -7,27 +7,30 @@ #include "mh/hashes.h" #include "mh/multihash.h" #include "libp2p/crypto/encoding/base58.h" +#include "ipfs/core/ipfs_node.h" int test_import_large_file() { size_t bytes_size = 1000000; //1mb unsigned char file_bytes[bytes_size]; const char* fileName = "/tmp/test_import_large.tmp"; + const char* repo_dir = "/tmp/.ipfs"; + struct IpfsNode* local_node = NULL; // create the necessary file create_bytes(file_bytes, bytes_size); create_file(fileName, file_bytes, bytes_size); // get the repo - drop_and_build_repository("/tmp/.ipfs", 4001, NULL, NULL); - struct FSRepo* fs_repo; - ipfs_repo_fsrepo_new("/tmp/.ipfs", NULL, &fs_repo); - ipfs_repo_fsrepo_open(fs_repo); + drop_and_build_repository(repo_dir, 4001, NULL, NULL); + if (!ipfs_node_online_new(repo_dir, &local_node)) { + return 0; + } // write to ipfs - struct Node* write_node; + struct HashtableNode* write_node; size_t bytes_written; - if (ipfs_import_file("/tmp", fileName, &write_node, fs_repo, &bytes_written, 1) == 0) { - ipfs_repo_fsrepo_free(fs_repo); + if (ipfs_import_file("/tmp", fileName, &write_node, local_node, &bytes_written, 1) == 0) { + ipfs_node_free(local_node); return 0; } @@ -44,46 +47,46 @@ int test_import_large_file() { for(int i = 0; i < 10; 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); - ipfs_node_free(write_node); + ipfs_node_free(local_node); + ipfs_hashtable_node_free(write_node); return 0; } } // make sure all went okay - struct Node* read_node; - 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); + struct HashtableNode* read_node; + if (ipfs_merkledag_get(write_node->hash, write_node->hash_size, &read_node, local_node->repo) == 0) { + ipfs_node_free(local_node); + ipfs_hashtable_node_free(write_node); return 0; } // the second block should be there - struct Node* read_node2; - if (ipfs_merkledag_get(read_node->head_link->hash, read_node->head_link->hash_size, &read_node2, fs_repo) == 0) { + struct HashtableNode* read_node2; + if (ipfs_merkledag_get(read_node->head_link->hash, read_node->head_link->hash_size, &read_node2, local_node->repo) == 0) { printf("Unable to find the linked node.\n"); - ipfs_repo_fsrepo_free(fs_repo); - ipfs_node_free(write_node); + ipfs_node_free(local_node); + ipfs_hashtable_node_free(write_node); return 0; } - ipfs_node_free(read_node2); + ipfs_hashtable_node_free(read_node2); // compare data if (write_node->data_size != read_node->data_size) { printf("Data size of nodes are not equal. Should be %lu but are %lu\n", write_node->data_size, read_node->data_size); - ipfs_repo_fsrepo_free(fs_repo); - ipfs_node_free(write_node); - ipfs_node_free(read_node); + ipfs_node_free(local_node); + ipfs_hashtable_node_free(write_node); + ipfs_hashtable_node_free(read_node); return 0; } for(int i = 0; i < write_node->data_size; i++) { if (write_node->data[i] != read_node->data[i]) { printf("Data within node is different at position %d. The value should be %02x, but was %02x.\n", i, write_node->data[i], read_node->data[i]); - ipfs_repo_fsrepo_free(fs_repo); - ipfs_node_free(write_node); - ipfs_node_free(read_node); + ipfs_node_free(local_node); + ipfs_hashtable_node_free(write_node); + ipfs_hashtable_node_free(read_node); return 0; } } @@ -93,18 +96,18 @@ int test_import_large_file() { unsigned char base58[base58_size]; 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); - ipfs_node_free(read_node); + ipfs_node_free(local_node); + ipfs_hashtable_node_free(write_node); + ipfs_hashtable_node_free(read_node); return 0; } // attempt to write file - if (ipfs_exporter_to_file(base58, "/tmp/test_import_large_file.rsl", fs_repo) == 0) { + if (ipfs_exporter_to_file(base58, "/tmp/test_import_large_file.rsl", local_node->repo) == 0) { printf("Unable to write file.\n"); - ipfs_repo_fsrepo_free(fs_repo); - ipfs_node_free(write_node); - ipfs_node_free(read_node); + ipfs_node_free(local_node); + ipfs_hashtable_node_free(write_node); + ipfs_hashtable_node_free(read_node); return 0; } @@ -112,9 +115,9 @@ int test_import_large_file() { size_t new_file_size = os_utils_file_size("/tmp/test_import_large_file.rsl"); if (new_file_size != bytes_size) { printf("File sizes are different. Should be %lu but the new one is %lu\n", bytes_size, new_file_size); - ipfs_repo_fsrepo_free(fs_repo); - ipfs_node_free(write_node); - ipfs_node_free(read_node); + ipfs_node_free(local_node); + ipfs_hashtable_node_free(write_node); + ipfs_hashtable_node_free(read_node); return 0; } @@ -131,27 +134,27 @@ int test_import_large_file() { bytes_read2 = fread(buf2, 1, 100, f2); if (bytes_read1 != bytes_read2) { printf("Error reading files for comparison. Read %lu bytes of file 1, but %lu bytes of file 2\n", bytes_read1, bytes_read2); - ipfs_repo_fsrepo_free(fs_repo); - ipfs_node_free(write_node); - ipfs_node_free(read_node); + ipfs_node_free(local_node); + ipfs_hashtable_node_free(write_node); + ipfs_hashtable_node_free(read_node); fclose(f1); fclose(f2); return 0; } if (memcmp(buf1, buf2, bytes_read1) != 0) { printf("The bytes between the files are different\n"); - ipfs_repo_fsrepo_free(fs_repo); - ipfs_node_free(write_node); - ipfs_node_free(read_node); + ipfs_node_free(local_node); + ipfs_hashtable_node_free(write_node); + ipfs_hashtable_node_free(read_node); fclose(f1); fclose(f2); return 0; } } - ipfs_repo_fsrepo_free(fs_repo); - ipfs_node_free(write_node); - ipfs_node_free(read_node); + ipfs_node_free(local_node); + ipfs_hashtable_node_free(write_node); + ipfs_hashtable_node_free(read_node); return 1; @@ -161,22 +164,22 @@ int test_import_small_file() { size_t bytes_size = 1000; unsigned char file_bytes[bytes_size]; const char* fileName = "/tmp/test_import_small.tmp"; + const char* repo_path = "/tmp/.ipfs"; + struct IpfsNode *local_node = NULL; // create the necessary file create_bytes(file_bytes, bytes_size); create_file(fileName, file_bytes, bytes_size); // get the repo - drop_and_build_repository("/tmp/.ipfs", 4001, NULL, NULL); - struct FSRepo* fs_repo; - ipfs_repo_fsrepo_new("/tmp/.ipfs", NULL, &fs_repo); - ipfs_repo_fsrepo_open(fs_repo); + drop_and_build_repository(repo_path, 4001, NULL, NULL); + ipfs_node_online_new(repo_path, &local_node); // write to ipfs - struct Node* write_node; + struct HashtableNode* write_node; size_t bytes_written; - if (ipfs_import_file("/tmp", fileName, &write_node, fs_repo, &bytes_written, 1) == 0) { - ipfs_repo_fsrepo_free(fs_repo); + if (ipfs_import_file("/tmp", fileName, &write_node, local_node, &bytes_written, 1) == 0) { + ipfs_node_free(local_node); return 0; } @@ -192,42 +195,42 @@ int test_import_small_file() { for(int i = 0; i < 10; 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); - ipfs_node_free(write_node); + ipfs_node_free(local_node); + ipfs_hashtable_node_free(write_node); return 0; } } // make sure all went okay - struct Node* read_node; - 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); + struct HashtableNode* read_node; + if (ipfs_merkledag_get(write_node->hash, write_node->hash_size, &read_node, local_node->repo) == 0) { + ipfs_node_free(local_node); + ipfs_hashtable_node_free(write_node); return 0; } // compare data if (write_node->data_size != bytes_size + 8 || write_node->data_size != read_node->data_size) { printf("Data size of nodes are not equal or are incorrect. Should be %lu but are %lu\n", write_node->data_size, read_node->data_size); - ipfs_repo_fsrepo_free(fs_repo); - ipfs_node_free(write_node); - ipfs_node_free(read_node); + ipfs_node_free(local_node); + ipfs_hashtable_node_free(write_node); + ipfs_hashtable_node_free(read_node); return 0; } for(int i = 0; i < bytes_size; i++) { if (write_node->data[i] != read_node->data[i]) { printf("Data within node is different at position %d\n", i); - ipfs_repo_fsrepo_free(fs_repo); - ipfs_node_free(write_node); - ipfs_node_free(read_node); + ipfs_node_free(local_node); + ipfs_hashtable_node_free(write_node); + ipfs_hashtable_node_free(read_node); return 0; } } - ipfs_repo_fsrepo_free(fs_repo); - ipfs_node_free(write_node); - ipfs_node_free(read_node); + ipfs_node_free(local_node); + ipfs_hashtable_node_free(write_node); + ipfs_hashtable_node_free(read_node); return 1; } diff --git a/test/node/test_node.h b/test/node/test_node.h index 8fd5b24..ccd57e2 100644 --- a/test/node/test_node.h +++ b/test/node/test_node.h @@ -16,14 +16,14 @@ int test_node() { retVal = ipfs_node_link_create(name2, ahash2, strlen((char*)ahash2), &mylink2); //Nodes - struct Node * Mynode; - retVal = ipfs_node_new_from_link(mylink, &Mynode); + struct HashtableNode * Mynode; + retVal = ipfs_hashtable_node_new_from_link(mylink, &Mynode); //mylink->name = "HAHA";//Testing for valid node creation - retVal = ipfs_node_add_link(Mynode, mylink2); + retVal = ipfs_hashtable_node_add_link(Mynode, mylink2); //mylink2->name = "HAHA";//Testing for valid node creation //struct NodeLink * ResultLink = ipfs_node_get_link_by_name(Mynode, "Simo"); - ipfs_node_remove_link_by_name("Simo", Mynode); - ipfs_node_free(Mynode); + ipfs_hashtable_node_remove_link_by_name("Simo", Mynode); + ipfs_hashtable_node_free(Mynode); return 1; } @@ -86,8 +86,8 @@ l_exit: * Test a node with 2 links */ int test_node_encode_decode() { - struct Node* control = NULL; - struct Node* results = NULL; + struct HashtableNode* control = NULL; + struct HashtableNode* results = NULL; struct NodeLink* link1 = NULL; struct NodeLink* link2 = NULL; int retVal = 0; @@ -95,29 +95,29 @@ int test_node_encode_decode() { unsigned char* buffer = NULL; // node - if (ipfs_node_new(&control) == 0) + if (ipfs_hashtable_node_new(&control) == 0) goto ed_exit; // first link if (ipfs_node_link_create((char*)"Link1", (unsigned char*)"QmLink1", 7, &link1) == 0) goto ed_exit; - if ( ipfs_node_add_link(control, link1) == 0) + if ( ipfs_hashtable_node_add_link(control, link1) == 0) goto ed_exit; // second link if (ipfs_node_link_create((char*)"Link2", (unsigned char*)"QmLink2", 7, &link2) == 0) goto ed_exit; - if ( ipfs_node_add_link(control, link2) == 0) + if ( ipfs_hashtable_node_add_link(control, link2) == 0) goto ed_exit; // encode - buffer_length = ipfs_node_protobuf_encode_size(control); + buffer_length = ipfs_hashtable_node_protobuf_encode_size(control); buffer = (unsigned char*)malloc(buffer_length); - if (ipfs_node_protobuf_encode(control, buffer, buffer_length, &buffer_length) == 0) + if (ipfs_hashtable_node_protobuf_encode(control, buffer, buffer_length, &buffer_length) == 0) goto ed_exit; // decode - if (ipfs_node_protobuf_decode(buffer, buffer_length, &results) == 0) + if (ipfs_hashtable_node_protobuf_decode(buffer, buffer_length, &results) == 0) goto ed_exit; // compare results @@ -144,9 +144,9 @@ int test_node_encode_decode() { ed_exit: // clean up if (control != NULL) - ipfs_node_free(control); + ipfs_hashtable_node_free(control); if (results != NULL) - ipfs_node_free(results); + ipfs_hashtable_node_free(results); if (buffer != NULL) free(buffer); diff --git a/test/node/test_resolver.h b/test/node/test_resolver.h index 45608d1..fa702f2 100644 --- a/test/node/test_resolver.h +++ b/test/node/test_resolver.h @@ -35,14 +35,14 @@ int test_resolver_get() { ipfs_node.repo = fs_repo; // find something that is already in the repository - struct Node* result = ipfs_resolver_get("QmbMecmXESf96ZNry7hRuzaRkEBhjqXpoYfPCwgFzVGDzB", NULL, &ipfs_node); + struct HashtableNode* result = ipfs_resolver_get("QmbMecmXESf96ZNry7hRuzaRkEBhjqXpoYfPCwgFzVGDzB", NULL, &ipfs_node); if (result == NULL) { free(test_dir); ipfs_repo_fsrepo_free(fs_repo); return 0; } - ipfs_node_free(result); + ipfs_hashtable_node_free(result); // find something where path includes the local node char path[255]; @@ -55,7 +55,7 @@ int test_resolver_get() { ipfs_repo_fsrepo_free(fs_repo); return 0; } - ipfs_node_free(result); + ipfs_hashtable_node_free(result); // find something by path result = ipfs_resolver_get("QmZBvycPAYScBoPEzm35zXHt6gYYV5t9PyWmr4sksLPNFS/hello_world.txt", NULL, &ipfs_node); @@ -65,7 +65,7 @@ int test_resolver_get() { return 0; } - ipfs_node_free(result); + ipfs_hashtable_node_free(result); free(test_dir); ipfs_repo_fsrepo_free(fs_repo); @@ -129,14 +129,14 @@ int test_resolver_remote_get() { strcpy(path, "/ipfs/"); strcat(path, remote_peer_id); strcat(path, "/QmZBvycPAYScBoPEzm35zXHt6gYYV5t9PyWmr4sksLPNFS/hello_world.txt"); - struct Node* result = ipfs_resolver_get(path, NULL, &local_node); + struct HashtableNode* result = ipfs_resolver_get(path, NULL, &local_node); if (result == NULL) { ipfs_repo_fsrepo_free(fs_repo); pthread_cancel(thread); return 0; } - ipfs_node_free(result); + ipfs_hashtable_node_free(result); ipfs_repo_fsrepo_free(fs_repo); pthread_cancel(thread); return 1; diff --git a/test/routing/test_routing.h b/test/routing/test_routing.h index 8cb75f8..ef56d0b 100644 --- a/test/routing/test_routing.h +++ b/test/routing/test_routing.h @@ -6,7 +6,9 @@ #include "multiaddr/multiaddr.h" #include "ipfs/core/daemon.h" +#include "ipfs/core/ipfs_node.h" #include "ipfs/routing/routing.h" +#include "ipfs/importer/exporter.h" #include "../test_helper.h" @@ -21,7 +23,7 @@ int test_routing_find_peer() { os_utils_setenv("IPFS_PATH", ipfs_path, 1); char* peer_id_1; char* peer_id_2; - struct FSRepo* fs_repo_2; + struct IpfsNode *local_node2; char* peer_id_3; pthread_t thread1; pthread_t thread2; @@ -45,11 +47,10 @@ int test_routing_find_peer() { // add a file, to prime the connection to peer 1 //TODO: Find a better way to do this... size_t bytes_written = 0; - ipfs_repo_fsrepo_new(ipfs_path, NULL, &fs_repo_2); - ipfs_repo_fsrepo_open(fs_repo_2); - struct Node* node = NULL; - ipfs_import_file(NULL, "/home/parallels/ipfstest/hello_world.txt", &node, fs_repo_2, &bytes_written, 0); - ipfs_repo_fsrepo_free(fs_repo_2); + ipfs_node_online_new(ipfs_path, &local_node2); + struct HashtableNode* node = NULL; + ipfs_import_file(NULL, "/home/parallels/ipfstest/hello_world.txt", &node, local_node2, &bytes_written, 0); + ipfs_node_free(local_node2); // start the daemon in a separate thread if (pthread_create(&thread2, NULL, test_routing_daemon_start, (void*)ipfs_path) < 0) return 0; @@ -74,7 +75,7 @@ int test_routing_find_peer() { local_node.routing->Bootstrap(local_node.routing); struct Libp2pPeer* result; - if (!local_node.routing->FindPeer(local_node.routing, peer_id_2, strlen(peer_id_2), &result)) + if (!local_node.routing->FindPeer(local_node.routing, (unsigned char*)peer_id_2, strlen(peer_id_2), &result)) return 0; if (result == NULL) { @@ -101,7 +102,7 @@ int test_routing_find_providers() { os_utils_setenv("IPFS_PATH", ipfs_path, 1); char* peer_id_1 = NULL; char* peer_id_2 = NULL; - struct FSRepo* fs_repo_2 = NULL;; + struct IpfsNode *local_node2 = NULL;; char* peer_id_3 = NULL; char* remote_peer_id = NULL; pthread_t thread1, thread2; @@ -134,11 +135,10 @@ int test_routing_find_providers() { // add a file, to prime the connection to peer 1 //TODO: Find a better way to do this... size_t bytes_written = 0; - ipfs_repo_fsrepo_new(ipfs_path, NULL, &fs_repo_2); - ipfs_repo_fsrepo_open(fs_repo_2); - struct Node* node = NULL; - ipfs_import_file(NULL, "/home/parallels/ipfstest/hello_world.txt", &node, fs_repo_2, &bytes_written, 0); - ipfs_repo_fsrepo_free(fs_repo_2); + ipfs_node_online_new(ipfs_path, &local_node2); + struct HashtableNode* node = NULL; + ipfs_import_file(NULL, "/home/parallels/ipfstest/hello_world.txt", &node, local_node2, &bytes_written, 0); + ipfs_node_free(local_node2); // start the daemon in a separate thread if (pthread_create(&thread2, NULL, test_routing_daemon_start, (void*)ipfs_path) < 0) { fprintf(stderr, "Unable to start thread 2\n"); @@ -234,7 +234,7 @@ int test_routing_find_providers() { ipfs_routing_online_free(local_node.routing); } if (node != NULL) - ipfs_node_free(node); + ipfs_hashtable_node_free(node); if (result != NULL) { // we have a vector of peers. Clean 'em up: for(int i = 0; i < result->total; i++) { @@ -258,7 +258,7 @@ int test_routing_provide() { os_utils_setenv("IPFS_PATH", ipfs_path, 1); char* peer_id_1 = NULL; char* peer_id_2 = NULL; - struct FSRepo* fs_repo_2 = NULL; + struct IpfsNode *local_node2 = NULL; pthread_t thread1, thread2; int thread1_started = 0, thread2_started = 0; struct MultiAddress* ma_peer1 = NULL; @@ -287,11 +287,10 @@ int test_routing_provide() { // add a file, to prime the connection to peer 1 //TODO: Find a better way to do this... size_t bytes_written = 0; - ipfs_repo_fsrepo_new(ipfs_path, NULL, &fs_repo_2); - ipfs_repo_fsrepo_open(fs_repo_2); - struct Node* node = NULL; - ipfs_import_file(NULL, "/home/parallels/ipfstest/hello_world.txt", &node, fs_repo_2, &bytes_written, 0); - ipfs_repo_fsrepo_free(fs_repo_2); + ipfs_node_online_new(ipfs_path, &local_node2); + struct HashtableNode* node = NULL; + ipfs_import_file(NULL, "/home/parallels/ipfstest/hello_world.txt", &node, local_node2, &bytes_written, 0); + ipfs_node_free(local_node2); // start the daemon in a separate thread if (pthread_create(&thread2, NULL, test_routing_daemon_start, (void*)ipfs_path) < 0) { fprintf(stderr, "Unable to start thread 2\n"); @@ -318,7 +317,135 @@ int test_routing_provide() { libp2p_utils_vector_free(ma_vector2); } if (node != NULL) - ipfs_node_free(node); + ipfs_hashtable_node_free(node); + libp2p_logger_free(); + return retVal; + +} + +/*** + * Attempt to retrieve a file from a previously unknown node + */ +int test_routing_retrieve_file_third_party() { + int retVal = 0; + + /* + libp2p_logger_add_class("online"); + libp2p_logger_add_class("multistream"); + libp2p_logger_add_class("null"); + libp2p_logger_add_class("dht_protocol"); + libp2p_logger_add_class("providerstore"); + libp2p_logger_add_class("peerstore"); + libp2p_logger_add_class("exporter"); + libp2p_logger_add_class("peer"); + libp2p_logger_add_class("test_routing"); + */ + + // clean out repository + char* ipfs_path = "/tmp/test1"; + char* peer_id_1 = NULL, *peer_id_2 = NULL, *peer_id_3 = NULL; + struct IpfsNode* ipfs_node2 = NULL, *ipfs_node3 = NULL; + pthread_t thread1, thread2; + int thread1_started = 0, thread2_started = 0; + struct MultiAddress* ma_peer1 = NULL; + struct Libp2pVector* ma_vector2 = NULL, *ma_vector3 = NULL; + struct HashtableNode* node = NULL, *result_node = NULL; + + // create peer 1 + drop_and_build_repository(ipfs_path, 4001, NULL, &peer_id_1); + char multiaddress_string[255]; + sprintf(multiaddress_string, "/ip4/127.0.0.1/tcp/4001/ipfs/%s", peer_id_1); + ma_peer1 = multiaddress_new_from_string(multiaddress_string); + // start the daemon in a separate thread + libp2p_logger_debug("test_routing", "Firing up daemon 1.\n"); + if (pthread_create(&thread1, NULL, test_routing_daemon_start, (void*)ipfs_path) < 0) { + fprintf(stderr, "Unable to start thread 1\n"); + goto exit; + } + thread1_started = 1; + + // wait for everything to start up + // JMJ debugging = + sleep(3); + + // create peer 2 + ipfs_path = "/tmp/test2"; + // create a vector to hold peer1's multiaddress so we can connect as a peer + ma_vector2 = libp2p_utils_vector_new(1); + libp2p_utils_vector_add(ma_vector2, ma_peer1); + // note: this distroys some things, as it frees the fs_repo_3: + drop_and_build_repository(ipfs_path, 4002, ma_vector2, &peer_id_2); + // add a file, to prime the connection to peer 1 + //TODO: Find a better way to do this... + size_t bytes_written = 0; + if (!ipfs_node_online_new(ipfs_path, &ipfs_node2)) + goto exit; + ipfs_node2->routing->Bootstrap(ipfs_node2->routing); + ipfs_import_file(NULL, "/home/parallels/ipfstest/hello_world.txt", &node, ipfs_node2, &bytes_written, 0); + ipfs_node_free(ipfs_node2); + // start the daemon in a separate thread + libp2p_logger_debug("test_routing", "Firing up daemon 2.\n"); + if (pthread_create(&thread2, NULL, test_routing_daemon_start, (void*)ipfs_path) < 0) { + fprintf(stderr, "Unable to start thread 2\n"); + goto exit; + } + thread2_started = 1; + + // wait for everything to start up + // JMJ debugging = + sleep(3); + + libp2p_logger_debug("test_routing", "Firing up the 3rd client\n"); + // create my peer, peer 3 + ipfs_path = "/tmp/test3"; + ma_peer1 = multiaddress_new_from_string(multiaddress_string); + ma_vector3 = libp2p_utils_vector_new(1); + libp2p_utils_vector_add(ma_vector3, ma_peer1); + drop_and_build_repository(ipfs_path, 4003, ma_vector3, &peer_id_3); + ipfs_node_online_new(ipfs_path, &ipfs_node3); + + ipfs_node3->routing->Bootstrap(ipfs_node3->routing); + + if (!ipfs_exporter_get_node(ipfs_node3, node->hash, node->hash_size, &result_node)) { + fprintf(stderr, "Get_Node returned false\n"); + goto exit; + } + + if (node->hash_size != result_node->hash_size) { + fprintf(stderr, "Node hash sizes do not match. Should be %lu but is %lu\n", node->hash_size, result_node->hash_size); + goto exit; + } + + if (node->data_size != result_node->data_size) { + fprintf(stderr, "Result sizes do not match. Should be %lu but is %lu\n", node->data_size, result_node->data_size); + goto exit; + } + + retVal = 1; + exit: + ipfs_daemon_stop(); + if (thread1_started) + pthread_join(thread1, NULL); + if (thread2_started) + pthread_join(thread2, NULL); + if (ipfs_node3 != NULL) + ipfs_node_free(ipfs_node3); + if (peer_id_1 != NULL) + free(peer_id_1); + if (peer_id_2 != NULL) + free(peer_id_2); + if (peer_id_3 != NULL) + free(peer_id_3); + if (ma_vector2 != NULL) { + libp2p_utils_vector_free(ma_vector2); + } + if (ma_vector3 != NULL) { + libp2p_utils_vector_free(ma_vector3); + } + if (node != NULL) + ipfs_hashtable_node_free(node); + if (result_node != NULL) + ipfs_hashtable_node_free(result_node); libp2p_logger_free(); return retVal; diff --git a/test/routing/test_supernode.h b/test/routing/test_supernode.h index 10d2626..355f356 100644 --- a/test/routing/test_supernode.h +++ b/test/routing/test_supernode.h @@ -64,7 +64,7 @@ int test_routing_supernode_get_remote_value() { struct SessionContext context; unsigned char* results = NULL; size_t results_size = 0; - struct Node* node; + struct HashtableNode* node; // unencode the base58 if (!libp2p_crypto_encoding_base58_decode(orig_multihash, strlen((char*)orig_multihash), &hash_ptr, &hash_size)) @@ -130,7 +130,7 @@ int test_routing_supernode_get_remote_value() { if (!libp2p_nodeio_get(&context, hash, hash_size, &results, &results_size)) goto exit; - if (!ipfs_node_protobuf_decode(results, results_size, &node)) + if (!ipfs_hashtable_node_protobuf_decode(results, results_size, &node)) goto exit; //we got it @@ -155,12 +155,12 @@ int test_routing_supernode_get_value() { int file_size = 1000; unsigned char bytes[file_size]; char* fullFileName = "/tmp/temp_file.bin"; - struct Node* write_node = NULL; + struct HashtableNode* write_node = NULL; size_t bytes_written = 0; struct Libp2pVector* multiaddresses; unsigned char* results; size_t results_size = 0; - struct Node* node = NULL; + struct HashtableNode* node = NULL; char* ip = NULL; if (!drop_build_and_open_repo("/tmp/.ipfs", &fs_repo)) @@ -194,13 +194,15 @@ int test_routing_supernode_get_value() { create_file(fullFileName, bytes, file_size); // write to ipfs - if (ipfs_import_file("/tmp", fullFileName, &write_node, fs_repo, &bytes_written, 1) == 0) { + if (ipfs_import_file("/tmp", fullFileName, &write_node, ipfs_node, &bytes_written, 1) == 0) { goto exit; } // announce to network that this can be provided - if (!ipfs_node->routing->Provide(ipfs_node->routing, (char*)write_node->hash, write_node->hash_size)) + /* + if (!ipfs_node->routing->Provide(ipfs_node->routing, (unsigned char*)write_node->hash, write_node->hash_size)) goto exit; + */ // ask the network who can provide this if (!ipfs_node->routing->FindProviders(ipfs_node->routing, write_node->hash, write_node->hash_size, &multiaddresses)) @@ -236,7 +238,7 @@ int test_routing_supernode_get_value() { if (!libp2p_nodeio_get(&context, write_node->hash, write_node->hash_size, &results, &results_size)) goto exit; - if (!ipfs_node_protobuf_decode(results, results_size, &node)) + if (!ipfs_hashtable_node_protobuf_decode(results, results_size, &node)) goto exit; //we got it diff --git a/test/testit.c b/test/testit.c index 6d5268f..4cd4d55 100644 --- a/test/testit.c +++ b/test/testit.c @@ -18,6 +18,7 @@ #include "core/test_ping.h" #include "core/test_null.h" #include "core/test_daemon.h" +#include "core/test_node.h" int testit(const char* name, int (*func)(void)) { printf("Testing %s...\n", name); @@ -57,6 +58,7 @@ const char* names[] = { "test_node", "test_node_link_encode_decode", "test_node_encode_decode", + "test_node_peerstore", "test_merkledag_add_data", "test_merkledag_get_data", "test_merkledag_add_node", @@ -67,6 +69,7 @@ const char* names[] = { "test_routing_provide", "test_routing_supernode_get_value", "test_routing_supernode_get_remote_value", + "test_routing_retrieve_file_third_party", "test_unixfs_encode_decode", "test_unixfs_encode_smallfile", "test_ping", @@ -103,6 +106,7 @@ int (*funcs[])(void) = { test_node, test_node_link_encode_decode, test_node_encode_decode, + test_node_peerstore, test_merkledag_add_data, test_merkledag_get_data, test_merkledag_add_node, @@ -113,6 +117,7 @@ int (*funcs[])(void) = { test_routing_provide, test_routing_supernode_get_value, test_routing_supernode_get_remote_value, + test_routing_retrieve_file_third_party, test_unixfs_encode_decode, test_unixfs_encode_smallfile, test_ping,