ipfs / kubo

An IPFS implementation in Go
https://docs.ipfs.tech/how-to/command-line-quick-start/
Other
16.03k stars 3k forks source link

Namespace description #36

Closed jbenet closed 9 years ago

jbenet commented 10 years ago

@whyrusleeping here's a rough spec of ipns / the namespace:

type NSResolver interface {
  Resolve(name string) (string, error)
}
// RoutingName is the de-serialized name structure that is stored (serialized) 
// in the routing system. Basically, a hash + a digital signature. (serialization can be
// protobuf, or a simple binary format)
type RoutingName {
  Hash        u.Key
  Signature []byte
}

// RoutingResolver implements NSResolver for the main IPFS SFS-like naming
type RoutingResolver {
  routing routing.IpfsRouting
  dag      mdag.DAGService
}

func (r *RoutingResolver) Resolve (name string) (string, error) {

  // name should be a multihash. if it isn't, error out here.

  // use the routing system to get the name.
  // /ipns/<name>
  key := u.Key(name) // or whatever
  val, err := r.routing.Get(key)
  if err != nil {
    return "", err
  }

  // name should be a public key retrievable from ipfs
  // /ipfs/<name>
  node, err :=  r.dag.Get(key)
  if err != nil {
    return "", err
  }

  // get PublicKey from node.Data
  pk := PublicKey(node.Data)

  // check sig with pk
  if !pk.Verify(val.Hash, val.Signature) {
    return "", errors.New("Invalid value. Not signed by PrivateKey corresponding to %v", pk)
  }

  // ok sig checks out. this is a valid name.
  return string(val.Hash)
}
// NameSystem is the object implementing IPNS. It adheres to the `NSResolver` 
// interface, and uses child `NSResolvers`, depending on what the name looks like.
// 
// hashes -> routing, domains -> dns, proquints -> proquint
// we can add `.bit` and `.onion` resolution here in the future
// 
// in non-routing cases, the values returned are hashes to lookup in the routing system.
// (most of the time, if not ALL of the time. still deciding on this). meaning that 
// a dns record: `DNS TXT ipns=<some-hash>` needs to then resolve `<some-hash>`
// via the routing system.
type NameSystem struct {
  routing   RoutingResolver
  dns        DNSResovler
  proquint ProquintResolver
}
whyrusleeping commented 10 years ago

Wont a DHT Get and a DAG Get return the same data?

jbenet commented 10 years ago

Addendum to above


// rename NSResolver -> Resolver

// previously RoutingName
type SignedLink {
  Hash      u.Key
  Signature []byte
}

type Publisher interface {
  Publish(*PubKey, *SignedLink) error
}

// this could be the same object as IpfsResolver actually...
type IpfsPublisher struct { ... }

func (p *IpfsPublisher) Publish(p *PubKey, l *SignedLink) error {
  // verify l.Hash exists and is reachable via IPFS
  ... p.dag.Get(l.Hash)

  // key is the ipns hash of PubKey (e.g. /ipns/<hash of pubkey>)
  key := NameKey(p.Hash())
  p.routing.PutValue(key, serialized(l))
}

func NameKey(hash u.Key) u.Key {
  // return hash of /ipns/<hash> (or whatever we go with)
}

type NameSystem interface {
   Resolver
   Publisher
}

type IPNS struct {
  *IpfsResolver
  *IpfsPublisher
}