offline.go 3.11 KB
Newer Older
Jeromy's avatar
Jeromy committed
1 2 3
package offline

import (
4
	"context"
Jeromy's avatar
Jeromy committed
5 6 7
	"errors"
	"time"

8
	dshelp "github.com/ipfs/go-ipfs/thirdparty/ds-help"
Jeromy's avatar
Jeromy committed
9

10
	cid "gx/ipfs/QmNw61A6sJoXMeP37mJRtQZdNhj5e3FdjoTN3v4FyE96Gk/go-cid"
11
	ci "gx/ipfs/QmP1DfoUjiWH2ZBo1PBH6FupdBucbDepx3HpWmEY6JMUpY/go-libp2p-crypto"
Łukasz Magiera's avatar
Łukasz Magiera committed
12
	ds "gx/ipfs/QmSiN66ybp5udnQnvhb6euiWiiQWdGvwMhAWa95cC1DTCV/go-datastore"
13 14
	record "gx/ipfs/QmWYCqr6UDqqD1bfRybaAPtbAqcN3TSJpveaBXMwbQ3ePZ/go-libp2p-record"
	pb "gx/ipfs/QmWYCqr6UDqqD1bfRybaAPtbAqcN3TSJpveaBXMwbQ3ePZ/go-libp2p-record/pb"
15
	pstore "gx/ipfs/QmXZSd1qR5BxZkPyuwfT5jpqQFScZccoZvDneXsKzCNHWX/go-libp2p-peerstore"
Jeromy's avatar
Jeromy committed
16
	proto "gx/ipfs/QmZ4Qi3GaRbjcx28Sme5eMH7RQjGkt8wHxt2a65oLaeFEV/gogo-protobuf/proto"
17
	routing "gx/ipfs/QmaNDbaV1wvPRLxTYepVsXrppXNjQ1NbrnG7ibAgKeyaXD/go-libp2p-routing"
18
	"gx/ipfs/QmdS9KpbDyPrieswibZhkod1oXqRwZJrUPzxCofAMWpFGq/go-libp2p-peer"
Jeromy's avatar
Jeromy committed
19 20 21 22 23 24 25 26 27 28 29
)

var ErrOffline = errors.New("routing system in offline mode")

func NewOfflineRouter(dstore ds.Datastore, privkey ci.PrivKey) routing.IpfsRouting {
	return &offlineRouting{
		datastore: dstore,
		sk:        privkey,
	}
}

Jeromy's avatar
Jeromy committed
30 31 32
// offlineRouting implements the IpfsRouting interface,
// but only provides the capability to Put and Get signed dht
// records to and from the local datastore.
Jeromy's avatar
Jeromy committed
33 34 35 36 37
type offlineRouting struct {
	datastore ds.Datastore
	sk        ci.PrivKey
}

38
func (c *offlineRouting) PutValue(ctx context.Context, key string, val []byte) error {
39
	rec, err := record.MakePutRecord(c.sk, key, val, false)
Jeromy's avatar
Jeromy committed
40 41 42 43 44 45 46 47
	if err != nil {
		return err
	}
	data, err := proto.Marshal(rec)
	if err != nil {
		return err
	}

48
	return c.datastore.Put(dshelp.NewKeyFromBinary([]byte(key)), data)
Jeromy's avatar
Jeromy committed
49 50
}

51
func (c *offlineRouting) GetValue(ctx context.Context, key string) ([]byte, error) {
52
	v, err := c.datastore.Get(dshelp.NewKeyFromBinary([]byte(key)))
Jeromy's avatar
Jeromy committed
53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
	if err != nil {
		return nil, err
	}

	byt, ok := v.([]byte)
	if !ok {
		return nil, errors.New("value stored in datastore not []byte")
	}
	rec := new(pb.Record)
	err = proto.Unmarshal(byt, rec)
	if err != nil {
		return nil, err
	}

	return rec.GetValue(), nil
}

70
func (c *offlineRouting) GetValues(ctx context.Context, key string, _ int) ([]routing.RecvdVal, error) {
71
	v, err := c.datastore.Get(dshelp.NewKeyFromBinary([]byte(key)))
72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
	if err != nil {
		return nil, err
	}

	byt, ok := v.([]byte)
	if !ok {
		return nil, errors.New("value stored in datastore not []byte")
	}
	rec := new(pb.Record)
	err = proto.Unmarshal(byt, rec)
	if err != nil {
		return nil, err
	}

	return []routing.RecvdVal{
		{Val: rec.GetValue()},
	}, nil
}

Jeromy's avatar
Jeromy committed
91 92
func (c *offlineRouting) FindPeer(ctx context.Context, pid peer.ID) (pstore.PeerInfo, error) {
	return pstore.PeerInfo{}, ErrOffline
Jeromy's avatar
Jeromy committed
93 94
}

95
func (c *offlineRouting) FindProvidersAsync(ctx context.Context, k *cid.Cid, max int) <-chan pstore.PeerInfo {
Jeromy's avatar
Jeromy committed
96
	out := make(chan pstore.PeerInfo)
Jeromy's avatar
Jeromy committed
97 98 99 100
	close(out)
	return out
}

101
func (c *offlineRouting) Provide(_ context.Context, k *cid.Cid, _ bool) error {
Jeromy's avatar
Jeromy committed
102 103 104 105 106 107 108
	return ErrOffline
}

func (c *offlineRouting) Ping(ctx context.Context, p peer.ID) (time.Duration, error) {
	return 0, ErrOffline
}

Jeromy's avatar
Jeromy committed
109
func (c *offlineRouting) Bootstrap(context.Context) error {
110 111 112
	return nil
}

Jeromy's avatar
Jeromy committed
113
// ensure offlineRouting matches the IpfsRouting interface
Jeromy's avatar
Jeromy committed
114
var _ routing.IpfsRouting = &offlineRouting{}