-
Notifications
You must be signed in to change notification settings - Fork 153
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #21 from gohornet/add-spammer
Add spammer plugin
- Loading branch information
Showing
11 changed files
with
447 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
package spammer | ||
|
||
import ( | ||
"fmt" | ||
"time" | ||
|
||
"github.com/iotaledger/iota.go/bundle" | ||
"github.com/iotaledger/iota.go/consts" | ||
"github.com/iotaledger/iota.go/converter" | ||
"github.com/iotaledger/iota.go/kerl" | ||
"github.com/iotaledger/iota.go/trinary" | ||
) | ||
|
||
func integerToAscii(number int) string { | ||
alphabet := "9ABCDEFGHIJKLMNOPQRSTUVWXYZ" | ||
|
||
result := "" | ||
for index := 0; index < 7; index++ { | ||
pos := number % 27 | ||
number /= 27 | ||
result = string(alphabet[pos]) + result | ||
} | ||
return result | ||
} | ||
|
||
// We don't need to care about the M-Bug in the spammer => much faster without | ||
func finalizeInsecure(bundle bundle.Bundle) (bundle.Bundle, error) { | ||
var valueTrits = make([]trinary.Trits, len(bundle)) | ||
var timestampTrits = make([]trinary.Trits, len(bundle)) | ||
var currentIndexTrits = make([]trinary.Trits, len(bundle)) | ||
var obsoleteTagTrits = make([]trinary.Trits, len(bundle)) | ||
var lastIndexTrits = trinary.PadTrits(trinary.IntToTrits(int64(bundle[0].LastIndex)), 27) | ||
|
||
for i := range bundle { | ||
valueTrits[i] = trinary.PadTrits(trinary.IntToTrits(bundle[i].Value), 81) | ||
timestampTrits[i] = trinary.PadTrits(trinary.IntToTrits(int64(bundle[i].Timestamp)), 27) | ||
currentIndexTrits[i] = trinary.PadTrits(trinary.IntToTrits(int64(bundle[i].CurrentIndex)), 27) | ||
obsoleteTagTrits[i] = trinary.PadTrits(trinary.MustTrytesToTrits(bundle[i].ObsoleteTag), 81) | ||
} | ||
|
||
var bundleHash trinary.Hash | ||
|
||
k := kerl.NewKerl() | ||
|
||
for i := 0; i < len(bundle); i++ { | ||
relevantTritsForBundleHash := trinary.MustTrytesToTrits( | ||
bundle[i].Address + | ||
trinary.MustTritsToTrytes(valueTrits[i]) + | ||
trinary.MustTritsToTrytes(obsoleteTagTrits[i]) + | ||
trinary.MustTritsToTrytes(timestampTrits[i]) + | ||
trinary.MustTritsToTrytes(currentIndexTrits[i]) + | ||
trinary.MustTritsToTrytes(lastIndexTrits), | ||
) | ||
k.Absorb(relevantTritsForBundleHash) | ||
} | ||
|
||
bundleHashTrits, err := k.Squeeze(consts.HashTrinarySize) | ||
if err != nil { | ||
return nil, err | ||
} | ||
bundleHash = trinary.MustTritsToTrytes(bundleHashTrits) | ||
|
||
// set the computed bundle hash on each tx in the bundle | ||
for i := range bundle { | ||
tx := &bundle[i] | ||
tx.Bundle = bundleHash | ||
} | ||
|
||
return bundle, nil | ||
} | ||
|
||
func createBundle(address string, msg string, tagSubstring string, txCount int, additionalMesssage ...string) (bundle.Bundle, error) { | ||
|
||
tag, err := trinary.NewTrytes(tagSubstring + integerToAscii(txCount)) | ||
if err != nil { | ||
return nil, fmt.Errorf("NewTrytes: %v", err.Error()) | ||
} | ||
now := time.Now() | ||
|
||
messageString := msg + fmt.Sprintf("\nCount: %06d", txCount) | ||
messageString += fmt.Sprintf("\nTimestamp: %s", now.Format(time.RFC3339)) | ||
if len(additionalMesssage) > 0 { | ||
messageString = fmt.Sprintf("%v\n%v", messageString, additionalMesssage[0]) | ||
} | ||
|
||
message, err := converter.ASCIIToTrytes(messageString) | ||
if err != nil { | ||
return nil, fmt.Errorf("ASCIIToTrytes: %v", err.Error()) | ||
} | ||
|
||
timestamp := uint64(now.UnixNano() / int64(time.Millisecond)) | ||
|
||
var b bundle.Bundle | ||
|
||
outEntry := bundle.BundleEntry{ | ||
Address: address, | ||
Value: 0, | ||
Tag: tag, | ||
Timestamp: timestamp, | ||
Length: uint64(1), | ||
SignatureMessageFragments: []trinary.Trytes{trinary.Pad(message, consts.SignatureMessageFragmentSizeInTrytes)}, | ||
} | ||
b = bundle.AddEntry(b, outEntry) | ||
|
||
// finalize bundle by adding the bundle hash | ||
b, err = finalizeInsecure(b) | ||
if err != nil { | ||
return nil, fmt.Errorf("Bundle.Finalize: %v", err.Error()) | ||
} | ||
|
||
return b, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
package spammer | ||
|
||
import flag "github.com/spf13/pflag" | ||
|
||
func init() { | ||
flag.String("spammer.address", "HORNET99INTEGRATED99SPAMMER999999999999999999999999999999999999999999999999999999", "Tx Address") | ||
flag.String("spammer.message", "Spamming with HORNET tipselect", "Message of the Tx") | ||
flag.String("spammer.tag", "HORNET99INTEGRATED99SPAMMER", "Tag of the Tx") | ||
flag.Uint("spammer.depth", 3, "Depth of the random walker") | ||
flag.Float64("spammer.tpsRateLimit", 0.10, "Rate limit for the spam (0 = no limit)") | ||
flag.Uint("spammer.workers", 1, "How many spammers should run in parallel") | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
package spammer | ||
|
||
import ( | ||
"runtime" | ||
"time" | ||
|
||
"github.com/gohornet/hornet/packages/logger" | ||
"github.com/gohornet/hornet/packages/model/tangle" | ||
"github.com/gohornet/hornet/packages/node" | ||
"github.com/gohornet/hornet/packages/shutdown" | ||
"github.com/gohornet/hornet/packages/timeutil" | ||
daemon "github.com/iotaledger/hive.go/daemon/ordered" | ||
"github.com/iotaledger/hive.go/parameter" | ||
"github.com/iotaledger/iota.go/consts" | ||
"github.com/iotaledger/iota.go/trinary" | ||
) | ||
|
||
var ( | ||
PLUGIN = node.NewPlugin("Spammer", node.Disabled, configure, run) | ||
log = logger.NewLogger("Spammer") | ||
|
||
address string | ||
message string | ||
tagSubstring string | ||
depth uint | ||
rateLimit float64 | ||
mwm int | ||
spammerWorkerCount int | ||
) | ||
|
||
func configure(plugin *node.Plugin) { | ||
|
||
address = trinary.Pad(parameter.NodeConfig.GetString("spammer.address"), consts.AddressTrinarySize/3)[:consts.AddressTrinarySize/3] | ||
message = parameter.NodeConfig.GetString("spammer.message") | ||
tagSubstring = trinary.Pad(parameter.NodeConfig.GetString("spammer.tag"), consts.TagTrinarySize/3)[:consts.TagTrinarySize/3] | ||
depth = parameter.NodeConfig.GetUint("spammer.depth") | ||
rateLimit = parameter.NodeConfig.GetFloat64("spammer.tpsRateLimit") | ||
mwm = parameter.NodeConfig.GetInt("protocol.mwm") | ||
spammerWorkerCount = int(parameter.NodeConfig.GetUint("spammer.workers")) | ||
|
||
if spammerWorkerCount >= runtime.NumCPU() { | ||
spammerWorkerCount = runtime.NumCPU() - 1 | ||
} | ||
if spammerWorkerCount < 1 { | ||
spammerWorkerCount = 1 | ||
} | ||
|
||
if int64(rateLimit) != 0 { | ||
rateLimitChannelSize := int64(rateLimit) * 2 | ||
if rateLimitChannelSize < 2 { | ||
rateLimitChannelSize = 2 | ||
} | ||
rateLimitChannel = make(chan struct{}, rateLimitChannelSize) | ||
|
||
// create a background worker that fills rateLimitChannel every second | ||
daemon.BackgroundWorker("Spammer rate limit channel", func(shutdownSignal <-chan struct{}) { | ||
timeutil.Ticker(func() { | ||
select { | ||
case rateLimitChannel <- struct{}{}: | ||
default: | ||
// Channel full | ||
} | ||
}, time.Duration(int64(float64(time.Second)/rateLimit)), shutdownSignal) | ||
}, shutdown.ShutdownPrioritySpammer) | ||
} | ||
|
||
if len(tagSubstring) > 20 { | ||
tagSubstring = string([]rune(tagSubstring)[:20]) | ||
} | ||
} | ||
|
||
func run(plugin *node.Plugin) { | ||
|
||
for i := 0; i < spammerWorkerCount; i++ { | ||
daemon.BackgroundWorker("Spammer", func(shutdownSignal <-chan struct{}) { | ||
log.Infof("Starting Spammer %d... done", i) | ||
|
||
for { | ||
select { | ||
case <-shutdownSignal: | ||
log.Infof("Stopping Spammer %d...", i) | ||
log.Infof("Stopping Spammer %d... done", i) | ||
return | ||
default: | ||
if tangle.IsNodeSynced() { | ||
doSpam(shutdownSignal) | ||
} | ||
} | ||
} | ||
}, shutdown.ShutdownPrioritySpammer) | ||
} | ||
} |
Oops, something went wrong.