diff --git a/.cproject b/.cproject index d05172c..a60437a 100644 --- a/.cproject +++ b/.cproject @@ -30,6 +30,7 @@ + diff --git a/blocks/Makefile b/blocks/Makefile index f830509..f64ebc1 100644 --- a/blocks/Makefile +++ b/blocks/Makefile @@ -1,5 +1,5 @@ CC = gcc -CFLAGS = -O0 -I../include -I../../c-libp2p/include -I../../c-multihash/include -I../../c-multiaddr/include -Wall +CFLAGS = -O0 -I../include -I../../c-libp2p/include -I../../c-multihash/include -I../../c-multiaddr/include -I../../c-protobuf -Wall ifdef DEBUG CFLAGS += -g3 diff --git a/cid/Makefile b/cid/Makefile index 08774d9..bb4c1ee 100644 --- a/cid/Makefile +++ b/cid/Makefile @@ -1,5 +1,5 @@ CC = gcc -CFLAGS = -O0 -I../include -I../../c-libp2p/include -I../../c-multihash/include -I../../c-multiaddr/include -Wall +CFLAGS = -O0 -I../include -I../../c-libp2p/include -I../../c-multihash/include -I../../c-multiaddr/include -I../../c-protobuf -Wall ifdef DEBUG CFLAGS += -g3 diff --git a/cid/cid.c b/cid/cid.c index 13a4ca1..7f0e365 100644 --- a/cid/cid.c +++ b/cid/cid.c @@ -10,8 +10,63 @@ #include "libp2p/crypto/encoding/base58.h" #include "ipfs/multibase/multibase.h" #include "mh/multihash.h" -#include "multiaddr/varint.h" +#include "varint.h" +enum WireType ipfs_cid_message_fields[] = { WIRETYPE_VARINT, WIRETYPE_VARINT, WIRETYPE_LENGTH_DELIMITED }; + + +size_t ipfs_cid_protobuf_encode_size(struct Cid* cid) { + return 11+12+cid->hash_length+11; +} + +int ipfs_cid_protobuf_encode(struct Cid* cid, unsigned char* buffer, size_t buffer_length, size_t* bytes_written) { + size_t bytes_used; + *bytes_written = 0; + int retVal = 0; + retVal = protobuf_encode_varint(1, ipfs_cid_message_fields[0], cid->version, buffer, buffer_length, &bytes_used); + *bytes_written += bytes_used; + retVal = protobuf_encode_varint(2, ipfs_cid_message_fields[1], cid->codec, &buffer[*bytes_written], buffer_length - (*bytes_written), &bytes_used); + *bytes_written += bytes_used; + retVal = protobuf_encode_length_delimited(3, ipfs_cid_message_fields[2], cid->hash, cid->hash_length, &buffer[*bytes_written], buffer_length - (*bytes_written), &bytes_used); + *bytes_written += bytes_used; + return 1; +} + +int ipfs_cid_protobuf_decode(unsigned char* buffer, size_t buffer_length, struct Cid** output) { + size_t pos = 0; + struct Cid cid; + int retVal = 0; + while(pos < buffer_length) { + size_t bytes_read = 0; + int field_no; + enum WireType field_type; + if (protobuf_decode_field_and_type(&buffer[pos], buffer_length, &field_no, &field_type, &bytes_read) == 0) { + return 0; + } + pos += bytes_read; + switch(field_no) { + case (1): + cid.version = varint_decode(&buffer[pos], buffer_length - pos, &bytes_read); + pos += bytes_read; + break; + case (2): + cid.codec = varint_decode(&buffer[pos], buffer_length - pos, &bytes_read); + pos += bytes_read; + break; + case (3): + retVal = protobuf_decode_length_delimited(&buffer[pos], buffer_length - pos, &cid.hash, &cid.hash_length, &bytes_read); + if (retVal == 0) + return 0; + pos += bytes_read; + break; + } + + } + + retVal = ipfs_cid_new(cid.version, cid.hash, cid.hash_length, cid.codec, output); + free(cid.hash); + return retVal; +} /** * Create a new CID based on the given hash @@ -118,16 +173,16 @@ int ipfs_cid_cast(unsigned char* incoming, size_t incoming_size, struct Cid* cid // This is not a multihash. Perhaps it is using varints. Try to peel the information out of the bytes. // first the version - int pos = 0, retVal = 0; + int pos = 0; size_t num_bytes = 0; - num_bytes = uvarint_decode32(&incoming[pos], incoming_size - pos, &cid->version); - if (num_bytes < 0 || cid->version > 1 || cid->version < 0) + cid->version = varint_decode(&incoming[pos], incoming_size - pos, &num_bytes); + if (num_bytes == 0 || cid->version > 1 || cid->version < 0) return 0; pos = num_bytes; // now the codec uint32_t codec = 0; - num_bytes = uvarint_decode32(&incoming[pos], incoming_size - pos, &codec); - if (num_bytes < 0) + codec = varint_decode(&incoming[pos], incoming_size - pos, &num_bytes); + if (num_bytes == 0) return 0; cid->codec = codec; pos += num_bytes; diff --git a/cmd/ipfs/Makefile b/cmd/ipfs/Makefile index 9021275..24b9bd5 100644 --- a/cmd/ipfs/Makefile +++ b/cmd/ipfs/Makefile @@ -1,5 +1,5 @@ CC = gcc -CFLAGS = -O0 -I../../include -I../../../c-libp2p/include -Wall +CFLAGS = -O0 -I../../include -I../../../c-libp2p/include -I../../../c-protobuf -Wall ifdef DEBUG CFLAGS += -g3 diff --git a/core/Makefile b/core/Makefile index 943ec08..94a443b 100644 --- a/core/Makefile +++ b/core/Makefile @@ -1,5 +1,5 @@ CC = gcc -CFLAGS = -O0 -I../include -I../../c-libp2p/include -Wall +CFLAGS = -O0 -I../include -I../../c-libp2p/include -I../../c-protobuf -Wall LFLAGS = DEPS = builder.h ipfs_node.h OBJS = builder.o diff --git a/importer/importer.c b/importer/importer.c new file mode 100644 index 0000000..3c5b324 --- /dev/null +++ b/importer/importer.c @@ -0,0 +1,46 @@ +#include + +#include "ipfs/importer/importer.h" + +#define MAX_DATA_SIZE 262144 // 1024 * 256; + +/** + * read the next chunk of bytes, create a node, and add a link to the node in the passed-in node + * @param file the file handle + * @param node the node to add to + * @returns number of bytes read + */ +int ipfs_import_chunk(FILE* file, struct Node* node) { + unsigned char buffer[MAX_DATA_SIZE]; + size_t bytes_read = fread(buffer, MAX_DATA_SIZE, 1, file); + if (node->data_size == 0) { + Node_Set_Data(node, buffer, bytes_read); + } else { + // create a new node, and link to the parent + struct Node* new_node = N_Create_From_Data(buffer, bytes_read); + // persist + // put link in node + Node_Add_Link(node, Create_Link("", new_node->cached->hash)); + Node_Delete(new_node); + } + return bytes_read; +} + +/** + * Creates a node based on an incoming file + * @param file_name the file to import + * @param node the root node (could have links to others) + * @returns true(1) on success + */ +int ipfs_import_file(const char* fileName, struct Node** node) { + int retVal = 1; + + FILE* file = fopen(fileName, "rb"); + *node = (struct Node)malloc(sizeof(struct Node)); + + // add all nodes + while (ipfs_import_chunk(file, *node) == MAX_DATA_SIZE) {} + fclose(file); + + return 1; +} diff --git a/include/ipfs/cid/cid.h b/include/ipfs/cid/cid.h index e499c41..1ce766b 100644 --- a/include/ipfs/cid/cid.h +++ b/include/ipfs/cid/cid.h @@ -6,6 +6,7 @@ #define __IPFS_CID_CID_H #include +#include "protobuf.h" #define CID_PROTOBUF 0x70 #define CID_CBOR 0x71 @@ -25,6 +26,30 @@ struct Cid { size_t hash_length; }; +/*** + * encode a Cid into a protobuf array of bytes + * @param incoming the incoming Cid struct + * @param buffer the buffer + * @param max_buffer_length the length of the buffer + * @param bytes_written the number of bytes written + */ +int ipfs_cid_protobuf_encode(struct Cid* incoming, unsigned char* buffer, size_t max_buffer_length, size_t* bytes_written); + +/*** + * decode an array of bytes into a Cid structure + * @param buffer the incming array of bytes + * @param buffer_length the length of the buffer + * @param output the Cid struct NOTE: all allocations are made by this function. Be sure to call free + * @returns true(1) on success + */ +int ipfs_cid_protobuf_decode(unsigned char* buffer, size_t buffer_length, struct Cid** output); + +/*** + * Returns a safe estimate of the required buffer size to encode the Cid struct + * @param incoming the struct to encode + * @returns the number of approximate bytes + */ +size_t ipfs_cid_protobuf_encode_size(struct Cid* incoming); /** * Create a new CID based on the given hash diff --git a/include/ipfs/importer/importer.h b/include/ipfs/importer/importer.h new file mode 100644 index 0000000..00c977c --- /dev/null +++ b/include/ipfs/importer/importer.h @@ -0,0 +1,12 @@ +#ifndef __IPFS_IMPORTER_IMPORTER_H__ +#define __IPFS_IMPORTER_IMPORTER_H__ + +/** + * Creates a node based on an incoming file + * @param file_name the file to import + * @param node the root node (could have links to others) + * @returns true(1) on success + */ +int ipfs_import_file(const char* fileName, struct Node** node); + +#endif /* INCLUDE_IPFS_IMPORTER_IMPORTER_H_ */ diff --git a/include/ipfs/merkledag/merkledag.h b/include/ipfs/merkledag/merkledag.h index fb0c682..9817187 100644 --- a/include/ipfs/merkledag/merkledag.h +++ b/include/ipfs/merkledag/merkledag.h @@ -1,3 +1,6 @@ +/*** + * Merkledag methods + */ #ifndef __IPFS_MERKLEDAG_H__ #define __IPFS_MERKLEDAG_H__ diff --git a/include/ipfs/node/node.h b/include/ipfs/node/node.h index c3a82f1..36cf0af 100644 --- a/include/ipfs/node/node.h +++ b/include/ipfs/node/node.h @@ -26,7 +26,7 @@ struct Node size_t data_size; unsigned char * encoded; struct Cid * cached; - int link_ammount; + int link_amount; struct Link * links[]; }; @@ -72,7 +72,7 @@ int Node_Set_Cached(struct Node * N, struct Cid * TheCid); * Sets pointers of encoded & cached to NULL /following go method * returns 1 on success 0 on failure */ -int Node_Set_Data(struct Node * N, unsigned char * Data); +int Node_Set_Data(struct Node * N, unsigned char * Data, size_t data_size); /*Node_Set_Encoded * @param NODE: the node you wish to alter (struct Node *) diff --git a/merkledag/Makefile b/merkledag/Makefile index a5f0784..aadae27 100644 --- a/merkledag/Makefile +++ b/merkledag/Makefile @@ -1,5 +1,5 @@ CC = gcc -CFLAGS = -O0 -I../include -I../../c-libp2p/include -I../../c-multihash/include -I../../c-multiaddr/include -Wall +CFLAGS = -O0 -I../include -I../../c-libp2p/include -I../../c-multihash/include -I../../c-multiaddr/include -I../../c-protobuf -Wall ifdef DEBUG CFLAGS += -g3 diff --git a/node/Makefile b/node/Makefile index 607fbec..40240eb 100644 --- a/node/Makefile +++ b/node/Makefile @@ -1,5 +1,5 @@ CC = gcc -CFLAGS = -O0 -I../include -I../../c-libp2p/include -I../../c-multihash/include -I../../c-multiaddr/include -Wall +CFLAGS = -O0 -I../include -I../../c-libp2p/include -I../../c-multihash/include -I../../c-multiaddr/include -I../../c-protobuf -Wall ifdef DEBUG CFLAGS += -g3 diff --git a/node/node.c b/node/node.c index 3dc0c51..caeb638 100644 --- a/node/node.c +++ b/node/node.c @@ -53,7 +53,7 @@ struct Node * Create_Empty_Node() N->cached = NULL; N->data = NULL; N->encoded = NULL; - N->link_ammount = 0; + N->link_amount = 0; return N; } @@ -77,7 +77,7 @@ int Node_Set_Cached(struct Node * N, struct Cid * TheCid) * Sets pointers of encoded & cached to NULL /following go method * returns 1 on success 0 on failure */ -int Node_Set_Data(struct Node * N, unsigned char * Data) +int Node_Set_Data(struct Node * N, unsigned char * Data, size_t data_size) { if(!N || !Data) { @@ -85,7 +85,12 @@ int Node_Set_Data(struct Node * N, unsigned char * Data) } N->encoded = NULL; N->cached = NULL; - N->data = Data; + N->data = malloc(sizeof(unsigned char) * data_size); + if (N->data == NULL) + return 0; + + memcpy(N->data, Data, data_size); + N->data_size = data_size; return 1; } @@ -126,9 +131,9 @@ struct Node * Node_Copy(struct Node * CP_Node) { struct Node * CN; CN = (struct Node*) malloc(sizeof(struct Node) + sizeof(struct Link) * 2); - if(CP_Node->link_ammount != 0) + if(CP_Node->link_amount != 0) { - for(int i=0; ilink_ammount; i++) + for(int i=0; ilink_amount; i++) { CN->links[i] = malloc(sizeof(struct Link)); } @@ -146,9 +151,9 @@ void Node_Delete(struct Node * N) { if(N) { - if(N->link_ammount > 0) + if(N->link_amount > 0) { - for(int i=0; ilink_ammount; i++) + for(int i=0; ilink_amount; i++) { free(N->links[i]); } @@ -171,7 +176,7 @@ void Node_Delete(struct Node * N) struct Link * Node_Get_Link(struct Node * N, char * Name) { struct Link * L; - for(int i=0;ilink_ammount;i++) + for(int i=0;ilink_amount;i++) { if(strcmp(N->links[i]->name,Name) == 0) { @@ -193,23 +198,23 @@ struct Link * Node_Get_Link(struct Node * N, char * Name) */ int Node_Remove_Link(char * Name, struct Node * mynode) { - for(int i=0; ilink_ammount; i++) + for(int i=0; ilink_amount; i++) { if(mynode->links[i]->name == Name) { - for(int x=i;xlink_ammount && x+1 != mynode->link_ammount;i++) + for(int x=i;xlink_amount && x+1 != mynode->link_amount;i++) { memcpy(mynode->links[x],mynode->links[x+1],sizeof(struct Link)); } - free(mynode->links[mynode->link_ammount-1]); - mynode->link_ammount--; + free(mynode->links[mynode->link_amount-1]); + mynode->link_amount--; return 1; } } return 0; } /* N_Add_Link - * Adds a link to your node + * Adds a link to your nodse * @param mynode: &yournode * @param mylink: the CID you want to create a node from * @param linksz: sizeof(your cid here) @@ -218,11 +223,11 @@ int Node_Remove_Link(char * Name, struct Node * mynode) struct Node * N_Add_Link(struct Node ** mynode, struct Link * mylink, size_t linksz) { struct Node * Nl = *mynode; - Nl->link_ammount++; + Nl->link_amount++; size_t calculatesize = 0; - if(Nl->link_ammount != 0) + if(Nl->link_amount != 0) { - for(int i=0; ilink_ammount-1;i++) + for(int i=0; ilink_amount-1;i++) { calculatesize = calculatesize + sizeof(Nl->links[i]); } @@ -233,8 +238,8 @@ struct Node * N_Add_Link(struct Node ** mynode, struct Link * mylink, size_t lin { Nl = (struct Node *) malloc(sizeof(struct Node) + linksz); } - Nl->links[Nl->link_ammount-1] = malloc(sizeof(struct Link)); - memcpy(Nl->links[Nl->link_ammount-1],mylink,sizeof(struct Link)); + Nl->links[Nl->link_amount-1] = malloc(sizeof(struct Link)); + memcpy(Nl->links[Nl->link_amount-1],mylink,sizeof(struct Link)); return Nl; } @@ -248,8 +253,7 @@ struct Node * N_Create_From_Link(struct Link * mylink) { struct Node * mynode; mynode = (struct Node *) malloc(sizeof(struct Node) + sizeof(struct Link)); - mynode->link_ammount = 0; - mynode->link_ammount++; + mynode->link_amount = 1; mynode->links[0] = malloc(sizeof(struct Link)); memcpy(mynode->links[0], mylink, sizeof(struct Link)); mynode->cached = NULL; @@ -267,10 +271,8 @@ struct Node * N_Create_From_Data(unsigned char * data, size_t data_size) { struct Node * mynode; mynode = (struct Node *) malloc(sizeof(struct Node)); - mynode->data = malloc(sizeof(unsigned char) * data_size); - memcpy(mynode->data, data, data_size); - mynode->data_size = data_size; - mynode->link_ammount=0; + Node_Set_Data(mynode, data, data_size); + mynode->link_amount=0; mynode->encoded = NULL; mynode->cached = NULL; return mynode; @@ -288,7 +290,7 @@ struct Node * N_Create_From_Encoded(unsigned char * data) struct Node * mynode; mynode = (struct Node *) malloc(sizeof(struct Node)); mynode->encoded = data; - mynode->link_ammount = 0; + mynode->link_amount = 0; mynode->data = NULL; mynode->cached = NULL; return mynode; diff --git a/repo/config/Makefile b/repo/config/Makefile index c0a1792..cf49611 100644 --- a/repo/config/Makefile +++ b/repo/config/Makefile @@ -1,5 +1,5 @@ CC = gcc -CFLAGS = -O0 -I../../include -I../../../c-libp2p/include -I../../../c-multihash/include -Wall +CFLAGS = -O0 -I../../include -I../../../c-libp2p/include -I../../../c-multihash/include -I../../../c-protobuf -Wall ifdef DEBUG CFLAGS += -g3 diff --git a/repo/fsrepo/Makefile b/repo/fsrepo/Makefile index 48e22d6..a4196c0 100644 --- a/repo/fsrepo/Makefile +++ b/repo/fsrepo/Makefile @@ -1,5 +1,5 @@ CC = gcc -CFLAGS = -O0 -I../../include -I../../../c-libp2p/include -I../../../lmdb/libraries/liblmdb -Wall +CFLAGS = -O0 -I../../include -I../../../c-libp2p/include -I../../../lmdb/libraries/liblmdb -I../../../c-protobuf -Wall ifdef DEBUG CFLAGS += -g3 diff --git a/repo/fsrepo/lmdb_datastore.c b/repo/fsrepo/lmdb_datastore.c index 62b29f5..9ac6e8d 100644 --- a/repo/fsrepo/lmdb_datastore.c +++ b/repo/fsrepo/lmdb_datastore.c @@ -175,10 +175,17 @@ int repo_fsrepo_lmdb_put(unsigned const char* key, size_t key_size, unsigned cha * @returns true(1) on success */ int repo_fsrepo_lmdb_put_block(const struct Block* block, const struct Datastore* datastore) { - return repo_fsrepo_lmdb_put(block->cid->hash, block->cid->hash_length, block->data, block->data_length, datastore); } +/*** + * Save a node in the datastore + */ +int repo_fsrepo_lmdb_put_node(const struct Node* node, const struct Datastore* datastore) { + // first the links, then the data + +} + /** * Open an lmdb database with the given parameters. * Note: for now, the parameters are not used diff --git a/test/Makefile b/test/Makefile index 9a247e6..c241eb0 100644 --- a/test/Makefile +++ b/test/Makefile @@ -1,5 +1,5 @@ CC = gcc -CFLAGS = -O0 -I../include -I../../c-libp2p/include -I../../c-multihash/include -I../../c-multiaddr/ -g3 -Wall +CFLAGS = -O0 -I../include -I../../c-libp2p/include -I../../c-multihash/include -I../../c-multiaddr/ -I../../c-protobuf -g3 -Wall LFLAGS = -L../../c-libp2p -L../../c-multihash -L../../c-multiaddr -lp2p -lm -lmultihash -lmultiaddr -lpthread DEPS = cmd/ipfs/test_init.h repo/test_repo_bootstrap_peers.h repo/test_repo_config.h repo/test_repo_identity.h cid/test_cid.h OBJS = testit.o test_helper.o \ @@ -18,7 +18,8 @@ OBJS = testit.o test_helper.o \ ../repo/config/config.o ../repo/config/identity.o \ ../repo/config/bootstrap_peers.o ../repo/config/datastore.o ../repo/config/gateway.o \ ../repo/config/addresses.o ../repo/config/swarm.o ../repo/config/peer.o \ - ../thirdparty/ipfsaddr/ipfs_addr.o + ../thirdparty/ipfsaddr/ipfs_addr.o \ + ../../c-protobuf/protobuf.o ../../c-protobuf/varint.o %.o: %.c $(DEPS) $(CC) -c -o $@ $< $(CFLAGS) diff --git a/test/cid/test_cid.h b/test/cid/test_cid.h index aa28841..8eb0d6f 100644 --- a/test/cid/test_cid.h +++ b/test/cid/test_cid.h @@ -106,3 +106,50 @@ int test_cid_cast_non_multihash() { return 1; } +int test_cid_protobuf_encode_decode() { + struct Cid tester; + tester.version = 1; + tester.codec = CID_ETHEREUM_BLOCK; + tester.hash = "ABC123"; + tester.hash_length = 6; + size_t bytes_written_to_buffer; + + // encode + size_t buffer_length = ipfs_cid_protobuf_encode_size(&tester); + unsigned char buffer[buffer_length]; + ipfs_cid_protobuf_encode(&tester, buffer, buffer_length, &bytes_written_to_buffer); + + // decode + struct Cid* results; + ipfs_cid_protobuf_decode(buffer, bytes_written_to_buffer, &results); + + // compare + if (tester.version != results->version) { + printf("Version %d does not match version %d\n", tester.version, results->version); + ipfs_cid_free(results); + return 0; + } + + if (tester.codec != results->codec) { + printf("Codec %02x does not match %02x\n", tester.codec, results->codec); + ipfs_cid_free(results); + return 0; + } + + if (tester.hash_length != results->hash_length) { + printf("Hash length %d does not match %d\n", tester.hash_length, results->hash_length); + ipfs_cid_free(results); + return 0; + } + + for(int i = 0; i < 6; i++) { + if (tester.hash[i] != results->hash[i]) { + printf("Hash character %c does not match %c at position %d", tester.hash[i], results->hash[i], i); + ipfs_cid_free(results); + return 0; + } + } + + ipfs_cid_free(results); + return 1; +} diff --git a/test/merkledag/test_merkledag.h b/test/merkledag/test_merkledag.h index be26a9d..a6120cb 100644 --- a/test/merkledag/test_merkledag.h +++ b/test/merkledag/test_merkledag.h @@ -2,30 +2,35 @@ #include "ipfs/node/node.h" #include "../test_helper.h" -int test_merkledag_get_data() { - int retVal = 0; - +struct FSRepo* createAndOpenRepo(const char* dir) { + int retVal = 1; // create a fresh repo - retVal = drop_and_build_repository("/tmp/.ipfs"); + retVal = drop_and_build_repository(dir); if (retVal == 0) - return 0; + return NULL; // open the fs repo struct RepoConfig* repo_config = NULL; struct FSRepo* fs_repo; - const char* path = "/tmp/.ipfs"; // create the struct - retVal = ipfs_repo_fsrepo_new((char*)path, repo_config, &fs_repo); + retVal = ipfs_repo_fsrepo_new(dir, repo_config, &fs_repo); if (retVal == 0) - return 0; + return NULL; // open the repository and read the config file retVal = ipfs_repo_fsrepo_open(fs_repo); if (retVal == 0) { ipfs_repo_fsrepo_free(fs_repo); - return 0; + return NULL; } + return fs_repo; +} + +int test_merkledag_get_data() { + int retVal = 0; + + struct FSRepo* fs_repo = createAndOpenRepo("/tmp/.ipfs"); // create data for node size_t binary_data_size = 256; @@ -81,28 +86,10 @@ int test_merkledag_get_data() { int test_merkledag_add_data() { int retVal = 0; - // create a fresh repo - retVal = drop_and_build_repository("/tmp/.ipfs"); - if (retVal == 0) + struct FSRepo* fs_repo = createAndOpenRepo("/tmp.ipfs"); + if (fs_repo == NULL) return 0; - // open the fs repo - struct RepoConfig* repo_config = NULL; - struct FSRepo* fs_repo; - const char* path = "/tmp/.ipfs"; - - // create the struct - retVal = ipfs_repo_fsrepo_new((char*)path, repo_config, &fs_repo); - if (retVal == 0) - return 0; - - // open the repository and read the config file - retVal = ipfs_repo_fsrepo_open(fs_repo); - if (retVal == 0) { - ipfs_repo_fsrepo_free(fs_repo); - return 0; - } - // get the size of the database int start_file_size = os_utils_file_size("/tmp/.ipfs/datastore/data.mdb"); @@ -198,3 +185,63 @@ int test_merkledag_add_data() { return 1; } + +/** + * Should save links + */ +int test_merkledag_add_node_with_links() { + int retVal = 0; + struct Link* link = NULL; + struct Node* node1 = NULL; + + struct FSRepo* fs_repo = createAndOpenRepo("/tmp/.ipfs"); + if (fs_repo == NULL) { + printf("Unable to create repo\n"); + return 0; + } + + // make link + link = Create_Link("", "abc123"); + node1 = N_Create_From_Link(link); + + retVal = ipfs_merkledag_add(node1, fs_repo); + if (retVal == 0) { + ipfs_repo_fsrepo_free(fs_repo); + Node_Delete(node1); + printf("Unable to add node\n"); + return 0; + } + // now look for it + struct Node* node2 = NULL; + retVal = ipfs_merkledag_get(node1->cached, &node2, fs_repo); + if (retVal == 0) { + ipfs_repo_fsrepo_free(fs_repo); + Node_Delete(node1); + return 0; + } + + if (node2->link_amount != node1->link_amount) { + ipfs_repo_fsrepo_free(fs_repo); + Node_Delete(node1); + Node_Delete(node2); + printf("Link number do not match. Should be %d and are %d\n", node1->link_amount, node2->link_amount); + return 0; + } + + // make sure hashes match + for(int i = 0; i < node1->links[0]->Lcid->hash_length; i++) { + if(node1->links[0]->Lcid->hash[i] != node2->links[0]->Lcid->hash[i]) { + ipfs_repo_fsrepo_free(fs_repo); + Node_Delete(node1); + Node_Delete(node2); + printf("Hashes do not match\n"); + return 0; + } + } + + Node_Delete(node1); + Node_Delete(node2); + ipfs_repo_fsrepo_free(fs_repo); + + return 1; +} diff --git a/test/node/test_node.h b/test/node/test_node.h index bdf89e9..940e9f7 100644 --- a/test/node/test_node.h +++ b/test/node/test_node.h @@ -33,7 +33,7 @@ int test_node() { struct Link * ResultLink = Node_Get_Link(Mynode, "Simo"); printf("\nResultLink: \nName: %s\nHash: %s\n", ResultLink->name, ResultLink->Lcid->hash); Node_Remove_Link("Simo", Mynode); - printf("Outlinkamt: %d\n", Mynode->link_ammount); + printf("Outlinkamt: %d\n", Mynode->link_amount); Free_Link(mylink); Free_Link(mylink2); Free_Link(ResultLink); diff --git a/test/storage/test_datastore.h b/test/storage/test_datastore.h index f7d21a5..c879a91 100644 --- a/test/storage/test_datastore.h +++ b/test/storage/test_datastore.h @@ -18,7 +18,7 @@ int test_ipfs_datastore_put() { const unsigned char* input = (unsigned char*)"Hello, world!"; // build the ipfs repository, then shut it down, so we can start fresh - drop_and_build_repository("/tmp/.ipfs"); + retVal = drop_and_build_repository("/tmp/.ipfs"); if (retVal == 0) return 0; diff --git a/test/testit.c b/test/testit.c index 8da3a93..68ed1e0 100644 --- a/test/testit.c +++ b/test/testit.c @@ -42,7 +42,9 @@ const char* names[] = { "test_ipfs_datastore_put", "test_node", "test_merkledag_add_data", - "test_merkledag_get_data" + "test_merkledag_get_data", + "test_merkledag_add_node_with_links", + "test_cid_protobuf_encode_decode" }; int (*funcs[])(void) = { @@ -66,7 +68,9 @@ int (*funcs[])(void) = { test_ipfs_datastore_put, test_node, test_merkledag_add_data, - test_merkledag_get_data + test_merkledag_get_data, + test_merkledag_add_node_with_links, + test_cid_protobuf_encode_decode, }; /**