Merge pull request #1705 from hayeah/cache-tipset-validation-progress

Cache tipset validation progress
This commit is contained in:
Aayush Rajasekaran 2020-06-16 00:14:11 -04:00 committed by GitHub
commit aa513d920e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 40 additions and 2 deletions

View File

@ -47,6 +47,7 @@ import (
var log = logging.Logger("chainstore") var log = logging.Logger("chainstore")
var chainHeadKey = dstore.NewKey("head") var chainHeadKey = dstore.NewKey("head")
var blockValidationCacheKeyPrefix = dstore.NewKey("blockValidation")
type ChainStore struct { type ChainStore struct {
bs bstore.Blockstore bs bstore.Blockstore
@ -215,6 +216,22 @@ func (cs *ChainStore) SubscribeHeadChanges(f func(rev, app []*types.TipSet) erro
cs.headChangeNotifs = append(cs.headChangeNotifs, f) cs.headChangeNotifs = append(cs.headChangeNotifs, f)
} }
func (cs *ChainStore) IsBlockValidated(ctx context.Context, blkid cid.Cid) (bool, error) {
key := blockValidationCacheKeyPrefix.Instance(blkid.String())
return cs.ds.Has(key)
}
func (cs *ChainStore) MarkBlockAsValidated(ctx context.Context, blkid cid.Cid) error {
key := blockValidationCacheKeyPrefix.Instance(blkid.String())
if err := cs.ds.Put(key, []byte{0}); err != nil {
return xerrors.Errorf("cache block validation: %w", err)
}
return nil
}
func (cs *ChainStore) SetGenesis(b *types.BlockHeader) error { func (cs *ChainStore) SetGenesis(b *types.BlockHeader) error {
ts, err := types.NewTipSet([]*types.BlockHeader{b}) ts, err := types.NewTipSet([]*types.BlockHeader{b})
if err != nil { if err != nil {

View File

@ -529,7 +529,24 @@ func blockSanityChecks(h *types.BlockHeader) error {
} }
// Should match up with 'Semantical Validation' in validation.md in the spec // Should match up with 'Semantical Validation' in validation.md in the spec
func (syncer *Syncer) ValidateBlock(ctx context.Context, b *types.FullBlock) error { func (syncer *Syncer) ValidateBlock(ctx context.Context, b *types.FullBlock) (err error) {
defer func() {
// b.Cid() could panic for empty blocks that are used in tests.
if rerr := recover(); rerr != nil {
err = xerrors.Errorf("validate block panic: %w", rerr)
return
}
}()
isValidated, err := syncer.store.IsBlockValidated(ctx, b.Cid())
if err != nil {
return xerrors.Errorf("check block validation cache %s: %w", b.Cid(), err)
}
if isValidated {
return nil
}
validationStart := time.Now() validationStart := time.Now()
defer func() { defer func() {
dur := time.Since(validationStart) dur := time.Since(validationStart)
@ -759,7 +776,11 @@ func (syncer *Syncer) ValidateBlock(ctx context.Context, b *types.FullBlock) err
} }
} }
return merr if err := syncer.store.MarkBlockAsValidated(ctx, b.Cid()); err != nil {
return xerrors.Errorf("caching block validation %s: %w", b.Cid(), err)
}
return nil
} }
func (syncer *Syncer) VerifyWinningPoStProof(ctx context.Context, h *types.BlockHeader, prevBeacon types.BeaconEntry, lbst cid.Cid, waddr address.Address) error { func (syncer *Syncer) VerifyWinningPoStProof(ctx context.Context, h *types.BlockHeader, prevBeacon types.BeaconEntry, lbst cid.Cid, waddr address.Address) error {