core.go 3.22 KB
Newer Older
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
1 2
package core

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
3
import (
4
	"encoding/base64"
5
	"errors"
Juan Batiz-Benet's avatar
go fmt  
Juan Batiz-Benet committed
6
	"fmt"
7

Juan Batiz-Benet's avatar
go fmt  
Juan Batiz-Benet committed
8
	ds "github.com/jbenet/datastore.go"
9
	b58 "github.com/jbenet/go-base58"
10
	"github.com/jbenet/go-ipfs/bitswap"
11
	bserv "github.com/jbenet/go-ipfs/blockservice"
Juan Batiz-Benet's avatar
go fmt  
Juan Batiz-Benet committed
12
	config "github.com/jbenet/go-ipfs/config"
13
	ci "github.com/jbenet/go-ipfs/crypto"
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
14
	merkledag "github.com/jbenet/go-ipfs/merkledag"
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
15
	path "github.com/jbenet/go-ipfs/path"
Juan Batiz-Benet's avatar
go fmt  
Juan Batiz-Benet committed
16
	peer "github.com/jbenet/go-ipfs/peer"
17 18 19 20 21
	routing "github.com/jbenet/go-ipfs/routing"
	dht "github.com/jbenet/go-ipfs/routing/dht"
	swarm "github.com/jbenet/go-ipfs/swarm"
	u "github.com/jbenet/go-ipfs/util"
	ma "github.com/jbenet/go-multiaddr"
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
22 23
)

Juan Batiz-Benet's avatar
go lint  
Juan Batiz-Benet committed
24
// IpfsNode is IPFS Core module. It represents an IPFS instance.
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
25 26
type IpfsNode struct {

Juan Batiz-Benet's avatar
go fmt  
Juan Batiz-Benet committed
27 28
	// the node's configuration
	Config *config.Config
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
29

Juan Batiz-Benet's avatar
go fmt  
Juan Batiz-Benet committed
30 31
	// the local node's identity
	Identity *peer.Peer
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
32

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
33 34
	// the map of other nodes (Peer instances)
	PeerMap *peer.Map
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
35

Juan Batiz-Benet's avatar
go fmt  
Juan Batiz-Benet committed
36 37
	// the local datastore
	Datastore ds.Datastore
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
38

Juan Batiz-Benet's avatar
go fmt  
Juan Batiz-Benet committed
39
	// the network message stream
40
	Swarm *swarm.Swarm
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
41

Juan Batiz-Benet's avatar
go fmt  
Juan Batiz-Benet committed
42
	// the routing system. recommend ipfs-dht
43
	Routing routing.IpfsRouting
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
44

Juan Batiz-Benet's avatar
go fmt  
Juan Batiz-Benet committed
45
	// the block exchange + strategy (bitswap)
46
	BitSwap *bitswap.BitSwap
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
47

Juan Batiz-Benet's avatar
go fmt  
Juan Batiz-Benet committed
48
	// the block service, get/add blocks.
49
	Blocks *bserv.BlockService
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
50

51 52 53
	// the merkle dag service, get/add objects.
	DAG *merkledag.DAGService

Juan Batiz-Benet's avatar
go fmt  
Juan Batiz-Benet committed
54
	// the path resolution system
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
55
	Resolver *path.Resolver
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
56

Juan Batiz-Benet's avatar
go fmt  
Juan Batiz-Benet committed
57 58
	// the name system, resolves paths to hashes
	// Namesys *namesys.Namesys
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
59 60
}

Juan Batiz-Benet's avatar
go lint  
Juan Batiz-Benet committed
61
// NewIpfsNode constructs a new IpfsNode based on the given config.
62
func NewIpfsNode(cfg *config.Config, online bool) (*IpfsNode, error) {
Juan Batiz-Benet's avatar
go fmt  
Juan Batiz-Benet committed
63
	if cfg == nil {
Juan Batiz-Benet's avatar
go lint  
Juan Batiz-Benet committed
64
		return nil, fmt.Errorf("configuration required")
Juan Batiz-Benet's avatar
go fmt  
Juan Batiz-Benet committed
65 66 67 68 69 70 71
	}

	d, err := makeDatastore(cfg.Datastore)
	if err != nil {
		return nil, err
	}

72 73
	var swap *bitswap.BitSwap
	if online {
74
		swap, err = loadBitswap(cfg, d)
75 76 77 78
		if err != nil {
			return nil, err
		}
	}
79 80

	bs, err := bserv.NewBlockService(d, swap)
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
81 82 83 84
	if err != nil {
		return nil, err
	}

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
85
	dag := &merkledag.DAGService{Blocks: bs}
86

Juan Batiz-Benet's avatar
go fmt  
Juan Batiz-Benet committed
87 88
	n := &IpfsNode{
		Config:    cfg,
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
89
		PeerMap:   &peer.Map{},
Juan Batiz-Benet's avatar
go fmt  
Juan Batiz-Benet committed
90
		Datastore: d,
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
91
		Blocks:    bs,
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
92 93
		DAG:       dag,
		Resolver:  &path.Resolver{DAG: dag},
Juan Batiz-Benet's avatar
go fmt  
Juan Batiz-Benet committed
94 95 96
	}

	return n, nil
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
97
}
98 99

func loadBitswap(cfg *config.Config, d ds.Datastore) (*bitswap.BitSwap, error) {
100
	maddr, err := ma.NewMultiaddr(cfg.Identity.Address)
101 102 103 104
	if err != nil {
		return nil, err
	}

105
	skb, err := base64.StdEncoding.DecodeString(cfg.Identity.PrivKey)
106 107 108 109
	if err != nil {
		return nil, err
	}

110 111 112
	sk, err := ci.UnmarshalPrivateKey(skb)
	if err != nil {
		return nil, err
113 114
	}

115
	local := &peer.Peer{
116
		ID:        peer.ID(b58.Decode(cfg.Identity.PeerID)),
117
		Addresses: []*ma.Multiaddr{maddr},
118 119
		PrivKey:   sk,
		PubKey:    sk.GetPublic(),
120 121 122
	}

	if len(local.ID) == 0 {
123
		return nil, errors.New("No peer ID in config! (was ipfs init run?)")
124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149
	}

	net := swarm.NewSwarm(local)
	err = net.Listen()
	if err != nil {
		return nil, err
	}

	route := dht.NewDHT(local, net, d)
	route.Start()

	for _, p := range cfg.Peers {
		maddr, err := ma.NewMultiaddr(p.Address)
		if err != nil {
			u.PErr("error: %v\n", err)
			continue
		}

		_, err = route.Connect(maddr)
		if err != nil {
			u.PErr("Bootstrapping error: %v\n", err)
		}
	}

	return bitswap.NewBitSwap(local, net, d, route), nil
}
150 151 152 153 154

func (n *IpfsNode) PinDagNode(nd *merkledag.Node) error {
	u.POut("Pinning node. Currently No-Op\n")
	return nil
}