mirror of
https://github.com/ipfs/kubo.git
synced 2025-09-09 23:42:20 +08:00
New NameSystem interface
type NameSystem interface { Resolver Publisher } should say it all. cc @whyrusleeping
This commit is contained in:
@ -19,7 +19,7 @@ func Publish(n *core.IpfsNode, args []string, opts map[string]interface{}, out i
|
|||||||
|
|
||||||
k := n.Identity.PrivKey
|
k := n.Identity.PrivKey
|
||||||
|
|
||||||
pub := nsys.NewPublisher(n.DAG, n.Routing)
|
pub := nsys.NewRoutingPublisher(n.Routing)
|
||||||
err := pub.Publish(k, args[0])
|
err := pub.Publish(k, args[0])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
11
core/core.go
11
core/core.go
@ -63,10 +63,7 @@ type IpfsNode struct {
|
|||||||
Resolver *path.Resolver
|
Resolver *path.Resolver
|
||||||
|
|
||||||
// the name system, resolves paths to hashes
|
// the name system, resolves paths to hashes
|
||||||
Namesys namesys.Resolver
|
Namesys namesys.NameSystem
|
||||||
|
|
||||||
// the routing publisher
|
|
||||||
Publisher namesys.Publisher
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewIpfsNode constructs a new IpfsNode based on the given config.
|
// NewIpfsNode constructs a new IpfsNode based on the given config.
|
||||||
@ -148,8 +145,7 @@ func NewIpfsNode(cfg *config.Config, online bool) (*IpfsNode, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dag := &merkledag.DAGService{Blocks: bs}
|
dag := &merkledag.DAGService{Blocks: bs}
|
||||||
resolve := namesys.NewMasterResolver(route, dag)
|
ns := namesys.NewNameSystem(route)
|
||||||
publisher := namesys.NewPublisher(dag, route)
|
|
||||||
|
|
||||||
success = true
|
success = true
|
||||||
return &IpfsNode{
|
return &IpfsNode{
|
||||||
@ -162,8 +158,7 @@ func NewIpfsNode(cfg *config.Config, online bool) (*IpfsNode, error) {
|
|||||||
Exchange: exchangeSession,
|
Exchange: exchangeSession,
|
||||||
Identity: local,
|
Identity: local,
|
||||||
Routing: route,
|
Routing: route,
|
||||||
Namesys: resolve,
|
Namesys: ns,
|
||||||
Publisher: publisher,
|
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,10 +43,7 @@ func NewMockNode() (*IpfsNode, error) {
|
|||||||
nd.DAG = &mdag.DAGService{bserv}
|
nd.DAG = &mdag.DAGService{bserv}
|
||||||
|
|
||||||
// Namespace resolver
|
// Namespace resolver
|
||||||
nd.Namesys = nsys.NewMasterResolver(dht, nd.DAG)
|
nd.Namesys = nsys.NewNameSystem(dht)
|
||||||
|
|
||||||
// Publisher
|
|
||||||
nd.Publisher = nsys.NewPublisher(nd.DAG, dht)
|
|
||||||
|
|
||||||
// Path resolver
|
// Path resolver
|
||||||
nd.Resolver = &path.Resolver{nd.DAG}
|
nd.Resolver = &path.Resolver{nd.DAG}
|
||||||
|
@ -397,7 +397,7 @@ func (n *Node) republishRoot() error {
|
|||||||
}
|
}
|
||||||
log.Debug("Publishing changes!")
|
log.Debug("Publishing changes!")
|
||||||
|
|
||||||
err = n.Ipfs.Publisher.Publish(root.key, ndkey.Pretty())
|
err = n.Ipfs.Namesys.Publish(root.key, ndkey.Pretty())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("ipns: Publish Failed: %s", err)
|
log.Error("ipns: Publish Failed: %s", err)
|
||||||
return err
|
return err
|
||||||
|
@ -4,9 +4,10 @@ import (
|
|||||||
"net"
|
"net"
|
||||||
|
|
||||||
b58 "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-base58"
|
b58 "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-base58"
|
||||||
mh "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multihash"
|
|
||||||
u "github.com/jbenet/go-ipfs/util"
|
|
||||||
isd "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-is-domain"
|
isd "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-is-domain"
|
||||||
|
mh "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multihash"
|
||||||
|
|
||||||
|
u "github.com/jbenet/go-ipfs/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
// DNSResolver implements a Resolver on DNS domains
|
// DNSResolver implements a Resolver on DNS domains
|
||||||
@ -15,8 +16,8 @@ type DNSResolver struct {
|
|||||||
// cache would need a timeout
|
// cache would need a timeout
|
||||||
}
|
}
|
||||||
|
|
||||||
// Matches implements Resolver
|
// CanResolve implements Resolver
|
||||||
func (r *DNSResolver) Matches(name string) bool {
|
func (r *DNSResolver) CanResolve(name string) bool {
|
||||||
return isd.IsDomain(name)
|
return isd.IsDomain(name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
43
namesys/interface.go
Normal file
43
namesys/interface.go
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
package namesys
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
|
||||||
|
ci "github.com/jbenet/go-ipfs/crypto"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ErrResolveFailed signals an error when attempting to resolve.
|
||||||
|
var ErrResolveFailed = errors.New("could not resolve name.")
|
||||||
|
|
||||||
|
// ErrPublishFailed signals an error when attempting to publish.
|
||||||
|
var ErrPublishFailed = errors.New("could not publish name.")
|
||||||
|
|
||||||
|
// Namesys represents a cohesive name publishing and resolving system.
|
||||||
|
//
|
||||||
|
// Publishing a name is the process of establishing a mapping, a key-value
|
||||||
|
// pair, according to naming rules and databases.
|
||||||
|
//
|
||||||
|
// Resolving a name is the process of looking up the value associated with the
|
||||||
|
// key (name).
|
||||||
|
type NameSystem interface {
|
||||||
|
Resolver
|
||||||
|
Publisher
|
||||||
|
}
|
||||||
|
|
||||||
|
// Resolver is an object capable of resolving names.
|
||||||
|
type Resolver interface {
|
||||||
|
|
||||||
|
// Resolve looks up a name, and returns the value previously published.
|
||||||
|
Resolve(name string) (value string, err error)
|
||||||
|
|
||||||
|
// CanResolve checks whether this Resolver can resolve a name
|
||||||
|
CanResolve(name string) bool
|
||||||
|
}
|
||||||
|
|
||||||
|
// Publisher is an object capable of publishing particular names.
|
||||||
|
type Publisher interface {
|
||||||
|
|
||||||
|
// Publish establishes a name-value mapping.
|
||||||
|
// TODO make this not PrivKey specific.
|
||||||
|
Publish(name ci.PrivKey, value string) error
|
||||||
|
}
|
57
namesys/namesys.go
Normal file
57
namesys/namesys.go
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
package namesys
|
||||||
|
|
||||||
|
import (
|
||||||
|
ci "github.com/jbenet/go-ipfs/crypto"
|
||||||
|
routing "github.com/jbenet/go-ipfs/routing"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ipnsNameSystem implements IPNS naming.
|
||||||
|
//
|
||||||
|
// Uses three Resolvers:
|
||||||
|
// (a) ipfs routing naming: SFS-like PKI names.
|
||||||
|
// (b) dns domains: resolves using links in DNS TXT records
|
||||||
|
// (c) proquints: interprets string as the raw byte data.
|
||||||
|
//
|
||||||
|
// It can only publish to: (a) ipfs routing naming.
|
||||||
|
//
|
||||||
|
type ipns struct {
|
||||||
|
resolvers []Resolver
|
||||||
|
publisher Publisher
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewNameSystem will construct the IPFS naming system based on Routing
|
||||||
|
func NewNameSystem(r routing.IpfsRouting) NameSystem {
|
||||||
|
return &ipns{
|
||||||
|
resolvers: []Resolver{
|
||||||
|
new(DNSResolver),
|
||||||
|
new(ProquintResolver),
|
||||||
|
NewRoutingResolver(r),
|
||||||
|
},
|
||||||
|
publisher: NewRoutingPublisher(r),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Resolve implements Resolver
|
||||||
|
func (ns *ipns) Resolve(name string) (string, error) {
|
||||||
|
for _, r := range ns.resolvers {
|
||||||
|
if r.CanResolve(name) {
|
||||||
|
return r.Resolve(name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "", ErrResolveFailed
|
||||||
|
}
|
||||||
|
|
||||||
|
// CanResolve implements Resolver
|
||||||
|
func (ns *ipns) CanResolve(name string) bool {
|
||||||
|
for _, r := range ns.resolvers {
|
||||||
|
if r.CanResolve(name) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// Publish implements Publisher
|
||||||
|
func (ns *ipns) Publish(name ci.PrivKey, value string) error {
|
||||||
|
return ns.publisher.Publish(name, value)
|
||||||
|
}
|
@ -1,8 +0,0 @@
|
|||||||
package namesys
|
|
||||||
|
|
||||||
type Resolver interface {
|
|
||||||
// Resolve returns a base58 encoded string
|
|
||||||
Resolve(string) (string, error)
|
|
||||||
|
|
||||||
Matches(string) bool
|
|
||||||
}
|
|
@ -8,13 +8,15 @@ import (
|
|||||||
|
|
||||||
type ProquintResolver struct{}
|
type ProquintResolver struct{}
|
||||||
|
|
||||||
func (r *ProquintResolver) Matches(name string) bool {
|
// CanResolve implements Resolver. Checks whether the name is a proquint string.
|
||||||
|
func (r *ProquintResolver) CanResolve(name string) bool {
|
||||||
ok, err := proquint.IsProquint(name)
|
ok, err := proquint.IsProquint(name)
|
||||||
return err == nil && ok
|
return err == nil && ok
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Resolve implements Resolver. Decodes the proquint string.
|
||||||
func (r *ProquintResolver) Resolve(name string) (string, error) {
|
func (r *ProquintResolver) Resolve(name string) (string, error) {
|
||||||
ok := r.Matches(name)
|
ok := r.CanResolve(name)
|
||||||
if !ok {
|
if !ok {
|
||||||
return "", errors.New("not a valid proquint string")
|
return "", errors.New("not a valid proquint string")
|
||||||
}
|
}
|
||||||
|
@ -7,32 +7,26 @@ import (
|
|||||||
"github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/goprotobuf/proto"
|
"github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/goprotobuf/proto"
|
||||||
|
|
||||||
ci "github.com/jbenet/go-ipfs/crypto"
|
ci "github.com/jbenet/go-ipfs/crypto"
|
||||||
mdag "github.com/jbenet/go-ipfs/merkledag"
|
|
||||||
routing "github.com/jbenet/go-ipfs/routing"
|
routing "github.com/jbenet/go-ipfs/routing"
|
||||||
u "github.com/jbenet/go-ipfs/util"
|
u "github.com/jbenet/go-ipfs/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// ipnsPublisher is capable of publishing and resolving names to the IPFS
|
||||||
|
// routing system.
|
||||||
type ipnsPublisher struct {
|
type ipnsPublisher struct {
|
||||||
dag *mdag.DAGService
|
|
||||||
routing routing.IpfsRouting
|
routing routing.IpfsRouting
|
||||||
}
|
}
|
||||||
|
|
||||||
type Publisher interface {
|
// NewRoutingPublisher constructs a publisher for the IPFS Routing name system.
|
||||||
Publish(ci.PrivKey, string) error
|
func NewRoutingPublisher(route routing.IpfsRouting) Publisher {
|
||||||
|
return &ipnsPublisher{routing: route}
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewPublisher(dag *mdag.DAGService, route routing.IpfsRouting) Publisher {
|
// Publish implements Publisher. Accepts a keypair and a value,
|
||||||
return &ipnsPublisher{
|
|
||||||
dag: dag,
|
|
||||||
routing: route,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Publish accepts a keypair and a value,
|
|
||||||
func (p *ipnsPublisher) Publish(k ci.PrivKey, value string) error {
|
func (p *ipnsPublisher) Publish(k ci.PrivKey, value string) error {
|
||||||
log.Debug("namesys: Publish %s", value)
|
log.Debug("namesys: Publish %s", value)
|
||||||
ctx := context.TODO()
|
ctx := context.TODO()
|
||||||
data, err := CreateEntryData(k, value)
|
data, err := createRoutingEntryData(k, value)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -63,7 +57,7 @@ func (p *ipnsPublisher) Publish(k ci.PrivKey, value string) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func CreateEntryData(pk ci.PrivKey, val string) ([]byte, error) {
|
func createRoutingEntryData(pk ci.PrivKey, val string) ([]byte, error) {
|
||||||
entry := new(IpnsEntry)
|
entry := new(IpnsEntry)
|
||||||
sig, err := pk.Sign([]byte(val))
|
sig, err := pk.Sign([]byte(val))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -4,9 +4,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
ds "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/datastore.go"
|
ds "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/datastore.go"
|
||||||
bs "github.com/jbenet/go-ipfs/blockservice"
|
|
||||||
ci "github.com/jbenet/go-ipfs/crypto"
|
ci "github.com/jbenet/go-ipfs/crypto"
|
||||||
mdag "github.com/jbenet/go-ipfs/merkledag"
|
|
||||||
"github.com/jbenet/go-ipfs/peer"
|
"github.com/jbenet/go-ipfs/peer"
|
||||||
mock "github.com/jbenet/go-ipfs/routing/mock"
|
mock "github.com/jbenet/go-ipfs/routing/mock"
|
||||||
u "github.com/jbenet/go-ipfs/util"
|
u "github.com/jbenet/go-ipfs/util"
|
||||||
@ -19,26 +17,15 @@ func TestRoutingResolve(t *testing.T) {
|
|||||||
lds := ds.NewMapDatastore()
|
lds := ds.NewMapDatastore()
|
||||||
d := mock.NewMockRouter(local, lds)
|
d := mock.NewMockRouter(local, lds)
|
||||||
|
|
||||||
bserv, err := bs.NewBlockService(lds, nil)
|
resolver := NewRoutingResolver(d)
|
||||||
if err != nil {
|
publisher := NewRoutingPublisher(d)
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
dag := &mdag.DAGService{Blocks: bserv}
|
|
||||||
|
|
||||||
resolve := NewMasterResolver(d, dag)
|
|
||||||
|
|
||||||
pub := ipnsPublisher{
|
|
||||||
dag: dag,
|
|
||||||
routing: d,
|
|
||||||
}
|
|
||||||
|
|
||||||
privk, pubk, err := ci.GenerateKeyPair(ci.RSA, 512)
|
privk, pubk, err := ci.GenerateKeyPair(ci.RSA, 512)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = pub.Publish(privk, "Hello")
|
err = publisher.Publish(privk, "Hello")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
@ -49,7 +36,7 @@ func TestRoutingResolve(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pkhash := u.Hash(pubkb)
|
pkhash := u.Hash(pubkb)
|
||||||
res, err := resolve.Resolve(u.Key(pkhash).Pretty())
|
res, err := resolver.Resolve(u.Key(pkhash).Pretty())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -1,42 +0,0 @@
|
|||||||
package namesys
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
|
|
||||||
mdag "github.com/jbenet/go-ipfs/merkledag"
|
|
||||||
"github.com/jbenet/go-ipfs/routing"
|
|
||||||
)
|
|
||||||
|
|
||||||
var ErrCouldntResolve = errors.New("could not resolve name.")
|
|
||||||
|
|
||||||
type masterResolver struct {
|
|
||||||
res []Resolver
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewMasterResolver(r routing.IpfsRouting, dag *mdag.DAGService) Resolver {
|
|
||||||
mr := new(masterResolver)
|
|
||||||
mr.res = []Resolver{
|
|
||||||
new(DNSResolver),
|
|
||||||
new(ProquintResolver),
|
|
||||||
NewRoutingResolver(r, dag),
|
|
||||||
}
|
|
||||||
return mr
|
|
||||||
}
|
|
||||||
|
|
||||||
func (mr *masterResolver) Resolve(name string) (string, error) {
|
|
||||||
for _, r := range mr.res {
|
|
||||||
if r.Matches(name) {
|
|
||||||
return r.Resolve(name)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return "", ErrCouldntResolve
|
|
||||||
}
|
|
||||||
|
|
||||||
func (mr *masterResolver) Matches(name string) bool {
|
|
||||||
for _, r := range mr.res {
|
|
||||||
if r.Matches(name) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
@ -8,32 +8,32 @@ import (
|
|||||||
|
|
||||||
mh "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multihash"
|
mh "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multihash"
|
||||||
ci "github.com/jbenet/go-ipfs/crypto"
|
ci "github.com/jbenet/go-ipfs/crypto"
|
||||||
mdag "github.com/jbenet/go-ipfs/merkledag"
|
routing "github.com/jbenet/go-ipfs/routing"
|
||||||
"github.com/jbenet/go-ipfs/routing"
|
|
||||||
u "github.com/jbenet/go-ipfs/util"
|
u "github.com/jbenet/go-ipfs/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
var log = u.Logger("namesys")
|
var log = u.Logger("namesys")
|
||||||
|
|
||||||
// RoutingResolver implements NSResolver for the main IPFS SFS-like naming
|
// routingResolver implements NSResolver for the main IPFS SFS-like naming
|
||||||
type RoutingResolver struct {
|
type routingResolver struct {
|
||||||
routing routing.IpfsRouting
|
routing routing.IpfsRouting
|
||||||
dag *mdag.DAGService
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewRoutingResolver(route routing.IpfsRouting, dagservice *mdag.DAGService) *RoutingResolver {
|
// NewRoutingResolver constructs a name resolver using the IPFS Routing system
|
||||||
return &RoutingResolver{
|
// to implement SFS-like naming on top.
|
||||||
routing: route,
|
func NewRoutingResolver(route routing.IpfsRouting) Resolver {
|
||||||
dag: dagservice,
|
return &routingResolver{routing: route}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *RoutingResolver) Matches(name string) bool {
|
// CanResolve implements Resolver. Checks whether name is a b58 encoded string.
|
||||||
|
func (r *routingResolver) CanResolve(name string) bool {
|
||||||
_, err := mh.FromB58String(name)
|
_, err := mh.FromB58String(name)
|
||||||
return err == nil
|
return err == nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *RoutingResolver) Resolve(name string) (string, error) {
|
// Resolve implements Resolver. Uses the IPFS routing system to resolve SFS-like
|
||||||
|
// names.
|
||||||
|
func (r *routingResolver) Resolve(name string) (string, error) {
|
||||||
log.Debug("RoutingResolve: '%s'", name)
|
log.Debug("RoutingResolve: '%s'", name)
|
||||||
ctx := context.TODO()
|
ctx := context.TODO()
|
||||||
hash, err := mh.FromB58String(name)
|
hash, err := mh.FromB58String(name)
|
||||||
|
Reference in New Issue
Block a user