From 78550d3639ea9b9272d395aa4ad654b1e42deaf5 Mon Sep 17 00:00:00 2001 From: talelbaz <63008512+talelbaz@users.noreply.github.com> Date: Sun, 6 Dec 2020 18:41:07 +0200 Subject: [PATCH] Adds "checkDelayedBlock" - checks if the block timeStamp is in the future. (#1183) * [#1056] Adds "checkDelayedBlock" - check if the block timeStamp is in future. Adds 2 new fields to blockValidator struct. Adds new Rule Error "ErrDelayedBlock" . * [#1056] Replace "ErrDelayedBlock" to "ErrBlockIsTooMuchInTheFuture". * [#1056] Replace "checkDelayedBlock" to "checkBlockTimeStampInIsolation". * [#1056] Cosmetics changes: timeStamp -> timestamp . * Merge remote-tracking branch 'origin/v0.8.2-dev' into droppedDelayedBlock # Conflicts: # domain/consensus/factory.go # domain/consensus/processes/blockvalidator/block_header_in_isolation.go # domain/consensus/processes/blockvalidator/blockvalidator.go Co-authored-by: tal --- domain/consensus/factory.go | 5 +- .../block_header_in_isolation.go | 18 ++++++ .../blockvalidator/blockvalidator.go | 60 ++++++++++--------- domain/consensus/ruleerrors/rule_error.go | 3 + 4 files changed, 57 insertions(+), 29 deletions(-) diff --git a/domain/consensus/factory.go b/domain/consensus/factory.go index 4462d3974..ddcd183b7 100644 --- a/domain/consensus/factory.go +++ b/domain/consensus/factory.go @@ -1,12 +1,11 @@ package consensus import ( + "github.com/kaspanet/kaspad/domain/consensus/processes/dagtraversalmanager" "io/ioutil" "os" "sync" - "github.com/kaspanet/kaspad/domain/consensus/processes/dagtraversalmanager" - "github.com/kaspanet/kaspad/infrastructure/db/database/ldb" consensusdatabase "github.com/kaspanet/kaspad/domain/consensus/database" @@ -152,6 +151,8 @@ func (f *factory) NewConsensus(dagParams *dagconfig.Params, db infrastructuredat dagParams.MaxBlockSize, dagParams.MergeSetSizeLimit, dagParams.MaxBlockParents, + dagParams.TimestampDeviationTolerance, + dagParams.TargetTimePerBlock, dbManager, difficultyManager, diff --git a/domain/consensus/processes/blockvalidator/block_header_in_isolation.go b/domain/consensus/processes/blockvalidator/block_header_in_isolation.go index a63f910ff..8fe275a82 100644 --- a/domain/consensus/processes/blockvalidator/block_header_in_isolation.go +++ b/domain/consensus/processes/blockvalidator/block_header_in_isolation.go @@ -4,6 +4,7 @@ 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/kaspanet/kaspad/util/mstime" "github.com/pkg/errors" ) @@ -15,6 +16,11 @@ func (v *blockValidator) ValidateHeaderInIsolation(blockHash *externalapi.Domain return err } + err = v.checkBlockTimestampInIsolation(header) + if err != nil { + return err + } + err = v.checkParentsLimit(header) if err != nil { return err @@ -35,3 +41,15 @@ func (v *blockValidator) checkParentsLimit(header *externalapi.DomainBlockHeader } return nil } + +func (v *blockValidator) checkBlockTimestampInIsolation(header *externalapi.DomainBlockHeader) error { + + blockTimestamp := header.TimeInMilliseconds + now := mstime.Now().UnixMilliseconds() + maxCurrentTime := now + int64(v.timestampDeviationTolerance)*v.targetTimePerBlock.Milliseconds() + if blockTimestamp > maxCurrentTime { + return errors.Wrapf( + ruleerrors.ErrBlockIsTooMuchInTheFuture, "The block timestamp is in the future.") + } + return nil +} diff --git a/domain/consensus/processes/blockvalidator/blockvalidator.go b/domain/consensus/processes/blockvalidator/blockvalidator.go index 2403a67fc..686bbf7a6 100644 --- a/domain/consensus/processes/blockvalidator/blockvalidator.go +++ b/domain/consensus/processes/blockvalidator/blockvalidator.go @@ -2,6 +2,7 @@ package blockvalidator import ( "math/big" + "time" "github.com/kaspanet/kaspad/domain/consensus/model" "github.com/kaspanet/kaspad/domain/consensus/model/externalapi" @@ -11,14 +12,16 @@ import ( // blockValidator exposes a set of validation classes, after which // it's possible to determine whether either a block is valid type blockValidator struct { - powMax *big.Int - skipPoW bool - genesisHash *externalapi.DomainHash - enableNonNativeSubnetworks bool - powMaxBits uint32 - maxBlockSize uint64 - mergeSetSizeLimit uint64 - maxBlockParents model.KType + powMax *big.Int + skipPoW bool + genesisHash *externalapi.DomainHash + enableNonNativeSubnetworks bool + powMaxBits uint32 + maxBlockSize uint64 + mergeSetSizeLimit uint64 + maxBlockParents model.KType + timestampDeviationTolerance uint64 + targetTimePerBlock time.Duration databaseContext model.DBReader difficultyManager model.DifficultyManager @@ -45,6 +48,8 @@ func New(powMax *big.Int, maxBlockSize uint64, mergeSetSizeLimit uint64, maxBlockParents model.KType, + timestampDeviationTolerance uint64, + targetTimePerBlock time.Duration, databaseContext model.DBReader, @@ -64,25 +69,26 @@ func New(powMax *big.Int, blockStatusStore model.BlockStatusStore) model.BlockValidator { return &blockValidator{ - powMax: powMax, - skipPoW: skipPoW, - genesisHash: genesisHash, - enableNonNativeSubnetworks: enableNonNativeSubnetworks, - powMaxBits: util.BigToCompact(powMax), - maxBlockSize: maxBlockSize, - mergeSetSizeLimit: mergeSetSizeLimit, - maxBlockParents: maxBlockParents, - - databaseContext: databaseContext, - difficultyManager: difficultyManager, - pastMedianTimeManager: pastMedianTimeManager, - transactionValidator: transactionValidator, - ghostdagManager: ghostdagManager, - dagTopologyManager: dagTopologyManager, - dagTraversalManager: dagTraversalManager, - coinbaseManager: coinbaseManager, - mergeDepthManager: mergeDepthManager, - pruningStore: pruningStore, + powMax: powMax, + skipPoW: skipPoW, + genesisHash: genesisHash, + enableNonNativeSubnetworks: enableNonNativeSubnetworks, + powMaxBits: util.BigToCompact(powMax), + maxBlockSize: maxBlockSize, + mergeSetSizeLimit: mergeSetSizeLimit, + maxBlockParents: maxBlockParents, + timestampDeviationTolerance: timestampDeviationTolerance, + targetTimePerBlock: targetTimePerBlock, + databaseContext: databaseContext, + difficultyManager: difficultyManager, + pastMedianTimeManager: pastMedianTimeManager, + transactionValidator: transactionValidator, + ghostdagManager: ghostdagManager, + dagTopologyManager: dagTopologyManager, + dagTraversalManager: dagTraversalManager, + coinbaseManager: coinbaseManager, + mergeDepthManager: mergeDepthManager, + pruningStore: pruningStore, blockStore: blockStore, ghostdagDataStore: ghostdagDataStore, diff --git a/domain/consensus/ruleerrors/rule_error.go b/domain/consensus/ruleerrors/rule_error.go index cf0c21798..051efccaf 100644 --- a/domain/consensus/ruleerrors/rule_error.go +++ b/domain/consensus/ruleerrors/rule_error.go @@ -234,6 +234,9 @@ var ( //ErrPruningPointViolation indicates that the pruning point isn't in the block past. ErrPruningPointViolation = newRuleError("ErrPruningPointViolation") + + //ErrBlockIsTooMuchInTheFuture indicates that the block timestamp is too much in the future. + ErrBlockIsTooMuchInTheFuture = newRuleError("ErrBlockIsTooMuchInTheFuture") ) // RuleError identifies a rule violation. It is used to indicate that