-
Notifications
You must be signed in to change notification settings - Fork 199
/
baseSender.go
112 lines (98 loc) · 3.85 KB
/
baseSender.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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
package sender
import (
"fmt"
"time"
"github.com/ElrondNetwork/elrond-go-core/core/check"
"github.com/ElrondNetwork/elrond-go-core/core/random"
"github.com/ElrondNetwork/elrond-go-core/marshal"
crypto "github.com/ElrondNetwork/elrond-go-crypto"
"github.com/ElrondNetwork/elrond-go/heartbeat"
)
var randomizer = &random.ConcurrentSafeIntRandomizer{}
const minTimeBetweenSends = time.Second
const minThresholdBetweenSends = 0.05 // 5%
const maxThresholdBetweenSends = 1.00 // 100%
// argBaseSender represents the arguments for base sender
type argBaseSender struct {
messenger heartbeat.P2PMessenger
marshaller marshal.Marshalizer
topic string
timeBetweenSends time.Duration
timeBetweenSendsWhenError time.Duration
thresholdBetweenSends float64
redundancyHandler heartbeat.NodeRedundancyHandler
privKey crypto.PrivateKey
}
type baseSender struct {
timerHandler
messenger heartbeat.P2PMessenger
marshaller marshal.Marshalizer
topic string
timeBetweenSends time.Duration
timeBetweenSendsWhenError time.Duration
thresholdBetweenSends float64
redundancy heartbeat.NodeRedundancyHandler
privKey crypto.PrivateKey
publicKey crypto.PublicKey
observerPublicKey crypto.PublicKey
}
func createBaseSender(args argBaseSender) baseSender {
bs := baseSender{
messenger: args.messenger,
marshaller: args.marshaller,
topic: args.topic,
timeBetweenSends: args.timeBetweenSends,
timeBetweenSendsWhenError: args.timeBetweenSendsWhenError,
thresholdBetweenSends: args.thresholdBetweenSends,
redundancy: args.redundancyHandler,
privKey: args.privKey,
publicKey: args.privKey.GeneratePublic(),
observerPublicKey: args.redundancyHandler.ObserverPrivateKey().GeneratePublic(),
}
bs.timerHandler = &timerWrapper{
timer: time.NewTimer(bs.computeRandomDuration(bs.timeBetweenSends)),
}
return bs
}
func checkBaseSenderArgs(args argBaseSender) error {
if check.IfNil(args.messenger) {
return heartbeat.ErrNilMessenger
}
if check.IfNil(args.marshaller) {
return heartbeat.ErrNilMarshaller
}
if len(args.topic) == 0 {
return heartbeat.ErrEmptySendTopic
}
if args.timeBetweenSends < minTimeBetweenSends {
return fmt.Errorf("%w for timeBetweenSends", heartbeat.ErrInvalidTimeDuration)
}
if args.timeBetweenSendsWhenError < minTimeBetweenSends {
return fmt.Errorf("%w for timeBetweenSendsWhenError", heartbeat.ErrInvalidTimeDuration)
}
if args.thresholdBetweenSends < minThresholdBetweenSends || args.thresholdBetweenSends > maxThresholdBetweenSends {
return fmt.Errorf("%w for thresholdBetweenSends, receieved %f, min allowed %f, max allowed %f",
heartbeat.ErrInvalidThreshold, args.thresholdBetweenSends, minThresholdBetweenSends, maxThresholdBetweenSends)
}
if check.IfNil(args.privKey) {
return heartbeat.ErrNilPrivateKey
}
if check.IfNil(args.redundancyHandler) {
return heartbeat.ErrNilRedundancyHandler
}
return nil
}
func (bs *baseSender) computeRandomDuration(baseDuration time.Duration) time.Duration {
timeBetweenSendsInNano := baseDuration.Nanoseconds()
maxThreshold := float64(timeBetweenSendsInNano) * bs.thresholdBetweenSends
randThreshold := randomizer.Intn(int(maxThreshold))
ret := time.Duration(timeBetweenSendsInNano + int64(randThreshold))
return ret
}
func (bs *baseSender) getCurrentPrivateAndPublicKeys() (crypto.PrivateKey, crypto.PublicKey) {
shouldUseOriginalKeys := !bs.redundancy.IsRedundancyNode() || (bs.redundancy.IsRedundancyNode() && !bs.redundancy.IsMainMachineActive())
if shouldUseOriginalKeys {
return bs.privKey, bs.publicKey
}
return bs.redundancy.ObserverPrivateKey(), bs.observerPublicKey
}