master
go 102 lines 3.33 KB
Raw
1 package node
2
3 import (
4 blockstore "github.com/ipfs/boxo/blockstore"
5 "github.com/ipfs/go-datastore"
6 config "github.com/ipfs/kubo/config"
7 "go.uber.org/fx"
8
9 "github.com/ipfs/boxo/filestore"
10 "github.com/ipfs/boxo/provider"
11 "github.com/ipfs/kubo/core/node/helpers"
12 "github.com/ipfs/kubo/repo"
13 "github.com/ipfs/kubo/thirdparty/verifbs"
14 )
15
16 // RepoConfig loads configuration from the repo
17 func RepoConfig(repo repo.Repo) (*config.Config, error) {
18 cfg, err := repo.Config()
19 return cfg, err
20 }
21
22 // Datastore provides the datastore
23 func Datastore(repo repo.Repo) datastore.Datastore {
24 return repo.Datastore()
25 }
26
27 // BaseBlocks is the lower level blockstore without GC or Filestore layers
28 type BaseBlocks blockstore.Blockstore
29
30 // BaseBlockstoreCtor creates cached blockstore backed by the provided datastore
31 func BaseBlockstoreCtor(
32 cacheOpts blockstore.CacheOpts,
33 hashOnRead bool,
34 writeThrough bool,
35 providingStrategy string,
36 ) func(mctx helpers.MetricsCtx, repo repo.Repo, prov DHTProvider, lc fx.Lifecycle) (bs BaseBlocks, err error) {
37 return func(mctx helpers.MetricsCtx, repo repo.Repo, prov DHTProvider, lc fx.Lifecycle) (bs BaseBlocks, err error) {
38 opts := []blockstore.Option{blockstore.WriteThrough(writeThrough)}
39
40 // Blockstore providing integration:
41 // When strategy includes "all" the blockstore directly provides blocks as they're Put.
42 // Important: Provide calls from blockstore are intentionally BLOCKING.
43 // The Provider implementation (not the blockstore) should handle concurrency/queuing.
44 // This avoids spawning unbounded goroutines for concurrent block additions.
45 strategyFlag := config.MustParseProvideStrategy(providingStrategy)
46 if strategyFlag&config.ProvideStrategyAll != 0 {
47 opts = append(opts, blockstore.Provider(prov))
48 }
49
50 // hash security
51 bs = blockstore.NewBlockstore(
52 repo.Datastore(),
53 opts...,
54 )
55 bs = &verifbs.VerifBS{Blockstore: bs}
56 bs, err = blockstore.CachedBlockstore(helpers.LifecycleCtx(mctx, lc), bs, cacheOpts)
57 if err != nil {
58 return nil, err
59 }
60
61 bs = blockstore.NewIdStore(bs)
62
63 if hashOnRead {
64 bs = &blockstore.ValidatingBlockstore{Blockstore: bs}
65 }
66
67 return
68 }
69 }
70
71 // GcBlockstoreCtor wraps the base blockstore with GC and Filestore layers
72 func GcBlockstoreCtor(bb BaseBlocks) (gclocker blockstore.GCLocker, gcbs blockstore.GCBlockstore, bs blockstore.Blockstore) {
73 gclocker = blockstore.NewGCLocker()
74 gcbs = blockstore.NewGCBlockstore(bb, gclocker)
75
76 bs = gcbs
77 return
78 }
79
80 // FilestoreBlockstoreCtor wraps GcBlockstore and adds Filestore support
81 func FilestoreBlockstoreCtor(
82 providingStrategy string,
83 ) func(repo repo.Repo, bb BaseBlocks, prov DHTProvider) (gclocker blockstore.GCLocker, gcbs blockstore.GCBlockstore, bs blockstore.Blockstore, fstore *filestore.Filestore) {
84 return func(repo repo.Repo, bb BaseBlocks, prov DHTProvider) (gclocker blockstore.GCLocker, gcbs blockstore.GCBlockstore, bs blockstore.Blockstore, fstore *filestore.Filestore) {
85 gclocker = blockstore.NewGCLocker()
86
87 var fstoreProv provider.MultihashProvider
88 strategyFlag := config.MustParseProvideStrategy(providingStrategy)
89 if strategyFlag&config.ProvideStrategyAll != 0 {
90 fstoreProv = prov
91 }
92
93 fstore = filestore.NewFilestore(bb, repo.FileManager(), fstoreProv)
94
95 // hash security
96 gcbs = blockstore.NewGCBlockstore(fstore, gclocker)
97 gcbs = &verifbs.VerifBSGC{GCBlockstore: gcbs}
98
99 bs = gcbs
100 return
101 }
102 }