Skip to content

Commit 9439be1

Browse files
IPLD selectors stub (#92)
1 parent 8c5aa42 commit 9439be1

File tree

4 files changed

+77
-4
lines changed

4 files changed

+77
-4
lines changed

core/storage/ipfs/merkledag/impl/merkledag_service_impl.cpp

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,21 @@
66
#include "storage/ipfs/merkledag/impl/merkledag_service_impl.hpp"
77

88
#include <boost/assert.hpp>
9+
#include <libp2p/multi/content_identifier_codec.hpp>
910
#include "storage/ipfs/merkledag/impl/node_impl.hpp"
1011

12+
using libp2p::multi::ContentIdentifierCodec;
13+
1114
namespace fc::storage::ipfs::merkledag {
12-
MerkleDagServiceImpl::MerkleDagServiceImpl(std::shared_ptr<BlockService> service)
15+
MerkleDagServiceImpl::MerkleDagServiceImpl(
16+
std::shared_ptr<BlockService> service)
1317
: block_service_{std::move(service)} {
1418
BOOST_ASSERT_MSG(block_service_ != nullptr,
1519
"MerkleDAG service: Block service not connected");
1620
}
1721

18-
outcome::result<void> MerkleDagServiceImpl::addNode(std::shared_ptr<const Node> node) {
22+
outcome::result<void> MerkleDagServiceImpl::addNode(
23+
std::shared_ptr<const Node> node) {
1924
return block_service_->addBlock(*node);
2025
}
2126

@@ -29,6 +34,30 @@ namespace fc::storage::ipfs::merkledag {
2934
return block_service_->removeBlock(cid);
3035
}
3136

37+
outcome::result<size_t> MerkleDagServiceImpl::select(
38+
gsl::span<const uint8_t> root_cid,
39+
gsl::span<const uint8_t> selector,
40+
std::function<bool(std::shared_ptr<const Node>)> handler) const {
41+
std::ignore = selector;
42+
OUTCOME_TRY(content_id, ContentIdentifierCodec::decode(root_cid));
43+
CID cid{std::move(content_id)};
44+
OUTCOME_TRY(root_node, getNode(cid));
45+
std::vector<std::shared_ptr<const Node>> node_set{};
46+
node_set.emplace_back(std::move(root_node));
47+
const auto &links = node_set.front()->getLinks();
48+
for (const auto& link : links) {
49+
auto request = getNode(link.get().getCID());
50+
if (request.has_error()) return ServiceError::UNRESOLVED_LINK;
51+
node_set.emplace_back(std::move(request.value()));
52+
}
53+
size_t sent_count{};
54+
for (const auto &node : node_set) {
55+
++sent_count;
56+
if (!handler(node)) break;
57+
}
58+
return sent_count;
59+
}
60+
3261
outcome::result<std::shared_ptr<Leaf>> MerkleDagServiceImpl::fetchGraph(
3362
const CID &cid) const {
3463
OUTCOME_TRY(node, getNode(cid));
@@ -38,8 +67,9 @@ namespace fc::storage::ipfs::merkledag {
3867
return root_leaf;
3968
}
4069

41-
outcome::result<std::shared_ptr<Leaf>> MerkleDagServiceImpl::fetchGraphOnDepth(
42-
const CID &cid, uint64_t depth) const {
70+
outcome::result<std::shared_ptr<Leaf>>
71+
MerkleDagServiceImpl::fetchGraphOnDepth(const CID &cid,
72+
uint64_t depth) const {
4373
OUTCOME_TRY(node, getNode(cid));
4474
auto leaf = std::make_shared<LeafImpl>(node->content());
4575
auto result = buildGraph(leaf, node->getLinks(), true, depth, 0);

core/storage/ipfs/merkledag/impl/merkledag_service_impl.hpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,12 @@ namespace fc::storage::ipfs::merkledag {
2828

2929
outcome::result<void> removeNode(const CID &cid) override;
3030

31+
outcome::result<size_t> select(
32+
gsl::span<const uint8_t> root_cid,
33+
gsl::span<const uint8_t> selector,
34+
std::function<bool(std::shared_ptr<const Node> node)> handler)
35+
const override;
36+
3137
outcome::result<std::shared_ptr<Leaf>> fetchGraph(
3238
const CID &cid) const override;
3339

core/storage/ipfs/merkledag/merkledag_service.hpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,20 @@ namespace fc::storage::ipfs::merkledag {
4343
*/
4444
virtual outcome::result<void> removeNode(const CID &cid) = 0;
4545

46+
/**
47+
* @brief Get nodes with IPLD-selector
48+
* @param root_cid - bytes of the root Node CID
49+
* @param selector - IPLD-selector raw bytes
50+
* @param handler - receiver of the selected Nodes, should return false to
51+
* break receiving process
52+
* @return count of the received by handler Nodes
53+
*/
54+
virtual outcome::result<size_t> select(
55+
gsl::span<const uint8_t> root_cid,
56+
gsl::span<const uint8_t> selector,
57+
std::function<bool(std::shared_ptr<const Node> node)> handler)
58+
const = 0;
59+
4660
/**
4761
* @brief Fetcg graph from given root node
4862
* @param cid - identifier of the root node

test/core/storage/ipfs/merkledag/ipfs_merkledag_service_test.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,29 @@ TEST_P(CommonFeaturesTest, FetchGraphSuccess) {
194194
ASSERT_EQ(fetched_structure, data.graph_structure);
195195
}
196196

197+
/**
198+
* @given Pre-generated nodes structure
199+
* @when Selecting nodes from DAG service
200+
* @then All operations must be successful and
201+
* selected nodes count must be count of root node children + 1 (self)
202+
*/
203+
TEST_P(CommonFeaturesTest, GraphSyncSelect) {
204+
const size_t nodes_count = data.nodes.front()->getLinks().size() + 1;
205+
EXPECT_OUTCOME_TRUE(
206+
root_cid, ContentIdentifierCodec::encode(data.nodes.front()->getCID()));
207+
std::vector<std::shared_ptr<const Node>> selected_nodes;
208+
std::function<bool(std::shared_ptr<const Node>)> handler =
209+
[&selected_nodes](std::shared_ptr<const Node> node) -> bool {
210+
selected_nodes.emplace_back(std::move(node));
211+
return true;
212+
};
213+
EXPECT_OUTCOME_TRUE(selected_count,
214+
merkledag_service_->select(
215+
root_cid, gsl::span<const uint8_t>{}, handler));
216+
ASSERT_EQ(selected_nodes.size(), selected_count);
217+
ASSERT_EQ(nodes_count, selected_count);
218+
}
219+
197220
/**
198221
* Pre-generated nodes, CIDs and serialized graph structures
199222
* Reference CIDs was generated by https://github.com/ipfs/go-merkledag

0 commit comments

Comments
 (0)