Commit 2944360f authored by Juan Batiz-Benet's avatar Juan Batiz-Benet

New NameSystem interface

    type NameSystem interface {
      Resolver
      Publisher
    }

should say it all.

cc @whyrusleeping
parent cf6efc7a
......@@ -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
......
......@@ -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"
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"
isd "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-is-domain"
)
// 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)
}
......
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
}
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)
}
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)
}
......
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)
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment