diff --git a/cid/cid.c b/cid/cid.c index e2c2600..3e4126b 100644 --- a/cid/cid.c +++ b/cid/cid.c @@ -251,6 +251,10 @@ int ipfs_cid_cast(const unsigned char* incoming, size_t incoming_size, struct Ci /** * Compare two cids + * + * TODO: find a common denominator between versions and codecs so that + * we can compare apples to apples. + * * @param a side A * @param b side B * @returns < 0 if side A is greater, > 0 if side B is greater, or 0 if equal diff --git a/exchange/bitswap/Makefile b/exchange/bitswap/Makefile index 513c40b..01337f0 100644 --- a/exchange/bitswap/Makefile +++ b/exchange/bitswap/Makefile @@ -7,7 +7,7 @@ endif LFLAGS = DEPS = -OBJS = bitswap.o message.o network.o peer_request_queue.o +OBJS = bitswap.o message.o network.o peer_request_queue.o want_manager.o %.o: %.c $(DEPS) $(CC) -c -o $@ $< $(CFLAGS) diff --git a/exchange/bitswap/bitswap.c b/exchange/bitswap/bitswap.c index ff3fe9d..8e637e6 100644 --- a/exchange/bitswap/bitswap.c +++ b/exchange/bitswap/bitswap.c @@ -2,10 +2,12 @@ * Methods for the Bitswap exchange */ #include +#include // for sleep() #include "ipfs/core/ipfs_node.h" #include "ipfs/exchange/exchange.h" #include "ipfs/exchange/bitswap/bitswap.h" #include "ipfs/exchange/bitswap/message.h" +#include "ipfs/exchange/bitswap/want_manager.h" /** * Create a new bitswap exchange @@ -89,6 +91,10 @@ int ipfs_bitswap_has_block(void* exchangeContext, struct Block* block) { * Implements the Exchange->GetBlock method * We're asking for this method to get the block from peers. Perhaps this should be * taking in a pointer to a callback, as this could take a while (or fail). + * @param exchangeContext a BitswapContext + * @param cid the Cid to look for + * @param block a pointer to where to put the result + * @returns true(1) if found, false(0) if not */ int ipfs_bitswap_get_block(void* exchangeContext, struct Cid* cid, struct Block** block) { struct BitswapContext* bitswapContext = (struct BitswapContext*)exchangeContext; @@ -97,6 +103,30 @@ int ipfs_bitswap_get_block(void* exchangeContext, struct Cid* cid, struct Block* if (bitswapContext->ipfsNode->blockstore->Get(bitswapContext->ipfsNode->blockstore->blockstoreContext, cid, block)) return 1; // now ask the network + //NOTE: this timeout should be configurable + int timeout = 10; + int waitSecs = 1; + int timeTaken = 0; + if (ipfs_bitswap_want_manager_add(bitswapContext, cid)) { + // loop waiting for it to fill + while(1) { + if (ipfs_bitswap_want_manager_received(bitswapContext, cid)) { + if (ipfs_bitswap_want_manager_get_block(bitswapContext, cid, block)) { + // NOTE: this should use reference counting + ipfs_bitswap_want_manager_remove(bitswapContext, cid); + return 1; + } + } + //TODO: This is a busy-loop. Find another way. + timeTaken += waitSecs; + if (timeTaken >= timeout) { + // It took too long. Stop looking. + ipfs_bitswap_want_manager_remove(bitswapContext, cid); + break; + } + sleep(waitSecs); + } + } } return 0; } diff --git a/exchange/bitswap/want_manager.c b/exchange/bitswap/want_manager.c new file mode 100644 index 0000000..0ad334b --- /dev/null +++ b/exchange/bitswap/want_manager.c @@ -0,0 +1,52 @@ +#include "ipfs/exchange/bitswap/want_manager.h" +#include "ipfs/exchange/bitswap/wantlist.h" + +/*** + * Add a Cid to the local wantlist + * @param context the context + * @param cid the Cid + * @returns true(1) on success, false(0) otherwise + */ +int ipfs_bitswap_want_manager_add(const struct BitswapContext* context, const struct Cid* cid) { + // first see if it is already here + // increment the reference count + return 0; +} + +/*** + * Checks to see if the requested block has been received + * @param context the context + * @param cid the Cid + * @returns true(1) if it has been received, false(0) otherwise + */ +int ipfs_bitswap_want_manager_received(const struct BitswapContext* context, const struct Cid* cid) { + // find the entry + // check the status + return 0; +} + +/*** + * retrieve a block from the WantManager. NOTE: a call to want_manager_received should be done first + * @param context the context + * @param cid the Cid to get + * @param block a pointer to the block that will be allocated + * @returns true(1) on success, false(0) otherwise + */ +int ipfs_bitswap_want_manager_get_block(const struct BitswapContext* context, const struct Cid* cid, struct Block** block) { + // find the entry + // return a copy of the block + return 0; +} + +/*** + * We no longer are requesting this block, so remove it from the queue + * NOTE: This is reference counted, as another process may have asked for it. + * @param context the context + * @param cid the Cid + * @returns true(1) on success, false(0) otherwise. + */ +int ipfs_bitswap_want_manager_remove(const struct BitswapContext* context, const struct Cid* cid) { + // decrement the reference count + // if it is zero, remove the entry (lock first) + return 0; +} diff --git a/include/ipfs/exchange/bitswap/bitswap.h b/include/ipfs/exchange/bitswap/bitswap.h index b16acf5..8667f2f 100644 --- a/include/ipfs/exchange/bitswap/bitswap.h +++ b/include/ipfs/exchange/bitswap/bitswap.h @@ -1,3 +1,5 @@ +#pragma once + /*** * Bitswap implements the exchange "interface" * @see ../exchange.h @@ -9,6 +11,7 @@ struct BitswapContext { struct SessionContext* sessionContext; struct IpfsNode* ipfsNode; + struct Wantlist* localWantlist; }; /** diff --git a/include/ipfs/exchange/bitswap/want_manager.h b/include/ipfs/exchange/bitswap/want_manager.h new file mode 100644 index 0000000..96faace --- /dev/null +++ b/include/ipfs/exchange/bitswap/want_manager.h @@ -0,0 +1,39 @@ +#pragma once + +#include "ipfs/blocks/block.h" +#include "ipfs/cid/cid.h" +#include "ipfs/exchange/bitswap/bitswap.h" + +/*** + * Add a Cid to the local wantlist + * @param context the context + * @param cid the Cid + * @returns true(1) on success, false(0) otherwise + */ +int ipfs_bitswap_want_manager_add(const struct BitswapContext* context, const struct Cid* cid); + +/*** + * Checks to see if the requested block has been received + * @param context the context + * @param cid the Cid + * @returns true(1) if it has been received, false(0) otherwise + */ +int ipfs_bitswap_want_manager_received(const struct BitswapContext* context, const struct Cid* cid); + +/*** + * retrieve a block from the WantManager. NOTE: a call to want_manager_received should be done first + * @param context the context + * @param cid the Cid to get + * @param block a pointer to the block that will be allocated + * @returns true(1) on success, false(0) otherwise + */ +int ipfs_bitswap_want_manager_get_block(const struct BitswapContext* context, const struct Cid* cid, struct Block** block); + +/*** + * We no longer are requesting this block, so remove it from the queue + * NOTE: This is reference counted, as another process may have asked for it. + * @param context the context + * @param cid the Cid + * @returns true(1) on success, false(0) otherwise. + */ +int ipfs_bitswap_want_manager_remove(const struct BitswapContext* context, const struct Cid* cid);