Skip to content

Commit

Permalink
bootstrap: use ipfsaddr for boostrap peers ⚠️
Browse files Browse the repository at this point in the history
⚠️ this commit makes your current configs unusable, as the
default bootstrap peers. You may need to edit your config.

Go from:

```js
Bootstrap: [
  {
    "Address": "/ip4/104.131.131.82/tcp/4001",
    "PeerID": "QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuJ"
  }
]
```

To:
```js
Bootstrap: [
  "/ip4/104.131.131.82/tcp/4001/ipfs/QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuJ"
]
```
  • Loading branch information
jbenet committed Jan 23, 2015
1 parent 9b367e8 commit 99c991c
Show file tree
Hide file tree
Showing 9 changed files with 101 additions and 85 deletions.
2 changes: 1 addition & 1 deletion cmd/ipfs/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ func initConfig(nBitsForKeypair int) (*config.Config, error) {
API: "/ip4/127.0.0.1/tcp/5001",
},

Bootstrap: bootstrapPeers,
Bootstrap: config.BootstrapPeerStrings(bootstrapPeers),
Datastore: *ds,
Logs: *logConfig,
Identity: identity,
Expand Down
33 changes: 13 additions & 20 deletions core/bootstrap.go
Original file line number Diff line number Diff line change
Expand Up @@ -213,32 +213,25 @@ func bootstrapConnect(ctx context.Context,
return nil
}

