-
Notifications
You must be signed in to change notification settings - Fork 199
/
hdrInterceptorProcessor.go
96 lines (79 loc) · 3.01 KB
/
hdrInterceptorProcessor.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 processor
import (
"sync"
"github.com/ElrondNetwork/elrond-go-core/core"
"github.com/ElrondNetwork/elrond-go-core/core/check"
"github.com/ElrondNetwork/elrond-go-core/data"
"github.com/ElrondNetwork/elrond-go/dataRetriever"
"github.com/ElrondNetwork/elrond-go/process"
)
var _ process.InterceptorProcessor = (*HdrInterceptorProcessor)(nil)
// HdrInterceptorProcessor is the processor used when intercepting headers
// (shard headers, meta headers) structs which satisfy HeaderHandler interface.
type HdrInterceptorProcessor struct {
headers dataRetriever.HeadersPool
blackList process.TimeCacher
registeredHandlers []func(topic string, hash []byte, data interface{})
mutHandlers sync.RWMutex
}
// NewHdrInterceptorProcessor creates a new TxInterceptorProcessor instance
func NewHdrInterceptorProcessor(argument *ArgHdrInterceptorProcessor) (*HdrInterceptorProcessor, error) {
if argument == nil {
return nil, process.ErrNilArgumentStruct
}
if check.IfNil(argument.Headers) {
return nil, process.ErrNilCacher
}
if check.IfNil(argument.BlockBlackList) {
return nil, process.ErrNilBlackListCacher
}
return &HdrInterceptorProcessor{
headers: argument.Headers,
blackList: argument.BlockBlackList,
registeredHandlers: make([]func(topic string, hash []byte, data interface{}), 0),
}, nil
}
// Validate checks if the intercepted data can be processed
func (hip *HdrInterceptorProcessor) Validate(data process.InterceptedData, _ core.PeerID) error {
interceptedHdr, ok := data.(process.HdrValidatorHandler)
if !ok {
return process.ErrWrongTypeAssertion
}
hip.blackList.Sweep()
isBlackListed := hip.blackList.Has(string(interceptedHdr.Hash()))
if isBlackListed {
return process.ErrHeaderIsBlackListed
}
return nil
}
// Save will save the received data into the headers cacher as hash<->[plain header structure]
// and in headersNonces as nonce<->hash
func (hip *HdrInterceptorProcessor) Save(data process.InterceptedData, _ core.PeerID, topic string) error {
interceptedHdr, ok := data.(process.HdrValidatorHandler)
if !ok {
return process.ErrWrongTypeAssertion
}
go hip.notify(interceptedHdr.HeaderHandler(), interceptedHdr.Hash(), topic)
hip.headers.AddHeader(interceptedHdr.Hash(), interceptedHdr.HeaderHandler())
return nil
}
// RegisterHandler registers a callback function to be notified of incoming headers
func (hip *HdrInterceptorProcessor) RegisterHandler(handler func(topic string, hash []byte, data interface{})) {
if handler == nil {
return
}
hip.mutHandlers.Lock()
hip.registeredHandlers = append(hip.registeredHandlers, handler)
hip.mutHandlers.Unlock()
}
// IsInterfaceNil returns true if there is no value under the interface
func (hip *HdrInterceptorProcessor) IsInterfaceNil() bool {
return hip == nil
}
func (hip *HdrInterceptorProcessor) notify(header data.HeaderHandler, hash []byte, topic string) {
hip.mutHandlers.RLock()
for _, handler := range hip.registeredHandlers {
handler(topic, hash, header)
}
hip.mutHandlers.RUnlock()
}