github.com/celestiaorg/celestia-node@v0.15.0-beta.1/nodebuilder/share/module.go (about)

     1  package share
     2  
     3  import (
     4  	"context"
     5  
     6  	"github.com/ipfs/go-datastore"
     7  	"github.com/libp2p/go-libp2p/core/host"
     8  	"github.com/libp2p/go-libp2p/p2p/net/conngater"
     9  	"go.uber.org/fx"
    10  
    11  	libhead "github.com/celestiaorg/go-header"
    12  	"github.com/celestiaorg/go-header/sync"
    13  
    14  	"github.com/celestiaorg/celestia-node/header"
    15  	"github.com/celestiaorg/celestia-node/nodebuilder/node"
    16  	modp2p "github.com/celestiaorg/celestia-node/nodebuilder/p2p"
    17  	"github.com/celestiaorg/celestia-node/share"
    18  	"github.com/celestiaorg/celestia-node/share/availability/full"
    19  	"github.com/celestiaorg/celestia-node/share/availability/light"
    20  	"github.com/celestiaorg/celestia-node/share/eds"
    21  	"github.com/celestiaorg/celestia-node/share/getters"
    22  	disc "github.com/celestiaorg/celestia-node/share/p2p/discovery"
    23  	"github.com/celestiaorg/celestia-node/share/p2p/peers"
    24  	"github.com/celestiaorg/celestia-node/share/p2p/shrexeds"
    25  	"github.com/celestiaorg/celestia-node/share/p2p/shrexnd"
    26  	"github.com/celestiaorg/celestia-node/share/p2p/shrexsub"
    27  )
    28  
    29  func ConstructModule(tp node.Type, cfg *Config, options ...fx.Option) fx.Option {
    30  	// sanitize config values before constructing module
    31  	cfgErr := cfg.Validate(tp)
    32  
    33  	baseComponents := fx.Options(
    34  		fx.Supply(*cfg),
    35  		fx.Error(cfgErr),
    36  		fx.Options(options...),
    37  		fx.Provide(newShareModule),
    38  		peerManagerComponents(tp, cfg),
    39  		discoveryComponents(cfg),
    40  		shrexSubComponents(),
    41  	)
    42  
    43  	bridgeAndFullComponents := fx.Options(
    44  		fx.Provide(getters.NewStoreGetter),
    45  		shrexServerComponents(cfg),
    46  		edsStoreComponents(cfg),
    47  		fullAvailabilityComponents(),
    48  		shrexGetterComponents(cfg),
    49  		fx.Provide(func(shrexSub *shrexsub.PubSub) shrexsub.BroadcastFn {
    50  			return shrexSub.Broadcast
    51  		}),
    52  	)
    53  
    54  	switch tp {
    55  	case node.Bridge:
    56  		return fx.Module(
    57  			"share",
    58  			baseComponents,
    59  			bridgeAndFullComponents,
    60  			fx.Provide(func() peers.Parameters {
    61  				return cfg.PeerManagerParams
    62  			}),
    63  			fx.Provide(bridgeGetter),
    64  			fx.Invoke(func(lc fx.Lifecycle, sub *shrexsub.PubSub) error {
    65  				lc.Append(fx.Hook{
    66  					OnStart: sub.Start,
    67  					OnStop:  sub.Stop,
    68  				})
    69  				return nil
    70  			}),
    71  		)
    72  	case node.Full:
    73  		return fx.Module(
    74  			"share",
    75  			baseComponents,
    76  			bridgeAndFullComponents,
    77  			fx.Provide(getters.NewIPLDGetter),
    78  			fx.Provide(fullGetter),
    79  		)
    80  	case node.Light:
    81  		return fx.Module(
    82  			"share",
    83  			baseComponents,
    84  			shrexGetterComponents(cfg),
    85  			lightAvailabilityComponents(cfg),
    86  			fx.Invoke(ensureEmptyEDSInBS),
    87  			fx.Provide(getters.NewIPLDGetter),
    88  			fx.Provide(lightGetter),
    89  			// shrexsub broadcaster stub for daser
    90  			fx.Provide(func() shrexsub.BroadcastFn {
    91  				return func(context.Context, shrexsub.Notification) error {
    92  					return nil
    93  				}
    94  			}),
    95  		)
    96  	default:
    97  		panic("invalid node type")
    98  	}
    99  }
   100  
   101  func discoveryComponents(cfg *Config) fx.Option {
   102  	return fx.Options(
   103  		fx.Invoke(func(disc *disc.Discovery) {}),
   104  		fx.Provide(fx.Annotate(
   105  			newDiscovery(cfg.Discovery),
   106  			fx.OnStart(func(ctx context.Context, d *disc.Discovery) error {
   107  				return d.Start(ctx)
   108  			}),
   109  			fx.OnStop(func(ctx context.Context, d *disc.Discovery) error {
   110  				return d.Stop(ctx)
   111  			}),
   112  		)),
   113  	)
   114  }
   115  
   116  func peerManagerComponents(tp node.Type, cfg *Config) fx.Option {
   117  	switch tp {
   118  	case node.Full, node.Light:
   119  		return fx.Options(
   120  			fx.Provide(func() peers.Parameters {
   121  				return cfg.PeerManagerParams
   122  			}),
   123  			fx.Provide(
   124  				func(
   125  					params peers.Parameters,
   126  					host host.Host,
   127  					connGater *conngater.BasicConnectionGater,
   128  					shrexSub *shrexsub.PubSub,
   129  					headerSub libhead.Subscriber[*header.ExtendedHeader],
   130  					// we must ensure Syncer is started before PeerManager
   131  					// so that Syncer registers header validator before PeerManager subscribes to headers
   132  					_ *sync.Syncer[*header.ExtendedHeader],
   133  				) (*peers.Manager, error) {
   134  					return peers.NewManager(
   135  						params,
   136  						host,
   137  						connGater,
   138  						peers.WithShrexSubPools(shrexSub, headerSub),
   139  					)
   140  				},
   141  			),
   142  		)
   143  	case node.Bridge:
   144  		return fx.Provide(peers.NewManager)
   145  	default:
   146  		panic("invalid node type")
   147  	}
   148  }
   149  
   150  func shrexSubComponents() fx.Option {
   151  	return fx.Provide(
   152  		func(ctx context.Context, h host.Host, network modp2p.Network) (*shrexsub.PubSub, error) {
   153  			return shrexsub.NewPubSub(ctx, h, network.String())
   154  		},
   155  	)
   156  }
   157  
   158  // shrexGetterComponents provides components for a shrex getter that
   159  // is capable of requesting
   160  func shrexGetterComponents(cfg *Config) fx.Option {
   161  	return fx.Options(
   162  		// shrex-nd client
   163  		fx.Provide(
   164  			func(host host.Host, network modp2p.Network) (*shrexnd.Client, error) {
   165  				cfg.ShrExNDParams.WithNetworkID(network.String())
   166  				return shrexnd.NewClient(cfg.ShrExNDParams, host)
   167  			},
   168  		),
   169  
   170  		// shrex-eds client
   171  		fx.Provide(
   172  			func(host host.Host, network modp2p.Network) (*shrexeds.Client, error) {
   173  				cfg.ShrExEDSParams.WithNetworkID(network.String())
   174  				return shrexeds.NewClient(cfg.ShrExEDSParams, host)
   175  			},
   176  		),
   177  
   178  		fx.Provide(fx.Annotate(
   179  			getters.NewShrexGetter,
   180  			fx.OnStart(func(ctx context.Context, getter *getters.ShrexGetter) error {
   181  				return getter.Start(ctx)
   182  			}),
   183  			fx.OnStop(func(ctx context.Context, getter *getters.ShrexGetter) error {
   184  				return getter.Stop(ctx)
   185  			}),
   186  		)),
   187  	)
   188  }
   189  
   190  func shrexServerComponents(cfg *Config) fx.Option {
   191  	return fx.Options(
   192  		fx.Invoke(func(edsSrv *shrexeds.Server, ndSrc *shrexnd.Server) {}),
   193  		fx.Provide(fx.Annotate(
   194  			func(host host.Host, store *eds.Store, network modp2p.Network) (*shrexeds.Server, error) {
   195  				cfg.ShrExEDSParams.WithNetworkID(network.String())
   196  				return shrexeds.NewServer(cfg.ShrExEDSParams, host, store)
   197  			},
   198  			fx.OnStart(func(ctx context.Context, server *shrexeds.Server) error {
   199  				return server.Start(ctx)
   200  			}),
   201  			fx.OnStop(func(ctx context.Context, server *shrexeds.Server) error {
   202  				return server.Stop(ctx)
   203  			}),
   204  		)),
   205  		fx.Provide(fx.Annotate(
   206  			func(
   207  				host host.Host,
   208  				store *eds.Store,
   209  				network modp2p.Network,
   210  			) (*shrexnd.Server, error) {
   211  				cfg.ShrExNDParams.WithNetworkID(network.String())
   212  				return shrexnd.NewServer(cfg.ShrExNDParams, host, store)
   213  			},
   214  			fx.OnStart(func(ctx context.Context, server *shrexnd.Server) error {
   215  				return server.Start(ctx)
   216  			}),
   217  			fx.OnStop(func(ctx context.Context, server *shrexnd.Server) error {
   218  				return server.Stop(ctx)
   219  			})),
   220  		),
   221  	)
   222  }
   223  
   224  func edsStoreComponents(cfg *Config) fx.Option {
   225  	return fx.Options(
   226  		fx.Provide(fx.Annotate(
   227  			func(path node.StorePath, ds datastore.Batching) (*eds.Store, error) {
   228  				return eds.NewStore(cfg.EDSStoreParams, string(path), ds)
   229  			},
   230  			fx.OnStart(func(ctx context.Context, store *eds.Store) error {
   231  				err := store.Start(ctx)
   232  				if err != nil {
   233  					return err
   234  				}
   235  				return ensureEmptyCARExists(ctx, store)
   236  			}),
   237  			fx.OnStop(func(ctx context.Context, store *eds.Store) error {
   238  				return store.Stop(ctx)
   239  			}),
   240  		)),
   241  	)
   242  }
   243  
   244  func fullAvailabilityComponents() fx.Option {
   245  	return fx.Options(
   246  		fx.Provide(fx.Annotate(
   247  			full.NewShareAvailability,
   248  			fx.OnStart(func(ctx context.Context, avail *full.ShareAvailability) error {
   249  				return avail.Start(ctx)
   250  			}),
   251  			fx.OnStop(func(ctx context.Context, avail *full.ShareAvailability) error {
   252  				return avail.Stop(ctx)
   253  			}),
   254  		)),
   255  		fx.Provide(func(avail *full.ShareAvailability) share.Availability {
   256  			return avail
   257  		}),
   258  	)
   259  }
   260  
   261  func lightAvailabilityComponents(cfg *Config) fx.Option {
   262  	return fx.Options(
   263  		fx.Provide(fx.Annotate(
   264  			light.NewShareAvailability,
   265  			fx.OnStop(func(ctx context.Context, la *light.ShareAvailability) error {
   266  				return la.Close(ctx)
   267  			}),
   268  		)),
   269  		fx.Provide(func() []light.Option {
   270  			return []light.Option{
   271  				light.WithSampleAmount(cfg.LightAvailability.SampleAmount),
   272  			}
   273  		}),
   274  		fx.Provide(func(avail *light.ShareAvailability) share.Availability {
   275  			return avail
   276  		}),
   277  	)
   278  }