forked from kaspanet/kaspad
/
block_header_in_isolation.go
75 lines (64 loc) · 2.4 KB
/
block_header_in_isolation.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
package blockvalidator
import (
"github.com/Kash-Protocol/kashd/domain/consensus/model"
"github.com/Kash-Protocol/kashd/domain/consensus/model/externalapi"
"github.com/Kash-Protocol/kashd/domain/consensus/ruleerrors"
"github.com/Kash-Protocol/kashd/domain/consensus/utils/consensushashing"
"github.com/Kash-Protocol/kashd/domain/consensus/utils/constants"
"github.com/Kash-Protocol/kashd/infrastructure/logger"
"github.com/Kash-Protocol/kashd/util/mstime"
"github.com/pkg/errors"
)
// ValidateHeaderInIsolation validates block headers in isolation from the current
// consensus state
func (v *blockValidator) ValidateHeaderInIsolation(stagingArea *model.StagingArea, blockHash *externalapi.DomainHash) error {
onEnd := logger.LogAndMeasureExecutionTime(log, "ValidateHeaderInIsolation")
defer onEnd()
header, err := v.blockHeaderStore.BlockHeader(v.databaseContext, stagingArea, blockHash)
if err != nil {
return err
}
if !blockHash.Equal(v.genesisHash) {
err = v.checkBlockVersion(header)
if err != nil {
return err
}
}
err = v.checkBlockTimestampInIsolation(header)
if err != nil {
return err
}
err = v.checkParentsLimit(header)
if err != nil {
return err
}
return nil
}
func (v *blockValidator) checkParentsLimit(header externalapi.BlockHeader) error {
hash := consensushashing.HeaderHash(header)
if len(header.DirectParents()) == 0 && !hash.Equal(v.genesisHash) {
return errors.Wrapf(ruleerrors.ErrNoParents, "block has no parents")
}
if uint64(len(header.DirectParents())) > uint64(v.maxBlockParents) {
return errors.Wrapf(ruleerrors.ErrTooManyParents, "block header has %d parents, but the maximum allowed amount "+
"is %d", len(header.DirectParents()), v.maxBlockParents)
}
return nil
}
func (v *blockValidator) checkBlockVersion(header externalapi.BlockHeader) error {
if header.Version() != constants.BlockVersion {
return errors.Wrapf(
ruleerrors.ErrWrongBlockVersion, "The block version should be %d", constants.BlockVersion)
}
return nil
}
func (v *blockValidator) checkBlockTimestampInIsolation(header externalapi.BlockHeader) error {
blockTimestamp := header.TimeInMilliseconds()
now := mstime.Now().UnixMilliseconds()
maxCurrentTime := now + int64(v.timestampDeviationTolerance)*v.targetTimePerBlock.Milliseconds()
if blockTimestamp > maxCurrentTime {
return errors.Wrapf(
ruleerrors.ErrTimeTooMuchInTheFuture, "The block timestamp is in the future.")
}
return nil
}