mirror of
https://github.com/kaspanet/kaspad.git
synced 2025-06-12 00:56:42 +00:00
[NOD-1555] Use stageDiff to update virtualDiffParents (#1139)
* [NOD-1555] Filter ancestors in updateVirtualDiffParents * [NOD-1555] Use stageDiff to update virtualDiffParents * [NOD-1555] Don't add existing blocks in addToVirtualDiffParents * [NOD-1555] Remove redundant check * [NOD-1555] Fix log and rename removeAncestorsFromVirtualDiffParents->removeAncestorsFromVirtualDiffParentsAndAssignDiffChild * [NOD-1555] Add logs * [NOD-1555] Fix comment * [NOD-1555] Fix logs
This commit is contained in:
parent
dec9ef5f75
commit
c1505b4748
@ -62,7 +62,7 @@ func (bss *blockStatusStore) Get(dbContext model.DBReader, blockHash *externalap
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return bss.deserializeHeader(statusBytes)
|
||||
return bss.deserializeBlockStatus(statusBytes)
|
||||
}
|
||||
|
||||
// Exists returns true if the blockStatus for the given blockHash exists
|
||||
@ -84,7 +84,7 @@ func (bss *blockStatusStore) serializeBlockStatus(status externalapi.BlockStatus
|
||||
return proto.Marshal(dbBlockStatus)
|
||||
}
|
||||
|
||||
func (bss *blockStatusStore) deserializeHeader(statusBytes []byte) (externalapi.BlockStatus, error) {
|
||||
func (bss *blockStatusStore) deserializeBlockStatus(statusBytes []byte) (externalapi.BlockStatus, error) {
|
||||
dbBlockStatus := &serialization.DbBlockStatus{}
|
||||
err := proto.Unmarshal(statusBytes, dbBlockStatus)
|
||||
if err != nil {
|
||||
|
@ -157,67 +157,67 @@ func (csm *consensusStateManager) resolveSingleBlockStatus(blockHash *externalap
|
||||
csm.multisetStore.Stage(blockHash, multiset)
|
||||
|
||||
log.Tracef("Staging the utxoDiff of block %s", blockHash)
|
||||
err = csm.utxoDiffStore.Stage(blockHash, pastUTXODiff, nil)
|
||||
err = csm.stageDiff(blockHash, pastUTXODiff, nil)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
log.Tracef("Updating the parent utxoDiffs of block %s", blockHash)
|
||||
err = csm.updateParentDiffs(blockHash, pastUTXODiff)
|
||||
log.Tracef("Remove block ancestors from virtual diff parents and assign %s as their diff child", blockHash)
|
||||
err = csm.removeAncestorsFromVirtualDiffParentsAndAssignDiffChild(blockHash, pastUTXODiff)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return externalapi.StatusValid, nil
|
||||
}
|
||||
func (csm *consensusStateManager) updateParentDiffs(
|
||||
blockHash *externalapi.DomainHash, pastUTXODiff *model.UTXODiff) error {
|
||||
log.Tracef("updateParentDiffs start for block %s", blockHash)
|
||||
defer log.Tracef("updateParentDiffs end for block %s", blockHash)
|
||||
|
||||
parentHashes, err := csm.dagTopologyManager.Parents(blockHash)
|
||||
func (csm *consensusStateManager) removeAncestorsFromVirtualDiffParentsAndAssignDiffChild(
|
||||
blockHash *externalapi.DomainHash, pastUTXODiff *model.UTXODiff) error {
|
||||
|
||||
log.Tracef("removeAncestorsFromVirtualDiffParentsAndAssignDiffChild start for block %s", blockHash)
|
||||
defer log.Tracef("removeAncestorsFromVirtualDiffParentsAndAssignDiffChild end for block %s", blockHash)
|
||||
|
||||
if *blockHash == *csm.genesisHash {
|
||||
log.Tracef("Genesis block doesn't have ancestors to remove from the virtual diff parents")
|
||||
return nil
|
||||
}
|
||||
|
||||
virtualDiffParents, err := csm.consensusStateStore.VirtualDiffParents(csm.databaseContext)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
log.Tracef("Parent hashes for block %s are: %s", blockHash, parentHashes)
|
||||
|
||||
for _, parentHash := range parentHashes {
|
||||
// skip all parents that already have a utxo-diff child
|
||||
parentHasUTXODiffChild, err := csm.utxoDiffStore.HasUTXODiffChild(csm.databaseContext, parentHash)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if parentHasUTXODiffChild {
|
||||
log.Tracef("Skipping parent %s of block %s because it "+
|
||||
"already has a UTXO diff-child", parentHash, blockHash)
|
||||
for _, virtualDiffParent := range virtualDiffParents {
|
||||
if *virtualDiffParent == *blockHash {
|
||||
log.Tracef("Skipping updating virtual diff parent %s "+
|
||||
"because it was updated before.", virtualDiffParent)
|
||||
continue
|
||||
}
|
||||
|
||||
parentStatus, err := csm.blockStatusStore.Get(csm.databaseContext, parentHash)
|
||||
isAncestorOfBlock, err := csm.dagTopologyManager.IsAncestorOf(virtualDiffParent, blockHash)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if parentStatus != externalapi.StatusValid {
|
||||
log.Tracef("Skipping parent %s of block %s because it "+
|
||||
"has a non-valid status %s", parentHash, blockHash, parentStatus)
|
||||
|
||||
if !isAncestorOfBlock {
|
||||
log.Tracef("Skipping block %s because it's not an "+
|
||||
"ancestor of %s", virtualDiffParent, blockHash)
|
||||
continue
|
||||
}
|
||||
|
||||
// parents that didn't have a utxo-diff child until now were actually virtual's diffParents.
|
||||
// Update them to have the new block as their utxo-diff child
|
||||
log.Tracef("Resolving new UTXO diff of parent %s", parentHash)
|
||||
parentCurrentDiff, err := csm.utxoDiffStore.UTXODiff(csm.databaseContext, parentHash)
|
||||
log.Tracef("Updating %s to be the diff child of %s", blockHash, virtualDiffParent)
|
||||
currentDiff, err := csm.utxoDiffStore.UTXODiff(csm.databaseContext, virtualDiffParent)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
parentNewDiff, err := utxoalgebra.DiffFrom(pastUTXODiff, parentCurrentDiff)
|
||||
newDiff, err := utxoalgebra.DiffFrom(pastUTXODiff, currentDiff)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
log.Tracef("The new UTXO diff parent %s resolved to: %s", parentHash, parentNewDiff)
|
||||
|
||||
log.Tracef("Staging the new UTXO diff and diff child for parent %s", parentHash)
|
||||
err = csm.utxoDiffStore.Stage(parentHash, parentNewDiff, blockHash)
|
||||
err = csm.stageDiff(virtualDiffParent, newDiff, blockHash)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -90,7 +90,7 @@ func (csm *consensusStateManager) setPruningPointUTXOSet(serializedUTXOSet []byt
|
||||
}
|
||||
|
||||
log.Tracef("Updating the header tips pruning point diff parents with an empty UTXO diff")
|
||||
err = csm.updateVirtualDiffParents(headerTipsPruningPoint, model.NewUTXODiff())
|
||||
err = csm.updateVirtualDiffParents(model.NewUTXODiff())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -4,7 +4,6 @@ import (
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/processes/consensusstatemanager/utxoalgebra"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/hashset"
|
||||
)
|
||||
|
||||
func (csm *consensusStateManager) updateVirtual(newBlockHash *externalapi.DomainHash, tips []*externalapi.DomainHash) error {
|
||||
@ -51,7 +50,7 @@ func (csm *consensusStateManager) updateVirtual(newBlockHash *externalapi.Domain
|
||||
}
|
||||
|
||||
log.Tracef("Updating the virtual diff parents after adding %s to the DAG", newBlockHash)
|
||||
err = csm.updateVirtualDiffParents(newBlockHash, virtualUTXODiff)
|
||||
err = csm.updateVirtualDiffParents(virtualUTXODiff)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -59,52 +58,16 @@ func (csm *consensusStateManager) updateVirtual(newBlockHash *externalapi.Domain
|
||||
return nil
|
||||
}
|
||||
|
||||
func (csm *consensusStateManager) updateVirtualDiffParents(
|
||||
newBlockHash *externalapi.DomainHash, virtualUTXODiff *model.UTXODiff) error {
|
||||
func (csm *consensusStateManager) updateVirtualDiffParents(virtualUTXODiff *model.UTXODiff) error {
|
||||
log.Tracef("updateVirtualDiffParents start")
|
||||
defer log.Tracef("updateVirtualDiffParents end")
|
||||
|
||||
log.Tracef("updateVirtualDiffParents start for block %s", newBlockHash)
|
||||
defer log.Tracef("updateVirtualDiffParents end for block %s", newBlockHash)
|
||||
|
||||
var newVirtualDiffParents []*externalapi.DomainHash
|
||||
if *newBlockHash == *csm.genesisHash {
|
||||
log.Tracef("Block %s is the genesis, so by definition "+
|
||||
"it is the only member of the new virtual diff parents set", newBlockHash)
|
||||
newVirtualDiffParents = []*externalapi.DomainHash{newBlockHash}
|
||||
} else {
|
||||
oldVirtualDiffParents, err := csm.consensusStateStore.VirtualDiffParents(csm.databaseContext)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
log.Tracef("The old virtual's diff parents are: %s", oldVirtualDiffParents)
|
||||
|
||||
// If the status of the new block is not `Valid` - virtualDiffParents didn't change
|
||||
status, err := csm.blockStatusStore.Get(csm.databaseContext, newBlockHash)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if status != externalapi.StatusValid {
|
||||
log.Tracef("The status of the new block %s is non-valid. "+
|
||||
"As such, don't change the diff parents of the virtual", newBlockHash)
|
||||
newVirtualDiffParents = oldVirtualDiffParents
|
||||
} else {
|
||||
log.Tracef("Block %s is valid. Updating the virtual diff parents", newBlockHash)
|
||||
newBlockParentsSlice, err := csm.dagTopologyManager.Parents(newBlockHash)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
newBlockParents := hashset.NewFromSlice(newBlockParentsSlice...)
|
||||
|
||||
newVirtualDiffParents = []*externalapi.DomainHash{newBlockHash}
|
||||
for _, virtualDiffParent := range oldVirtualDiffParents {
|
||||
if !newBlockParents.Contains(virtualDiffParent) {
|
||||
newVirtualDiffParents = append(newVirtualDiffParents, virtualDiffParent)
|
||||
}
|
||||
}
|
||||
}
|
||||
virtualDiffParents, err := csm.consensusStateStore.VirtualDiffParents(csm.databaseContext)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
log.Tracef("The new virtual diff parents are: %s", newVirtualDiffParents)
|
||||
|
||||
for _, virtualDiffParent := range newVirtualDiffParents {
|
||||
for _, virtualDiffParent := range virtualDiffParents {
|
||||
log.Tracef("Calculating new UTXO diff for virtual diff parent %s", virtualDiffParent)
|
||||
virtualDiffParentUTXODiff, err := csm.utxoDiffStore.UTXODiff(csm.databaseContext, virtualDiffParent)
|
||||
if err != nil {
|
||||
@ -114,13 +77,13 @@ func (csm *consensusStateManager) updateVirtualDiffParents(
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Tracef("Staging new UTXO diff for virtual diff parent %s: %s", virtualDiffParent, newDiff)
|
||||
err = csm.utxoDiffStore.Stage(virtualDiffParent, newDiff, nil)
|
||||
err = csm.stageDiff(virtualDiffParent, newDiff, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
log.Tracef("Staging the new virtual UTXO diff parents")
|
||||
return csm.consensusStateStore.StageVirtualDiffParents(newVirtualDiffParents)
|
||||
return nil
|
||||
}
|
||||
|
@ -0,0 +1,84 @@
|
||||
package consensusstatemanager
|
||||
|
||||
import (
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
func (csm *consensusStateManager) stageDiff(blockHash *externalapi.DomainHash,
|
||||
utxoDiff *model.UTXODiff, utxoDiffChild *externalapi.DomainHash) error {
|
||||
|
||||
log.Tracef("stageDiff start for block %s", blockHash)
|
||||
defer log.Tracef("stageDiff end for block %s", blockHash)
|
||||
|
||||
log.Tracef("Staging block %s as the diff child of %s", utxoDiffChild, blockHash)
|
||||
err := csm.utxoDiffStore.Stage(blockHash, utxoDiff, utxoDiffChild)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if utxoDiffChild == nil {
|
||||
log.Tracef("Adding block %s to the virtual diff parents", blockHash)
|
||||
return csm.addToVirtualDiffParents(blockHash)
|
||||
}
|
||||
|
||||
log.Tracef("Removing block %s from the virtual diff parents", blockHash)
|
||||
return csm.removeFromVirtualDiffParents(blockHash)
|
||||
}
|
||||
|
||||
func (csm *consensusStateManager) addToVirtualDiffParents(blockHash *externalapi.DomainHash) error {
|
||||
log.Tracef("addToVirtualDiffParents start for block %s", blockHash)
|
||||
defer log.Tracef("addToVirtualDiffParents end for block %s", blockHash)
|
||||
|
||||
var oldVirtualDiffParents []*externalapi.DomainHash
|
||||
if *blockHash != *csm.genesisHash {
|
||||
var err error
|
||||
oldVirtualDiffParents, err = csm.consensusStateStore.VirtualDiffParents(csm.databaseContext)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
isInVirtualDiffParents := false
|
||||
for _, diffParent := range oldVirtualDiffParents {
|
||||
if *diffParent == *blockHash {
|
||||
isInVirtualDiffParents = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if isInVirtualDiffParents {
|
||||
log.Tracef("Block %s is already a virtual diff parent, so there's no need to add it", blockHash)
|
||||
return nil
|
||||
}
|
||||
|
||||
newVirtualDiffParents := append([]*externalapi.DomainHash{blockHash}, oldVirtualDiffParents...)
|
||||
log.Tracef("Staging virtual diff parents after adding %s to it", blockHash)
|
||||
return csm.consensusStateStore.StageVirtualDiffParents(newVirtualDiffParents)
|
||||
}
|
||||
|
||||
func (csm *consensusStateManager) removeFromVirtualDiffParents(blockHash *externalapi.DomainHash) error {
|
||||
log.Tracef("removeFromVirtualDiffParents start for block %s", blockHash)
|
||||
defer log.Tracef("removeFromVirtualDiffParents end for block %s", blockHash)
|
||||
|
||||
oldVirtualDiffParents, err := csm.consensusStateStore.VirtualDiffParents(csm.databaseContext)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
newVirtualDiffParents := make([]*externalapi.DomainHash, 0, len(oldVirtualDiffParents)-1)
|
||||
for _, diffParent := range oldVirtualDiffParents {
|
||||
if *diffParent != *blockHash {
|
||||
newVirtualDiffParents = append(newVirtualDiffParents, diffParent)
|
||||
}
|
||||
}
|
||||
|
||||
if len(newVirtualDiffParents) != len(oldVirtualDiffParents)-1 {
|
||||
return errors.Errorf("expected to remove one member from virtual diff parents and "+
|
||||
"have a length of %d but got length of %d", len(oldVirtualDiffParents)-1, len(newVirtualDiffParents))
|
||||
}
|
||||
|
||||
log.Tracef("Staging virtual diff parents after removing %s from it", blockHash)
|
||||
return csm.consensusStateStore.StageVirtualDiffParents(newVirtualDiffParents)
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user