package mockrouting import ( "context" "errors" "time" dshelp "github.com/ipfs/go-ipfs/thirdparty/ds-help" "gx/ipfs/QmeDA8gNhvRTsbrjEieay5wezupJDiky8xvCzDABbsGzmp/go-testutil" routing "gx/ipfs/QmPCGUjMRuBcPybZFpjhzpifwPP9wPRoiy5geTQKU4vqWA/go-libp2p-routing" u "gx/ipfs/QmPsAfmDBnZN3kZGSuNwvCNDZiHneERSKmRcFyG3UkvcT3/go-ipfs-util" logging "gx/ipfs/QmSpJByNKFX1sCsHBEp3R73FL4NF6FnQTEGyNAXHm2GS52/go-log" ma "gx/ipfs/QmW8s4zTsUoX1Q6CeYxVKPyqSKbF7H1YDUyTostBtZ8DaG/go-multiaddr" dhtpb "gx/ipfs/QmWGtsyPYEoiqTtWLpeUA2jpW4YSZgarKDD2zivYAFz7sR/go-libp2p-record/pb" peer "gx/ipfs/QmWNY7dV54ZDYmTA1ykVdwNCqC11mpU4zSUp6XDpLTH9eG/go-libp2p-peer" pstore "gx/ipfs/QmYijbtjCxFEjSXaudaQAUz3LN5VKLssm8WCUsRoqzXmQR/go-libp2p-peerstore" proto "gx/ipfs/QmZ4Qi3GaRbjcx28Sme5eMH7RQjGkt8wHxt2a65oLaeFEV/gogo-protobuf/proto" ds "gx/ipfs/QmdHG8MAuARdGHxx4rPQASLcvhz24fzjSQq7AJRAQEorq5/go-datastore" cid "gx/ipfs/QmeSrf6pzut73u6zLQkRFQ3ygt3k6XFT2kjdYP8Tnkwwyg/go-cid" ) var log = logging.Logger("mockrouter") type client struct { datastore ds.Datastore server server peer testutil.Identity } // FIXME(brian): is this method meant to simulate putting a value into the network? func (c *client) PutValue(ctx context.Context, key string, val []byte) error { log.Debugf("PutValue: %s", key) rec := new(dhtpb.Record) rec.Value = val rec.Key = proto.String(string(key)) rec.TimeReceived = proto.String(u.FormatRFC3339(time.Now())) data, err := proto.Marshal(rec) if err != nil { return err } return c.datastore.Put(dshelp.NewKeyFromBinary([]byte(key)), data) } // FIXME(brian): is this method meant to simulate getting a value from the network? func (c *client) GetValue(ctx context.Context, key string) ([]byte, error) { log.Debugf("GetValue: %s", key) v, err := c.datastore.Get(dshelp.NewKeyFromBinary([]byte(key))) if err != nil { return nil, err } data, ok := v.([]byte) if !ok { return nil, errors.New("could not cast value from datastore") } rec := new(dhtpb.Record) err = proto.Unmarshal(data, rec) if err != nil { return nil, err } return rec.GetValue(), nil } func (c *client) GetValues(ctx context.Context, key string, count int) ([]routing.RecvdVal, error) { log.Debugf("GetValues: %s", key) data, err := c.GetValue(ctx, key) if err != nil { return nil, err } return []routing.RecvdVal{{Val: data, From: c.peer.ID()}}, nil } func (c *client) FindProviders(ctx context.Context, key *cid.Cid) ([]pstore.PeerInfo, error) { return c.server.Providers(key), nil } func (c *client) FindPeer(ctx context.Context, pid peer.ID) (pstore.PeerInfo, error) { log.Debugf("FindPeer: %s", pid) return pstore.PeerInfo{}, nil } func (c *client) FindProvidersAsync(ctx context.Context, k *cid.Cid, max int) <-chan pstore.PeerInfo { out := make(chan pstore.PeerInfo) go func() { defer close(out) for i, p := range c.server.Providers(k) { if max <= i { return } select { case out <- p: case <-ctx.Done(): return } } }() return out } // Provide returns once the message is on the network. Value is not necessarily // visible yet. func (c *client) Provide(_ context.Context, key *cid.Cid, brd bool) error { if !brd { return nil } info := pstore.PeerInfo{ ID: c.peer.ID(), Addrs: []ma.Multiaddr{c.peer.Address()}, } return c.server.Announce(info, key) } func (c *client) Ping(ctx context.Context, p peer.ID) (time.Duration, error) { return 0, nil } func (c *client) Bootstrap(context.Context) error { return nil } var _ routing.IpfsRouting = &client{}