c-ipfs/test/routing/test_routing.h
2017-09-28 13:21:34 -05:00

772 lines
24 KiB
C

#pragma once
#include <pthread.h>
#include <fcntl.h>
#include <sys/stat.h>
#include "libp2p/os/utils.h"
#include "libp2p/utils/logger.h"
#include "multiaddr/multiaddr.h"
#include "ipfs/cmd/cli.h"
#include "ipfs/core/daemon.h"
#include "ipfs/core/ipfs_node.h"
#include "ipfs/routing/routing.h"
#include "ipfs/importer/importer.h"
#include "ipfs/importer/exporter.h"
#include "../test_helper.h"
/***
* "publish" a hash to the datastore (for ipns)
*/
int test_routing_put_value() {
int retVal = 0;
char* ipfs_path_publisher = "/tmp/ipfs_1";
char* peer_id_publisher = NULL;
struct MultiAddress* ma_publisher = NULL;
pthread_t thread_publisher;
int publisher_thread_started = 0;
struct CliArguments* arguments = NULL;
libp2p_logger_add_class("test_routing");
// fire up the "publisher"
if (!drop_and_build_repository(ipfs_path_publisher, 4001, NULL, &peer_id_publisher)) {
libp2p_logger_error("test_routing", "Unable to drop and build repository.\n");
goto exit;
}
char multiaddress_string[255];
sprintf(multiaddress_string, "/ip4/127.0.0.1/tcp/4001/ipfs/%s", peer_id_publisher);
ma_publisher = multiaddress_new_from_string(multiaddress_string);
if (pthread_create(&thread_publisher, NULL, test_daemon_start, (void*)ipfs_path_publisher) < 0) {
libp2p_logger_error("test_routing", "Unable to start first daemon.\n");
goto exit;
}
publisher_thread_started = 1;
sleep(3);
// import the file into the "publisher"
char* args[] = { "ipfs", "--config", ipfs_path_publisher, "add", "-r", "~/site"};
arguments = cli_arguments_new(6, args);
ipfs_import_files(arguments);
cli_arguments_free(arguments);
// now "publish" to publisher
libp2p_logger_debug("test_routing", "About to publish to publisher.\n");
char* args2[] = {"ipfs", "--config", ipfs_path_publisher, "name", "publish", "QmZtAEqmnXMZkwVPKdyMGxUoo35cQMzNhmq6CN3DvgRwAD" };
arguments = cli_arguments_new(6, args2);
if (!ipfs_name(arguments))
goto exit;
cli_arguments_free(arguments);
arguments = NULL;
// see if we have what we should...
libp2p_logger_debug("test_routing", "About to ask for the server to resolve the publisher.\n");
char* args3[] = {"ipfs", "--config", ipfs_path_publisher, "resolve", peer_id_publisher};
arguments = cli_arguments_new(5, args3);
if (!ipfs_name(arguments))
goto exit;
retVal = 1;
exit:
ipfs_daemon_stop();
if (publisher_thread_started) {
pthread_join(thread_publisher, NULL);
}
multiaddress_free(ma_publisher);
cli_arguments_free(arguments);
return retVal;
}
/***
* "publish" a hash to the datastore (for ipns)
*/
int test_routing_put_value_and_resolve() {
int retVal = 0;
char* ipfs_path_publisher = "/tmp/ipfs_1";
char* peer_id_publisher = NULL;
struct MultiAddress* ma_publisher = NULL;
pthread_t thread_publisher;
int publisher_thread_started = 0;
pthread_t thread_consumer;
char* ipfs_path_consumer = "/tmp/ipfs_2";
char* peer_id_consumer = NULL;
int consumer_thread_started = 0;
struct Libp2pVector* ma_vector = NULL;
struct CliArguments* arguments = NULL;
libp2p_logger_add_class("test_routing");
// fire up the "publisher"
if (!drop_and_build_repository(ipfs_path_publisher, 4001, NULL, &peer_id_publisher)) {
libp2p_logger_error("test_routing", "Unable to drop and build repository.\n");
goto exit;
}
char multiaddress_string[255];
sprintf(multiaddress_string, "/ip4/127.0.0.1/tcp/4001/ipfs/%s", peer_id_publisher);
ma_publisher = multiaddress_new_from_string(multiaddress_string);
if (pthread_create(&thread_publisher, NULL, test_daemon_start, (void*)ipfs_path_publisher) < 0) {
libp2p_logger_error("test_routing", "Unable to start first daemon.\n");
goto exit;
}
publisher_thread_started = 1;
sleep(3);
// import the file into the "publisher"
char* args[] = { "ipfs", "--config", ipfs_path_publisher, "add", "-r", "~/site"};
arguments = cli_arguments_new(6, args);
ipfs_import_files(arguments);
cli_arguments_free(arguments);
// fire up the "consumer"
ma_vector = libp2p_utils_vector_new(1);
libp2p_utils_vector_add(ma_vector, ma_publisher);
drop_and_build_repository(ipfs_path_consumer, 4002, ma_vector, &peer_id_consumer);
if (pthread_create(&thread_consumer, NULL, test_daemon_start, (void*)ipfs_path_consumer) < 0)
goto exit;
consumer_thread_started = 1;
// wait for everything to fire up
sleep(3);
// now "publish" to publisher
libp2p_logger_debug("test_routing", "About to publish to publisher.\n");
char* args2[] = {"ipfs", "--config", ipfs_path_publisher, "name", "publish", "QmZtAEqmnXMZkwVPKdyMGxUoo35cQMzNhmq6CN3DvgRwAD" };
arguments = cli_arguments_new(6, args2);
if (!ipfs_name(arguments))
goto exit;
cli_arguments_free(arguments);
arguments = NULL;
// see if we have what we should...
libp2p_logger_debug("test_routing", "About to ask for the server to resolve the publisher.\n");
char* args3[] = {"ipfs", "--config", ipfs_path_consumer, "resolve", peer_id_publisher};
//char* results = NULL;
arguments = cli_arguments_new(5, args3);
if (!ipfs_name(arguments))
goto exit;
retVal = 1;
exit:
ipfs_daemon_stop();
if (publisher_thread_started) {
pthread_join(thread_publisher, NULL);
}
if (consumer_thread_started) {
pthread_join(thread_consumer, NULL);
}
multiaddress_free(ma_publisher);
cli_arguments_free(arguments);
return retVal;
}
int test_routing_find_peer() {
int retVal = 0;
char* ipfs_path1 = "/tmp/ipfs_1";
char* ipfs_path2 = "/tmp/ipfs_2";
char* ipfs_path3 = "/tmp/ipfs_3";
pthread_t thread1;
pthread_t thread2;
pthread_t thread3;
int thread1_started = 0, thread2_started = 0, thread3_started = 0;
char* peer_id_1 = NULL;
char* peer_id_2 = NULL;
char* peer_id_3 = NULL;
struct IpfsNode* local_node = NULL;
struct IpfsNode* local_node2 = NULL;
struct IpfsNode* local_node3 = NULL;
struct FSRepo* fs_repo = NULL;
struct MultiAddress* ma_peer1;
struct Libp2pVector *ma_vector = NULL;
struct Libp2pPeer* result = NULL;
struct HashtableNode *node = NULL;
struct Libp2pVector* peers = NULL;
//libp2p_logger_add_class("online");
//libp2p_logger_add_class("null");
//libp2p_logger_add_class("daemon");
//libp2p_logger_add_class("dht_protocol");
//libp2p_logger_add_class("peerstore");
// create peer 1
drop_and_build_repository(ipfs_path1, 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
if (pthread_create(&thread1, NULL, test_daemon_start, (void*)ipfs_path2) < 0)
goto exit;
thread1_started = 1;
sleep(3);
// create peer 2
ma_vector = libp2p_utils_vector_new(1);
libp2p_utils_vector_add(ma_vector, ma_peer1);
drop_and_build_repository(ipfs_path2, 4002, ma_vector, &peer_id_2);
// start the daemon in a separate thread
if (pthread_create(&thread2, NULL, test_daemon_start, (void*)ipfs_path2) < 0)
goto exit;
thread2_started = 1;
// JMJ wait for everything to start up
sleep(3);
// add a file to peer 2
size_t bytes_written = 0;
ipfs_node_offline_new(ipfs_path2, &local_node2);
ipfs_import_file(NULL, "hello.txt", &node, local_node2, &bytes_written, 0);
ipfs_node_free(local_node2);
// create my peer, peer 3
libp2p_utils_vector_add(ma_vector, ma_peer1);
drop_and_build_repository(ipfs_path3, 4003, ma_vector, &peer_id_3);
// start the daemon in a separate thread
if (pthread_create(&thread3, NULL, test_daemon_start, (void*)ipfs_path3) < 0)
goto exit;
thread3_started = 1;
sleep(3);
ipfs_node_offline_new(ipfs_path3, &local_node3);
if (!local_node3->routing->FindProviders(local_node->routing, (unsigned char*)peer_id_2, strlen(peer_id_2), &peers)) {
fprintf(stderr, "Unable to find peer %s by asking %s\n", peer_id_2, peer_id_1);
goto exit;
}
if (result == NULL) {
fprintf(stderr, "Result was NULL\n");
goto exit;
}
struct MultiAddress *remote_address = result->addr_head->item;
fprintf(stderr, "Remote address is: %s\n", remote_address->string);
retVal = 1;
exit:
ipfs_daemon_stop();
if (thread1_started)
pthread_join(thread1, NULL);
if (thread2_started)
pthread_join(thread2, NULL);
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 (fs_repo != NULL)
ipfs_repo_fsrepo_free(fs_repo);
if (ma_peer1 != NULL)
multiaddress_free(ma_peer1);
if (ma_vector != NULL)
libp2p_utils_vector_free(ma_vector);
if (node != NULL)
ipfs_hashtable_node_free(node);
if (local_node != NULL)
ipfs_node_free(local_node);
if (result != NULL)
libp2p_peer_free(result);
return retVal;
}
int test_routing_find_providers() {
int retVal = 0;
char* ipfs_path1 = "/tmp/ipfs_1";
char* ipfs_path2 = "/tmp/ipfs_2";
char* ipfs_path3 = "/tmp/ipfs_3";
char* peer_id_1 = NULL;
char* peer_id_2 = NULL;
char* peer_id_3 = NULL;
//struct IpfsNode *local_node1 = NULL;
struct IpfsNode *local_node2 = NULL;
struct IpfsNode *local_node3 = NULL;
char* remote_peer_id = 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 FSRepo* fs_repo = NULL;
struct HashtableNode* node = NULL;
struct Libp2pVector* result = NULL;
// create peer 1
drop_and_build_repository(ipfs_path1, 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
if (pthread_create(&thread1, NULL, test_daemon_start, (void*)ipfs_path1) < 0) {
fprintf(stderr, "Unable to start thread 1\n");
goto exit;
}
thread1_started = 1;
sleep(3);
// create peer 2
// 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 destroys some things, as it frees the fs_repo:
drop_and_build_repository(ipfs_path2, 4002, ma_vector2, &peer_id_2);
// start the daemon in a separate thread
if (pthread_create(&thread2, NULL, test_daemon_start, (void*)ipfs_path2) < 0) {
fprintf(stderr, "Unable to start thread 2\n");
goto exit;
}
thread2_started = 1;
// wait for everything to start up
// JMJ debugging =
sleep(3);
// add a file, to prime the connection to peer 1
size_t bytes_written = 0;
ipfs_node_offline_new(ipfs_path2, &local_node2);
ipfs_import_file(NULL, "/home/parallels/ipfstest/hello_world.txt", &node, local_node2, &bytes_written, 0);
ipfs_node_free(local_node2);
// create my peer, peer 3
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_path3, 4003, ma_vector3, &peer_id_3);
ipfs_node_offline_new(ipfs_path3, &local_node3);
if (!local_node3->routing->FindProviders(local_node3->routing, node->hash, node->hash_size, &result)) {
fprintf(stderr, "Unable to find a provider\n");
goto exit;
}
if (result == NULL) {
fprintf(stderr, "Provider array is NULL\n");
goto exit;
}
// connect to peer 2
struct Libp2pPeer *remote_peer = NULL;
for(int i = 0; i < result->total; i++) {
remote_peer = (struct Libp2pPeer*)libp2p_utils_vector_get(result, i);
if (remote_peer->connection_type == CONNECTION_TYPE_CONNECTED
|| libp2p_peer_connect(&local_node3->identity->private_key, remote_peer, local_node3->peerstore, local_node3->repo->config->datastore, 5)) {
break;
}
remote_peer = NULL;
}
if (remote_peer == NULL) {
fprintf(stderr, "Remote Peer is NULL\n");
goto exit;
}
remote_peer_id = malloc(remote_peer->id_size + 1);
memcpy(remote_peer_id, remote_peer->id, remote_peer->id_size);
remote_peer_id[remote_peer->id_size] = 0;
fprintf(stderr, "Remote address is: %s\n", remote_peer_id);
free(remote_peer_id);
remote_peer_id = NULL;
retVal = 1;
exit:
ipfs_daemon_stop();
if (fs_repo != NULL)
ipfs_repo_fsrepo_free(fs_repo);
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 (thread1_started)
pthread_join(thread1, NULL);
if (thread2_started)
pthread_join(thread2, NULL);
if (ma_vector2 != NULL) {
libp2p_utils_vector_free(ma_vector2);
}
if (ma_vector3 != NULL) {
libp2p_utils_vector_free(ma_vector3);
}
if (local_node3 != NULL) {
ipfs_node_free(local_node3);
}
if (node != NULL)
ipfs_hashtable_node_free(node);
if (result != NULL) {
// we have a vector of peers. Clean 'em up:
/* free the vector, not the peers.
for(int i = 0; i < result->total; i++) {
struct Libp2pPeer* p = (struct Libp2pPeer*)libp2p_utils_vector_get(result, i);
libp2p_peer_free(p);
}
*/
libp2p_utils_vector_free(result);
}
return retVal;
}
/***
* Fire up a "client" and "server" and let the client tell the server he's providing a file
*/
int test_routing_provide() {
int retVal = 0;
// clean out repository
char* ipfs_path = "/tmp/test1";
os_utils_setenv("IPFS_PATH", ipfs_path, 1);
char* peer_id_1 = NULL;
char* peer_id_2 = NULL;
struct IpfsNode *local_node2 = NULL;
pthread_t thread1, thread2;
int thread1_started = 0, thread2_started = 0;
struct MultiAddress* ma_peer1 = NULL;
struct Libp2pVector* ma_vector2 = NULL;
struct HashtableNode* node = NULL;
libp2p_logger_add_class("daemon");
libp2p_logger_add_class("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
if (pthread_create(&thread1, NULL, test_daemon_start, (void*)ipfs_path) < 0) {
fprintf(stderr, "Unable to start thread 1\n");
goto exit;
}
thread1_started = 1;
// create peer 2
ipfs_path = "/tmp/test2";
os_utils_setenv("IPFS_PATH", ipfs_path, 1);
// 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:
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;
ipfs_node_offline_new(ipfs_path, &local_node2);
uint8_t *bytes = (unsigned char*)"hello, world!\n";
char* filename = "test1.txt";
create_file(filename, bytes, strlen((char*)bytes));
ipfs_import_file(NULL, filename, &node, local_node2, &bytes_written, 0);
ipfs_node_free(local_node2);
// start the daemon in a separate thread
if (pthread_create(&thread2, NULL, test_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
sleep(3);
retVal = 1;
exit:
ipfs_daemon_stop();
if (peer_id_1 != NULL)
free(peer_id_1);
if (peer_id_2 != NULL)
free(peer_id_2);
if (thread1_started)
pthread_join(thread1, NULL);
if (thread2_started)
pthread_join(thread2, NULL);
if (ma_vector2 != NULL) {
libp2p_utils_vector_free(ma_vector2);
}
if (node != NULL)
ipfs_hashtable_node_free(node);
if (ma_peer1 != NULL)
multiaddress_free(ma_peer1);
return retVal;
}
/***
* Attempt to retrieve a file from a previously unknown node
*/
int test_routing_retrieve_file_third_party() {
int retVal = 0;
char* ipfs_path_1 = "/tmp/ipfs_1", *ipfs_path_2 = "/tmp/ipfs_2", *ipfs_path_3 = "/tmp/ipfs_3";
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, thread3;
int thread1_started = 0, thread2_started = 0, thread3_started = 0;
struct MultiAddress* ma_peer1 = NULL;
struct Libp2pVector* ma_vector2 = NULL, *ma_vector3 = NULL;
struct HashtableNode* node = NULL, *result_node = NULL;
char multiaddress_string[255] = "";
char hash[256] = "";
libp2p_logger_add_class("online");
libp2p_logger_add_class("offline");
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");
libp2p_logger_add_class("api");
libp2p_logger_add_class("secio");
// clean out repository
// create peer 1
if (!drop_and_build_repository(ipfs_path_1, 4001, NULL, &peer_id_1))
goto exit;
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, our central server. Named: %s.\n", peer_id_1);
if (pthread_create(&thread1, NULL, test_daemon_start, (void*)ipfs_path_1) < 0) {
libp2p_logger_error("test_routing", "Unable to start thread 1\n");
goto exit;
}
thread1_started = 1;
// create peer 2, that will host the file
// 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 destroys some things, as it frees the fs_repo:
drop_and_build_repository(ipfs_path_2, 4002, ma_vector2, &peer_id_2);
multiaddress_free(ma_peer1);
// start the daemon in a separate thread
libp2p_logger_debug("test_routing", "Firing up daemon 2, which will host the file. Named %s.\n", peer_id_2);
if (pthread_create(&thread2, NULL, test_daemon_start, (void*)ipfs_path_2) < 0) {
libp2p_logger_error("test_routing", "Unable to start thread 2.\n");
goto exit;
}
thread2_started = 1;
// wait for everything to start up
sleep(3);
//TODO: add a file to server 2
uint8_t *bytes = (unsigned char*)"hello, world!\n";
char* filename = "test1.txt";
create_file(filename, bytes, strlen((char*)bytes));
size_t bytes_written;
ipfs_node_offline_new(ipfs_path_2, &ipfs_node2);
ipfs_import_file(NULL, filename, &node, ipfs_node2, &bytes_written, 0);
memset(hash, 0, 256);
ipfs_cid_hash_to_base58(node->hash, node->hash_size, (unsigned char*)hash, 256);
libp2p_logger_debug("test_routing", "Inserted file with hash %s into server %s.\n", hash, peer_id_2);
ipfs_node_free(ipfs_node2);
// wait for everything to start up
sleep(3);
// create my peer, peer 3
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_3, 4003, ma_vector3, &peer_id_3);
multiaddress_free(ma_peer1);
libp2p_logger_debug("test_routing", "Firing up daemon 3, which is our leech. Named: %s.\n", peer_id_3);
if (pthread_create(&thread3, NULL, test_daemon_start, (void*)ipfs_path_3) < 0) {
libp2p_logger_error("test_routing", "Unable to start thread 3.\n");
goto exit;
}
thread3_started = 1;
sleep(3);
//now have peer 3 ask for a file that is on peer 2, but peer 3 only knows of peer 1
ipfs_node_offline_new(ipfs_path_3, &ipfs_node3);
libp2p_logger_debug("test_routing", "Client of daemon 3 will now attempt to look for %s.\n", hash);
if (!ipfs_exporter_get_node(ipfs_node3, node->hash, node->hash_size, &result_node)) {
libp2p_logger_error("test_routing", "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 (thread3_started)
pthread_join(thread3, 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);
return retVal;
}
/***
* Attempt to retrieve a large file from a previously unknown node
*/
int test_routing_retrieve_large_file() {
int retVal = 0;
/*
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("peer");
libp2p_logger_add_class("test_routing");
*/
libp2p_logger_add_class("exporter");
libp2p_logger_add_class("online");
// 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;
FILE *fd;
char* temp_file_name = "/tmp/largefile.tmp";
unlink(temp_file_name);
// 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_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);
multiaddress_free(ma_peer1);
// 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/test_import_large.tmp", &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_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);
// see if we get the entire file
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);
multiaddress_free(ma_peer1);
ipfs_node_online_new(ipfs_path, &ipfs_node3);
ipfs_node3->routing->Bootstrap(ipfs_node3->routing);
fd = fopen(temp_file_name, "w+");
ipfs_exporter_object_cat_to_file(ipfs_node3, node->hash, node->hash_size, fd);
fclose(fd);
struct stat buf;
stat(temp_file_name, &buf);
if (buf.st_size != 1000000) {
fprintf(stderr, "File size should be 1000000, but is %lu\n", (unsigned long)buf.st_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);
return retVal;
}