Skip to content

Commit

Permalink
feat: run cid check and add test
Browse files Browse the repository at this point in the history
  • Loading branch information
2color committed Aug 27, 2024
1 parent 99c8ffd commit 23bef22
Show file tree
Hide file tree
Showing 5 changed files with 103 additions and 53 deletions.
97 changes: 46 additions & 51 deletions daemon.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ type daemon struct {

// number of providers at which to stop looking for providers in the DHT
// When doing a check only with a CID
var MaxProvidersCount = 3
var MaxProvidersCount = 10

func newDaemon(ctx context.Context, acceleratedDHT bool) (*daemon, error) {
rm, err := NewResourceManager()
Expand Down Expand Up @@ -112,18 +112,18 @@ func (d *daemon) mustStart() {

type providerOutput struct {
ID string
ConnectionError string
Addrs []string
ConnectionMaddrs []string
BitswapCheckOutput BitswapCheckOutput
}

func (d *daemon) runCidCheck(cidStr string) (*[]providerOutput, error) {
func (d *daemon) runCidCheck(ctx context.Context, cidStr string) (*[]providerOutput, error) {
cid, err := cid.Decode(cidStr)
if err != nil {
return nil, err
}

ctx := context.Background()
out := make([]providerOutput, 0, MaxProvidersCount)

queryCtx, cancel := context.WithCancel(ctx)
Expand All @@ -133,64 +133,59 @@ func (d *daemon) runCidCheck(cidStr string) (*[]providerOutput, error) {
var wg sync.WaitGroup
var mu sync.Mutex

for {
select {
case provider, ok := <-provsCh:
if !ok {
// Channel closed, all providers processed
return &out, nil
for provider := range provsCh {
wg.Add(1)
go func(provider peer.AddrInfo) {
defer wg.Done()
addrs := make([]string, len(provider.Addrs))
for i, addr := range provider.Addrs {
addrs[i] = addr.String()
}
wg.Add(1)
go func(provider peer.AddrInfo) {
defer wg.Done()

addrs := make([]string, len(provider.Addrs))
for i, addr := range provider.Addrs {
addrs[i] = addr.String()
}

provOutput := providerOutput{
ID: provider.ID.String(),
Addrs: addrs,
BitswapCheckOutput: BitswapCheckOutput{},
}
provOutput := providerOutput{
ID: provider.ID.String(),
Addrs: addrs,
BitswapCheckOutput: BitswapCheckOutput{},
}
log.Printf("provider output: %v\n", provOutput)

testHost, err := d.createTestHost()
if err != nil {
log.Printf("Error creating test host: %v", err)
return
}
defer testHost.Close()
testHost, err := d.createTestHost()
if err != nil {
log.Printf("Error creating test host: %v\n", err)
return
}
defer testHost.Close()

// Test Is the target connectable
dialCtx, dialCancel := context.WithTimeout(ctx, time.Second*15)
defer dialCancel()
// Test Is the target connectable
dialCtx, dialCancel := context.WithTimeout(ctx, time.Second*15)
defer dialCancel()

// we call NewStream to force NAT hole punching
// See https://github.com/libp2p/go-libp2p/issues/2714
testHost.Connect(dialCtx, provider)
_, connErr := testHost.NewStream(dialCtx, provider.ID, "/ipfs/bitswap/1.2.0", "/ipfs/bitswap/1.1.0", "/ipfs/bitswap/1.0.0", "/ipfs/bitswap")
// Call NewStream to force NAT hole punching. see https://github.com/libp2p/go-libp2p/issues/2714
testHost.Connect(dialCtx, provider)
_, connErr := testHost.NewStream(dialCtx, provider.ID, "/ipfs/bitswap/1.2.0", "/ipfs/bitswap/1.1.0", "/ipfs/bitswap/1.0.0", "/ipfs/bitswap")

if connErr != nil {
provOutput.BitswapCheckOutput.Error = fmt.Sprintf("error dialing to peer: %s", connErr.Error())
} else {
// TODO: Modify checkBitswapCID and vole to accept `AddrInfo` so that it can test any of the connections
provOutput.BitswapCheckOutput = checkBitswapCID(ctx, testHost, cid, provider.Addrs[0])
if connErr != nil {
provOutput.ConnectionError = fmt.Sprintf("error dialing to peer: %s", connErr.Error())
} else {
// since we pass a libp2p host that's already connected to the peer the actual connection maddr we pass in doesn't matter
p2pAddr, _ := multiaddr.NewMultiaddr("/p2p/" + provider.ID.String())
provOutput.BitswapCheckOutput = checkBitswapCID(ctx, testHost, cid, p2pAddr)

for _, c := range testHost.Network().ConnsToPeer(provider.ID) {
provOutput.ConnectionMaddrs = append(provOutput.ConnectionMaddrs, c.RemoteMultiaddr().String())
}
for _, c := range testHost.Network().ConnsToPeer(provider.ID) {
provOutput.ConnectionMaddrs = append(provOutput.ConnectionMaddrs, c.RemoteMultiaddr().String())
}
}

mu.Lock()
out = append(out, provOutput)
mu.Unlock()
}(provider)
case <-ctx.Done():
// Context cancelled
return &out, ctx.Err()
}
mu.Lock()
out = append(out, provOutput)
mu.Unlock()
}(provider)
}

// Wait for all goroutines to finish
wg.Wait()

return &out, nil
}

type peerCheckOutput struct {
Expand Down
28 changes: 28 additions & 0 deletions integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -157,4 +157,32 @@ func TestBasicIntegration(t *testing.T) {
obj.Value("DataAvailableOverBitswap").Object().Value("Found").Boolean().IsFalse()
obj.Value("DataAvailableOverBitswap").Object().Value("Responded").Boolean().IsTrue()
})

t.Run("Data found on reachable peer with just cid", func(t *testing.T) {
testData := []byte(t.Name())
mh, err := multihash.Sum(testData, multihash.SHA2_256, -1)
require.NoError(t, err)
testCid := cid.NewCidV1(cid.Raw, mh)
testBlock, err := blocks.NewBlockWithCid(testData, testCid)
require.NoError(t, err)
err = bstore.Put(ctx, testBlock)
require.NoError(t, err)
err = dhtClient.Provide(ctx, testCid, true)
require.NoError(t, err)

res := test.Query(t, "http://localhost:1234", testCid.String())

res.Length().IsEqual(1)
res.Value(0).Object().Value("ID").String().IsEqual(h.ID().String())
res.Value(0).Object().Value("ConnectionError").String().IsEmpty()
testHostAddrs := h.Addrs()
for _, addr := range testHostAddrs {
res.Value(0).Object().Value("Addrs").Array().ContainsAny(addr.String())
}

res.Value(0).Object().Value("ConnectionMaddrs").Array()
res.Value(0).Object().Value("BitswapCheckOutput").Object().Value("Error").String().IsEmpty()
res.Value(0).Object().Value("BitswapCheckOutput").Object().Value("Found").Boolean().IsTrue()
res.Value(0).Object().Value("BitswapCheckOutput").Object().Value("Responded").Boolean().IsTrue()
})
}
2 changes: 1 addition & 1 deletion main.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ func startServer(ctx context.Context, d *daemon, tcpListener, metricsUsername, m
var data interface{}

if maStr == "" {
data, err = d.runCidCheck(cidStr)
data, err = d.runCidCheck(r.Context(), cidStr)
} else {
data, err = d.runPeerCheck(maStr, cidStr)
}
Expand Down
20 changes: 20 additions & 0 deletions test/tools.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,26 @@ func Query(
JSON(opts).Object()
}

func QueryCid(
t *testing.T,
url string,
cid string,
) *httpexpect.Array {
expectedContentType := "application/json"

opts := httpexpect.ContentOpts{
MediaType: expectedContentType,
}

e := httpexpect.Default(t, url)

return e.GET("/check").
WithQuery("cid", cid).
Expect().
Status(http.StatusOK).
JSON(opts).Array()
}

func GetEnv(key string, fallback string) string {
if value, ok := os.LookupEnv(key); ok {
return value
Expand Down
9 changes: 8 additions & 1 deletion web/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ <h1 class="dib pa3 ma0 lh-tight">
<label class="db mt3 f6 fw6" for="cid">CID</label>
<input class="db w-100 pa2" type="text" id="cid" name="cid" required>
<label class="db mt3 f6 fw6" for="ma">Multiaddr</label>
<input class="db w-100 pa2" type="text" id="multiaddr" name="multiaddr" placeholder="/p2p/12D3Koo..." required />
<input class="db w-100 pa2" type="text" id="multiaddr" name="multiaddr" placeholder="/p2p/12D3Koo..." />
<details class="mt3">
<summary class="f6 fw6">Optional fields</summary>
<label class="db mt3 f6 fw6" for="backendURL">Backend URL</label>
Expand All @@ -47,6 +47,10 @@ <h1 class="dib pa3 ma0 lh-tight">
</button>
</div>
<div id="output" style="white-space:pre;" class="lh-copy fw6"></div>
<details class="mt3">
<summary class="f6 fw6">Output</summary>
<pre><code id="raw-output" style="white-space:pre;" class="lh-copy fw6 language-json"></code></pre>
</details>
</form>
</section>
<section class="mw8 center lh-copy dark-gray pv4 ph2 ph4-ns">
Expand Down Expand Up @@ -133,6 +137,9 @@ <h2 class="f4">What does it mean if I get an error?</h2>

if (res.ok) {
const respObj = await res.json()
const rawOutput = document.getElementById('raw-output')
rawOutput.textContent = JSON.stringify(respObj, null, 2)

const output = formatOutput(formData, respObj)
showOutput(output)
} else {
Expand Down

0 comments on commit 23bef22

Please sign in to comment.