Change consensus API to a single ResolveVirtual call

This commit is contained in:
msutton 2022-07-08 11:38:39 +03:00
parent fa20e016cb
commit 92e0051b3b
5 changed files with 63 additions and 60 deletions

View File

@ -686,31 +686,24 @@ func (flow *handleIBDFlow) banIfBlockIsHeaderOnly(block *externalapi.DomainBlock
} }
func (flow *handleIBDFlow) resolveVirtual(estimatedVirtualDAAScoreTarget uint64) error { func (flow *handleIBDFlow) resolveVirtual(estimatedVirtualDAAScoreTarget uint64) error {
virtualDAAScoreStart, err := flow.Domain().Consensus().GetVirtualDAAScore() err := flow.Domain().Consensus().ResolveVirtual(func(virtualDAAScoreStart uint64, virtualDAAScore uint64) {
if err != nil {
return err
}
for i := 0; ; i++ {
if i%10 == 0 {
virtualDAAScore, err := flow.Domain().Consensus().GetVirtualDAAScore()
if err != nil {
return err
}
var percents int var percents int
if estimatedVirtualDAAScoreTarget-virtualDAAScoreStart <= 0 { if estimatedVirtualDAAScoreTarget-virtualDAAScoreStart <= 0 {
percents = 100 percents = 100
} else { } else {
percents = int(float64(virtualDAAScore-virtualDAAScoreStart) / float64(estimatedVirtualDAAScoreTarget-virtualDAAScoreStart) * 100) percents = int(float64(virtualDAAScore-virtualDAAScoreStart) / float64(estimatedVirtualDAAScoreTarget-virtualDAAScoreStart) * 100)
} }
log.Infof("Resolving virtual. Estimated progress: %d%%", percents) if percents < 0 {
percents = 0
} else if percents > 100 {
percents = 100
} }
isCompletelyResolved, err := flow.Domain().Consensus().ResolveVirtual() log.Infof("Resolving virtual. Estimated progress: %d%%", percents)
})
if err != nil { if err != nil {
return err return err
} }
if isCompletelyResolved {
log.Infof("Resolved virtual") log.Infof("Resolved virtual")
err = flow.OnNewBlockTemplate() err = flow.OnNewBlockTemplate()
if err != nil { if err != nil {
@ -718,5 +711,3 @@ func (flow *handleIBDFlow) resolveVirtual(estimatedVirtualDAAScoreTarget uint64)
} }
return nil return nil
} }
}
}

View File

@ -888,15 +888,42 @@ func (s *consensus) PopulateMass(transaction *externalapi.DomainTransaction) {
s.transactionValidator.PopulateMass(transaction) s.transactionValidator.PopulateMass(transaction)
} }
func (s *consensus) ResolveVirtual() (bool, error) { func (s *consensus) ResolveVirtual(progressReportCallback func(uint64, uint64)) error {
s.lock.Lock() virtualDAAScoreStart, err := s.GetVirtualDAAScore()
defer s.lock.Unlock() if err != nil {
return err
}
for i := 0; ; i++ {
if i%10 == 0 {
virtualDAAScore, err := s.GetVirtualDAAScore()
if err != nil {
return err
}
progressReportCallback(virtualDAAScoreStart, virtualDAAScore)
}
// In order to prevent a situation that the consensus lock is held for too much time, we // In order to prevent a situation that the consensus lock is held for too much time, we
// release the lock each time resolve 100 blocks. // release the lock each time resolve 100 blocks.
// Note: maxBlocksToResolve should be smaller than finality interval in order to avoid a situation // Note: maxBlocksToResolve should be smaller than finality interval in order to avoid a situation
// where UpdatePruningPointByVirtual skips a pruning point. // where UpdatePruningPointByVirtual skips a pruning point.
return s.resolveVirtualNoLock(100) isCompletelyResolved, err := s.resolveVirtualChunkWithLock(100)
if err != nil {
return err
}
if isCompletelyResolved {
break
}
}
return nil
}
func (s *consensus) resolveVirtualChunkWithLock(maxBlocksToResolve uint64) (bool, error) {
s.lock.Lock()
defer s.lock.Unlock()
return s.resolveVirtualNoLock(maxBlocksToResolve)
} }
func (s *consensus) resolveVirtualNoLock(maxBlocksToResolve uint64) (bool, error) { func (s *consensus) resolveVirtualNoLock(maxBlocksToResolve uint64) (bool, error) {

View File

@ -590,7 +590,7 @@ func TestFinalityResolveVirtual(t *testing.T) {
} }
for i := 0; ; i++ { for i := 0; ; i++ {
isCompletelyResolved, err := tc.ResolveVirtual() err := tc.ResolveVirtual(nil)
if err != nil { if err != nil {
panic(err) panic(err)
} }

View File

@ -48,7 +48,7 @@ type Consensus interface {
Anticone(blockHash *DomainHash) ([]*DomainHash, error) Anticone(blockHash *DomainHash) ([]*DomainHash, error)
EstimateNetworkHashesPerSecond(startHash *DomainHash, windowSize int) (uint64, error) EstimateNetworkHashesPerSecond(startHash *DomainHash, windowSize int) (uint64, error)
PopulateMass(transaction *DomainTransaction) PopulateMass(transaction *DomainTransaction)
ResolveVirtual() (bool, error) ResolveVirtual(progressReportCallback func(uint64, uint64)) error
BlockDAAWindowHashes(blockHash *DomainHash) ([]*DomainHash, error) BlockDAAWindowHashes(blockHash *DomainHash) ([]*DomainHash, error)
TrustedDataDataDAAHeader(trustedBlockHash, daaBlockHash *DomainHash, daaBlockWindowIndex uint64) (*TrustedDataDataDAAHeader, error) TrustedDataDataDAAHeader(trustedBlockHash, daaBlockHash *DomainHash, daaBlockWindowIndex uint64) (*TrustedDataDataDAAHeader, error)
TrustedBlockAssociatedGHOSTDAGDataBlockHashes(blockHash *DomainHash) ([]*DomainHash, error) TrustedBlockAssociatedGHOSTDAGDataBlockHashes(blockHash *DomainHash) ([]*DomainHash, error)

View File

@ -214,34 +214,19 @@ func syncConsensuses(syncer, syncee externalapi.Consensus) error {
return err return err
} }
virtualDAAScoreStart, err := syncee.GetVirtualDAAScore() err = syncer.ResolveVirtual(func(virtualDAAScoreStart uint64, virtualDAAScore uint64) {
if err != nil { if estimatedVirtualDAAScoreTarget-virtualDAAScoreStart <= 0 {
return err percents = 100
} else {
percents = int(float64(virtualDAAScore-virtualDAAScoreStart) / float64(estimatedVirtualDAAScoreTarget-virtualDAAScoreStart) * 100)
} }
percents = 0
for i := 0; ; i++ {
if i%10 == 0 {
virtualDAAScore, err := syncee.GetVirtualDAAScore()
if err != nil {
return err
}
newPercents := int(float64(virtualDAAScore-virtualDAAScoreStart) / float64(estimatedVirtualDAAScoreTarget-virtualDAAScoreStart) * 100)
if newPercents > percents {
percents = newPercents
log.Infof("Resolving virtual. Estimated progress: %d%%", percents) log.Infof("Resolving virtual. Estimated progress: %d%%", percents)
} })
}
isCompletelyResolved, err := syncee.ResolveVirtual()
if err != nil { if err != nil {
return err return err
} }
if isCompletelyResolved {
log.Infof("Resolved virtual") log.Infof("Resolved virtual")
break
}
}
return nil return nil
} }