Update Slices More Efficiently (#4789)

* better cached states

* lint

* jim's review
This commit is contained in:
Nishant Das
2020-02-07 23:06:39 +08:00
committed by GitHub
parent 7ba2c897ad
commit 669e1ea787
5 changed files with 32 additions and 5 deletions

View File

@@ -22,6 +22,12 @@ type ChainInfoFetcher interface {
FinalizationFetcher
}
// ChainCleaner describes an interface to clean obsolete data
// stored in the blockchain service.
type ChainCleaner interface {
ClearCachedStates()
}
// TimeFetcher retrieves the Eth2 data that's related to time.
type TimeFetcher interface {
GenesisTime() time.Time

View File

@@ -269,6 +269,12 @@ func (s *Service) Status() error {
return nil
}
// ClearCachedStates removes all stored caches states. This is done after the node
// is synced.
func (s *Service) ClearCachedStates() {
s.initSyncState = map[[32]byte]*stateTrie.BeaconState{}
}
// This gets called to update canonical root mapping.
func (s *Service) saveHead(ctx context.Context, signed *ethpb.SignedBeaconBlock, r [32]byte) error {
s.headLock.Lock()

View File

@@ -231,3 +231,8 @@ func (ms *ChainService) Participation(epoch uint64) *precompute.Balance {
func (ms *ChainService) IsValidAttestation(ctx context.Context, att *ethpb.Attestation) bool {
return ms.ValidAttestation
}
// ClearCachedStates is a no-op.
func (ms *ChainService) ClearCachedStates() {
// no-op
}

View File

@@ -106,7 +106,9 @@ func (b *BeaconState) UpdateBlockRootAtIndex(idx uint64, blockRoot [32]byte) err
r := b.state.BlockRoots
if ref := b.sharedFieldReferences[blockRoots]; ref.refs > 1 {
// Copy on write since this is a shared array.
r = b.BlockRoots()
newRoots := make([][]byte, len(r))
copy(newRoots, r)
r = newRoots
ref.refs--
b.sharedFieldReferences[blockRoots] = &reference{refs: 1}
@@ -150,7 +152,9 @@ func (b *BeaconState) UpdateStateRootAtIndex(idx uint64, stateRoot [32]byte) err
r := b.state.StateRoots
if ref := b.sharedFieldReferences[stateRoots]; ref.refs > 1 {
// Perform a copy since this is a shared reference and we don't want to mutate others.
r = b.StateRoots()
newRoots := make([][]byte, len(r))
copy(newRoots, r)
r = newRoots
ref.refs--
b.sharedFieldReferences[stateRoots] = &reference{refs: 1}
@@ -289,8 +293,9 @@ func (b *BeaconState) UpdateValidatorAtIndex(idx uint64, val *ethpb.Validator) e
v := b.state.Validators
if ref := b.sharedFieldReferences[validators]; ref.refs > 1 {
// Perform a copy since this is a shared reference and we don't want to mutate others.
v = b.Validators()
newVals := make([]*ethpb.Validator, len(v))
copy(newVals, v)
v = newVals
ref.refs--
b.sharedFieldReferences[validators] = &reference{refs: 1}
}
@@ -381,7 +386,9 @@ func (b *BeaconState) UpdateRandaoMixesAtIndex(val []byte, idx uint64) error {
b.lock.RLock()
mixes := b.state.RandaoMixes
if refs := b.sharedFieldReferences[randaoMixes].refs; refs > 1 {
mixes = b.RandaoMixes()
newSlice := make([][]byte, len(mixes))
copy(newSlice, mixes)
mixes = newSlice
b.sharedFieldReferences[randaoMixes].refs--
b.sharedFieldReferences[randaoMixes] = &reference{refs: 1}
}

View File

@@ -25,6 +25,7 @@ var _ = shared.Service(&Service{})
type blockchainService interface {
blockchain.BlockReceiver
blockchain.HeadFetcher
blockchain.ChainCleaner
}
const (
@@ -129,6 +130,7 @@ func (s *Service) Start() {
}
log.Infof("Synced up to slot %d", s.chain.HeadSlot())
s.synced = true
s.chain.ClearCachedStates()
}
// Stop initial sync.
@@ -167,6 +169,7 @@ func (s *Service) Resync() error {
log = log.WithError(err)
}
log.WithField("slot", s.chain.HeadSlot()).Info("Resync attempt complete")
s.chain.ClearCachedStates()
return nil
}