diff --git a/core/builder.go b/core/builder.go index 1fdec9944a3306954a3004c95d8cc97c7a8b6d40..f880099275ffd26c8556ee187af7cad545ba5ac7 100644 --- a/core/builder.go +++ b/core/builder.go @@ -5,7 +5,8 @@ import ( "crypto/rand" "encoding/base64" "errors" - "github.com/ipfs/go-ipfs/provider" + "fmt" + "os" "syscall" "time" @@ -15,7 +16,7 @@ import ( pin "github.com/ipfs/go-ipfs/pin" repo "github.com/ipfs/go-ipfs/repo" cidv0v1 "github.com/ipfs/go-ipfs/thirdparty/cidv0v1" - "github.com/ipfs/go-ipfs/thirdparty/verifbs" + verifbs "github.com/ipfs/go-ipfs/thirdparty/verifbs" bserv "github.com/ipfs/go-blockservice" ds "github.com/ipfs/go-datastore" @@ -25,6 +26,7 @@ import ( cfg "github.com/ipfs/go-ipfs-config" offline "github.com/ipfs/go-ipfs-exchange-offline" offroute "github.com/ipfs/go-ipfs-routing/offline" + provider "github.com/ipfs/go-ipfs/provider" ipns "github.com/ipfs/go-ipns" dag "github.com/ipfs/go-merkledag" metrics "github.com/ipfs/go-metrics-interface" @@ -36,6 +38,7 @@ import ( p2phost "github.com/libp2p/go-libp2p-host" peer "github.com/libp2p/go-libp2p-peer" pstore "github.com/libp2p/go-libp2p-peerstore" + pstoreds "github.com/libp2p/go-libp2p-peerstore/pstoreds" pstoremem "github.com/libp2p/go-libp2p-peerstore/pstoremem" record "github.com/libp2p/go-libp2p-record" ) @@ -130,23 +133,33 @@ func defaultRepo(dstore repo.Datastore) (repo.Repo, error) { } // 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) +func NewNode(ctx context.Context, bcfg *BuildCfg) (*IpfsNode, error) { + if bcfg == nil { + bcfg = new(BuildCfg) } - err := cfg.fillDefaults() + err := bcfg.fillDefaults() if err != nil { return nil, err } ctx = metrics.CtxScope(ctx, "ipfs") + config, err := bcfg.Repo.Config() + if err != nil { + return nil, err + } + + ps, err := setupPeerstore(ctx, bcfg.Repo.Datastore(), &config.Experimental.Peerstore) + if err != nil { + return nil, fmt.Errorf("failed while creating peerstore: %s", err) + } + n := &IpfsNode{ - IsOnline: cfg.Online, - Repo: cfg.Repo, + IsOnline: bcfg.Online, + Repo: bcfg.Repo, ctx: ctx, - Peerstore: pstoremem.NewPeerstore(), + Peerstore: ps, } n.RecordValidator = record.NamespacedValidator{ @@ -157,7 +170,7 @@ func NewNode(ctx context.Context, cfg *BuildCfg) (*IpfsNode, error) { // TODO: this is a weird circular-ish dependency, rework it n.proc = goprocessctx.WithContextAndTeardown(ctx, n.teardown) - if err := setupNode(ctx, n, cfg); err != nil { + if err := setupNode(ctx, n, bcfg); err != nil { n.Close() return nil, err } @@ -291,3 +304,39 @@ func setupNode(ctx context.Context, n *IpfsNode, cfg *BuildCfg) error { return n.loadFilesRoot() } + +func setupPeerstore(ctx context.Context, dstore repo.Datastore, pcfg *cfg.Peerstore) (pstore.Peerstore, error) { + switch pcfg.Type { + case "", cfg.PeerstoreMemory: + return pstoremem.NewPeerstore(), nil + + case cfg.PeerstoreDatastore: + dcfg := pcfg.Datastore + opts := pstoreds.DefaultOpts() + opts.GCLookaheadInterval = 0 // ensure lookahead is disabled. + + if dcfg.Cache.Disable { + opts.CacheSize = 0 + } else if dcfg.Cache.Size > 0 { + opts.CacheSize = uint(dcfg.Cache.Size) + } + + if dcfg.GC.Disable { + opts.GCPurgeInterval = 0 + } else if dcfg.GC.PurgeIntervalMillis > 0 { + opts.GCPurgeInterval = time.Duration(dcfg.GC.PurgeIntervalMillis) * time.Millisecond + } + + if dcfg.GC.LookaheadIntervalMillis > 0 { + opts.GCLookaheadInterval = time.Duration(dcfg.GC.LookaheadIntervalMillis) * time.Millisecond + } + + if dcfg.GC.InitDelayMillis != nil { + opts.GCInitialDelay = time.Duration(*dcfg.GC.InitDelayMillis) * time.Millisecond + } + + return pstoreds.NewPeerstore(ctx, dstore, opts) + } + + return nil, fmt.Errorf("unsupported peerstore type: %s", pcfg.Type) +}