From 3ac605744fc41c29e4e4fc85d3dec395df9f7f48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Wed, 3 Apr 2019 16:34:14 +0200 Subject: [PATCH] Separate function to parse BuildCfg into Options MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Ɓukasz Magiera --- core/builder.go | 135 +------------------------------------------ core/ncore.go | 29 ---------- core/node/builder.go | 68 ++++++++++++++++++++++ core/node/groups.go | 74 ++++++++++++++++++++++-- core/node/helpers.go | 24 ++++++++ core/node/libp2p.go | 2 +- 6 files changed, 164 insertions(+), 168 deletions(-) delete mode 100644 core/ncore.go diff --git a/core/builder.go b/core/builder.go index 1c1bf880c..64b4acee6 100644 --- a/core/builder.go +++ b/core/builder.go @@ -2,154 +2,25 @@ package core import ( "context" - "crypto/rand" - "encoding/base64" - "errors" "go.uber.org/fx" "github.com/ipfs/go-ipfs/core/bootstrap" "github.com/ipfs/go-ipfs/core/node" - - repo "github.com/ipfs/go-ipfs/repo" - - ds "github.com/ipfs/go-datastore" - dsync "github.com/ipfs/go-datastore/sync" - cfg "github.com/ipfs/go-ipfs-config" - metrics "github.com/ipfs/go-metrics-interface" - resolver "github.com/ipfs/go-path/resolver" - ci "github.com/libp2p/go-libp2p-crypto" - peer "github.com/libp2p/go-libp2p-peer" ) -type BuildCfg node.BuildCfg - -func (cfg *BuildCfg) fillDefaults() error { - if cfg.Repo != nil && cfg.NilRepo { - return errors.New("cannot set a Repo and specify nilrepo at the same time") - } - - if cfg.Repo == nil { - var d ds.Datastore - if cfg.NilRepo { - d = ds.NewNullDatastore() - } else { - d = ds.NewMapDatastore() - } - r, err := defaultRepo(dsync.MutexWrap(d)) - if err != nil { - return err - } - cfg.Repo = r - } - - if cfg.Routing == nil { - cfg.Routing = node.DHTOption - } - - if cfg.Host == nil { - cfg.Host = node.DefaultHostOption - } - - return nil -} - -func defaultRepo(dstore repo.Datastore) (repo.Repo, error) { - c := cfg.Config{} - priv, pub, err := ci.GenerateKeyPairWithReader(ci.RSA, 1024, rand.Reader) - if err != nil { - return nil, err - } - - pid, err := peer.IDFromPublicKey(pub) - if err != nil { - return nil, err - } - - privkeyb, err := priv.Bytes() - if err != nil { - return nil, err - } - - c.Bootstrap = cfg.DefaultBootstrapAddresses - c.Addresses.Swarm = []string{"/ip4/0.0.0.0/tcp/4001"} - c.Identity.PeerID = pid.Pretty() - c.Identity.PrivKey = base64.StdEncoding.EncodeToString(privkeyb) - - return &repo.Mock{ - D: dstore, - C: c, - }, nil -} +type BuildCfg = node.BuildCfg // Alias for compatibility until we properly refactor the constructor interface // NewNode constructs and returns an IpfsNode using the given cfg. func NewNode(ctx context.Context, cfg *BuildCfg) (*IpfsNode, error) { - if cfg == nil { - cfg = new(BuildCfg) - } - - err := cfg.fillDefaults() - if err != nil { - return nil, err - } - - ctx = metrics.CtxScope(ctx, "ipfs") - - repoOption := fx.Provide(func(lc fx.Lifecycle) repo.Repo { - lc.Append(fx.Hook{ - OnStop: func(ctx context.Context) error { - return cfg.Repo.Close() - }, - }) - - return cfg.Repo - }) - - metricsCtx := fx.Provide(func() node.MetricsCtx { - return node.MetricsCtx(ctx) - }) - - hostOption := fx.Provide(func() node.HostOption { - return cfg.Host - }) - - routingOption := fx.Provide(func() node.RoutingOption { - return cfg.Routing - }) - - params := fx.Options( - repoOption, - hostOption, - routingOption, - metricsCtx, - ) - - core := fx.Options( - fx.Provide(node.BlockServiceCtor), - fx.Provide(node.DagCtor), - fx.Provide(resolver.NewBasicResolver), - fx.Provide(node.Pinning), - fx.Provide(node.Files), - ) - n := &IpfsNode{ ctx: ctx, } app := fx.New( + node.IPFS(ctx, cfg), + fx.NopLogger, - fx.Provide(baseProcess), - - params, - node.Storage((*node.BuildCfg)(cfg)), - node.Identity, - node.IPNS, - node.Networked((*node.BuildCfg)(cfg)), - - fx.Invoke(setupSharding), - - core, - fx.Extract(n), ) diff --git a/core/ncore.go b/core/ncore.go deleted file mode 100644 index 4704a71af..000000000 --- a/core/ncore.go +++ /dev/null @@ -1,29 +0,0 @@ -package core - -import ( - "context" - - "github.com/jbenet/goprocess" - "go.uber.org/fx" - - iconfig "github.com/ipfs/go-ipfs-config" - uio "github.com/ipfs/go-unixfs/io" -) - -//////////////////// -// libp2p - -func setupSharding(cfg *iconfig.Config) { - // TEMP: setting global sharding switch here - uio.UseHAMTSharding = cfg.Experimental.ShardingEnabled -} - -func baseProcess(lc fx.Lifecycle) goprocess.Process { - p := goprocess.WithParent(goprocess.Background()) - lc.Append(fx.Hook{ - OnStop: func(_ context.Context) error { - return p.Close() - }, - }) - return p -} diff --git a/core/node/builder.go b/core/node/builder.go index 112d1f7fe..267aac895 100644 --- a/core/node/builder.go +++ b/core/node/builder.go @@ -1,6 +1,16 @@ package node import ( + "crypto/rand" + "encoding/base64" + "errors" + + ds "github.com/ipfs/go-datastore" + dsync "github.com/ipfs/go-datastore/sync" + cfg "github.com/ipfs/go-ipfs-config" + ci "github.com/libp2p/go-libp2p-crypto" + peer "github.com/libp2p/go-libp2p-peer" + "github.com/ipfs/go-ipfs/repo" ) @@ -34,3 +44,61 @@ func (cfg *BuildCfg) getOpt(key string) bool { return cfg.ExtraOpts[key] } + +func (cfg *BuildCfg) fillDefaults() error { + if cfg.Repo != nil && cfg.NilRepo { + return errors.New("cannot set a Repo and specify nilrepo at the same time") + } + + if cfg.Repo == nil { + var d ds.Datastore + if cfg.NilRepo { + d = ds.NewNullDatastore() + } else { + d = ds.NewMapDatastore() + } + r, err := defaultRepo(dsync.MutexWrap(d)) + if err != nil { + return err + } + cfg.Repo = r + } + + if cfg.Routing == nil { + cfg.Routing = DHTOption + } + + if cfg.Host == nil { + cfg.Host = DefaultHostOption + } + + return nil +} + +func defaultRepo(dstore repo.Datastore) (repo.Repo, error) { + c := cfg.Config{} + priv, pub, err := ci.GenerateKeyPairWithReader(ci.RSA, 1024, rand.Reader) + if err != nil { + return nil, err + } + + pid, err := peer.IDFromPublicKey(pub) + if err != nil { + return nil, err + } + + privkeyb, err := priv.Bytes() + if err != nil { + return nil, err + } + + c.Bootstrap = cfg.DefaultBootstrapAddresses + c.Addresses.Swarm = []string{"/ip4/0.0.0.0/tcp/4001"} + c.Identity.PeerID = pid.Pretty() + c.Identity.PrivKey = base64.StdEncoding.EncodeToString(privkeyb) + + return &repo.Mock{ + D: dstore, + C: c, + }, nil +} diff --git a/core/node/groups.go b/core/node/groups.go index 083d69d6b..7bcbbfb4b 100644 --- a/core/node/groups.go +++ b/core/node/groups.go @@ -1,12 +1,17 @@ package node import ( + "context" + offline "github.com/ipfs/go-ipfs-exchange-offline" + "github.com/ipfs/go-metrics-interface" + "github.com/ipfs/go-path/resolver" "go.uber.org/fx" offroute "github.com/ipfs/go-ipfs-routing/offline" "github.com/ipfs/go-ipfs/p2p" "github.com/ipfs/go-ipfs/provider" + "github.com/ipfs/go-ipfs/repo" ) var BaseLibP2P = fx.Options( @@ -35,8 +40,8 @@ func LibP2P(cfg *BuildCfg) fx.Option { return fx.Options( BaseLibP2P, - MaybeProvide(P2PNoSecurity, cfg.DisableEncryptedConnections), - MaybeProvide(Pubsub, cfg.getOpt("pubsub") || cfg.getOpt("ipnsps")), + maybeProvide(P2PNoSecurity, cfg.DisableEncryptedConnections), + maybeProvide(Pubsub, cfg.getOpt("pubsub") || cfg.getOpt("ipnsps")), fx.Provide(P2PSmuxTransport(cfg.getOpt("mplex"))), fx.Provide(P2POnlineRouting(cfg.getOpt("ipnsps"))), @@ -84,6 +89,7 @@ func Online(cfg *BuildCfg) fx.Option { Providers, ) } + var Offline = fx.Options( fx.Provide(offline.Exchange), fx.Provide(OfflineNamesysCtor), @@ -91,6 +97,14 @@ var Offline = fx.Options( fx.Provide(provider.NewOfflineProvider), ) +var Core = fx.Options( + fx.Provide(BlockServiceCtor), + fx.Provide(DagCtor), + fx.Provide(resolver.NewBasicResolver), + fx.Provide(Pinning), + fx.Provide(Files), +) + func Networked(cfg *BuildCfg) fx.Option { if cfg.Online { return Online(cfg) @@ -98,9 +112,57 @@ func Networked(cfg *BuildCfg) fx.Option { return Offline } -func MaybeProvide(opt interface{}, enable bool) fx.Option { - if enable { - return fx.Provide(opt) +func IPFS(ctx context.Context, cfg *BuildCfg) fx.Option { + if cfg == nil { + cfg = new(BuildCfg) } - return fx.Options() + + err := cfg.fillDefaults() + if err != nil { + return fx.Error(err) + } + + ctx = metrics.CtxScope(ctx, "ipfs") + + repoOption := fx.Provide(func(lc fx.Lifecycle) repo.Repo { + lc.Append(fx.Hook{ + OnStop: func(ctx context.Context) error { + return cfg.Repo.Close() + }, + }) + + return cfg.Repo + }) + + metricsCtx := fx.Provide(func() MetricsCtx { + return MetricsCtx(ctx) + }) + + hostOption := fx.Provide(func() HostOption { + return cfg.Host + }) + + routingOption := fx.Provide(func() RoutingOption { + return cfg.Routing + }) + + params := fx.Options( + repoOption, + hostOption, + routingOption, + metricsCtx, + ) + + return fx.Options( + params, + fx.Provide(baseProcess), + fx.Invoke(setupSharding), + + Storage(cfg), + Identity, + IPNS, + Networked(cfg), + + Core, + ) } diff --git a/core/node/helpers.go b/core/node/helpers.go index a785124a3..bca088f70 100644 --- a/core/node/helpers.go +++ b/core/node/helpers.go @@ -3,6 +3,8 @@ package node import ( "context" + config "github.com/ipfs/go-ipfs-config" + uio "github.com/ipfs/go-unixfs/io" "github.com/jbenet/goprocess" "go.uber.org/fx" ) @@ -41,3 +43,25 @@ func (lp *lcProcess) Run(f goprocess.ProcessFunc) { }, }) } + +func maybeProvide(opt interface{}, enable bool) fx.Option { + if enable { + return fx.Provide(opt) + } + return fx.Options() +} + +func setupSharding(cfg *config.Config) { + // TEMP: setting global sharding switch here + uio.UseHAMTSharding = cfg.Experimental.ShardingEnabled +} + +func baseProcess(lc fx.Lifecycle) goprocess.Process { + p := goprocess.WithParent(goprocess.Background()) + lc.Append(fx.Hook{ + OnStop: func(_ context.Context) error { + return p.Close() + }, + }) + return p +} diff --git a/core/node/libp2p.go b/core/node/libp2p.go index 8405b8cc9..5fa22d155 100644 --- a/core/node/libp2p.go +++ b/core/node/libp2p.go @@ -122,7 +122,7 @@ type Libp2pOpts struct { Opts []libp2p.Option `group:"libp2p"` } -type PNetFingerprint []byte // TODO: find some better place +type PNetFingerprint []byte func P2PPNet(repo repo.Repo) (opts Libp2pOpts, fp PNetFingerprint, err error) { swarmkey, err := repo.SwarmKey() if err != nil || swarmkey == nil {