-
Notifications
You must be signed in to change notification settings - Fork 65
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(mobile): Add base mobile ipfs node
* Split pkg into repo/host/node * host build mobile dedicated host (noop for the moment) * repo build mobile dedicated repo, exactly the same as ipfs repo but add the ability to add some custom configuration * node build mobile dedicated node with the particularity to create a mobile host * the main package can be bind using gomobile to create a ready-to-use framework/aar * individual pkg can be imported instead and be used for specific project * Add simple makefile that show how to build the thing
- Loading branch information
Showing
10 changed files
with
1,482 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
BUILD_DIR_IOS ?= ./build/ios | ||
BUILD_DIR_ANDROID ?= ./build/android | ||
|
||
GOMOBILES_OPT ?= | ||
|
||
build: build.android build.ios | ||
|
||
build.android: | ||
@mkdir -p $(BUILD_DIR_IOS) | ||
gomobile bind -v $(GOMOBILES_OPT) -target=android -o $(BUILD_DIR_IOS)/ipfs.aar github.com/berty/gomobile-ipfs | ||
|
||
build.ios: | ||
@mkdir -p $(BUILD_DIR_IOS) | ||
gomobile bind -v $(GOMOBILES_OPT) -target=ios -o $(BUILD_DIR_IOS)/ipfs.framework github.com/berty/gomobile-ipfs |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
module github.com/berty/gomobile-ipfs | ||
|
||
go 1.12 | ||
|
||
require ( | ||
berty.tech/go-ipfs-log v0.0.0-20190805145225-165c94541925 | ||
github.com/AndreasBriese/bbloom v0.0.0-20190306092124-e2d15f34fcf9 // indirect | ||
github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2 // indirect | ||
github.com/ipfs/go-datastore v0.0.5 | ||
github.com/ipfs/go-filestore v0.0.2 | ||
github.com/ipfs/go-ipfs v0.4.21 | ||
github.com/ipfs/go-ipfs-config v0.0.3 | ||
github.com/libp2p/go-libp2p v0.3.0 | ||
github.com/libp2p/go-libp2p-core v0.2.0 | ||
github.com/multiformats/go-multiaddr v0.0.4 | ||
github.com/spf13/cobra v0.0.5 // indirect | ||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859 // indirect | ||
golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb // indirect | ||
google.golang.org/appengine v1.4.0 // indirect | ||
) | ||
|
||
// @HOTFIX | ||
replace github.com/dgraph-io/badger v2.0.0-rc.2+incompatible => github.com/dgraph-io/badger v2.0.0-rc2+incompatible |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,135 @@ | ||
package host | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
|
||
p2p "github.com/libp2p/go-libp2p" | ||
p2p_connmgr "github.com/libp2p/go-libp2p-core/connmgr" | ||
p2p_event "github.com/libp2p/go-libp2p-core/event" | ||
p2p_host "github.com/libp2p/go-libp2p-core/host" | ||
p2p_network "github.com/libp2p/go-libp2p-core/network" | ||
p2p_peer "github.com/libp2p/go-libp2p-core/peer" | ||
p2p_pstore "github.com/libp2p/go-libp2p-core/peerstore" | ||
p2p_protocol "github.com/libp2p/go-libp2p-core/protocol" | ||
p2p_config "github.com/libp2p/go-libp2p/config" | ||
|
||
ipfs_p2p "github.com/ipfs/go-ipfs/core/node/libp2p" | ||
|
||
ma "github.com/multiformats/go-multiaddr" | ||
) | ||
|
||
// MobileHost is an host | ||
var _ p2p_host.Host = (*MobileHost)(nil) | ||
|
||
type MobileHost struct { | ||
p2p_host.Host | ||
} | ||
|
||
func NewMobileHostOption(mcfg *MobileConfig) ipfs_p2p.HostOption { | ||
return func(ctx context.Context, id p2p_peer.ID, ps p2p_pstore.Peerstore, options ...p2p.Option) (p2p_host.Host, error) { | ||
pkey := ps.PrivKey(id) | ||
if pkey == nil { | ||
return nil, fmt.Errorf("missing private key for node ID: %s", id.Pretty()) | ||
} | ||
|
||
options = append([]p2p.Option{p2p.Identity(pkey), p2p.Peerstore(ps)}, options...) | ||
|
||
cfg := &p2p_config.Config{} | ||
if err := cfg.Apply(options...); err != nil { | ||
return nil, err | ||
} | ||
|
||
return NewMobileHost(ctx, mcfg, cfg) | ||
} | ||
} | ||
|
||
func NewMobileHost(ctx context.Context, _ *MobileConfig, cfg *p2p.Config) (p2p_host.Host, error) { | ||
host, err := cfg.NewNode(ctx) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
// @TODO: MobileHost custom config | ||
|
||
return &MobileHost{ | ||
Host: host, | ||
}, nil | ||
} | ||
|
||
// ID returns the (local) peer.ID associated with this Host | ||
func (mh *MobileHost) ID() p2p_peer.ID { | ||
return mh.Host.ID() | ||
} | ||
|
||
// Peerstore returns the Host's repository of Peer Addresses and Keys. | ||
func (mh *MobileHost) Peerstore() p2p_pstore.Peerstore { | ||
return mh.Host.Peerstore() | ||
} | ||
|
||
// Returns the listen addresses of the Host | ||
func (mh *MobileHost) Addrs() []ma.Multiaddr { | ||
return mh.Host.Addrs() | ||
} | ||
|
||
// Networks returns the Network interface of the Host | ||
func (mh *MobileHost) Network() p2p_network.Network { | ||
return mh.Host.Network() | ||
} | ||
|
||
// Mux returns the Mux multiplexing incoming streams to protocol handlers | ||
func (mh *MobileHost) Mux() p2p_protocol.Switch { | ||
return mh.Host.Mux() | ||
} | ||
|
||
// Connect ensures there is a connection between this host and the peer with | ||
// given peer.ID. Connect will absorb the addresses in pi into its internal | ||
// peerstore. If there is not an active connection, Connect will issue a | ||
// h.Network.Dial, and block until a connection is open, or an error is | ||
// returned. // TODO: Relay + NAT. | ||
func (mh *MobileHost) Connect(ctx context.Context, pi p2p_peer.AddrInfo) error { | ||
return mh.Host.Connect(ctx, pi) | ||
} | ||
|
||
// SetStreamHandler sets the protocol handler on the Host's Mux. | ||
// This is equivalent to: | ||
// host.Mux().SetHandler(proto, handler) | ||
// (Threadsafe) | ||
func (mh *MobileHost) SetStreamHandler(pid p2p_protocol.ID, handler p2p_network.StreamHandler) { | ||
mh.Host.SetStreamHandler(pid, handler) | ||
} | ||
|
||
// SetStreamHandlerMatch sets the protocol handler on the Host's Mux | ||
// using a matching function for protocol selection. | ||
func (mh *MobileHost) SetStreamHandlerMatch(pid p2p_protocol.ID, m func(string) bool, h p2p_network.StreamHandler) { | ||
mh.Host.SetStreamHandlerMatch(pid, m, h) | ||
} | ||
|
||
// RemoveStreamHandler removes a handler on the mux that was set by | ||
// SetStreamHandler | ||
func (mh *MobileHost) RemoveStreamHandler(pid p2p_protocol.ID) { | ||
mh.Host.RemoveStreamHandler(pid) | ||
} | ||
|
||
// NewStream opens a new stream to given peer p, and writes a p2p/protocol | ||
// header with given ProtocolID. If there is no connection to p, attempts | ||
// to create one. If ProtocolID is "", writes no header. | ||
// (Threadsafe) | ||
func (mh *MobileHost) NewStream(ctx context.Context, p p2p_peer.ID, pids ...p2p_protocol.ID) (p2p_network.Stream, error) { | ||
return mh.Host.NewStream(ctx, p, pids...) | ||
} | ||
|
||
// Close shuts down the host, its Network, and services. | ||
func (mh *MobileHost) Close() error { | ||
return mh.Host.Close() | ||
} | ||
|
||
// ConnManager returns this hosts connection manager | ||
func (mh *MobileHost) ConnManager() p2p_connmgr.ConnManager { | ||
return mh.ConnManager() | ||
} | ||
|
||
// EventBus returns the hosts eventbus | ||
func (mh *MobileHost) EventBus() p2p_event.Bus { | ||
return mh.Host.EventBus() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
package host | ||
|
||
import ( | ||
"bytes" | ||
"encoding/json" | ||
"fmt" | ||
) | ||
|
||
type MobileConfig struct { | ||
} | ||
|
||
func FromMap(v map[string]interface{}) (*Config, error) { | ||
buf := new(bytes.Buffer) | ||
if err := json.NewEncoder(buf).Encode(v); err != nil { | ||
return nil, err | ||
} | ||
var conf MobileConfig | ||
if err := json.NewDecoder(buf).Decode(&conf); err != nil { | ||
return nil, fmt.Errorf("failure to decode config: %s", err) | ||
} | ||
return &conf, nil | ||
} | ||
|
||
func ToMap(conf *MobileConfig) (map[string]interface{}, error) { | ||
buf := new(bytes.Buffer) | ||
if err := json.NewEncoder(buf).Encode(conf); err != nil { | ||
return nil, err | ||
} | ||
var m map[string]interface{} | ||
if err := json.NewDecoder(buf).Decode(&m); err != nil { | ||
return nil, fmt.Errorf("failure to decode config: %s", err) | ||
} | ||
return m, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
package mobile | ||
|
||
import "fmt" | ||
|
||
type Node interface { | ||
// Close ipfs node | ||
Close() error | ||
} | ||
|
||
type Repo interface { | ||
// Close ipfs node | ||
Close() error | ||
} | ||
|
||
func NewNode(r *Repo) (Node, error) { | ||
if !r.IsInitialized() { | ||
return fmt.Errorf("repo not initialized") | ||
} | ||
|
||
repo := r.Open() | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
package node | ||
|
||
import ( | ||
"context" | ||
|
||
mobile_host "github.com/berty/gomobile-ipfs/host" | ||
ipfs_core "github.com/ipfs/go-ipfs/core" | ||
ipfs_repo "github.com/ipfs/go-ipfs/core/repo" | ||
) | ||
|
||
// type Node interface { | ||
// // Close ipfs node | ||
// Close() error | ||
// } | ||
|
||
type IpfsMobile struct { | ||
ipfsNode *ipfs_core.IpfsNode | ||
} | ||
|
||
func (im *IpfsMobile) Close() error { | ||
return im.ipfsNode.Close() | ||
} | ||
|
||
func NewNode(ctx context.Context, repo *ipfs_repo.Repo) (*IpfsMobile, error) { | ||
mcfg := mobile_host.NewMobileConfigFromRepo(repo) | ||
cfg := &ipfs_core.BuildCfg{ | ||
Online: true, | ||
Permanent: false, | ||
DisableEncryptedConnections: false, | ||
NilRepo: false, | ||
Repo: ipfsrepo, | ||
Host: mobile_host.NewMobileHostOption(mcfg), | ||
} | ||
|
||
inode, err := ipfs_core.NewNode(context.Background(), cfg) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
return &IpfsMobile{ | ||
ipfsNode: inode, | ||
}, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
package repo | ||
|
||
import ( | ||
"encoding/json" | ||
"fmt" | ||
"io/ioutil" | ||
"path/filepath" | ||
|
||
ipfs_config "github.com/ipfs/go-ipfs-config" | ||
ipfs_fsrepo "github.com/ipfs/go-ipfs/core/repo/fsrepo" | ||
) | ||
|
||
const mobileFile = "mobile" | ||
|
||
func (r *MobileRepo) IsInitialized() bool { | ||
return ipfs_fsrepo.IsInitialized(r.path) | ||
} | ||
|
||
func (r *MobileRepo) getPath() string { | ||
repoPath = filepath.Clean(r.path) | ||
return filepath.Join(repoPath, mobileFile) | ||
} | ||
|
||
func (r *MobileRepo) SetMobileConfig(tmp map[string]interface{}) (err error) { | ||
// mobilePath := r.getPath() | ||
|
||
// var template interface{} | ||
// if err = json.Unmarshal(rawcfg, &template); err != nil { | ||
// return | ||
// } | ||
|
||
if mapcfg, ok := template.(map[string]interface{}); ok { | ||
var cfg *ipfs_config.Config | ||
|
||
if cfg, err = ipfs_config.FromMap(mapcfg); err == nil { | ||
r.config = cfg | ||
} | ||
|
||
return | ||
} | ||
|
||
err = fmt.Errorf("unable to cast config to map") | ||
return | ||
} | ||
|
||
func (r *MobileRepo) GetMobileConfig() (rawcfg []byte, err error) { | ||
if r.config == nil { | ||
err = fmt.Errorf("no config loaded") | ||
return | ||
} | ||
|
||
var mapcfg interface{} | ||
|
||
if mapcfg, err = ipfs_config.ToMap(r.config); err != nil { | ||
return | ||
} | ||
|
||
rawcfg, err = json.Marshal(mapcfg) | ||
return | ||
} | ||
|
||
func (r *MobileRepo) Init() (err error) { | ||
if r.config == nil { | ||
if r.config, err = ipfs_config.Init(ioutil.Discard, 2048); err != nil { | ||
return | ||
} | ||
} | ||
|
||
err = ipfs_fsrepo.Init(r.path, r.config) | ||
return | ||
} |
Oops, something went wrong.