Split ApplyPruningPointProof to multiple small database transactions (#1937)

* Split ApplyPruningPointProof to multiple small database transactions.

* Increase the timeout duration in TestIBDWithPruning.

* Increase the timeout duration in simple-sync.

* Explain that if ApplyPruningPointProof fails, the database must be discarded.
This commit is contained in:
stasatdaglabs 2022-02-06 10:36:27 +02:00 committed by GitHub
parent b1229f7908
commit 27ba9d0374
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 20 additions and 17 deletions

View File

@ -748,18 +748,7 @@ func (s *consensus) ApplyPruningPointProof(pruningPointProof *externalapi.Prunin
s.lock.Lock()
defer s.lock.Unlock()
stagingArea := model.NewStagingArea()
err := s.pruningProofManager.ApplyPruningPointProof(stagingArea, pruningPointProof)
if err != nil {
return err
}
err = staging.CommitAllChanges(s.databaseContext, stagingArea)
if err != nil {
return err
}
return nil
return s.pruningProofManager.ApplyPruningPointProof(pruningPointProof)
}
func (s *consensus) BlockDAAWindowHashes(blockHash *externalapi.DomainHash) ([]*externalapi.DomainHash, error) {

View File

@ -6,5 +6,5 @@ import "github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
type PruningProofManager interface {
BuildPruningPointProof(stagingArea *StagingArea) (*externalapi.PruningPointProof, error)
ValidatePruningPointProof(pruningPointProof *externalapi.PruningPointProof) error
ApplyPruningPointProof(stagingArea *StagingArea, pruningPointProof *externalapi.PruningPointProof) error
ApplyPruningPointProof(pruningPointProof *externalapi.PruningPointProof) error
}

View File

@ -17,6 +17,7 @@ import (
"github.com/kaspanet/kaspad/domain/consensus/utils/hashset"
"github.com/kaspanet/kaspad/infrastructure/db/database"
"github.com/kaspanet/kaspad/infrastructure/logger"
"github.com/kaspanet/kaspad/util/staging"
"github.com/pkg/errors"
"math/big"
)
@ -607,13 +608,19 @@ func (ppm *pruningProofManager) dagProcesses(
return reachabilityManagers, dagTopologyManagers, ghostdagManagers
}
func (ppm *pruningProofManager) ApplyPruningPointProof(stagingArea *model.StagingArea, pruningPointProof *externalapi.PruningPointProof) error {
// ApplyPruningPointProof applies the given pruning proof to the current consensus. Specifically,
// it's meant to be used against the StagingConsensus during headers-proof IBD. Note that for
// performance reasons this operation is NOT atomic. If the process fails for whatever reason
// (e.g. the process was killed) then the database for this consensus MUST be discarded.
func (ppm *pruningProofManager) ApplyPruningPointProof(pruningPointProof *externalapi.PruningPointProof) error {
onEnd := logger.LogAndMeasureExecutionTime(log, "ApplyPruningPointProof")
defer onEnd()
for blockLevel, headers := range pruningPointProof.Headers {
var selectedTip *externalapi.DomainHash
for i, header := range headers {
stagingArea := model.NewStagingArea()
blockHash := consensushashing.HeaderHash(header)
if header.BlockLevel() < blockLevel {
return errors.Wrapf(ruleerrors.ErrPruningProofWrongBlockLevel, "block %s level is %d when it's "+
@ -693,11 +700,18 @@ func (ppm *pruningProofManager) ApplyPruningPointProof(stagingArea *model.Stagin
return err
}
}
err = staging.CommitAllChanges(ppm.databaseContext, stagingArea)
if err != nil {
return err
}
}
}
pruningPointHeader := pruningPointProof.Headers[0][len(pruningPointProof.Headers[0])-1]
pruningPoint := consensushashing.HeaderHash(pruningPointHeader)
stagingArea := model.NewStagingArea()
ppm.consensusStateStore.StageTips(stagingArea, []*externalapi.DomainHash{pruningPoint})
return nil
return staging.CommitAllChanges(ppm.databaseContext, stagingArea)
}

View File

@ -37,7 +37,7 @@ func mineLoop(syncerRPCClient, syncedRPCClient *rpc.Client) error {
}
start := time.Now()
const timeToPropagate = 10 * time.Second
const timeToPropagate = 30 * time.Second
select {
case <-syncedRPCClient.OnBlockAdded:
case <-time.After(timeToPropagate):

View File

@ -89,7 +89,7 @@ func TestIBDWithPruning(t *testing.T) {
start := time.Now()
for range ticker.C {
if time.Since(start) > 2*defaultTimeout {
if time.Since(start) > 30*time.Second {
t.Fatalf("Timeout waiting for IBD to finish.")
}