mirror of
https://github.com/ipfs/kubo.git
synced 2026-02-21 18:37:45 +08:00
Some checks are pending
CodeQL / codeql (push) Waiting to run
Docker Check / lint (push) Waiting to run
Docker Check / build (push) Waiting to run
Gateway Conformance / gateway-conformance (push) Waiting to run
Gateway Conformance / gateway-conformance-libp2p-experiment (push) Waiting to run
Go Build / go-build (push) Waiting to run
Go Check / go-check (push) Waiting to run
Go Lint / go-lint (push) Waiting to run
Go Test / go-test (push) Waiting to run
Interop / interop-prep (push) Waiting to run
Interop / helia-interop (push) Blocked by required conditions
Interop / ipfs-webui (push) Blocked by required conditions
Sharness / sharness-test (push) Waiting to run
Spell Check / spellcheck (push) Waiting to run
This allows Kubo to respond to the GetClosestPeers() http routing v1 endpoint as spec'ed here: https://github.com/ipfs/specs/pull/476 It is based on work from https://github.com/ipfs/boxo/pull/1021 We let IpfsNode implmement the contentRouter.Client interface with the new method. We use our WAN-DHT to get the closest peers. Additionally, Routing V1 HTTP API is exposed by default which enables light clients in browsers to use Kubo Gateway as delegated routing backend Co-authored-by: Marcin Rataj <lidel@lidel.org>
146 lines
4.1 KiB
Go
146 lines
4.1 KiB
Go
package httprouting
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"sync"
|
|
"time"
|
|
|
|
"github.com/ipfs/boxo/ipns"
|
|
"github.com/ipfs/boxo/routing/http/server"
|
|
"github.com/ipfs/boxo/routing/http/types"
|
|
"github.com/ipfs/boxo/routing/http/types/iter"
|
|
"github.com/ipfs/go-cid"
|
|
"github.com/libp2p/go-libp2p/core/peer"
|
|
"github.com/libp2p/go-libp2p/core/routing"
|
|
)
|
|
|
|
// MockHTTPContentRouter provides /routing/v1
|
|
// (https://specs.ipfs.tech/routing/http-routing-v1/) server implementation
|
|
// based on github.com/ipfs/boxo/routing/http/server
|
|
type MockHTTPContentRouter struct {
|
|
m sync.Mutex
|
|
provideBitswapCalls int
|
|
findProvidersCalls int
|
|
findPeersCalls int
|
|
getClosestPeersCalls int
|
|
providers map[cid.Cid][]types.Record
|
|
peers map[peer.ID][]*types.PeerRecord
|
|
Debug bool
|
|
}
|
|
|
|
func (r *MockHTTPContentRouter) FindProviders(ctx context.Context, key cid.Cid, limit int) (iter.ResultIter[types.Record], error) {
|
|
if r.Debug {
|
|
fmt.Printf("MockHTTPContentRouter.FindProviders(%s)\n", key.String())
|
|
}
|
|
r.m.Lock()
|
|
defer r.m.Unlock()
|
|
r.findProvidersCalls++
|
|
if r.providers == nil {
|
|
r.providers = make(map[cid.Cid][]types.Record)
|
|
}
|
|
records, found := r.providers[key]
|
|
if !found {
|
|
return iter.FromSlice([]iter.Result[types.Record]{}), nil
|
|
}
|
|
results := make([]iter.Result[types.Record], len(records))
|
|
for i, rec := range records {
|
|
results[i] = iter.Result[types.Record]{Val: rec}
|
|
if r.Debug {
|
|
fmt.Printf("MockHTTPContentRouter.FindProviders(%s) result: %+v\n", key.String(), rec)
|
|
}
|
|
}
|
|
return iter.FromSlice(results), nil
|
|
}
|
|
|
|
// nolint deprecated
|
|
func (r *MockHTTPContentRouter) ProvideBitswap(ctx context.Context, req *server.BitswapWriteProvideRequest) (time.Duration, error) {
|
|
r.m.Lock()
|
|
defer r.m.Unlock()
|
|
r.provideBitswapCalls++
|
|
return 0, nil
|
|
}
|
|
|
|
func (r *MockHTTPContentRouter) FindPeers(ctx context.Context, pid peer.ID, limit int) (iter.ResultIter[*types.PeerRecord], error) {
|
|
r.m.Lock()
|
|
defer r.m.Unlock()
|
|
r.findPeersCalls++
|
|
|
|
if r.peers == nil {
|
|
r.peers = make(map[peer.ID][]*types.PeerRecord)
|
|
}
|
|
records, found := r.peers[pid]
|
|
if !found {
|
|
return iter.FromSlice([]iter.Result[*types.PeerRecord]{}), nil
|
|
}
|
|
|
|
results := make([]iter.Result[*types.PeerRecord], len(records))
|
|
for i, rec := range records {
|
|
results[i] = iter.Result[*types.PeerRecord]{Val: rec}
|
|
if r.Debug {
|
|
fmt.Printf("MockHTTPContentRouter.FindPeers(%s) result: %+v\n", pid.String(), rec)
|
|
}
|
|
}
|
|
return iter.FromSlice(results), nil
|
|
}
|
|
|
|
func (r *MockHTTPContentRouter) GetIPNS(ctx context.Context, name ipns.Name) (*ipns.Record, error) {
|
|
return nil, routing.ErrNotSupported
|
|
}
|
|
|
|
func (r *MockHTTPContentRouter) PutIPNS(ctx context.Context, name ipns.Name, rec *ipns.Record) error {
|
|
return routing.ErrNotSupported
|
|
}
|
|
|
|
func (r *MockHTTPContentRouter) NumFindProvidersCalls() int {
|
|
r.m.Lock()
|
|
defer r.m.Unlock()
|
|
return r.findProvidersCalls
|
|
}
|
|
|
|
// AddProvider adds a record for a given CID
|
|
func (r *MockHTTPContentRouter) AddProvider(key cid.Cid, record types.Record) {
|
|
r.m.Lock()
|
|
defer r.m.Unlock()
|
|
if r.providers == nil {
|
|
r.providers = make(map[cid.Cid][]types.Record)
|
|
}
|
|
r.providers[key] = append(r.providers[key], record)
|
|
|
|
peerRecord, ok := record.(*types.PeerRecord)
|
|
if ok {
|
|
if r.peers == nil {
|
|
r.peers = make(map[peer.ID][]*types.PeerRecord)
|
|
}
|
|
pid := peerRecord.ID
|
|
r.peers[*pid] = append(r.peers[*pid], peerRecord)
|
|
}
|
|
}
|
|
|
|
func (r *MockHTTPContentRouter) GetClosestPeers(ctx context.Context, key cid.Cid) (iter.ResultIter[*types.PeerRecord], error) {
|
|
r.m.Lock()
|
|
defer r.m.Unlock()
|
|
r.getClosestPeersCalls++
|
|
|
|
if r.peers == nil {
|
|
r.peers = make(map[peer.ID][]*types.PeerRecord)
|
|
}
|
|
pid, err := peer.FromCid(key)
|
|
if err != nil {
|
|
return iter.FromSlice([]iter.Result[*types.PeerRecord]{}), nil
|
|
}
|
|
records, found := r.peers[pid]
|
|
if !found {
|
|
return iter.FromSlice([]iter.Result[*types.PeerRecord]{}), nil
|
|
}
|
|
|
|
results := make([]iter.Result[*types.PeerRecord], len(records))
|
|
for i, rec := range records {
|
|
results[i] = iter.Result[*types.PeerRecord]{Val: rec}
|
|
if r.Debug {
|
|
fmt.Printf("MockHTTPContentRouter.GetPeers(%s) result: %+v\n", pid.String(), rec)
|
|
}
|
|
}
|
|
return iter.FromSlice(results), nil
|
|
}
|