lotus/node/modules/chain.go

171 lines
5.3 KiB
Go
Raw Normal View History

2019-08-01 14:19:53 +00:00
package modules
import (
"bytes"
"context"
2020-02-27 21:45:31 +00:00
2019-08-01 14:19:53 +00:00
"github.com/ipfs/go-bitswap"
2019-08-08 17:16:41 +00:00
"github.com/ipfs/go-bitswap/network"
2019-08-01 14:19:53 +00:00
"github.com/ipfs/go-blockservice"
"github.com/ipfs/go-datastore"
blockstore "github.com/ipfs/go-ipfs-blockstore"
"github.com/ipld/go-car"
2019-08-01 14:19:53 +00:00
"github.com/libp2p/go-libp2p-core/host"
"github.com/libp2p/go-libp2p-core/routing"
pubsub "github.com/libp2p/go-libp2p-pubsub"
2019-08-01 14:19:53 +00:00
"go.uber.org/fx"
"golang.org/x/xerrors"
2020-04-17 14:47:19 +00:00
"github.com/filecoin-project/sector-storage/ffiwrapper"
"github.com/filecoin-project/specs-actors/actors/runtime"
"github.com/filecoin-project/lotus/chain"
"github.com/filecoin-project/lotus/chain/beacon"
2019-11-15 21:35:29 +00:00
"github.com/filecoin-project/lotus/chain/blocksync"
2019-12-01 23:11:43 +00:00
"github.com/filecoin-project/lotus/chain/messagepool"
"github.com/filecoin-project/lotus/chain/stmgr"
"github.com/filecoin-project/lotus/chain/store"
"github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/journal"
"github.com/filecoin-project/lotus/node/modules/dtypes"
"github.com/filecoin-project/lotus/node/modules/helpers"
"github.com/filecoin-project/lotus/node/repo"
2019-08-01 14:19:53 +00:00
)
func ChainExchange(mctx helpers.MetricsCtx, lc fx.Lifecycle, host host.Host, rt routing.Routing, bs dtypes.ChainGCBlockstore) dtypes.ChainExchange {
2019-08-06 22:04:21 +00:00
// prefix protocol for chain bitswap
// (so bitswap uses /chain/ipfs/bitswap/1.0.0 internally for chain sync stuff)
2019-08-08 17:16:41 +00:00
bitswapNetwork := network.NewFromIpfsHost(host, rt, network.Prefix("/chain"))
bitswapOptions := []bitswap.Option{bitswap.ProvideEnabled(false)}
exch := bitswap.New(helpers.LifecycleCtx(mctx, lc), bitswapNetwork, bs, bitswapOptions...)
2019-08-01 14:19:53 +00:00
lc.Append(fx.Hook{
OnStop: func(ctx context.Context) error {
return exch.Close()
},
})
return exch
}
2020-03-31 23:13:37 +00:00
func MessagePool(lc fx.Lifecycle, sm *stmgr.StateManager, ps *pubsub.PubSub, ds dtypes.MetadataDS, nn dtypes.NetworkName) (*messagepool.MessagePool, error) {
2019-12-02 19:39:50 +00:00
mpp := messagepool.NewProvider(sm, ps)
2020-03-31 23:13:37 +00:00
mp, err := messagepool.New(mpp, ds, nn)
2019-11-23 19:01:56 +00:00
if err != nil {
return nil, xerrors.Errorf("constructing mpool: %w", err)
}
lc.Append(fx.Hook{
OnStop: func(_ context.Context) error {
return mp.Close()
},
})
2019-11-23 19:01:56 +00:00
return mp, nil
}
2020-05-16 18:31:14 +00:00
func ChainBlockstore(lc fx.Lifecycle, mctx helpers.MetricsCtx, r repo.LockedRepo) (dtypes.ChainBlockstore, error) {
blocks, err := r.Datastore("/chain")
2019-08-01 14:19:53 +00:00
if err != nil {
return nil, err
}
bs := blockstore.NewBlockstore(blocks)
2020-05-16 18:31:14 +00:00
cbs, err := blockstore.CachedBlockstore(helpers.LifecycleCtx(mctx, lc), bs, blockstore.DefaultCacheOpts())
if err != nil {
return nil, err
}
return blockstore.NewIdStore(cbs), nil
2019-08-01 14:19:53 +00:00
}
func ChainGCBlockstore(bs dtypes.ChainBlockstore, gcl dtypes.ChainGCLocker) dtypes.ChainGCBlockstore {
return blockstore.NewGCBlockstore(bs, gcl)
}
func ChainBlockservice(bs dtypes.ChainBlockstore, rem dtypes.ChainExchange) dtypes.ChainBlockService {
return blockservice.New(bs, rem)
}
func ChainStore(lc fx.Lifecycle, bs dtypes.ChainBlockstore, ds dtypes.MetadataDS, syscalls runtime.Syscalls, journal journal.Journal) *store.ChainStore {
chain := store.NewChainStore(bs, ds, syscalls, journal)
2019-08-01 14:19:53 +00:00
if err := chain.Load(); err != nil {
log.Warnf("loading chain state from disk: %s", err)
}
2019-08-01 14:19:53 +00:00
return chain
}
func ErrorGenesis() Genesis {
return func() (header *types.BlockHeader, e error) {
return nil, xerrors.New("No genesis block provided, provide the file with 'lotus daemon --genesis=[genesis file]'")
}
}
func LoadGenesis(genBytes []byte) func(dtypes.ChainBlockstore) Genesis {
return func(bs dtypes.ChainBlockstore) Genesis {
return func() (header *types.BlockHeader, e error) {
c, err := car.LoadCar(bs, bytes.NewReader(genBytes))
if err != nil {
2020-02-27 23:14:15 +00:00
return nil, xerrors.Errorf("loading genesis car file failed: %w", err)
2019-08-01 14:19:53 +00:00
}
if len(c.Roots) != 1 {
return nil, xerrors.New("expected genesis file to have one root")
}
root, err := bs.Get(c.Roots[0])
if err != nil {
2020-02-27 23:14:15 +00:00
return nil, err
2019-08-01 14:19:53 +00:00
}
2020-02-27 23:14:15 +00:00
h, err := types.DecodeBlock(root.RawData())
if err != nil {
return nil, xerrors.Errorf("decoding block failed: %w", err)
}
return h, nil
2019-08-01 14:19:53 +00:00
}
}
}
2020-03-31 23:13:37 +00:00
func DoSetGenesis(_ dtypes.AfterGenesisSet) {}
func SetGenesis(cs *store.ChainStore, g Genesis) (dtypes.AfterGenesisSet, error) {
2019-08-01 14:19:53 +00:00
_, err := cs.GetGenesis()
if err == nil {
2020-03-31 23:13:37 +00:00
return dtypes.AfterGenesisSet{}, nil // already set, noop
2019-08-01 14:19:53 +00:00
}
if err != datastore.ErrNotFound {
2020-03-31 23:13:37 +00:00
return dtypes.AfterGenesisSet{}, xerrors.Errorf("getting genesis block failed: %w", err)
2019-08-01 14:19:53 +00:00
}
genesis, err := g()
if err != nil {
2020-03-31 23:13:37 +00:00
return dtypes.AfterGenesisSet{}, xerrors.Errorf("genesis func failed: %w", err)
2019-08-01 14:19:53 +00:00
}
2020-03-31 23:13:37 +00:00
return dtypes.AfterGenesisSet{}, cs.SetGenesis(genesis)
}
func NetworkName(mctx helpers.MetricsCtx, lc fx.Lifecycle, cs *store.ChainStore, _ dtypes.AfterGenesisSet) (dtypes.NetworkName, error) {
ctx := helpers.LifecycleCtx(mctx, lc)
netName, err := stmgr.GetNetworkName(ctx, stmgr.NewStateManager(cs), cs.GetHeaviestTipSet().ParentState())
return netName, err
2019-08-01 14:19:53 +00:00
}
2019-11-15 21:35:29 +00:00
2020-04-17 14:47:19 +00:00
func NewSyncer(lc fx.Lifecycle, sm *stmgr.StateManager, bsync *blocksync.BlockSync, h host.Host, beacon beacon.RandomBeacon, verifier ffiwrapper.Verifier) (*chain.Syncer, error) {
syncer, err := chain.NewSyncer(sm, bsync, h.ConnManager(), h.ID(), beacon, verifier)
2019-11-15 21:35:29 +00:00
if err != nil {
return nil, err
}
lc.Append(fx.Hook{
OnStart: func(_ context.Context) error {
syncer.Start()
return nil
},
OnStop: func(_ context.Context) error {
syncer.Stop()
return nil
},
})
return syncer, nil
}