Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support standalone miner-market process #6356

Merged
merged 106 commits into from
Jul 13, 2021

Conversation

nonsense
Copy link
Member

@nonsense nonsense commented May 31, 2021

Associated docs: filecoin-project/filecoin-docs#890


This PR is a cherry-picked version of #5983. Closes #5149.


  1. It introduces the concept of Subsystems within the lotus-miner process - currently:
  • StorageMarket
  • Mining
  • Sealing
  • SectorStorage
  1. It adds support for running the miner market module as a separate process.
  2. A lotus-miner market service connects to the main lotus process for all sealing/storage interactions, or:
  • market service runs StorageMarget subsystem
  • main miner service runs Mining, Sealing and SectorStorage subsystems.

Depending on configuration options, this PR provides flexibility for the the miner to be split into multiple processes, or to be run as one process as is currently the case.


Currently the deployment flow for running a market module as a separate process is the following:

  1. Create backup of the original miner repo / metadata (i.e. something like: export LOTUS_BACKUP_BASE_PATH=~/.lotusbackup && export LOTUS_MINER_PATH=~/.lotusminer && export LOTUS_PATH=~/.devlotus && lotus-miner backup ~/.lotusbackup/backupfile)
  2. Initialise the market service based on the backup from 1, and generate a new libp2p identity (i.e. something like:
APISEALER=`./lotus-miner auth api-info --perm=admin`

export LOTUS_PATH=~/.devLotus && export LOTUS_MINER_PATH=~/.restoredrepo && ./lotus-miner init service --enable-market --api-sealer=$APISEALER --api-sector-index=$APISEALER --config=~/.lotusmarket/config.toml --storage-config=~/.lotusmarket/storage.json ~/.lotusbackup/backupfile

This would also send a message on chain and update the address for the given miner, so that the markets process is the point of entry from the on-chain DHT.
3. Run market service as well as main miner service (i.e. something like:

./lotus-miner run --nosync
LOTUS_MINER_PATH=~/.restoredrepo ./lotus-miner run --nosync

TODO:

TODO FROM PARENT:

  • Fix api deps
    • (don't depend on ffi)
  • Fix node tests
  • Delegate market node auth to the main node (storage subsystem assumes that)
    • Put API Secret behind an interface, in DI replace the implementation by the main node API
  • Figure out what to do about local market-node storage
    • Either drop completely (likely preferred initially)
      • This likely just means making the local storage implementation ignore paths, or (a bit cleaner) making it possible to run Remote store without a Local store
    • Or register storage properly (and handle disconnects, a bit like workers do)
  • Use http-mode jsonrpc for talking to the main Sterage/Sealing node (for reliability)
  • Don't construct miner Libp2p node when not needed
    • Mostly just shifting things around in the node builder
  • Bump API versions which need bumping
    • Miner version at least
  • Check API versions on reconnect
  • Setup docs - initial docs for splitting miner and markets service filecoin-docs#890
  • Write integration test
    • Copy one of the api/test/deal.go tests, and run in this setup

FOLLOW UP / NICE TO HAVE:

  • Add Testground testplan, so that we support both mode of operation - separate processes for miner and markets, as well as one process for miner and markets
  • Return nicer errors from unsupported api calls when subsystems are disabled
    • Not sure if we can do much better than if x == nil { error(module x is disabled) }
  • Improve dev experience with respect to setup

@magik6k
Copy link
Contributor

magik6k commented May 31, 2021

This will likely conflict with #6280 a bunch (it also cherry-picks from my PR)

@jacobheun jacobheun added epic/MRA team/ignite Issues and PRs being tracked by Team Ignite at Protocol Labs labels Jun 1, 2021
@nonsense nonsense force-pushed the nonsense/split-market-miner-processes branch from 68ab7b4 to 6b014f5 Compare July 7, 2021 12:15
Copy link
Contributor

@magik6k magik6k left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks almost mergable, just a couple of small comments

@@ -242,7 +243,14 @@ func ConfigCommon(cfg *config.Common) Option {
urls = append(urls, "http://"+ip+"/remote") // TODO: This makes no assumptions, and probably could...
return urls, nil
}),
ApplyIf(func(s *Settings) bool { return s.Online },
ApplyIf(func(s *Settings) bool { return s.Base }), // apply only if Base has already been applied
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking at this now, it probably makes more sense for this to Error if base isn't applied here

extern/sector-storage/stores/remote.go Show resolved Hide resolved
node/builder.go Outdated Show resolved Hide resolved
Override(new(stores.SectorIndex), From(new(modules.MinerSealingService))),
),

If(cfg.Subsystems.EnableStorageMarket,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why don't we include the LibP2P option here (and in the client options)? This should allow us to get rid of settings.enableLibp2pNode

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will give this a try, but I am not sure it is possible, as there are some configs that need to be applied earlier.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree. Now that we've separated Libp2p from Online, enableLibp2pNode maps directly to enabling the Libp2p aggregate. This should be feasible.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh wait, I think this may have to do with the fact that we need to read the Config to know whether to enable or not the libp2p node, right?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only when Markets is enabled in the miner config, should we enable libp2p. So it's a bit of a chicken and egg, and that's why it's convoluted.

Copy link
Member

@raulk raulk Jul 7, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, no. It should be possible, as ConfigStorageMiner and ConfigureFullNode have access to the config, and can decide whether to insert the Libp2p aggregate within the Options they return.

node/modules/storageminer.go Outdated Show resolved Hide resolved
Copy link
Member

@raulk raulk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Initial comments. We probably want to bring consistency between the terms "subsystem" and "service" -- we use them a bit interchangeably?

cmd/lotus-storage-miner/init_service.go Outdated Show resolved Hide resolved
node/config/def.go Outdated Show resolved Hide resolved
node/impl/common/mock/mock.go Outdated Show resolved Hide resolved
Comment on lines +56 to +62
PieceStore dtypes.ProviderPieceStore `optional:"true"`
StorageProvider storagemarket.StorageProvider `optional:"true"`
RetrievalProvider retrievalmarket.RetrievalProvider `optional:"true"`
DataTransfer dtypes.ProviderDataTransfer `optional:"true"`
DealPublisher *storageadapter.DealPublisher `optional:"true"`
SectorBlocks *sectorblocks.SectorBlocks `optional:"true"`
Host host.Host `optional:"true"`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should move these out to a MarketsAPI struct and embed it here.

node/impl/storminer.go Show resolved Hide resolved
Copy link
Member

@raulk raulk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, besides the comments! This was a heroic effort. Awesome work here, @nonsense and @magik6k ❤️ This is the start of a more modular Lotus!

Some top-level comments:

  • Let's standardise on the name "subsystem" or "service". We use both interchangeably and it's confusing (service in the cli tooling, subsystem in the config). Either is fine with me, unless we do want to use both because they refer to different things now, or we expect them to (e.g. service as a collection of subsystems?). If so, we should document the difference.
  • OK to merge the changes in the testkit as is. I can follow-up with a new PR to bring more order/structure to that and de-entropise.
  • We may need commands to query a lotus node to know which subsystems is running, and to know which other APIs it's interacting with, but that can be a follow-up.

extern/sector-storage/manager.go Outdated Show resolved Hide resolved
extern/storage-sealing/input.go Show resolved Hide resolved
node/modules/storageminer.go Show resolved Hide resolved
node/modules/storageminer.go Outdated Show resolved Hide resolved
cmd/lotus-storage-miner/init_restore.go Outdated Show resolved Hide resolved
Comment on lines 61 to 63
if err := checkV1ApiSupport(ctx, cctx); err != nil {
return err
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't need this any longer?

if cctx.Args().Len() != 1 {
return xerrors.Errorf("expected 1 argument")
}
func restore(ctx context.Context, cctx *cli.Context, manageConfig func(*config.StorageMiner) error, after func(api lapi.FullNode, addr address.Address, peerid peer.ID, mi miner.MinerInfo) error) error {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FYI, I wasn't able to review this file because the diff is too noisy and I'm not familiar with this command. I trust @magik6k here.

cmd/lotus-storage-miner/run.go Show resolved Hide resolved
cmd/lotus-storage-miner/init_service.go Outdated Show resolved Hide resolved
@nonsense nonsense force-pushed the nonsense/split-market-miner-processes branch from c884d81 to 7728d6b Compare July 12, 2021 12:38
Copy link
Contributor

@magik6k magik6k left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, I think this is in good enough shape to land in master, just one cosmetic suggestion.

Name: "enable-market",
Usage: "enable market module",
&cli.StringSliceFlag{
Name: "name",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe type? lotus-miner init service --name markets ... looks a bit weild

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Renamed to type.

@nonsense nonsense force-pushed the nonsense/split-market-miner-processes branch from 4299bdd to 2af02af Compare July 13, 2021 10:57
@nonsense
Copy link
Member Author

nonsense commented Jul 13, 2021

@magik6k @raulk in the last commit (2af02af), I renamed --name to --type and also addressed the UX problems with storage-config.json:

restore is used both for backup restoration and for initialisation of new services, so it needs to support 3 modes:

  • restoring from backup where the user wants to restore a given storage-config.json
  • restoring from backup where the user wants to restore other parts from their backup, and keep their existing storage-config.json
  • initialising a new markets type service, where we need a blank storage-config.json (with empty set of StoragePaths), since at the moment Remote requires a Local store, which requires a proper config.

So parsing of the storage-config.json is extracted away, and we call restore with the necessary *stores.StorageConfig


Docs at filecoin-project/filecoin-docs#890 have also been addressed to not mention storage-config.json anymore and use --type, so UX is better now for miners who want to split the monolith.

Copy link
Contributor

@magik6k magik6k left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@magik6k magik6k merged commit 837322e into master Jul 13, 2021
@magik6k magik6k deleted the nonsense/split-market-miner-processes branch July 13, 2021 15:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
P2 P2: Should be resolved team/ignite Issues and PRs being tracked by Team Ignite at Protocol Labs
Projects
None yet
Development

Successfully merging this pull request may close these issues.

concept of a miner DMZ
6 participants