1
0
mirror of https://github.com/ipfs/kubo.git synced 2025-09-10 22:49:13 +08:00
Files
kubo/routing/routing.go
Jeromy cfcc3d6a1b ipns record selection via sequence numbers
This commit adds a sequence number to the IpnsEntry protobuf
that is used to determine which among a set of entries for the same key
is the 'most correct'.

GetValues has been added to the routing interface to retrieve a set of
records from the dht, for the caller to select from.

GetValue (singular) will call GetValues, select the 'best' record, and
then update that record to peers we received outdated records from.
This will help keep the dht consistent.

License: MIT
Signed-off-by: Jeromy <jeromyj@gmail.com>
2015-09-29 09:47:41 -07:00

91 lines
2.9 KiB
Go

// package routing defines the interface for a routing system used by ipfs.
package routing
import (
"errors"
context "github.com/ipfs/go-ipfs/Godeps/_workspace/src/golang.org/x/net/context"
key "github.com/ipfs/go-ipfs/blocks/key"
ci "github.com/ipfs/go-ipfs/p2p/crypto"
peer "github.com/ipfs/go-ipfs/p2p/peer"
)
// ErrNotFound is returned when a search fails to find anything
var ErrNotFound = errors.New("routing: not found")
// IpfsRouting is the routing module interface
// It is implemented by things like DHTs, etc.
type IpfsRouting interface {
FindProvidersAsync(context.Context, key.Key, int) <-chan peer.PeerInfo
// Basic Put/Get
// PutValue adds value corresponding to given Key.
PutValue(context.Context, key.Key, []byte) error
// GetValue searches for the value corresponding to given Key.
GetValue(context.Context, key.Key) ([]byte, error)
// GetValues searches for values corresponding to given Key.
//
// Passing a value of '0' for the count argument will cause the
// routing interface to return values only from cached or local storage
// and return an error if no cached value is found.
//
// Passing a value of '1' will return a local value if found, and query
// the network for the first value it finds otherwise.
// As a result, a value of '1' is mostly useful for cases where the record
// in question has only one valid value (such as public keys)
GetValues(c context.Context, k key.Key, count int) ([]RecvdVal, error)
// Value provider layer of indirection.
// This is what DSHTs (Coral and MainlineDHT) do to store large values in a DHT.
// Announce that this node can provide value for given key
Provide(context.Context, key.Key) error
// Find specific Peer
// FindPeer searches for a peer with given ID, returns a peer.PeerInfo
// with relevant addresses.
FindPeer(context.Context, peer.ID) (peer.PeerInfo, error)
// Bootstrap allows callers to hint to the routing system to get into a
// Boostrapped state
Bootstrap(context.Context) error
// TODO expose io.Closer or plain-old Close error
}
// RecvdVal represents a dht value record that has been received from a given peer
// it is used to track peers with expired records in order to correct them.
type RecvdVal struct {
From peer.ID
Val []byte
}
type PubKeyFetcher interface {
GetPublicKey(context.Context, peer.ID) (ci.PubKey, error)
}
// KeyForPublicKey returns the key used to retrieve public keys
// from the dht.
func KeyForPublicKey(id peer.ID) key.Key {
return key.Key("/pk/" + string(id))
}
func GetPublicKey(r IpfsRouting, ctx context.Context, pkhash []byte) (ci.PubKey, error) {
if dht, ok := r.(PubKeyFetcher); ok {
// If we have a DHT as our routing system, use optimized fetcher
return dht.GetPublicKey(ctx, peer.ID(pkhash))
} else {
key := key.Key("/pk/" + string(pkhash))
pkval, err := r.GetValue(ctx, key)
if err != nil {
return nil, err
}
// get PublicKey from node.Data
return ci.UnmarshalPublicKey(pkval)
}
}