Ori Newman 48e1a2c396
New headers first flow (#1211)
* Get rid of insertMode

* Rename AddBlockToVirtual->AddBlock

* When F is not in the future of P, enforce finality with P and not with F.

* Don't allow blocks with invalid parents or with missing block body

* Check finality violation before checking block status

* Implement CalculateIndependentPruningPoint

* Move checkBlockStatus to validateBlock

* Add ValidateBlock to block processor interface

* Adjust SetPruningPoint to the new IBD flow

* Add pruning store to CSM's constructor

* Flip wrong condition on AddHeaderTip

* Fix func (hts *headerSelectedTipStore) Has

* Fix block stage order

* Call to ValidateBodyInContext from validatePostProofOfWork

* Enable overrideDAGParams

* Update log

* Rename SetPruningPoint to ValidateAndInsertPruningPoint and move most of its logic inside block processor

* Rename hasValidatedHeader->hasValidatedOnlyHeader

* Fix typo

* Name return values for fetchMissingUTXOSet

* Add comment

* Return ErrMissingParents when block body is missing

* Add logs and comments

* Fix merge error

* Fix pruning point calculation to be by virtual selected parent

* Replace CalculateIndependentPruningPoint to CalculatePruningPointByHeaderSelectedTip

* Fix isAwaitingUTXOSet to check pruning point by headers

* Change isAwaitingUTXOSet indication

* Remove IsBlockInHeaderPruningPointFuture from BlockInfo

* Fix LowestChainBlockAboveOrEqualToBlueScore

* Add validateNewPruningPointTransactions

* Add validateNewPruningAgainstPastUTXO

* Rename set_pruning_utxo_set.go to update_pruning_utxo_set.go

* Check missing block body hashes by missing block instead of status

* Validate pruning point against past UTXO with the pruning point as block hash

* Remove virtualHeaderHash

* Fix comment

* Fix imports
2020-12-14 17:53:08 +02:00

68 lines
1.8 KiB
Go

package blockprocessor
import (
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
"github.com/kaspanet/kaspad/domain/consensus/ruleerrors"
"github.com/kaspanet/kaspad/domain/consensus/utils/consensushashing"
"github.com/pkg/errors"
)
func (bp *blockProcessor) validateBlockAndDiscardChanges(block *externalapi.DomainBlock) error {
defer bp.discardAllChanges()
return bp.validateBlock(block)
}
func (bp *blockProcessor) validateBlock(block *externalapi.DomainBlock) error {
blockHash := consensushashing.HeaderHash(block.Header)
log.Debugf("Validating block %s", blockHash)
err := bp.checkBlockStatus(block)
if err != nil {
return err
}
hasValidatedHeader, err := bp.hasValidatedOnlyHeader(blockHash)
if err != nil {
return err
}
if !hasValidatedHeader {
log.Tracef("Staging block %s header", blockHash)
bp.blockHeaderStore.Stage(blockHash, block.Header)
} else {
log.Tracef("Block %s header is already known, so no need to stage it", blockHash)
}
// If any validation until (included) proof-of-work fails, simply
// return an error without writing anything in the database.
// This is to prevent spamming attacks.
err = bp.validatePreProofOfWork(block)
if err != nil {
return err
}
if !hasValidatedHeader {
err = bp.blockValidator.ValidatePruningPointViolationAndProofOfWorkAndDifficulty(blockHash)
if err != nil {
return err
}
}
// If in-context validations fail, discard all changes and store the
// block with StatusInvalid.
err = bp.validatePostProofOfWork(block)
if err != nil {
if errors.As(err, &ruleerrors.RuleError{}) {
bp.discardAllChanges()
hash := consensushashing.BlockHash(block)
bp.blockStatusStore.Stage(hash, externalapi.StatusInvalid)
commitErr := bp.commitAllChanges()
if commitErr != nil {
return commitErr
}
}
return err
}
return nil
}