core.go 2.81 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 (
Juan Batiz-Benet's avatar
go fmt  
Juan Batiz-Benet committed
4
	"fmt"
5

Juan Batiz-Benet's avatar
go fmt  
Juan Batiz-Benet committed
6
	ds "github.com/jbenet/datastore.go"
7
	"github.com/jbenet/go-ipfs/bitswap"
8
	bserv "github.com/jbenet/go-ipfs/blockservice"
Juan Batiz-Benet's avatar
go fmt  
Juan Batiz-Benet committed
9
	config "github.com/jbenet/go-ipfs/config"
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
10
	merkledag "github.com/jbenet/go-ipfs/merkledag"
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
11
	path "github.com/jbenet/go-ipfs/path"
Juan Batiz-Benet's avatar
go fmt  
Juan Batiz-Benet committed
12
	peer "github.com/jbenet/go-ipfs/peer"
13 14 15 16 17
	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
18 19
)

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

Juan Batiz-Benet's avatar
go fmt  
Juan Batiz-Benet committed
23 24
	// the node's configuration
	Config *config.Config
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
25

Juan Batiz-Benet's avatar
go fmt  
Juan Batiz-Benet committed
26 27
	// the local node's identity
	Identity *peer.Peer
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
28

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
29 30
	// the map of other nodes (Peer instances)
	PeerMap *peer.Map
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
31

Juan Batiz-Benet's avatar
go fmt  
Juan Batiz-Benet committed
32 33
	// the local datastore
	Datastore ds.Datastore
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
34

Juan Batiz-Benet's avatar
go fmt  
Juan Batiz-Benet committed
35
	// the network message stream
36
	Swarm *swarm.Swarm
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
37

Juan Batiz-Benet's avatar
go fmt  
Juan Batiz-Benet committed
38
	// the routing system. recommend ipfs-dht
39
	Routing routing.IpfsRouting
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
40

Juan Batiz-Benet's avatar
go fmt  
Juan Batiz-Benet committed
41
	// the block exchange + strategy (bitswap)
42
	BitSwap *bitswap.BitSwap
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
43

Juan Batiz-Benet's avatar
go fmt  
Juan Batiz-Benet committed
44
	// the block service, get/add blocks.
45
	Blocks *bserv.BlockService
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
46

47 48 49
	// the merkle dag service, get/add objects.
	DAG *merkledag.DAGService

Juan Batiz-Benet's avatar
go fmt  
Juan Batiz-Benet committed
50
	// the path resolution system
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
51
	Resolver *path.Resolver
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
52

Juan Batiz-Benet's avatar
go fmt  
Juan Batiz-Benet committed
53 54
	// the name system, resolves paths to hashes
	// Namesys *namesys.Namesys
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
55 56
}

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

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

68 69
	var swap *bitswap.BitSwap
	if online {
70
		swap, err = loadBitswap(cfg, d)
71 72 73 74
		if err != nil {
			return nil, err
		}
	}
75 76

	bs, err := bserv.NewBlockService(d, swap)
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
77 78 79 80
	if err != nil {
		return nil, err
	}

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

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

	return n, nil
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
93
}
94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137

func loadBitswap(cfg *config.Config, d ds.Datastore) (*bitswap.BitSwap, error) {
	maddr, err := ma.NewMultiaddr("/ip4/127.0.0.1/tcp/4001")
	if err != nil {
		return nil, err
	}

	local := &peer.Peer{
		ID:        peer.ID(cfg.Identity.PeerID),
		Addresses: []*ma.Multiaddr{maddr},
	}

	if len(local.ID) == 0 {
		mh, err := u.Hash([]byte("blah blah blah ID"))
		if err != nil {
			return nil, err
		}
		local.ID = peer.ID(mh)
	}

	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
}