Code Cleanup plus making providerstore smarter
This commit is contained in:
parent
90b1e2c3c8
commit
a137c2c43e
9 changed files with 82 additions and 33 deletions
|
@ -21,6 +21,7 @@ struct Libp2pPeer {
|
|||
struct Libp2pLinkedList* addr_head; // protobuf field 2 of multiaddr bytes (repeatable) (stored here as a struct MultiAddr)
|
||||
enum ConnectionType connection_type; // protobuf field 3 (a varint)
|
||||
struct SessionContext *sessionContext; // not protobuf'd, the current connection to the peer
|
||||
int is_local; // not protobuf'd, true if this is the local peer
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -33,10 +33,10 @@ void libp2p_peer_entry_free(struct PeerEntry* in);
|
|||
|
||||
/**
|
||||
* Creates a new empty peerstore
|
||||
* @param peer_id the peer id as a null terminated string
|
||||
* @param local_peer the local peer
|
||||
* @returns an empty peerstore or NULL on error
|
||||
*/
|
||||
struct Peerstore* libp2p_peerstore_new(const char* peer_id);
|
||||
struct Peerstore* libp2p_peerstore_new(const struct Libp2pPeer* local_peer);
|
||||
|
||||
/**
|
||||
* Deallocate resources used by the peerstore
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
#pragma once
|
||||
|
||||
#include "libp2p/db/datastore.h"
|
||||
#include "libp2p/peer/peer.h"
|
||||
|
||||
/**
|
||||
* Contains a hash and the peer id of
|
||||
* who can provide it
|
||||
|
@ -18,13 +21,16 @@ struct ProviderEntry {
|
|||
*/
|
||||
struct ProviderStore {
|
||||
struct Libp2pVector* provider_entries;
|
||||
// this is requred so we can look locally for requests
|
||||
const struct Datastore* datastore;
|
||||
const struct Libp2pPeer* local_peer;
|
||||
};
|
||||
|
||||
/**
|
||||
* Create a new ProviderStore
|
||||
* @returns a ProviderStore struct
|
||||
*/
|
||||
struct ProviderStore* libp2p_providerstore_new();
|
||||
struct ProviderStore* libp2p_providerstore_new(const struct Datastore* datastore, const struct Libp2pPeer* local_peer);
|
||||
|
||||
/***
|
||||
* Clean resources used by a ProviderStore
|
||||
|
|
|
@ -21,6 +21,7 @@ struct Libp2pPeer* libp2p_peer_new() {
|
|||
out->addr_head = NULL;
|
||||
out->connection_type = CONNECTION_TYPE_NOT_CONNECTED;
|
||||
out->sessionContext = NULL;
|
||||
out->is_local = 0;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
@ -122,6 +123,7 @@ int libp2p_peer_connect(struct RsaPrivateKey* privateKey, struct Libp2pPeer* pee
|
|||
struct Libp2pPeer* libp2p_peer_copy(const struct Libp2pPeer* in) {
|
||||
struct Libp2pPeer* out = libp2p_peer_new();
|
||||
if (out != NULL) {
|
||||
out->is_local = in->is_local;
|
||||
out->id_size = in->id_size;
|
||||
out->id = malloc(in->id_size);
|
||||
if (out->id == NULL) {
|
||||
|
|
|
@ -36,19 +36,13 @@ struct PeerEntry* libp2p_peer_entry_copy(struct PeerEntry* in) {
|
|||
* @param peer_id the peer id as a null terminated string
|
||||
* @returns an empty peerstore or NULL on error
|
||||
*/
|
||||
struct Peerstore* libp2p_peerstore_new(const char* peer_id) {
|
||||
struct Peerstore* libp2p_peerstore_new(const struct Libp2pPeer* local_peer) {
|
||||
struct Peerstore* out = (struct Peerstore*)malloc(sizeof(struct Peerstore));
|
||||
if (out != NULL) {
|
||||
out->head_entry = NULL;
|
||||
out->last_entry = NULL;
|
||||
// now add this peer as the first entry
|
||||
struct Libp2pPeer* peer = libp2p_peer_new();
|
||||
peer->connection_type = CONNECTION_TYPE_NOT_CONNECTED;
|
||||
peer->id_size = strlen(peer_id);
|
||||
peer->id = malloc(peer->id_size);
|
||||
memcpy(peer->id, peer_id, peer->id_size);
|
||||
libp2p_peerstore_add_peer(out, peer);
|
||||
libp2p_peer_free(peer);
|
||||
libp2p_peerstore_add_peer(out, local_peer);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
@ -149,10 +143,7 @@ int libp2p_peerstore_add_peer(struct Peerstore* peerstore, const struct Libp2pPe
|
|||
*/
|
||||
struct PeerEntry* libp2p_peerstore_get_peer_entry(struct Peerstore* peerstore, const unsigned char* peer_id, size_t peer_id_size) {
|
||||
struct Libp2pLinkedList* current = peerstore->head_entry;
|
||||
// JMJ Debugging
|
||||
int count = 0;
|
||||
while(current != NULL) {
|
||||
count++;
|
||||
struct Libp2pPeer* peer = ((struct PeerEntry*)current->item)->peer;
|
||||
if (peer->id_size == peer_id_size) {
|
||||
if (memcmp(peer_id, peer->id, peer->id_size) == 0) {
|
||||
|
|
|
@ -1,31 +1,25 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "libp2p/peer/providerstore.h"
|
||||
#include "libp2p/utils/vector.h"
|
||||
#include "libp2p/utils/logger.h"
|
||||
|
||||
struct ProviderEntry {
|
||||
unsigned char* hash;
|
||||
int hash_size;
|
||||
unsigned char* peer_id;
|
||||
int peer_id_size;
|
||||
};
|
||||
|
||||
struct ProviderStore {
|
||||
struct Libp2pVector* provider_entries;
|
||||
};
|
||||
|
||||
/***
|
||||
* Stores hashes, and peers where you can possibly get them
|
||||
*/
|
||||
|
||||
/**
|
||||
* Create a new ProviderStore
|
||||
* @param datastore the datastore (required in order to look for the file locally)
|
||||
* @param local_peer the local peer
|
||||
* @returns a ProviderStore struct
|
||||
*/
|
||||
struct ProviderStore* libp2p_providerstore_new() {
|
||||
struct ProviderStore* libp2p_providerstore_new(const struct Datastore* datastore, const struct Libp2pPeer* local_peer) {
|
||||
struct ProviderStore* out = (struct ProviderStore*)malloc(sizeof(struct ProviderStore));
|
||||
if (out != NULL) {
|
||||
out->datastore = datastore;
|
||||
out->local_peer = local_peer;
|
||||
out->provider_entries = libp2p_utils_vector_new(4);
|
||||
}
|
||||
return out;
|
||||
|
@ -61,7 +55,7 @@ void libp2p_providerstore_free(struct ProviderStore* in) {
|
|||
}
|
||||
}
|
||||
|
||||
int libp2p_providerstore_add(struct ProviderStore* store, unsigned char* hash, int hash_size, const unsigned char* peer_id, int peer_id_size) {
|
||||
int libp2p_providerstore_add(struct ProviderStore* store, const unsigned char* hash, int hash_size, const unsigned char* peer_id, int peer_id_size) {
|
||||
char hash_str[hash_size + 1];
|
||||
memcpy(hash_str, hash, hash_size);
|
||||
hash_str[hash_size] = 0;
|
||||
|
@ -80,8 +74,32 @@ int libp2p_providerstore_add(struct ProviderStore* store, unsigned char* hash, i
|
|||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* See if someone has announced a key. If so, pass the peer_id
|
||||
* NOTE: This will check to see if I can provide it from my datastore
|
||||
*
|
||||
* @param store the list of providers
|
||||
* @param hash what we're looking for
|
||||
* @param hash_size the length of the hash
|
||||
* @param peer_id the peer_id of who can provide it
|
||||
* @param peer_id_size the allocated size of peer_id
|
||||
* @returns true(1) if we found something, false(0) if not.
|
||||
*/
|
||||
int libp2p_providerstore_get(struct ProviderStore* store, const unsigned char* hash, int hash_size, unsigned char** peer_id, int *peer_id_size) {
|
||||
struct ProviderEntry* current = NULL;
|
||||
// can I provide it locally?
|
||||
size_t results_size = 65535;
|
||||
unsigned char results[results_size];
|
||||
if (store->datastore->datastore_get((const char*)hash, hash_size, &results[0], results_size, &results_size, store->datastore)) {
|
||||
// we found it locally. Let them know
|
||||
*peer_id = malloc(store->local_peer->id_size);
|
||||
if (*peer_id == NULL)
|
||||
return 0;
|
||||
*peer_id_size = store->local_peer->id_size;
|
||||
memcpy(*peer_id, store->local_peer->id, *peer_id_size);
|
||||
return 1;
|
||||
}
|
||||
// skip index 0, as we checked above...
|
||||
for (int i = 0; i < store->provider_entries->total; i++) {
|
||||
current = (struct ProviderEntry*)libp2p_utils_vector_get(store->provider_entries, i);
|
||||
if (current->hash_size == hash_size && memcmp(current->hash, hash, hash_size) == 0) {
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include "libp2p/net/stream.h"
|
||||
#include "libp2p/routing/dht_protocol.h"
|
||||
#include "libp2p/record/message.h"
|
||||
#include "libp2p/utils/linked_list.h"
|
||||
#include "libp2p/utils/logger.h"
|
||||
#include "libp2p/conn/session.h"
|
||||
|
||||
|
@ -96,18 +97,40 @@ int libp2p_routing_dht_handle_get_providers(struct SessionContext* session, stru
|
|||
// This shouldn't be needed, but just in case:
|
||||
message->provider_peer_head = NULL;
|
||||
|
||||
// Can I provide it?
|
||||
// Can I provide it locally?
|
||||
unsigned char buf[65535];
|
||||
size_t buf_size = 0;
|
||||
if (session->datastore->datastore_get(message->key, message->key_size, &buf[0], buf_size, &buf_size, session->datastore)) {
|
||||
// we can provide this hash from our datastore
|
||||
message->provider_peer_head = libp2p_utils_linked_list_new();
|
||||
struct Libp2pPeer* local_peer = (struct Libp2pPeer*)peerstore->head_entry->item;
|
||||
message->provider_peer_head->item = local_peer;
|
||||
}
|
||||
// Can I provide it because someone announced it earlier?
|
||||
if (libp2p_providerstore_get(providerstore, (unsigned char*)message->key, message->key_size, &peer_id, &peer_id_size)) {
|
||||
libp2p_logger_debug("dht_protocol", "I can provide a provider for this key.\n");
|
||||
// we have a peer id, convert it to a peer object
|
||||
struct Libp2pPeer* peer = libp2p_peerstore_get_peer(peerstore, peer_id, peer_id_size);
|
||||
if (peer != NULL) {
|
||||
// add it to the message
|
||||
if (message->provider_peer_head == NULL) {
|
||||
message->provider_peer_head = libp2p_utils_linked_list_new();
|
||||
message->provider_peer_head->item = libp2p_peer_copy(peer);
|
||||
message->provider_peer_head->item = peer;
|
||||
} else {
|
||||
struct Libp2pLinkedList* current = message->provider_peer_head;
|
||||
// find the last one in the list
|
||||
while (current->next != NULL) {
|
||||
current = current->next;
|
||||
}
|
||||
// add to the list
|
||||
current->next = libp2p_utils_linked_list_new();
|
||||
current->next->item = peer;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
libp2p_logger_debug("dht_protocol", "I cannot provide a provider for this key.\n");
|
||||
}
|
||||
if (peer_id != NULL)
|
||||
free(peer_id);
|
||||
// TODO: find closer peers
|
||||
/*
|
||||
|
|
|
@ -24,7 +24,10 @@ int test_peer() {
|
|||
* Test the peerstore
|
||||
*/
|
||||
int test_peerstore() {
|
||||
struct Peerstore* peerstore = libp2p_peerstore_new("Qmabcdefg");
|
||||
struct Libp2pPeer* peer = libp2p_peer_new();
|
||||
peer->id = "Qmabcdefg";
|
||||
peer->id_size = strlen(peer->id);
|
||||
struct Peerstore* peerstore = libp2p_peerstore_new(peer);
|
||||
struct PeerEntry* peer_entry = NULL;
|
||||
struct PeerEntry* results = NULL;
|
||||
int retVal = 0;
|
||||
|
@ -57,6 +60,8 @@ int test_peerstore() {
|
|||
libp2p_peerstore_free(peerstore);
|
||||
if (peer_entry != NULL)
|
||||
libp2p_peer_entry_free(peer_entry);
|
||||
if (peer != NULL)
|
||||
libp2p_peer_free(peer);
|
||||
return retVal;
|
||||
}
|
||||
|
||||
|
|
|
@ -102,7 +102,10 @@ void libp2p_logger_vlog(const char* area, int log_level, const char* format, va_
|
|||
else
|
||||
found = libp2p_logger_watching_class(area);
|
||||
if (found) {
|
||||
vfprintf(stderr, format, argptr);
|
||||
int new_format_size = strlen(format) + strlen(area) + 10;
|
||||
char new_format[new_format_size];
|
||||
sprintf(&new_format[0], "[%s] %s", area, format);
|
||||
vfprintf(stderr, new_format, argptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue