-
Notifications
You must be signed in to change notification settings - Fork 151
/
spammer.go
102 lines (84 loc) · 3.04 KB
/
spammer.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
package spammer
import (
"context"
"fmt"
"time"
"github.com/iotaledger/hive.go/serializer"
"github.com/iotaledger/hornet/pkg/metrics"
"github.com/iotaledger/hornet/pkg/model/hornet"
"github.com/iotaledger/hornet/pkg/model/storage"
"github.com/iotaledger/hornet/pkg/pow"
iotago "github.com/iotaledger/iota.go/v2"
)
// SendMessageFunc is a function which sends a message to the network.
type SendMessageFunc = func(msg *storage.Message) error
// SpammerTipselFunc selects tips for the spammer.
type SpammerTipselFunc = func() (isSemiLazy bool, tips hornet.MessageIDs, err error)
// Spammer is used to issue messages to the IOTA network to create load on the tangle.
type Spammer struct {
networkID uint64
message string
index string
indexSemiLazy string
tipselFunc SpammerTipselFunc
powHandler *pow.Handler
sendMessageFunc SendMessageFunc
serverMetrics *metrics.ServerMetrics
}
// New creates a new spammer instance.
func New(networkID uint64, message string, index string, indexSemiLazy string, tipselFunc SpammerTipselFunc, powHandler *pow.Handler, sendMessageFunc SendMessageFunc, serverMetrics *metrics.ServerMetrics) *Spammer {
return &Spammer{
networkID: networkID,
message: message,
index: index,
indexSemiLazy: indexSemiLazy,
tipselFunc: tipselFunc,
powHandler: powHandler,
sendMessageFunc: sendMessageFunc,
serverMetrics: serverMetrics,
}
}
func (s *Spammer) DoSpam(ctx context.Context) (time.Duration, time.Duration, error) {
timeStart := time.Now()
isSemiLazy, tips, err := s.tipselFunc()
if err != nil {
return time.Duration(0), time.Duration(0), err
}
durationGTTA := time.Since(timeStart)
indexation := s.index
if isSemiLazy {
indexation = s.indexSemiLazy
}
index := []byte(indexation)
if len(index) > storage.IndexationIndexLength {
index = index[:storage.IndexationIndexLength]
}
txCount := int(s.serverMetrics.SentSpamMessages.Load()) + 1
now := time.Now()
messageString := s.message
messageString += fmt.Sprintf("\nCount: %06d", txCount)
messageString += fmt.Sprintf("\nTimestamp: %s", now.Format(time.RFC3339))
messageString += fmt.Sprintf("\nTipselection: %v", durationGTTA.Truncate(time.Microsecond))
iotaMsg := &iotago.Message{
NetworkID: s.networkID,
Parents: tips.ToSliceOfArrays(),
Payload: &iotago.Indexation{Index: index, Data: []byte(messageString)},
}
timeStart = time.Now()
if _, err := s.powHandler.DoPoW(ctx, iotaMsg, 1, func() (tips hornet.MessageIDs, err error) {
// refresh tips of the spammer if PoW takes longer than a configured duration.
_, refreshedTips, err := s.tipselFunc()
return refreshedTips, err
}); err != nil {
return time.Duration(0), time.Duration(0), err
}
durationPOW := time.Since(timeStart)
msg, err := storage.NewMessage(iotaMsg, serializer.DeSeriModePerformValidation)
if err != nil {
return time.Duration(0), time.Duration(0), err
}
if err := s.sendMessageFunc(msg); err != nil {
return time.Duration(0), time.Duration(0), err
}
return durationGTTA, durationPOW, nil
}