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

feat: chainstore: batch writes of tipsets #10800

Merged
merged 1 commit into from
May 2, 2023
Merged

Conversation

arajasek
Copy link
Contributor

@arajasek arajasek commented May 2, 2023

Related Issues

Helps with #10788, but does NOT close it.

Proposed Changes

  • Refactor the chainstore to persist tipsets in a batch
  • The batching logic already exists, so this is mostly about providing input in a batch to this method

Additional Info

When syncing calibnet, this reduces the time to persist all headers from 4-5 minutes, to < 15 seconds. This will have less of an impact for folks syncing from snapshots, but is still a worthwhile perf gain.

Checklist

Before you mark the PR ready for review, please make sure that:

  • Commits have a clear commit message.
  • PR title is in the form of of <PR type>: <area>: <change being made>
    • example: fix: mempool: Introduce a cache for valid signatures
    • PR type: fix, feat, build, chore, ci, docs, perf, refactor, revert, style, test
    • area, e.g. api, chain, state, market, mempool, multisig, networking, paych, proving, sealing, wallet, deps
  • New features have usage guidelines and / or documentation updates in
  • Tests exist for new functionality or change in behavior
  • CI is green

@arajasek arajasek requested a review from a team as a code owner May 2, 2023 14:10
return xerrors.Errorf("failed to persist block headers: %w", err)
func (cs *ChainStore) PersistTipsets(ctx context.Context, tipsets []*types.TipSet) error {
toPersist := make([]*types.BlockHeader, 0, len(tipsets)*int(build.BlocksPerEpoch))
tsBlks := make([]block.Block, 0, len(tipsets)*int(build.BlocksPerEpoch))
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
tsBlks := make([]block.Block, 0, len(tipsets)*int(build.BlocksPerEpoch))
tsBlks := make([]block.Block, 0, len(tipsets))

@@ -123,11 +123,9 @@ func (cs *ChainStore) Import(ctx context.Context, r io.Reader) (*types.TipSet, e
}

ts := root
tssToPersist := make([]*types.TipSet, 0, uint64(TipsetkeyBackfillRange)*build.BlocksPerEpoch)
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
tssToPersist := make([]*types.TipSet, 0, uint64(TipsetkeyBackfillRange)*build.BlocksPerEpoch)
tssToPersist := make([]*types.TipSet, 0, uint64(TipsetkeyBackfillRange))

return xerrors.Errorf("failed to persist block headers: %w", err)
func (cs *ChainStore) PersistTipsets(ctx context.Context, tipsets []*types.TipSet) error {
toPersist := make([]*types.BlockHeader, 0, len(tipsets)*int(build.BlocksPerEpoch))
tsBlks := make([]block.Block, 0, len(tipsets)*int(build.BlocksPerEpoch))
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: capacity should just be len(tipsets) since theres one ts key per tipset. You could also just use the iteration index from range tipsets and set the slice directly since you know the exact size on initialization unlike the slice of blocks.

@@ -123,11 +123,9 @@ func (cs *ChainStore) Import(ctx context.Context, r io.Reader) (*types.TipSet, e
}

ts := root
tssToPersist := make([]*types.TipSet, 0, uint64(TipsetkeyBackfillRange)*build.BlocksPerEpoch)
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: drop *build.BlocksPerEpoch since one slice item per tipset

if err != nil {
return nil, err
}
tssToPersist = append(tssToPersist, ts)
parentTsKey := ts.Parents()
ts, err = cs.LoadTipSet(ctx, parentTsKey)
Copy link
Contributor

Choose a reason for hiding this comment

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

Sanity checking since I don't know this code: is this actually going to work now that we are not persisting tipsets one by one in this loop before the check? We're putting these tipsets to cs somewhere else first right?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

My understanding is yes, because we've already Put all of these objects into our store above. This loop is about:

  • sanity checking that we have them
  • writing the TsKeys into the store for Eth stuff

It's probably not actually any faster to batch this, but I figured we might as well for cleanness.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants