Ori Newman d748089a14
Update the virtual after overriding the virtual UTXO set (#1811)
* Update the virtual after overriding the virtual utxo set

* Put the updateVirtual inside importVirtualUTXOSetAndPruningPointUTXOSet

* Add pruningPoint to importVirtualUTXOSetAndPruningPointUTXOSet

* Remove sanity check
2021-08-02 17:02:15 +03:00

94 lines
2.5 KiB
Go

package consensusstatemanager
import (
"github.com/kaspanet/kaspad/domain/consensus/model"
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
"github.com/kaspanet/kaspad/infrastructure/logger"
"github.com/kaspanet/kaspad/util/staging"
"sort"
)
func (csm *consensusStateManager) ResolveVirtual(maxBlocksToResolve uint64) (bool, error) {
onEnd := logger.LogAndMeasureExecutionTime(log, "csm.ResolveVirtual")
defer onEnd()
readStagingArea := model.NewStagingArea()
tips, err := csm.consensusStateStore.Tips(readStagingArea, csm.databaseContext)
if err != nil {
return false, err
}
var sortErr error
sort.Slice(tips, func(i, j int) bool {
selectedParent, err := csm.ghostdagManager.ChooseSelectedParent(readStagingArea, tips[i], tips[j])
if err != nil {
sortErr = err
return false
}
return selectedParent.Equal(tips[i])
})
if sortErr != nil {
return false, sortErr
}
var selectedTip *externalapi.DomainHash
isCompletelyResolved := true
for _, tip := range tips {
log.Infof("Resolving tip %s", tip)
resolveStagingArea := model.NewStagingArea()
unverifiedBlocks, err := csm.getUnverifiedChainBlocks(resolveStagingArea, tip)
if err != nil {
return false, err
}
resolveTip := tip
hasMoreUnverifiedThanMax := maxBlocksToResolve != 0 && uint64(len(unverifiedBlocks)) > maxBlocksToResolve
if hasMoreUnverifiedThanMax {
resolveTip = unverifiedBlocks[uint64(len(unverifiedBlocks))-maxBlocksToResolve]
log.Infof("Has more than %d blocks to resolve. Changing the resolve tip to %s", maxBlocksToResolve, resolveTip)
}
blockStatus, reversalData, err := csm.resolveBlockStatus(resolveStagingArea, resolveTip, true)
if err != nil {
return false, err
}
if blockStatus == externalapi.StatusUTXOValid {
selectedTip = resolveTip
isCompletelyResolved = !hasMoreUnverifiedThanMax
err = staging.CommitAllChanges(csm.databaseContext, resolveStagingArea)
if err != nil {
return false, err
}
if reversalData != nil {
err = csm.ReverseUTXODiffs(resolveTip, reversalData)
if err != nil {
return false, err
}
}
break
}
}
if selectedTip == nil {
log.Warnf("Non of the DAG tips are valid")
return true, nil
}
updateVirtualStagingArea := model.NewStagingArea()
_, err = csm.updateVirtualWithParents(updateVirtualStagingArea, []*externalapi.DomainHash{selectedTip})
if err != nil {
return false, err
}
err = staging.CommitAllChanges(csm.databaseContext, updateVirtualStagingArea)
if err != nil {
return false, err
}
return isCompletelyResolved, nil
}