mirror of
https://github.com/ipfs/kubo.git
synced 2025-09-09 19:32:24 +08:00

- updated go-ctxgroup and goprocess ctxgroup: AddChildGroup was changed to AddChild. Used in two files: - p2p/net/mock/mock_net.go - routing/dht/dht.go - updated context from hg repo to git prev. commit in hg was ad01a6fcc8a19d3a4478c836895ffe883bd2ceab. (context: make parentCancelCtx iterative) represents commit 84f8955a887232b6308d79c68b8db44f64df455c in git repo - updated context to master (b6fdb7d8a4ccefede406f8fe0f017fb58265054c) Aaron Jacobs (2): net/context: Don't accept a context in the DoSomethingSlow example. context: Be clear that users must cancel the result of WithCancel. Andrew Gerrand (1): go.net: use golang.org/x/... import paths Bryan C. Mills (1): net/context: Don't leak goroutines in Done example. Damien Neil (1): context: fix removal of cancelled timer contexts from parent David Symonds (2): context: Fix WithValue example code. net: add import comments. Sameer Ajmani (1): context: fix TestAllocs to account for ints in interfaces
183 lines
4.5 KiB
Go
183 lines
4.5 KiB
Go
package bitswap
|
|
|
|
import (
|
|
"errors"
|
|
|
|
context "github.com/jbenet/go-ipfs/Godeps/_workspace/src/golang.org/x/net/context"
|
|
bsmsg "github.com/jbenet/go-ipfs/exchange/bitswap/message"
|
|
bsnet "github.com/jbenet/go-ipfs/exchange/bitswap/network"
|
|
peer "github.com/jbenet/go-ipfs/p2p/peer"
|
|
routing "github.com/jbenet/go-ipfs/routing"
|
|
mockrouting "github.com/jbenet/go-ipfs/routing/mock"
|
|
delay "github.com/jbenet/go-ipfs/thirdparty/delay"
|
|
util "github.com/jbenet/go-ipfs/util"
|
|
testutil "github.com/jbenet/go-ipfs/util/testutil"
|
|
)
|
|
|
|
func VirtualNetwork(rs mockrouting.Server, d delay.D) Network {
|
|
return &network{
|
|
clients: make(map[peer.ID]bsnet.Receiver),
|
|
delay: d,
|
|
routingserver: rs,
|
|
}
|
|
}
|
|
|
|
type network struct {
|
|
clients map[peer.ID]bsnet.Receiver
|
|
routingserver mockrouting.Server
|
|
delay delay.D
|
|
}
|
|
|
|
func (n *network) Adapter(p testutil.Identity) bsnet.BitSwapNetwork {
|
|
client := &networkClient{
|
|
local: p.ID(),
|
|
network: n,
|
|
routing: n.routingserver.Client(p),
|
|
}
|
|
n.clients[p.ID()] = client
|
|
return client
|
|
}
|
|
|
|
func (n *network) HasPeer(p peer.ID) bool {
|
|
_, found := n.clients[p]
|
|
return found
|
|
}
|
|
|
|
// TODO should this be completely asynchronous?
|
|
// TODO what does the network layer do with errors received from services?
|
|
func (n *network) SendMessage(
|
|
ctx context.Context,
|
|
from peer.ID,
|
|
to peer.ID,
|
|
message bsmsg.BitSwapMessage) error {
|
|
|
|
receiver, ok := n.clients[to]
|
|
if !ok {
|
|
return errors.New("Cannot locate peer on network")
|
|
}
|
|
|
|
// nb: terminate the context since the context wouldn't actually be passed
|
|
// over the network in a real scenario
|
|
|
|
go n.deliver(receiver, from, message)
|
|
|
|
return nil
|
|
}
|
|
|
|
func (n *network) deliver(
|
|
r bsnet.Receiver, from peer.ID, message bsmsg.BitSwapMessage) error {
|
|
if message == nil || from == "" {
|
|
return errors.New("Invalid input")
|
|
}
|
|
|
|
n.delay.Wait()
|
|
|
|
nextPeer, nextMsg := r.ReceiveMessage(context.TODO(), from, message)
|
|
|
|
if (nextPeer == "" && nextMsg != nil) || (nextMsg == nil && nextPeer != "") {
|
|
return errors.New("Malformed client request")
|
|
}
|
|
|
|
if nextPeer == "" && nextMsg == nil { // no response to send
|
|
return nil
|
|
}
|
|
|
|
nextReceiver, ok := n.clients[nextPeer]
|
|
if !ok {
|
|
return errors.New("Cannot locate peer on network")
|
|
}
|
|
go n.deliver(nextReceiver, nextPeer, nextMsg)
|
|
return nil
|
|
}
|
|
|
|
// TODO
|
|
func (n *network) SendRequest(
|
|
ctx context.Context,
|
|
from peer.ID,
|
|
to peer.ID,
|
|
message bsmsg.BitSwapMessage) (
|
|
incoming bsmsg.BitSwapMessage, err error) {
|
|
|
|
r, ok := n.clients[to]
|
|
if !ok {
|
|
return nil, errors.New("Cannot locate peer on network")
|
|
}
|
|
nextPeer, nextMsg := r.ReceiveMessage(context.TODO(), from, message)
|
|
|
|
// TODO dedupe code
|
|
if (nextPeer == "" && nextMsg != nil) || (nextMsg == nil && nextPeer != "") {
|
|
r.ReceiveError(errors.New("Malformed client request"))
|
|
return nil, nil
|
|
}
|
|
|
|
// TODO dedupe code
|
|
if nextPeer == "" && nextMsg == nil {
|
|
return nil, nil
|
|
}
|
|
|
|
// TODO test when receiver doesn't immediately respond to the initiator of the request
|
|
if nextPeer != from {
|
|
go func() {
|
|
nextReceiver, ok := n.clients[nextPeer]
|
|
if !ok {
|
|
// TODO log the error?
|
|
}
|
|
n.deliver(nextReceiver, nextPeer, nextMsg)
|
|
}()
|
|
return nil, nil
|
|
}
|
|
return nextMsg, nil
|
|
}
|
|
|
|
type networkClient struct {
|
|
local peer.ID
|
|
bsnet.Receiver
|
|
network *network
|
|
routing routing.IpfsRouting
|
|
}
|
|
|
|
func (nc *networkClient) SendMessage(
|
|
ctx context.Context,
|
|
to peer.ID,
|
|
message bsmsg.BitSwapMessage) error {
|
|
return nc.network.SendMessage(ctx, nc.local, to, message)
|
|
}
|
|
|
|
func (nc *networkClient) SendRequest(
|
|
ctx context.Context,
|
|
to peer.ID,
|
|
message bsmsg.BitSwapMessage) (incoming bsmsg.BitSwapMessage, err error) {
|
|
return nc.network.SendRequest(ctx, nc.local, to, message)
|
|
}
|
|
|
|
// FindProvidersAsync returns a channel of providers for the given key
|
|
func (nc *networkClient) FindProvidersAsync(ctx context.Context, k util.Key, max int) <-chan peer.ID {
|
|
|
|
// NB: this function duplicates the PeerInfo -> ID transformation in the
|
|
// bitswap network adapter. Not to worry. This network client will be
|
|
// deprecated once the ipfsnet.Mock is added. The code below is only
|
|
// temporary.
|
|
|
|
out := make(chan peer.ID)
|
|
go func() {
|
|
defer close(out)
|
|
providers := nc.routing.FindProvidersAsync(ctx, k, max)
|
|
for info := range providers {
|
|
select {
|
|
case <-ctx.Done():
|
|
case out <- info.ID:
|
|
}
|
|
}
|
|
}()
|
|
return out
|
|
}
|
|
|
|
// Provide provides the key to the network
|
|
func (nc *networkClient) Provide(ctx context.Context, k util.Key) error {
|
|
return nc.routing.Provide(ctx, k)
|
|
}
|
|
|
|
func (nc *networkClient) SetDelegate(r bsnet.Receiver) {
|
|
nc.Receiver = r
|
|
}
|