mirror of
https://github.com/ipfs/kubo.git
synced 2025-09-10 05:52: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
|
||||
|
||||
pub := nsys.NewPublisher(n.DAG, n.Routing)
|
||||
pub := nsys.NewRoutingPublisher(n.Routing)
|
||||
err := pub.Publish(k, args[0])
|
||||
if err != nil {
|
||||
return err
|
||||
|
11
core/core.go
11
core/core.go
@ -63,10 +63,7 @@ type IpfsNode struct {
|
||||
Resolver *path.Resolver
|
||||
|
||||
// the name system, resolves paths to hashes
|
||||
Namesys namesys.Resolver
|
||||
|
||||
// the routing publisher
|
||||
Publisher namesys.Publisher
|
||||
Namesys namesys.NameSystem
|
||||
}
|
||||
|
||||
// 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}
|
||||
resolve := namesys.NewMasterResolver(route, dag)
|
||||
publisher := namesys.NewPublisher(dag, route)
|
||||
ns := namesys.NewNameSystem(route)
|
||||
|
||||
success = true
|
||||
return &IpfsNode{
|
||||
@ -162,8 +158,7 @@ func NewIpfsNode(cfg *config.Config, online bool) (*IpfsNode, error) {
|
||||
Exchange: exchangeSession,
|
||||
Identity: local,
|
||||
Routing: route,
|
||||
Namesys: resolve,
|
||||
Publisher: publisher,
|
||||
Namesys: ns,
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
@ -43,10 +43,7 @@ func NewMockNode() (*IpfsNode, error) {
|
||||
nd.DAG = &mdag.DAGService{bserv}
|
||||
|
||||
// Namespace resolver
|
||||
nd.Namesys = nsys.NewMasterResolver(dht, nd.DAG)
|
||||
|
||||
// Publisher
|
||||
nd.Publisher = nsys.NewPublisher(nd.DAG, dht)
|
||||
nd.Namesys = nsys.NewNameSystem(dht)
|
||||
|
||||
// Path resolver
|
||||
nd.Resolver = &path.Resolver{nd.DAG}
|
||||
|
@ -397,7 +397,7 @@ func (n *Node) republishRoot() error {
|
||||
}
|
||||
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 {
|
||||
log.Error("ipns: Publish Failed: %s", err)
|
||||
return err
|
||||
|
@ -4,9 +4,10 @@ import (
|
||||
"net"
|
||||
|
||||
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"
|
||||
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
|
||||
@ -15,8 +16,8 @@ type DNSResolver struct {
|
||||
// cache would need a timeout
|
||||
}
|
||||
|
||||
// Matches implements Resolver
|
||||
func (r *DNSResolver) Matches(name string) bool {
|
||||
// CanResolve implements Resolver
|
||||
func (r *DNSResolver) CanResolve(name string) bool {
|
||||
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{}
|
||||
|
||||
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)
|
||||
return err == nil && ok
|
||||
}
|
||||
|
||||
// Resolve implements Resolver. Decodes the proquint string.
|
||||
func (r *ProquintResolver) Resolve(name string) (string, error) {
|
||||
ok := r.Matches(name)
|
||||
ok := r.CanResolve(name)
|
||||
if !ok {
|
||||
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"
|
||||
|
||||
ci "github.com/jbenet/go-ipfs/crypto"
|
||||
mdag "github.com/jbenet/go-ipfs/merkledag"
|
||||
routing "github.com/jbenet/go-ipfs/routing"
|
||||
u "github.com/jbenet/go-ipfs/util"
|
||||
)
|
||||
|
||||
// ipnsPublisher is capable of publishing and resolving names to the IPFS
|
||||
// routing system.
|
||||
type ipnsPublisher struct {
|
||||
dag *mdag.DAGService
|
||||
routing routing.IpfsRouting
|
||||
}
|
||||
|
||||
type Publisher interface {
|
||||
Publish(ci.PrivKey, string) error
|
||||
// NewRoutingPublisher constructs a publisher for the IPFS Routing name system.
|
||||
func NewRoutingPublisher(route routing.IpfsRouting) Publisher {
|
||||
return &ipnsPublisher{routing: route}
|
||||
}
|
||||
|
||||
func NewPublisher(dag *mdag.DAGService, route routing.IpfsRouting) Publisher {
|
||||
return &ipnsPublisher{
|
||||
dag: dag,
|
||||
routing: route,
|
||||
}
|
||||
}
|
||||
|
||||
// Publish accepts a keypair and a value,
|
||||
// Publish implements Publisher. Accepts a keypair and a value,
|
||||
func (p *ipnsPublisher) Publish(k ci.PrivKey, value string) error {
|
||||
log.Debug("namesys: Publish %s", value)
|
||||
ctx := context.TODO()
|
||||
data, err := CreateEntryData(k, value)
|
||||
data, err := createRoutingEntryData(k, value)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -63,7 +57,7 @@ func (p *ipnsPublisher) Publish(k ci.PrivKey, value string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func CreateEntryData(pk ci.PrivKey, val string) ([]byte, error) {
|
||||
func createRoutingEntryData(pk ci.PrivKey, val string) ([]byte, error) {
|
||||
entry := new(IpnsEntry)
|
||||
sig, err := pk.Sign([]byte(val))
|
||||
if err != nil {
|
||||
|
@ -4,9 +4,7 @@ import (
|
||||
"testing"
|
||||
|
||||
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"
|
||||
mdag "github.com/jbenet/go-ipfs/merkledag"
|
||||
"github.com/jbenet/go-ipfs/peer"
|
||||
mock "github.com/jbenet/go-ipfs/routing/mock"
|
||||
u "github.com/jbenet/go-ipfs/util"
|
||||
@ -19,26 +17,15 @@ func TestRoutingResolve(t *testing.T) {
|
||||
lds := ds.NewMapDatastore()
|
||||
d := mock.NewMockRouter(local, lds)
|
||||
|
||||
bserv, err := bs.NewBlockService(lds, nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
dag := &mdag.DAGService{Blocks: bserv}
|
||||
|
||||
resolve := NewMasterResolver(d, dag)
|
||||
|
||||
pub := ipnsPublisher{
|
||||
dag: dag,
|
||||
routing: d,
|
||||
}
|
||||
resolver := NewRoutingResolver(d)
|
||||
publisher := NewRoutingPublisher(d)
|
||||
|
||||
privk, pubk, err := ci.GenerateKeyPair(ci.RSA, 512)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
err = pub.Publish(privk, "Hello")
|
||||
err = publisher.Publish(privk, "Hello")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@ -49,7 +36,7 @@ func TestRoutingResolve(t *testing.T) {
|
||||
}
|
||||
|
||||
pkhash := u.Hash(pubkb)
|
||||
res, err := resolve.Resolve(u.Key(pkhash).Pretty())
|
||||
res, err := resolver.Resolve(u.Key(pkhash).Pretty())
|
||||
if err != nil {
|
||||
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"
|
||||
ci "github.com/jbenet/go-ipfs/crypto"
|
||||
mdag "github.com/jbenet/go-ipfs/merkledag"
|
||||
"github.com/jbenet/go-ipfs/routing"
|
||||
routing "github.com/jbenet/go-ipfs/routing"
|
||||
u "github.com/jbenet/go-ipfs/util"
|
||||
)
|
||||
|
||||
var log = u.Logger("namesys")
|
||||
|
||||
// RoutingResolver implements NSResolver for the main IPFS SFS-like naming
|
||||
type RoutingResolver struct {
|
||||
// routingResolver implements NSResolver for the main IPFS SFS-like naming
|
||||
type routingResolver struct {
|
||||
routing routing.IpfsRouting
|
||||
dag *mdag.DAGService
|
||||
}
|
||||
|
||||
func NewRoutingResolver(route routing.IpfsRouting, dagservice *mdag.DAGService) *RoutingResolver {
|
||||
return &RoutingResolver{
|
||||
routing: route,
|
||||
dag: dagservice,
|
||||
}
|
||||
// NewRoutingResolver constructs a name resolver using the IPFS Routing system
|
||||
// to implement SFS-like naming on top.
|
||||
func NewRoutingResolver(route routing.IpfsRouting) Resolver {
|
||||
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)
|
||||
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)
|
||||
ctx := context.TODO()
|
||||
hash, err := mh.FromB58String(name)
|
||||
|
Reference in New Issue
Block a user