Skip to content
This repository has been archived by the owner on Jun 20, 2023. It is now read-only.

Improve go-namesys documentation #1

Merged
merged 4 commits into from
Feb 19, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 11 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,20 @@
# go-namesys

[![](https://img.shields.io/badge/made%20by-Protocol%20Labs-blue.svg?style=flat-square)](http://ipn.io)
[![](https://img.shields.io/badge/made%20by-Protocol%20Labs-blue.svg?style=flat-square)](http://protocol.ai)
[![](https://img.shields.io/badge/project-IPFS-blue.svg?style=flat-square)](http://ipfs.io/)
[![standard-readme compliant](https://img.shields.io/badge/standard--readme-OK-green.svg?style=flat-square)](https://github.com/RichardLitt/standard-readme)
[![Go Reference](https://pkg.go.dev/badge/github.com/ipfs/go-namesys.svg)](https://pkg.go.dev/github.com/ipfs/go-namesys)
[![Travis CI](https://travis-ci.com/ipfs/go-namesys.svg?branch=master)](https://travis-ci.com/ipfs/go-namesys)


> go-namesys provides publish and resolution support for the /ipns/ namespace

go-namesys allows to publish and resolve IPNS records or dnslink domain names.
Package namesys defines `Resolver` and `Publisher` interfaces for IPNS paths, that is, paths in the form of `/ipns/<name_to_be_resolved>`. A "resolved" IPNS path becomes an `/ipfs/<cid>` path.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SGTM.

Note: we probably want to allow access to partial resolutions (or returning the full resolution path), but that's later 😄


Traditionally, these paths would be in the form of `/ipns/peer_id`, which references an IPNS record in a distributed `ValueStore` (usually the IPFS DHT).

Additionally, the /ipns/ namespace can also be used with domain names that use DNSLink (/ipns/my.domain.example, see https://dnslink.io) and proquint strings.

The package provides implementations for all three resolvers.

## Table of Contents

Expand All @@ -29,6 +35,8 @@ go-namesys allows to publish and resolve IPNS records or dnslink domain names.
import "github.com/ipfs/go-namesys"
```

See the [Pkg.go.dev documentation](https://pkg.go.dev/github.com/ipfs/go-namesys)

## Contribute

PRs accepted.
Expand Down
5 changes: 3 additions & 2 deletions dns.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
const ethTLD = "eth"
const linkTLD = "link"

// LookupTXTFunc is a generic type for a function that lookups TXT record values.
type LookupTXTFunc func(name string) (txt []string, err error)

// DNSResolver implements a Resolver on DNS domains
Expand Down Expand Up @@ -146,10 +147,10 @@ func parseEntry(txt string) (path.Path, error) {
return p, nil
}

return tryParseDnsLink(txt)
return tryParseDNSLink(txt)
}

func tryParseDnsLink(txt string) (path.Path, error) {
func tryParseDNSLink(txt string) (path.Path, error) {
parts := strings.SplitN(txt, "=", 2)
if len(parts) == 2 && parts[0] == "dnslink" {
return path.ParsePath(parts[1])
Expand Down
2 changes: 1 addition & 1 deletion interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ var ErrResolveRecursion = errors.New(
// 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.
// NameSystem 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.
Expand Down
13 changes: 13 additions & 0 deletions namesys.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,16 @@
// Package namesys defines Resolver and Publisher interfaces for IPNS paths,
// that is, IPFS paths in the form of /ipns/<name_to_be_resolved>. A "resolved"
// IPNS path becomes an /ipfs/<cid> path.
//
// Traditionally, these paths would be in the form of /ipns/peer_id, which
// references an IPNS record in a distributed ValueStore (usually the IPFS
// DHT).
//
// Additionally, the /ipns/ namespace can also be used with domain names that
// use DNSLink (/ipns/my.domain.example, see https://dnslink.io) and proquint
// strings.
//
// The package provides implementations for all three resolvers.
package namesys

import (
Expand Down
2 changes: 2 additions & 0 deletions proquint.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import (
opts "github.com/ipfs/interface-go-ipfs-core/options/namesys"
)

// ProquintResolver implements the Resolver interface for proquint identifiers
// (see http://arxiv.org/html/0901.4016).
type ProquintResolver struct{}

// Resolve implements Resolver.
Expand Down
14 changes: 13 additions & 1 deletion publisher.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ import (

const ipnsPrefix = "/ipns/"

// DefaultRecordEOL specifies the time that the network will cache IPNS
// records after being publihsed. Records should be re-published before this
// interval expires.
const DefaultRecordEOL = 24 * time.Hour

// IpnsPublisher is capable of publishing and resolving names to the IPFS
Expand Down Expand Up @@ -49,11 +52,13 @@ func (p *IpnsPublisher) Publish(ctx context.Context, k ci.PrivKey, value path.Pa
return p.PublishWithEOL(ctx, k, value, time.Now().Add(DefaultRecordEOL))
}

// IpnsDsKey returns a datastore key given an IPNS identifier (peer
// ID). Defines the storage key for IPNS records in the local datastore.
func IpnsDsKey(id peer.ID) ds.Key {
return ds.NewKey("/ipns/" + base32.RawStdEncoding.EncodeToString([]byte(id)))
}

// PublishedNames returns the latest IPNS records published by this node and
// ListPublished returns the latest IPNS records published by this node and
// their expiration times.
//
// This method will not search the routing system for records published by other
Expand Down Expand Up @@ -212,6 +217,9 @@ func checkCtxTTL(ctx context.Context) (time.Duration, bool) {
return d, ok
}

// PutRecordToRouting publishes the given entry using the provided ValueStore,
// keyed on the ID associated with the provided public key. The public key is
// also made available to the routing system so that entries can be verified.
func PutRecordToRouting(ctx context.Context, r routing.ValueStore, k ci.PubKey, entry *pb.IpnsEntry) error {
ctx, cancel := context.WithCancel(ctx)
defer cancel()
Expand Down Expand Up @@ -260,6 +268,8 @@ func waitOnErrChan(ctx context.Context, errs chan error) error {
}
}

// PublishPublicKey stores the given public key in the ValueStore with the
// given key.
func PublishPublicKey(ctx context.Context, r routing.ValueStore, k string, pubk ci.PubKey) error {
log.Debugf("Storing pubkey at: %s", k)
pkbytes, err := pubk.Bytes()
Expand All @@ -271,6 +281,8 @@ func PublishPublicKey(ctx context.Context, r routing.ValueStore, k string, pubk
return r.PutValue(ctx, k, pkbytes)
}

// PublishEntry stores the given IpnsEntry in the ValueStore with the given
// ipnskey.
func PublishEntry(ctx context.Context, r routing.ValueStore, ipnskey string, rec *pb.IpnsEntry) error {
data, err := proto.Marshal(rec)
if err != nil {
Expand Down
6 changes: 6 additions & 0 deletions republisher/repub.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
// Package republisher provides a utility to automatically re-publish IPNS
// records related to the keys in a Keystore.
package republisher

import (
Expand Down Expand Up @@ -36,6 +38,8 @@ var FailureRetryInterval = time.Minute * 5
// DefaultRecordLifetime is the default lifetime for IPNS records
const DefaultRecordLifetime = time.Hour * 24

// Republisher facilitates the regular publishing of all the IPNS records
// associated to keys in a Keystore.
type Republisher struct {
ns namesys.Publisher
ds ds.Datastore
Expand All @@ -60,6 +64,8 @@ func NewRepublisher(ns namesys.Publisher, ds ds.Datastore, self ic.PrivKey, ks k
}
}

// Run starts the republisher facility. It can be stopped by stopping the
// provided proc.
func (rp *Republisher) Run(proc goprocess.Process) {
timer := time.NewTimer(InitialRebroadcastDelay)
defer timer.Stop()
Expand Down
7 changes: 3 additions & 4 deletions resolve_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,13 @@ import (
mockrouting "github.com/ipfs/go-ipfs-routing/mock"
ipns "github.com/ipfs/go-ipns"
path "github.com/ipfs/go-path"
testutil "github.com/libp2p/go-libp2p-testing/net"
tnet "github.com/libp2p/go-libp2p-testing/net"
)

func TestRoutingResolve(t *testing.T) {
dstore := dssync.MutexWrap(ds.NewMapDatastore())
serv := mockrouting.NewServer()
id := testutil.RandIdentityOrFatal(t)
id := tnet.RandIdentityOrFatal(t)
d := serv.ClientWithDatastore(context.Background(), id, dstore)

resolver := NewIpnsResolver(d)
Expand All @@ -44,7 +43,7 @@ func TestRoutingResolve(t *testing.T) {

func TestPrexistingExpiredRecord(t *testing.T) {
dstore := dssync.MutexWrap(ds.NewMapDatastore())
d := mockrouting.NewServer().ClientWithDatastore(context.Background(), testutil.RandIdentityOrFatal(t), dstore)
d := mockrouting.NewServer().ClientWithDatastore(context.Background(), tnet.RandIdentityOrFatal(t), dstore)

resolver := NewIpnsResolver(d)
publisher := NewIpnsPublisher(d, dstore)
Expand Down Expand Up @@ -78,7 +77,7 @@ func TestPrexistingExpiredRecord(t *testing.T) {

func TestPrexistingRecord(t *testing.T) {
dstore := dssync.MutexWrap(ds.NewMapDatastore())
d := mockrouting.NewServer().ClientWithDatastore(context.Background(), testutil.RandIdentityOrFatal(t), dstore)
d := mockrouting.NewServer().ClientWithDatastore(context.Background(), tnet.RandIdentityOrFatal(t), dstore)

resolver := NewIpnsResolver(d)
publisher := NewIpnsPublisher(d, dstore)
Expand Down