github.com/keltia/go-ipfs@v0.3.8-0.20150909044612-210793031c63/routing/offline/offline.go (about)

     1  package offline
     2  
     3  import (
     4  	"errors"
     5  	"time"
     6  
     7  	proto "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/gogo/protobuf/proto"
     8  	ds "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-datastore"
     9  	context "github.com/ipfs/go-ipfs/Godeps/_workspace/src/golang.org/x/net/context"
    10  	key "github.com/ipfs/go-ipfs/blocks/key"
    11  	ci "github.com/ipfs/go-ipfs/p2p/crypto"
    12  	"github.com/ipfs/go-ipfs/p2p/peer"
    13  	routing "github.com/ipfs/go-ipfs/routing"
    14  	pb "github.com/ipfs/go-ipfs/routing/dht/pb"
    15  	record "github.com/ipfs/go-ipfs/routing/record"
    16  	eventlog "github.com/ipfs/go-ipfs/thirdparty/eventlog"
    17  )
    18  
    19  var log = eventlog.Logger("offlinerouting")
    20  
    21  var ErrOffline = errors.New("routing system in offline mode")
    22  
    23  func NewOfflineRouter(dstore ds.Datastore, privkey ci.PrivKey) routing.IpfsRouting {
    24  	return &offlineRouting{
    25  		datastore: dstore,
    26  		sk:        privkey,
    27  	}
    28  }
    29  
    30  // offlineRouting implements the IpfsRouting interface,
    31  // but only provides the capability to Put and Get signed dht
    32  // records to and from the local datastore.
    33  type offlineRouting struct {
    34  	datastore ds.Datastore
    35  	sk        ci.PrivKey
    36  }
    37  
    38  func (c *offlineRouting) PutValue(ctx context.Context, key key.Key, val []byte) error {
    39  	rec, err := record.MakePutRecord(c.sk, key, val, false)
    40  	if err != nil {
    41  		return err
    42  	}
    43  	data, err := proto.Marshal(rec)
    44  	if err != nil {
    45  		return err
    46  	}
    47  
    48  	return c.datastore.Put(key.DsKey(), data)
    49  }
    50  
    51  func (c *offlineRouting) GetValue(ctx context.Context, key key.Key) ([]byte, error) {
    52  	v, err := c.datastore.Get(key.DsKey())
    53  	if err != nil {
    54  		return nil, err
    55  	}
    56  
    57  	byt, ok := v.([]byte)
    58  	if !ok {
    59  		return nil, errors.New("value stored in datastore not []byte")
    60  	}
    61  	rec := new(pb.Record)
    62  	err = proto.Unmarshal(byt, rec)
    63  	if err != nil {
    64  		return nil, err
    65  	}
    66  
    67  	return rec.GetValue(), nil
    68  }
    69  
    70  func (c *offlineRouting) FindProviders(ctx context.Context, key key.Key) ([]peer.PeerInfo, error) {
    71  	return nil, ErrOffline
    72  }
    73  
    74  func (c *offlineRouting) FindPeer(ctx context.Context, pid peer.ID) (peer.PeerInfo, error) {
    75  	return peer.PeerInfo{}, ErrOffline
    76  }
    77  
    78  func (c *offlineRouting) FindProvidersAsync(ctx context.Context, k key.Key, max int) <-chan peer.PeerInfo {
    79  	out := make(chan peer.PeerInfo)
    80  	close(out)
    81  	return out
    82  }
    83  
    84  func (c *offlineRouting) Provide(_ context.Context, key key.Key) error {
    85  	return ErrOffline
    86  }
    87  
    88  func (c *offlineRouting) Ping(ctx context.Context, p peer.ID) (time.Duration, error) {
    89  	return 0, ErrOffline
    90  }
    91  
    92  func (c *offlineRouting) Bootstrap(context.Context) error {
    93  	return nil
    94  }
    95  
    96  // ensure offlineRouting matches the IpfsRouting interface
    97  var _ routing.IpfsRouting = &offlineRouting{}