-
Notifications
You must be signed in to change notification settings - Fork 199
/
headerValidator.go
96 lines (81 loc) · 2.7 KB
/
headerValidator.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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
package block
import (
"bytes"
"github.com/ElrondNetwork/elrond-go/core"
"github.com/ElrondNetwork/elrond-go/core/check"
"github.com/ElrondNetwork/elrond-go/data"
"github.com/ElrondNetwork/elrond-go/hashing"
"github.com/ElrondNetwork/elrond-go/marshal"
"github.com/ElrondNetwork/elrond-go/process"
)
var _ process.HeaderConstructionValidator = (*headerValidator)(nil)
// ArgsHeaderValidator are the arguments needed to create a new header validator
type ArgsHeaderValidator struct {
Hasher hashing.Hasher
Marshalizer marshal.Marshalizer
}
type headerValidator struct {
hasher hashing.Hasher
marshalizer marshal.Marshalizer
}
// NewHeaderValidator returns a new header validator
func NewHeaderValidator(args ArgsHeaderValidator) (*headerValidator, error) {
if check.IfNil(args.Hasher) {
return nil, process.ErrNilHasher
}
if check.IfNil(args.Marshalizer) {
return nil, process.ErrNilMarshalizer
}
return &headerValidator{
hasher: args.Hasher,
marshalizer: args.Marshalizer,
}, nil
}
// IsHeaderConstructionValid verified if header is constructed correctly on top of other
func (h *headerValidator) IsHeaderConstructionValid(currHeader, prevHeader data.HeaderHandler) error {
if check.IfNil(prevHeader) {
return process.ErrNilBlockHeader
}
if check.IfNil(currHeader) {
return process.ErrNilBlockHeader
}
if prevHeader.GetRound() >= currHeader.GetRound() {
log.Trace("round does not match",
"shard", currHeader.GetShardID(),
"local header round", prevHeader.GetRound(),
"received round", currHeader.GetRound())
return process.ErrLowerRoundInBlock
}
if currHeader.GetNonce() != prevHeader.GetNonce()+1 {
log.Trace("nonce does not match",
"shard", currHeader.GetShardID(),
"local header nonce", prevHeader.GetNonce(),
"received nonce", currHeader.GetNonce())
return process.ErrWrongNonceInBlock
}
prevHeaderHash, err := core.CalculateHash(h.marshalizer, h.hasher, prevHeader)
if err != nil {
return err
}
if !bytes.Equal(currHeader.GetPrevHash(), prevHeaderHash) {
log.Trace("header hash does not match",
"shard", currHeader.GetShardID(),
"local header hash", prevHeaderHash,
"received header with prev hash", currHeader.GetPrevHash(),
)
return process.ErrBlockHashDoesNotMatch
}
if !bytes.Equal(currHeader.GetPrevRandSeed(), prevHeader.GetRandSeed()) {
log.Trace("header random seed does not match",
"shard", currHeader.GetShardID(),
"local header random seed", prevHeader.GetRandSeed(),
"received header with prev random seed", currHeader.GetPrevRandSeed(),
)
return process.ErrRandSeedDoesNotMatch
}
return nil
}
// IsInterfaceNil returns if underlying object is true
func (h *headerValidator) IsInterfaceNil() bool {
return h == nil
}