func toPeerInfos(bpeers []config.BootstrapPeer) ([]peer.PeerInfo, error) {
func toPeerInfos(bpeers []config.BootstrapPeer) []peer.PeerInfo {
var peers []peer.PeerInfo
for _, bootstrap := range bpeers {
p, err := toPeerInfo(bootstrap)
if err != nil {
return nil, err
}
peers = append(peers, p)
peers = append(peers, toPeerInfo(bootstrap))
}
return peers, nil
return peers
}

func toPeerInfo(bootstrap config.BootstrapPeer) (p peer.PeerInfo, err error) {
id, err := peer.IDB58Decode(bootstrap.PeerID)
if err != nil {
return
}
maddr, err := ma.NewMultiaddr(bootstrap.Address)
if err != nil {
return
}
p = peer.PeerInfo{
ID: id,
Addrs: []ma.Multiaddr{maddr},
func toPeerInfo(bp config.BootstrapPeer) peer.PeerInfo {
// for now, we drop the "ipfs addr" part of the multiaddr. the rest
// of the codebase currently uses addresses without the peerid part.
m := bp.Multiaddr()
s := ma.Split(m)
m = ma.Join(s[len(s)-1])

return peer.PeerInfo{
ID: bp.ID(),
Addrs: []ma.Multiaddr{m},
}
return
}

func randomSubsetOfPeers(in []peer.PeerInfo, max int) []peer.PeerInfo {
Expand Down
45 changes: 29 additions & 16 deletions core/commands/bootstrap.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package commands
import (
"bytes"
"io"
"sort"

cmds "github.com/jbenet/go-ipfs/commands"
repo "github.com/jbenet/go-ipfs/repo"
Expand All @@ -19,11 +20,11 @@ import (
// Note: this is here -- and not inside cmd/ipfs/init.go -- because of an
// import dependency issue. TODO: move this into a config/default/ package.
var DefaultBootstrapAddresses = []string{
"/ip4/104.131.131.82/tcp/4001/QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuJ", // mars.i.ipfs.io
"/ip4/104.236.176.52/tcp/4001/QmSoLnSGccFuZQJzRadHn95W2CrSFmZuTdDWP8HXaHca9z", // neptune (to be neptune.i.ipfs.io)
"/ip4/104.236.179.241/tcp/4001/QmSoLpPVmHKQ4XTPdz8tjDFgdeRFkpV8JgYq8JVJ69RrZm", // pluto (to be pluto.i.ipfs.io)
"/ip4/162.243.248.213/tcp/4001/QmSoLueR4xBeUbY9WZ9xGUUxunbKWcrNFTDAadQJmocnWm", // uranus (to be uranus.i.ipfs.io)
"/ip4/128.199.219.111/tcp/4001/QmSoLSafTMBsPKadTEgaXctDQVcqN88CNLHXMkTNwMKPnu", // saturn (to be saturn.i.ipfs.io)
"/ip4/104.131.131.82/tcp/4001/ipfs/QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuJ", // mars.i.ipfs.io
"/ip4/104.236.176.52/tcp/4001/ipfs/QmSoLnSGccFuZQJzRadHn95W2CrSFmZuTdDWP8HXaHca9z", // neptune (to be neptune.i.ipfs.io)
"/ip4/104.236.179.241/tcp/4001/ipfs/QmSoLpPVmHKQ4XTPdz8tjDFgdeRFkpV8JgYq8JVJ69RrZm", // pluto (to be pluto.i.ipfs.io)
"/ip4/162.243.248.213/tcp/4001/ipfs/QmSoLueR4xBeUbY9WZ9xGUUxunbKWcrNFTDAadQJmocnWm", // uranus (to be uranus.i.ipfs.io)
"/ip4/128.199.219.111/tcp/4001/ipfs/QmSoLSafTMBsPKadTEgaXctDQVcqN88CNLHXMkTNwMKPnu", // saturn (to be saturn.i.ipfs.io)
}

type BootstrapOutput struct {
Expand Down Expand Up @@ -196,7 +197,11 @@ var bootstrapListCmd = &cmds.Command{
return nil, err
}

peers := cfg.Bootstrap
peers, err := cfg.BootstrapPeers()
if err != nil {
return nil, err
}

return &BootstrapOutput{peers}, nil
},
Type: BootstrapOutput{},
Expand All @@ -218,9 +223,10 @@ func bootstrapMarshaler(res cmds.Response) (io.Reader, error) {

func bootstrapWritePeers(w io.Writer, prefix string, peers []config.BootstrapPeer) error {

for _, peer := range peers {
s := prefix + peer.Address + "/" + peer.PeerID + "\n"
_, err := w.Write([]byte(s))
pstrs := config.BootstrapPeerStrings(peers)
sort.Stable(sort.StringSlice(pstrs))
for _, peer := range pstrs {
_, err := w.Write([]byte(peer + "\n"))
if err != nil {
return err
}
Expand All @@ -234,14 +240,14 @@ func bootstrapAdd(r repo.Repo, cfg *config.Config, peers []config.BootstrapPeer)
for _, peer := range peers {
duplicate := false
for _, peer2 := range cfg.Bootstrap {
if peer.Address == peer2.Address && peer.PeerID == peer2.PeerID {
if peer.Equal(peer2) {
duplicate = true
break
}
}

if !duplicate {
cfg.Bootstrap = append(cfg.Bootstrap, peer)
cfg.Bootstrap = append(cfg.Bootstrap, peer.String())
added = append(added, peer)
}
}
Expand All @@ -257,10 +263,15 @@ func bootstrapRemove(r repo.Repo, cfg *config.Config, toRemove []config.Bootstra
removed := make([]config.BootstrapPeer, 0, len(toRemove))
keep := make([]config.BootstrapPeer, 0, len(cfg.Bootstrap))

for _, peer := range cfg.Bootstrap {
peers, err := cfg.BootstrapPeers()
if err != nil {
return nil, err
}

for _, peer := range peers {
found := false
for _, peer2 := range toRemove {
if peer.Address == peer2.Address && peer.PeerID == peer2.PeerID {
if peer.Equal(peer2) {
found = true
removed = append(removed, peer)
break
Expand All @@ -271,7 +282,7 @@ func bootstrapRemove(r repo.Repo, cfg *config.Config, toRemove []config.Bootstra
keep = append(keep, peer)
}
}
cfg.Bootstrap = keep
cfg.SetBootstrapPeers(keep)

if err := r.SetConfig(cfg); err != nil {
return nil, err
Expand All @@ -281,8 +292,10 @@ func bootstrapRemove(r repo.Repo, cfg *config.Config, toRemove []config.Bootstra
}

func bootstrapRemoveAll(r repo.Repo, cfg *config.Config) ([]config.BootstrapPeer, error) {
removed := make([]config.BootstrapPeer, len(cfg.Bootstrap))
copy(removed, cfg.Bootstrap)
removed, err := cfg.BootstrapPeers()
if err != nil {
return nil, err
}

cfg.Bootstrap = nil
if err := r.SetConfig(cfg); err != nil {
Expand Down
13 changes: 10 additions & 3 deletions core/core.go
Original file line number Diff line number Diff line change
Expand Up @@ -305,10 +305,9 @@ func (n *IpfsNode) Bootstrap(cfg BootstrapConfig) error {
// freshest bootstrap peers from config. this responds to live changes.
if cfg.BootstrapPeers == nil {
cfg.BootstrapPeers = func() []peer.PeerInfo {
bpeers := n.Repo.Config().Bootstrap
ps, err := toPeerInfos(bpeers)
ps, err := n.loadBootstrapPeers()
if err != nil {
log.Error("failed to parse bootstrap peers from config: %s", bpeers)
log.Error("failed to parse bootstrap peers from config: %s", n.Repo.Config().Bootstrap)
return nil
}
return ps
Expand Down Expand Up @@ -357,6 +356,14 @@ func (n *IpfsNode) loadPrivateKey() error {
return nil
}

func (n *IpfsNode) loadBootstrapPeers() ([]peer.PeerInfo, error) {
parsed, err := n.Repo.Config().BootstrapPeers()
if err != nil {
return nil, err
}
return toPeerInfos(parsed), nil
}

// SetupOfflineRouting loads the local nodes private key and
// uses it to instantiate a routing system in offline mode.
// This is primarily used for offline ipns modifications.
Expand Down
55 changes: 21 additions & 34 deletions repo/config/bootstrap_peers.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,51 +2,30 @@ package config

import (
"errors"
"strings"

ma "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr"
mh "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multihash"
iaddr "github.com/jbenet/go-ipfs/util/ipfsaddr"
)

// BootstrapPeer is a peer used to bootstrap the network.
type BootstrapPeer struct {
Address string
PeerID string // until multiaddr supports ipfs, use another field.
type BootstrapPeer iaddr.IPFSAddr

// ErrInvalidPeerAddr signals an address is not a valid peer address.
var ErrInvalidPeerAddr = errors.New("invalid peer address")

func (c *Config) BootstrapPeers() ([]BootstrapPeer, error) {
return ParseBootstrapPeers(c.Bootstrap)
}

func (bp *BootstrapPeer) String() string {
return bp.Address + "/" + bp.PeerID
func (c *Config) SetBootstrapPeers(bps []BootstrapPeer) {
c.Bootstrap = BootstrapPeerStrings(bps)
}

func ParseBootstrapPeer(addr string) (BootstrapPeer, error) {
// to be replaced with just multiaddr parsing, once ptp is a multiaddr protocol
idx := strings.LastIndex(addr, "/")
if idx == -1 {
return BootstrapPeer{}, errors.New("invalid address")
}
addrS := addr[:idx]
peeridS := addr[idx+1:]

// make sure addrS parses as a multiaddr.
if len(addrS) > 0 {
maddr, err := ma.NewMultiaddr(addrS)
if err != nil {
return BootstrapPeer{}, err
}

addrS = maddr.String()
}

// make sure idS parses as a peer.ID
_, err := mh.FromB58String(peeridS)
ia, err := iaddr.ParseString(addr)
if err != nil {
return BootstrapPeer{}, err
return nil, err
}

return BootstrapPeer{
Address: addrS,
PeerID: peeridS,
}, nil
return BootstrapPeer(ia), err
}

func ParseBootstrapPeers(addrs []string) ([]BootstrapPeer, error) {
Expand All @@ -60,3 +39,11 @@ func ParseBootstrapPeers(addrs []string) ([]BootstrapPeer, error) {
}
return peers, nil
}

func BootstrapPeerStrings(bps []BootstrapPeer) []string {
bpss := make([]string, len(bps))
for i, p := range bps {
bpss[i] = p.String()
}
return bpss
}
16 changes: 8 additions & 8 deletions repo/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,14 @@ var log = u.Logger("config")

// Config is used to load IPFS config files.
type Config struct {
Identity Identity // local node's peer identity
Datastore Datastore // local node's storage
Addresses Addresses // local node's addresses
Mounts Mounts // local node's mount points
Version Version // local node's version management
Bootstrap []BootstrapPeer // local nodes's bootstrap peers
Tour Tour // local node's tour position
Logs Logs // local node's event log configuration
Identity Identity // local node's peer identity
Datastore Datastore // local node's storage
Addresses Addresses // local node's addresses
Mounts Mounts // local node's mount points
Version Version // local node's version management
Bootstrap []string // local nodes's bootstrap peer addresses
Tour Tour // local node's tour position
Logs Logs // local node's event log configuration
}

const (
Expand Down
2 changes: 1 addition & 1 deletion test/3nodetest/client/run.sh
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
ipfs bootstrap add /ip4/$BOOTSTRAP_PORT_4011_TCP_ADDR/tcp/$BOOTSTRAP_PORT_4011_TCP_PORT/QmNXuBh8HFsWq68Fid8dMbGNQTh7eG6hV9rr1fQyfmfomE
ipfs bootstrap add /ip4/$BOOTSTRAP_PORT_4011_TCP_ADDR/tcp/$BOOTSTRAP_PORT_4011_TCP_PORT/ipfs/QmNXuBh8HFsWq68Fid8dMbGNQTh7eG6hV9rr1fQyfmfomE

This comment has been minimized.

Copy link
@jbenet

jbenet Jan 23, 2015

Author Member

@briantigerchow isn't this enough? do i have to change anything else?



echo "3nodetest> starting client daemon"
Expand Down
4 changes: 2 additions & 2 deletions test/3nodetest/server/run.sh
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
# must be connected to bootstrap node
ipfs bootstrap add /ip4/$BOOTSTRAP_PORT_4011_TCP_ADDR/tcp/$BOOTSTRAP_PORT_4011_TCP_PORT/QmNXuBh8HFsWq68Fid8dMbGNQTh7eG6hV9rr1fQyfmfomE
ipfs bootstrap add /ip4/$BOOTSTRAP_PORT_4011_TCP_ADDR/tcp/$BOOTSTRAP_PORT_4011_TCP_PORT/ipfs/QmNXuBh8HFsWq68Fid8dMbGNQTh7eG6hV9rr1fQyfmfomE

# wait for daemon to start/bootstrap
# alternatively use ipfs swarm connect
echo "3nodetest> starting server daemon"
ipfs daemon &
sleep 3
# TODO instead of bootrapping: ipfs swarm connect /ip4/$BOOTSTRAP_PORT_4011_TCP_ADDR/tcp/$BOOTSTRAP_PORT_4011_TCP_PORT/QmNXuBh8HFsWq68Fid8dMbGNQTh7eG6hV9rr1fQyfmfomE
# TODO instead of bootrapping: ipfs swarm connect /ip4/$BOOTSTRAP_PORT_4011_TCP_ADDR/tcp/$BOOTSTRAP_PORT_4011_TCP_PORT/ipfs/QmNXuBh8HFsWq68Fid8dMbGNQTh7eG6hV9rr1fQyfmfomE

# must mount this volume from data container
ipfs add -q /data/filetiny > tmptiny
Expand Down
16 changes: 16 additions & 0 deletions util/ipfsaddr/ipfsaddr.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ var ErrInvalidAddr = errors.New("invalid ipfs address")
type IPFSAddr interface {
ID() peer.ID
Multiaddr() ma.Multiaddr
String() string
Equal(b interface{}) bool
}

type ipfsAddr struct {
Expand All @@ -30,6 +32,20 @@ func (a ipfsAddr) Multiaddr() ma.Multiaddr {
return a.ma
}

func (a ipfsAddr) String() string {
return a.ma.String()
}

func (a ipfsAddr) Equal(b interface{}) bool {
if ib, ok := b.(IPFSAddr); ok {
return a.Multiaddr().Equal(ib.Multiaddr())
}
if mb, ok := b.(ma.Multiaddr); ok {
return a.Multiaddr().Equal(mb)
}
return false
}

// ParseString parses a string representation of an address into an IPFSAddr
func ParseString(str string) (a IPFSAddr, err error) {
if str == "" {
Expand Down

0 comments on commit 99c991c

Please sign in to comment.