More code for storage

Pushing through on the ipfs block put use case. Building out the
necessary code to write to the blockstore.
This commit is contained in:
John Jones 2016-11-28 16:13:46 -05:00
parent 74a5afe169
commit 4626b69381
14 changed files with 217 additions and 26 deletions

View file

@ -11,6 +11,7 @@ all:
cd os; make all; cd os; make all;
cd repo; make all; cd repo; make all;
cd flatfs; make all; cd flatfs; make all;
cd datastore; make all;
cd thirdparty; make all; cd thirdparty; make all;
cd test; make all; cd test; make all;
@ -23,6 +24,7 @@ clean:
cd os; make clean; cd os; make clean;
cd repo; make clean; cd repo; make clean;
cd flatfs; make clean; cd flatfs; make clean;
cd datastore; make clean;
cd thirdparty; make clean; cd thirdparty; make clean;
cd test; make clean; cd test; make clean;

View file

@ -4,6 +4,7 @@
#include <stdlib.h> #include <stdlib.h>
#include "libp2p/crypto/sha256.h"
#include "ipfs/blocks/block.h" #include "ipfs/blocks/block.h"
#include "ipfs/cid/cid.h" #include "ipfs/cid/cid.h"
@ -14,14 +15,31 @@
* @param block a pointer to the struct Block that will be created * @param block a pointer to the struct Block that will be created
* @returns true(1) on success * @returns true(1) on success
*/ */
int ipfs_blocks_block_new(unsigned char* data, size_t data_size, struct Block* block) { int ipfs_blocks_block_new(unsigned char* data, size_t data_size, struct Block** block) {
// allocate memory for structure
(*block) = (struct Block*)malloc(sizeof(struct Block));
if ((*block) == NULL)
return 0;
// cid
char hash[32]; char hash[32];
ipfs_crypto_hashing_sha256(data, hash, 32); if (libp2p_crypto_hashing_sha256(data, hash, 32) == 0) {
ipfs_cid_new(0, hash, 32, CID_PROTOBUF, block->cid); free(*block);
return 0;
}
if (ipfs_cid_new(0, hash, 32, CID_PROTOBUF, (*block)->cid) == 0) {
free(*block);
return 0;
}
block->data = malloc(sizeof(unsigned char) * data_size); block->data = malloc(sizeof(unsigned char) * data_size);
if (block->data == NULL) if (block->data == NULL) {
ipfs_ci_free((*block)->cid);
free(*block);
return 0; return 0;
}
memcpy(block->data, data, data_size); memcpy(block->data, data, data_size);
return 1; return 1;
@ -36,5 +54,6 @@ int ipfs_blocks_block_free(struct Block* block) {
ipfs_cid_free(block->cid); ipfs_cid_free(block->cid);
if (block->data != NULL) if (block->data != NULL)
free(block->data); free(block->data);
free(block);
return 1; return 1;
} }

View file

@ -37,5 +37,8 @@ int ipfs_blockstore_get(struct Cid* cid, struct Block* block) {
* @returns true(1) on success * @returns true(1) on success
*/ */
int ipfs_blockstore_put(struct Block* block) { int ipfs_blockstore_put(struct Block* block) {
// from blockstore.go line 118
// TODO: Get Datastore key
// TODO: send to Put with key
return 0; return 0;
} }

View file

@ -23,11 +23,17 @@
* @param cid where to put the results * @param cid where to put the results
* @returns true(1) on success * @returns true(1) on success
*/ */
int cid_new(int version, unsigned char* hash, size_t hash_length, const char codec, struct Cid* cid) { int ipfs_cid_new(int version, unsigned char* hash, size_t hash_length, const char codec, struct Cid** ptrToCid) {
// allocate memory // allocate memory
cid->hash = malloc(sizeof(unsigned char) * hash_length); *ptrToCid = (struct Cid*)malloc(sizeof(struct Cid));
if (cid->hash == NULL) struct Cid* cid = *ptrToCid;
if (cid == NULL)
return 0; return 0;
cid->hash = malloc(sizeof(unsigned char) * hash_length);
if (cid->hash == NULL) {
free(cid);
return 0;
}
// assign values // assign values
cid->version = version; cid->version = version;
cid->codec = codec; cid->codec = codec;
@ -43,9 +49,10 @@ int cid_new(int version, unsigned char* hash, size_t hash_length, const char cod
* @param cid the struct * @param cid the struct
* @returns 1 * @returns 1
*/ */
int cid_free(struct Cid* cid) { int ipfs_cid_free(struct Cid* cid) {
if (cid->hash != NULL) if (cid->hash != NULL)
free(cid->hash); free(cid->hash);
free(cid);
return 1; return 1;
} }
@ -56,7 +63,7 @@ int cid_free(struct Cid* cid) {
* @cid the Cid struct to fill * @cid the Cid struct to fill
* @return true(1) on success * @return true(1) on success
*/ */
int cid_decode_from_string(const unsigned char* incoming, size_t incoming_length, struct Cid* cid) { int ipfs_cid_decode_from_string(const unsigned char* incoming, size_t incoming_length, struct Cid** cid) {
int retVal = 0; int retVal = 0;
if (incoming_length < 2) if (incoming_length < 2)
@ -71,7 +78,7 @@ int cid_decode_from_string(const unsigned char* incoming, size_t incoming_length
if (retVal == 0) if (retVal == 0)
return 0; return 0;
// now we have the hash, build the object // now we have the hash, build the object
return cid_new(0, hash, hash_length, CID_PROTOBUF, cid); return ipfs_cid_new(0, hash, hash_length, CID_PROTOBUF, cid);
} }
// TODO: finish this // TODO: finish this
@ -99,7 +106,7 @@ int cid_decode_from_string(const unsigned char* incoming, size_t incoming_length
* @param incoming_size the size of the array * @param incoming_size the size of the array
* @param cid the Cid structure to fill * @param cid the Cid structure to fill
*/ */
int cid_cast(unsigned char* incoming, size_t incoming_size, struct Cid* cid) { int ipfs_cid_cast(unsigned char* incoming, size_t incoming_size, struct Cid* cid) {
// this is a multihash // this is a multihash
if (incoming_size == 34 && incoming[0] == 18 && incoming[1] == 32) { if (incoming_size == 34 && incoming[0] == 18 && incoming[1] == 32) {
cid->hash_length = mh_multihash_length(incoming, incoming_size); cid->hash_length = mh_multihash_length(incoming, incoming_size);

18
datastore/Makefile Normal file
View file

@ -0,0 +1,18 @@
CC = gcc
CFLAGS = -O0 -I../include -I../../c-libp2p/include -I../../c-multihash/include -I../../c-multiaddr/include
ifdef DEBUG
CFLAGS += -g3
endif
LFLAGS =
DEPS = ../include/ipfsdatastore/ds_helper.h
OBJS = ds_helper.o
%.o: %.c $(DEPS)
$(CC) -c -o $@ $< $(CFLAGS)
all: $(OBJS)
clean:
rm -f *.o

55
datastore/ds_helper.c Normal file
View file

@ -0,0 +1,55 @@
/**
* Some code to help with the datastore / blockstore interface
*/
#include "libp2p/crypto/encoding/base32.h"
#include "ipfs/datastore/ds_helper.h"
/**
* Generate a key based on the passed in binary_array
* @param binary_array what to base the key on
* @param array_length the size of the binary array
* @param results where the key will be put
* @param max_results_length the size of the results buffer
* @param results_length the length of the generated key
* @returns true(1) on success
*/
int ipfs_datastore_helper_ds_key_from_binary(unsigned char* binary_array, size_t array_length,
char* results, size_t max_results_length, size_t* results_length) {
size_t encoded_length = libp2p_crypto_encoding_base32_encode_size(array_length);
if (encoded_length > max_results_length)
return 0;
*results_length = max_results_length;
int retVal = libp2p_crypto_encoding_base32_encode(binary_array, array_length, results, results_length);
if (retVal == 0) {
*results_length = 0;
return 0;
}
return 1;
}
/**
* Generate a binary array based on the passed in datastore key
* @param ds_key the base32 encoded key
* @param key_length the length of the base32 "string"
* @param binary_array where to put the decoded value
* @param max_binary_array_length the memory size of binary_array
* @param completed_binary_array_length the length of what was written to the binary_array
* @returns true(1) on success
*/
int ipfs_datastore_helper_binary_from_ds_key(unsigned char* ds_key, size_t key_length, unsigned char* binary_array,
size_t max_binary_array_length, size_t* completed_binary_array_length) {
size_t decoded_length = libp2p_crypto_encoding_base32_decode_size(key_length);
if (decoded_length > max_binary_array_length)
return 0;
*completed_binary_array_length = max_binary_array_length;
int retVal = libp2p_crypto_encoding_base32_decode(ds_key, key_length, binary_array, completed_binary_array_length);
if (retVal == 0) {
*completed_binary_array_length = 0;
return 0;
}
return 1;
}

View file

@ -17,7 +17,7 @@ struct Block {
* @param block a pointer to the struct Block that will be created * @param block a pointer to the struct Block that will be created
* @returns true(1) on success * @returns true(1) on success
*/ */
int ipfs_blocks_block_new(unsigned char* data, size_t data_size, struct Block* block); int ipfs_blocks_block_new(unsigned char* data, size_t data_size, struct Block** block);
/*** /***
* Free resources used by the creation of a block * Free resources used by the creation of a block

View file

@ -33,14 +33,14 @@ struct Cid {
* @param cid where to put the results * @param cid where to put the results
* @returns true(1) on success * @returns true(1) on success
*/ */
int cid_new(int version, unsigned char* hash, size_t hash_length, const char codec, struct Cid* cid); int ipfs_cid_new(int version, unsigned char* hash, size_t hash_length, const char codec, struct Cid** cid);
/*** /***
* Free the resources from a Cid * Free the resources from a Cid
* @param cid the struct * @param cid the struct
* @returns 1 * @returns 1
*/ */
int cid_free(struct Cid* cid); int ipfs_cid_free(struct Cid* cid);
/*** /***
* Fill a Cid struct based on a base 58 encoded string * Fill a Cid struct based on a base 58 encoded string
@ -49,7 +49,7 @@ int cid_free(struct Cid* cid);
* @cid the Cid struct to fill * @cid the Cid struct to fill
* @return true(1) on success * @return true(1) on success
*/ */
int cid_decode_from_string(const unsigned char* incoming, size_t incoming_length, struct Cid* cid); int ipfs_cid_decode_from_string(const unsigned char* incoming, size_t incoming_length, struct Cid** cid);
/*** /***
* Turn a multibase decoded string of bytes into a Cid struct * Turn a multibase decoded string of bytes into a Cid struct
@ -57,6 +57,6 @@ int cid_decode_from_string(const unsigned char* incoming, size_t incoming_length
* @param incoming_size the size of the array * @param incoming_size the size of the array
* @param cid the Cid structure to fill * @param cid the Cid structure to fill
*/ */
int cid_cast(unsigned char* incoming, size_t incoming_size, struct Cid* cid); int ipfs_cid_cast(unsigned char* incoming, size_t incoming_size, struct Cid* cid);
#endif #endif

View file

@ -0,0 +1,33 @@
/**
* Some code to help with the datastore / blockstore interface
*/
#ifndef __IPFS_DATASTORE_DS_HELPER_H__
#define __IPFS_DATASTORE_DS_HELPER_H__
#include <string.h>
/**
* Generate a key based on the passed in binary_array
* @param binary_array what to base the key on
* @param array_length the size of the binary array
* @param results where the key will be put
* @param max_results_length the size of the results buffer
* @param results_length the length of the generated key
* @returns true(1) on success
*/
int ipfs_datastore_helper_ds_key_from_binary(unsigned char* binary_array, size_t array_length,
char* results, size_t max_results_length, size_t* results_length);
/**
* Generate a binary array based on the passed in datastore key
* @param ds_key the base32 encoded key
* @param key_length the length of the base32 "string"
* @param binary_array where to put the decoded value
* @param max_binary_array_length the memory size of binary_array
* @param completed_binary_array_length the length of what was written to the binary_array
* @returns true(1) on success
*/
int ipfs_datastore_helper_binary_from_ds_key(unsigned char* ds_key, size_t key_length, unsigned char* binary_array,
size_t max_binary_array_length, size_t* completed_binary_array_length);
#endif

15
merkledag/merkledag.c Normal file
View file

@ -0,0 +1,15 @@
/**
* A basic storage building block of the IPFS system
*/
/***
* Adds a node to the dagService and blockService
* @param node the node to add
* @returns true(1) on success
*/
int ipfs_merkledag_add(struct Node* node) {
// taken from merkledag.go line 59
// TODO: put in blockstore
// TODO: call HasBlock (unsure why as yet)
}

View file

@ -8,7 +8,7 @@ OBJS = testit.o ../cmd/ipfs/init.o ../commands/argument.o ../commands/command_op
../repo/config/bootstrap_peers.o ../repo/config/datastore.o ../repo/config/gateway.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 \ ../repo/config/addresses.o ../repo/config/swarm.o ../repo/config/peer.o \
../thirdparty/ipfsaddr/ipfs_addr.o ../cid/cid.o ../multibase/multibase.o \ ../thirdparty/ipfsaddr/ipfs_addr.o ../cid/cid.o ../multibase/multibase.o \
../flatfs/flatfs.o ../flatfs/flatfs.o ../datastore/ds_helper.o
%.o: %.c $(DEPS) %.o: %.c $(DEPS)
$(CC) -c -o $@ $< $(CFLAGS) $(CC) -c -o $@ $< $(CFLAGS)

View file

@ -10,25 +10,25 @@
int test_cid_new_free() { int test_cid_new_free() {
struct Cid cid; struct Cid* cid;
const unsigned char* hash = "ABC123"; const unsigned char* hash = "ABC123";
int retVal = cid_new(0, (unsigned char*)hash, strlen((char*)hash), CID_PROTOBUF, &cid); int retVal = ipfs_cid_new(0, (unsigned char*)hash, strlen((char*)hash), CID_PROTOBUF, &cid);
if (retVal == 0) if (retVal == 0)
return 0; return 0;
if (cid.version != 0) if (cid->version != 0)
return 0; return 0;
if (cid.codec != CID_PROTOBUF) if (cid->codec != CID_PROTOBUF)
return 0; return 0;
if (cid.hash_length != strlen((char*)hash)) if (cid->hash_length != strlen((char*)hash))
return 0; return 0;
if (strncmp((char*)cid.hash, (char*)hash, 6) != 0) if (strncmp((char*)cid->hash, (char*)hash, 6) != 0)
return 0; return 0;
return cid_free(&cid); return ipfs_cid_free(cid);
} }
/*** /***
@ -53,7 +53,7 @@ int test_cid_cast_multihash() {
// now call cast // now call cast
struct Cid cid; struct Cid cid;
retVal = cid_cast(multihash, multihash_size, &cid); retVal = ipfs_cid_cast(multihash, multihash_size, &cid);
if (retVal == 0) if (retVal == 0)
return 0; return 0;
// check results // check results
@ -90,7 +90,7 @@ int test_cid_cast_non_multihash() {
// now call cast // now call cast
struct Cid cid; struct Cid cid;
int retVal = cid_cast(array, array_size, &cid); int retVal = ipfs_cid_cast(array, array_size, &cid);
if (retVal == 0) if (retVal == 0)
return 0; return 0;
// check results // check results

View file

@ -0,0 +1,37 @@
#include "ipfs/datastore/ds_helper.h"
int test_ds_key_from_binary() {
size_t original_incoming_length = 10;
size_t incoming_length = original_incoming_length;
unsigned char incoming[incoming_length + 5]; // give a little wiggle room
unsigned char* ptrIncoming = &incoming[0];
for(int i = 0; i < incoming_length; i++) {
incoming[i] = i;
}
size_t outgoing_length = 100;
char outgoing[outgoing_length];
char* ptrOutgoing = &outgoing[0];
memset(outgoing, 0, outgoing_length);
int retVal = ipfs_datastore_helper_ds_key_from_binary(ptrIncoming, incoming_length, ptrOutgoing, outgoing_length, &outgoing_length);
if (retVal == 0)
return 0;
// now undo it and see if we get the same thing back...
retVal = ipfs_datastore_helper_binary_from_ds_key(ptrOutgoing, outgoing_length, incoming, incoming_length + 5, &incoming_length);
if (retVal == 0)
return 0;
if (original_incoming_length != incoming_length)
return 0;
for(int i = 0; i < original_incoming_length; i++) {
if (incoming[i] != i)
return 0;
}
return 1;
}

View file

@ -5,6 +5,7 @@
#include "cmd/ipfs/test_init.h" #include "cmd/ipfs/test_init.h"
#include "cid/test_cid.h" #include "cid/test_cid.h"
#include "flatfs/test_flatfs.h" #include "flatfs/test_flatfs.h"
#include "storage/test_ds_helper.h"
int testit(const char* name, int (*func)(void)) { int testit(const char* name, int (*func)(void)) {
printf("Testing %s...\n", name); printf("Testing %s...\n", name);
@ -33,6 +34,7 @@ int main(int argc, char** argv) {
counter += testit("test_flatfs_get_directory", test_flatfs_get_directory); counter += testit("test_flatfs_get_directory", test_flatfs_get_directory);
counter += testit("test_flatfs_get_filename", test_flatfs_get_filename); counter += testit("test_flatfs_get_filename", test_flatfs_get_filename);
counter += testit("test_flatfs_get_full_filename", test_flatfs_get_full_filename); counter += testit("test_flatfs_get_full_filename", test_flatfs_get_full_filename);
counter += testit("test_ds_key_from_binary", test_ds_key_from_binary);
if (counter > 0) { if (counter > 0) {
printf("***** There were %d failed test(s) *****\n", counter); printf("***** There were %d failed test(s) *****\n", counter);
} else { } else {