2016-11-28 21:13:46 +00:00
|
|
|
/**
|
|
|
|
* A basic storage building block of the IPFS system
|
|
|
|
*/
|
2016-12-23 14:37:43 +00:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
2016-11-28 21:13:46 +00:00
|
|
|
|
2016-12-23 14:37:43 +00:00
|
|
|
#include "libp2p/crypto/sha256.h"
|
2016-12-23 22:21:04 +00:00
|
|
|
#include "mh/multihash.h"
|
|
|
|
#include "mh/hashes.h"
|
2016-12-05 15:50:17 +00:00
|
|
|
#include "ipfs/merkledag/merkledag.h"
|
2016-12-23 14:37:43 +00:00
|
|
|
#include "ipfs/unixfs/unixfs.h"
|
2016-12-05 15:50:17 +00:00
|
|
|
|
2016-12-24 01:12:51 +00:00
|
|
|
|
2016-11-28 21:13:46 +00:00
|
|
|
/***
|
|
|
|
* Adds a node to the dagService and blockService
|
|
|
|
* @param node the node to add
|
2016-12-23 14:37:43 +00:00
|
|
|
* @param fs_repo the repo to add to
|
|
|
|
* @param bytes_written the number of bytes written
|
2016-11-28 21:13:46 +00:00
|
|
|
* @returns true(1) on success
|
|
|
|
*/
|
2016-12-23 14:37:43 +00:00
|
|
|
int ipfs_merkledag_add(struct Node* node, struct FSRepo* fs_repo, size_t* bytes_written) {
|
2016-11-28 21:13:46 +00:00
|
|
|
// taken from merkledag.go line 59
|
2016-12-23 14:37:43 +00:00
|
|
|
int retVal = 0;
|
2016-11-28 21:13:46 +00:00
|
|
|
|
2016-12-23 15:49:30 +00:00
|
|
|
// compute the hash if necessary
|
2016-12-23 14:37:43 +00:00
|
|
|
if (node->hash == NULL) {
|
2016-12-23 15:49:30 +00:00
|
|
|
size_t protobuf_size = ipfs_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);
|
|
|
|
|
|
|
|
node->hash_size = 32;
|
|
|
|
node->hash = (unsigned char*)malloc(node->hash_size);
|
|
|
|
if (node->hash == NULL) {
|
|
|
|
return 0;
|
|
|
|
}
|
2017-02-13 10:34:56 +00:00
|
|
|
if (libp2p_crypto_hashing_sha256((char*)protobuf, bytes_encoded, &node->hash[0]) == 0) {
|
2016-12-23 15:49:30 +00:00
|
|
|
free(node->hash);
|
|
|
|
return 0;
|
|
|
|
}
|
2016-12-23 14:37:43 +00:00
|
|
|
}
|
2016-12-05 15:50:17 +00:00
|
|
|
|
2016-12-14 17:07:43 +00:00
|
|
|
// write to block store & datastore
|
2016-12-23 14:37:43 +00:00
|
|
|
retVal = ipfs_repo_fsrepo_node_write(node, fs_repo, bytes_written);
|
2016-12-05 15:50:17 +00:00
|
|
|
if (retVal == 0) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// TODO: call HasBlock (unsure why as yet)
|
|
|
|
return 1;
|
2016-11-28 21:13:46 +00:00
|
|
|
}
|
2016-12-05 22:23:58 +00:00
|
|
|
|
|
|
|
/***
|
2016-12-22 15:21:18 +00:00
|
|
|
* Retrieves a node from the datastore based on the hash
|
|
|
|
* @param hash the key to look for
|
|
|
|
* @param hash_size the length of the key
|
2016-12-05 22:23:58 +00:00
|
|
|
* @param node the node to be created
|
|
|
|
* @param fs_repo the repository
|
|
|
|
* @returns true(1) on success
|
|
|
|
*/
|
2016-12-21 11:40:19 +00:00
|
|
|
int ipfs_merkledag_get(const unsigned char* hash, size_t hash_size, struct Node** node, const struct FSRepo* fs_repo) {
|
2016-12-05 22:23:58 +00:00
|
|
|
int retVal = 1;
|
2016-12-14 17:07:43 +00:00
|
|
|
size_t key_length = 100;
|
|
|
|
unsigned char key[key_length];
|
|
|
|
|
|
|
|
// look for the node in the datastore. If it is not there, it is not a node.
|
|
|
|
// If it exists, it is only a block.
|
2016-12-21 11:40:19 +00:00
|
|
|
retVal = fs_repo->config->datastore->datastore_get((char*)hash, hash_size, key, key_length, &key_length, fs_repo->config->datastore);
|
2016-12-05 22:23:58 +00:00
|
|
|
if (retVal == 0)
|
|
|
|
return 0;
|
|
|
|
|
2016-12-23 15:49:30 +00:00
|
|
|
// we have the record from the db. Go get the node from the blockstore
|
|
|
|
retVal = ipfs_repo_fsrepo_node_read(hash, hash_size, node, fs_repo);
|
2016-12-15 18:06:12 +00:00
|
|
|
if (retVal == 0) {
|
|
|
|
return 0;
|
|
|
|
}
|
2016-12-14 17:07:43 +00:00
|
|
|
|
2017-01-02 04:48:09 +00:00
|
|
|
// set the hash
|
|
|
|
ipfs_node_set_hash(*node, hash, hash_size);
|
|
|
|
|
2016-12-15 18:06:12 +00:00
|
|
|
return 1;
|
2016-12-05 22:23:58 +00:00
|
|
|
}
|
2016-12-30 00:05:44 +00:00
|
|
|
|
|
|
|
int ipfs_merkledag_get_by_multihash(const unsigned char* multihash, size_t multihash_length, struct Node** node, const struct FSRepo* fs_repo) {
|
|
|
|
// convert to hash
|
|
|
|
size_t hash_size = 0;
|
|
|
|
unsigned char* hash = NULL;
|
|
|
|
if (mh_multihash_digest(multihash, multihash_length, &hash, &hash_size) < 0) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
return ipfs_merkledag_get(hash, hash_size, node, fs_repo);
|
|
|
|
}
|