Newer
Older
Angelo Capossele
committed
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
package client
import (
"sync"
"github.com/iotaledger/goshimmer/packages/metrics"
"github.com/iotaledger/goshimmer/packages/vote"
"github.com/iotaledger/goshimmer/plugins/analysis/packet"
"github.com/iotaledger/goshimmer/plugins/autopeering/local"
"github.com/iotaledger/hive.go/identity"
)
var (
finalized map[string]vote.Opinion
finalizedMutex sync.RWMutex
)
func onFinalized(ev *vote.OpinionEvent) {
finalizedMutex.Lock()
finalized[ev.ID] = ev.Opinion
finalizedMutex.Unlock()
}
func onRoundExecuted(roundStats *vote.RoundStats) {
// get own ID
nodeID := make([]byte, len(identity.ID{}))
if local.GetInstance() != nil {
copy(nodeID, local.GetInstance().ID().Bytes())
}
chunks := splitFPCVoteContext(roundStats.ActiveVoteContexts)
for _, chunk := range chunks {
rs := vote.RoundStats{
Duration: roundStats.Duration,
RandUsed: roundStats.RandUsed,
ActiveVoteContexts: chunk,
}
hb := &packet.FPCHeartbeat{
OwnID: nodeID,
RoundStats: rs,
}
finalizedMutex.Lock()
hb.Finalized = finalized
finalized = make(map[string]vote.Opinion)
finalizedMutex.Unlock()
// abort if empty round and no finalized conflicts.
if len(chunk) == 0 && len(hb.Finalized) == 0 {
return
}
data, err := packet.NewFPCHeartbeatMessage(hb)
if err != nil {
log.Debugw("FPC heartbeat message skipped", "error", err)
return
}
log.Debugw("Client: onRoundExecuted data size", "len", len(data))
if _, err = conn.Write(data); err != nil {
log.Debugw("Error while writing to connection", "Description", err)
return
}
// trigger AnalysisOutboundBytes event
metrics.Events().AnalysisOutboundBytes.Trigger(uint64(len(data)))
}
}
func splitFPCVoteContext(ctx map[string]*vote.Context) (chunk []map[string]*vote.Context) {
chunk = make([]map[string]*vote.Context, 1)
i, counter := 0, 0
chunk[i] = make(map[string]*vote.Context)
if len(ctx) < voteContextChunkThreshold {
chunk[i] = ctx
return
}
for conflictID, voteCtx := range ctx {
counter++
if counter >= voteContextChunkThreshold {
counter = 0
i++
chunk = append(chunk, make(map[string]*vote.Context))
}
chunk[i][conflictID] = voteCtx
}
return
}