diff --git a/main.go b/main.go index 928652848245ce63a37a29830c9540d467cb53fc..bf91966f1f9ad06f9bd1a968f9fbe86441515b1c 100644 --- a/main.go +++ b/main.go @@ -4,16 +4,21 @@ import ( "net/http" _ "net/http/pprof" + "github.com/iotaledger/goshimmer/plugins/analysis" + "github.com/iotaledger/goshimmer/plugins/autopeering" + "github.com/iotaledger/goshimmer/plugins/cli" "github.com/iotaledger/goshimmer/plugins/config" + "github.com/iotaledger/goshimmer/plugins/gossip" "github.com/iotaledger/goshimmer/plugins/gracefulshutdown" "github.com/iotaledger/goshimmer/plugins/logger" - + "github.com/iotaledger/goshimmer/plugins/metrics" + "github.com/iotaledger/goshimmer/plugins/remotelog" "github.com/iotaledger/goshimmer/plugins/tangle" + "github.com/iotaledger/goshimmer/plugins/webapi" + webapi_gtta "github.com/iotaledger/goshimmer/plugins/webapi/gtta" + webapi_spammer "github.com/iotaledger/goshimmer/plugins/webapi/spammer" + webapi_auth "github.com/iotaledger/goshimmer/plugins/webauth" - "github.com/iotaledger/goshimmer/plugins/autopeering" - "github.com/iotaledger/goshimmer/plugins/cli" - "github.com/iotaledger/goshimmer/plugins/gossip" - "github.com/iotaledger/goshimmer/plugins/remotelog" "github.com/iotaledger/hive.go/node" ) @@ -32,20 +37,20 @@ func main() { gossip.PLUGIN, gracefulshutdown.PLUGIN, - /* - analysis.PLUGIN, - metrics.PLUGIN, + analysis.PLUGIN, + metrics.PLUGIN, + + webapi.PLUGIN, + webapi_auth.PLUGIN, + webapi_gtta.PLUGIN, + webapi_spammer.PLUGIN, - webapi.PLUGIN, - webapi_auth.PLUGIN, - webapi_gtta.PLUGIN, - webapi_spammer.PLUGIN, + /* webapi_broadcastData.PLUGIN, webapi_getTransactionTrytesByHash.PLUGIN, webapi_getTransactionObjectsByHash.PLUGIN, webapi_findTransactionHashes.PLUGIN, webapi_getNeighbors.PLUGIN, - webapi_spammer.PLUGIN, //spa.PLUGIN, //graph.PLUGIN, diff --git a/packages/binary/spammer/spammer.go b/packages/binary/spammer/spammer.go new file mode 100644 index 0000000000000000000000000000000000000000..95b4bd5aa243211cab416c144f68574b983f10cf --- /dev/null +++ b/packages/binary/spammer/spammer.go @@ -0,0 +1,83 @@ +package spammer + +import ( + "sync" + "time" + + "github.com/iotaledger/hive.go/types" + + "github.com/iotaledger/goshimmer/packages/binary/identity" + "github.com/iotaledger/goshimmer/packages/binary/tangle" + "github.com/iotaledger/goshimmer/packages/binary/tangle/model/transaction" + "github.com/iotaledger/goshimmer/packages/binary/tangle/model/transaction/payload/data" + "github.com/iotaledger/goshimmer/packages/binary/tangle/tipselector" +) + +type Spammer struct { + tangle *tangle.Tangle + tipSelector *tipselector.TipSelector + + running bool + startStopMutex sync.Mutex + shutdownSignal chan types.Empty +} + +func New(tangle *tangle.Tangle, tipSelector *tipselector.TipSelector) *Spammer { + return &Spammer{ + tangle: tangle, + tipSelector: tipSelector, + } +} + +func (spammer *Spammer) Start(tps int) { + spammer.startStopMutex.Lock() + defer spammer.startStopMutex.Unlock() + + if !spammer.running { + spammer.running = true + + go spammer.run(tps) + } +} + +func (spammer *Spammer) Shutdown() { + spammer.startStopMutex.Lock() + defer spammer.startStopMutex.Unlock() + + if !spammer.running { + spammer.running = false + + spammer.shutdownSignal <- types.Void + } +} + +func (spammer *Spammer) run(tps int) { + currentSentCounter := 0 + start := time.Now() + + for { + select { + case <-spammer.shutdownSignal: + return + + default: + trunkTransactionId, branchTransactionId := spammer.tipSelector.GetTips() + spammer.tangle.AttachTransaction( + transaction.New(trunkTransactionId, branchTransactionId, identity.Generate(), data.New([]byte("SPAM"))), + ) + + currentSentCounter++ + + // rate limit to the specified TPS + if currentSentCounter >= tps { + duration := time.Since(start) + if duration < time.Second { + time.Sleep(time.Second - duration) + } + + start = time.Now() + currentSentCounter = 0 + } + } + } +} diff --git a/packages/transactionspammer/transactionspammer.go b/packages/transactionspammer/transactionspammer.go deleted file mode 100644 index 00493158b87578f095deb48939f49321475ded94..0000000000000000000000000000000000000000 --- a/packages/transactionspammer/transactionspammer.go +++ /dev/null @@ -1,104 +0,0 @@ -package transactionspammer - -import ( - "strings" - "sync" - "time" - - "github.com/iotaledger/goshimmer/packages/gossip" - "github.com/iotaledger/goshimmer/packages/model/meta_transaction" - "github.com/iotaledger/goshimmer/packages/model/value_transaction" - "github.com/iotaledger/goshimmer/packages/shutdown" - "github.com/iotaledger/goshimmer/plugins/autopeering/local" - "github.com/iotaledger/goshimmer/plugins/tipselection" - "github.com/iotaledger/hive.go/daemon" - "github.com/iotaledger/hive.go/logger" -) - -const logEveryNTransactions = 5000 - -var log *logger.Logger - -var spamming = false -var spammingMutex sync.Mutex - -var shutdownSignal chan struct{} -var done chan struct{} - -func init() { - shutdownSignal = make(chan struct{}) - done = make(chan struct{}) -} - -var targetAddress = strings.Repeat("SPAMMMMER", 9) - -func Start(tps uint64) { - log = logger.NewLogger("Transaction Spammer") - spammingMutex.Lock() - spamming = true - spammingMutex.Unlock() - - daemon.BackgroundWorker("Transaction Spammer", func(daemonShutdownSignal <-chan struct{}) { - start := time.Now() - - var totalSentCounter, currentSentCounter uint64 - - log.Infof("started spammer...will output sent count every %d transactions", logEveryNTransactions) - defer log.Infof("spammer stopped, spammed %d transactions", totalSentCounter) - for { - select { - case <-daemonShutdownSignal: - return - - case <-shutdownSignal: - done <- struct{}{} - return - - default: - currentSentCounter++ - totalSentCounter++ - - tx := value_transaction.New() - tx.SetHead(true) - tx.SetTail(true) - tx.SetAddress(targetAddress) - tx.SetBranchTransactionHash(tipselection.GetRandomTip()) - tx.SetTrunkTransactionHash(tipselection.GetRandomTip(tx.GetBranchTransactionHash())) - tx.SetTimestamp(uint(time.Now().Unix())) - if err := tx.DoProofOfWork(meta_transaction.MIN_WEIGHT_MAGNITUDE); err != nil { - log.Warn("PoW failed", err) - continue - } - - gossip.Events.TransactionReceived.Trigger(&gossip.TransactionReceivedEvent{Data: tx.GetBytes(), Peer: &local.GetInstance().Peer}) - - if totalSentCounter%logEveryNTransactions == 0 { - log.Infof("spammed %d transactions", totalSentCounter) - } - - // rate limit to the specified TPS - if currentSentCounter >= tps { - duration := time.Since(start) - - if duration < time.Second { - time.Sleep(time.Second - duration) - } - - start = time.Now() - currentSentCounter = 0 - } - } - } - }, shutdown.ShutdownPriorityTangleSpammer) -} - -func Stop() { - spammingMutex.Lock() - if spamming { - shutdownSignal <- struct{}{} - // wait for spammer to be done - <-done - spamming = false - } - spammingMutex.Unlock() -} diff --git a/plugins/tangle/tangle.go b/plugins/tangle/plugin.go similarity index 97% rename from plugins/tangle/tangle.go rename to plugins/tangle/plugin.go index 23edfe1fd03392590e9e5929308ed8b6e55395a8..533d644f3c2e52ad49b8f2c361a8f5ca6866f401 100644 --- a/plugins/tangle/tangle.go +++ b/plugins/tangle/plugin.go @@ -63,7 +63,7 @@ func configure(*node.Plugin) { } func run(*node.Plugin) { - daemon.BackgroundWorker("Tangle", func(shutdownSignal <-chan struct{}) { + _ = daemon.BackgroundWorker("Tangle", func(shutdownSignal <-chan struct{}) { <-shutdownSignal TransactionParser.Shutdown() diff --git a/plugins/webapi/gtta/plugin.go b/plugins/webapi/gtta/plugin.go index 54444bce56bcbb2a7df88dc54816433f5871e762..4e05e8e3c7a0de8b3e523ce948de8bfec2ab23c9 100644 --- a/plugins/webapi/gtta/plugin.go +++ b/plugins/webapi/gtta/plugin.go @@ -3,10 +3,10 @@ package gtta import ( "net/http" - "github.com/iotaledger/goshimmer/plugins/tipselection" + "github.com/iotaledger/goshimmer/packages/binary/tangle/model/transaction" + "github.com/iotaledger/goshimmer/plugins/tangle" "github.com/iotaledger/goshimmer/plugins/webapi" "github.com/iotaledger/hive.go/node" - "github.com/iotaledger/iota.go/trinary" "github.com/labstack/echo" ) @@ -15,17 +15,15 @@ var PLUGIN = node.NewPlugin("WebAPI GTTA Endpoint", node.Disabled, func(plugin * }) func Handler(c echo.Context) error { - - branchTransactionHash := tipselection.GetRandomTip() - trunkTransactionHash := tipselection.GetRandomTip(branchTransactionHash) + trunkTransactionId, branchTransactionId := tangle.TipSelector.GetTips() return c.JSON(http.StatusOK, Response{ - BranchTransaction: branchTransactionHash, - TrunkTransaction: trunkTransactionHash, + TrunkTransaction: trunkTransactionId, + BranchTransaction: branchTransactionId, }) } type Response struct { - BranchTransaction trinary.Trytes `json:"branchTransaction"` - TrunkTransaction trinary.Trytes `json:"trunkTransaction"` + BranchTransaction transaction.Id `json:"branchTransaction"` + TrunkTransaction transaction.Id `json:"trunkTransaction"` } diff --git a/plugins/webapi/spammer/plugin.go b/plugins/webapi/spammer/plugin.go index 7aa057fc2fc18c85982fa27ef373b1f8a3b586b6..a5d9345bdfa5f8bffcddb1c501c6dc12ae9fc19d 100644 --- a/plugins/webapi/spammer/plugin.go +++ b/plugins/webapi/spammer/plugin.go @@ -1,50 +1,19 @@ package spammer import ( - "net/http" - - "github.com/iotaledger/goshimmer/packages/transactionspammer" + "github.com/iotaledger/goshimmer/packages/binary/spammer" + "github.com/iotaledger/goshimmer/plugins/tangle" "github.com/iotaledger/goshimmer/plugins/webapi" + "github.com/iotaledger/hive.go/node" - "github.com/labstack/echo" ) +var transactionSpammer *spammer.Spammer + var PLUGIN = node.NewPlugin("Spammer", node.Disabled, configure) func configure(plugin *node.Plugin) { - webapi.Server.GET("spammer", WebApiHandler) -} - -func WebApiHandler(c echo.Context) error { - - var request Request - if err := c.Bind(&request); err != nil { - return c.JSON(http.StatusBadRequest, Response{Error: err.Error()}) - } - - switch request.Cmd { - case "start": - if request.Tps == 0 { - request.Tps = 1 - } - - transactionspammer.Stop() - transactionspammer.Start(request.Tps) - return c.JSON(http.StatusOK, Response{Message: "started spamming transactions"}) - case "stop": - transactionspammer.Stop() - return c.JSON(http.StatusOK, Response{Message: "stopped spamming transactions"}) - default: - return c.JSON(http.StatusBadRequest, Response{Error: "invalid cmd in request"}) - } -} - -type Response struct { - Message string `json:"message"` - Error string `json:"error"` -} + transactionSpammer = spammer.New(tangle.Instance, tangle.TipSelector) -type Request struct { - Cmd string `json:"cmd"` - Tps uint64 `json:"tps"` + webapi.Server.GET("spammer", handleRequest) } diff --git a/plugins/webapi/spammer/webapi.go b/plugins/webapi/spammer/webapi.go new file mode 100644 index 0000000000000000000000000000000000000000..f85f6e623d9723911ed5e731b64d8d0f707214fb --- /dev/null +++ b/plugins/webapi/spammer/webapi.go @@ -0,0 +1,40 @@ +package spammer + +import ( + "net/http" + + "github.com/labstack/echo" +) + +func handleRequest(c echo.Context) error { + var request Request + if err := c.Bind(&request); err != nil { + return c.JSON(http.StatusBadRequest, Response{Error: err.Error()}) + } + + switch request.Cmd { + case "start": + if request.Tps == 0 { + request.Tps = 1 + } + + transactionSpammer.Shutdown() + transactionSpammer.Start(request.Tps) + return c.JSON(http.StatusOK, Response{Message: "started spamming transactions"}) + case "stop": + transactionSpammer.Shutdown() + return c.JSON(http.StatusOK, Response{Message: "stopped spamming transactions"}) + default: + return c.JSON(http.StatusBadRequest, Response{Error: "invalid cmd in request"}) + } +} + +type Response struct { + Message string `json:"message"` + Error string `json:"error"` +} + +type Request struct { + Cmd string `json:"cmd"` + Tps int `json:"tps"` +}