From 5b4fd056be052ee6fa816657d69b98f62c36a349 Mon Sep 17 00:00:00 2001 From: Luca Moser <moser.luca@gmail.com> Date: Mon, 27 Jan 2020 15:41:53 +0100 Subject: [PATCH] removes unused plugins (#186) --- main.go | 7 - plugins/dashboard/parameters.go | 13 - plugins/dashboard/plugin.go | 81 --- plugins/dashboard/tps.go | 160 ----- plugins/dashboard/tps_template.go | 346 ----------- plugins/ui/files.go | 995 ------------------------------ plugins/ui/logger.go | 34 - plugins/ui/nodeInfo.go | 83 --- plugins/ui/src/builder.js | 58 -- plugins/ui/src/css/styles.css | 204 ------ plugins/ui/src/favicon.ico | Bin 16958 -> 0 bytes plugins/ui/src/index.html | 159 ----- plugins/ui/src/js/forcegraph.js | 58 -- plugins/ui/src/js/icons.js | 20 - plugins/ui/src/js/initials.js | 14 - plugins/ui/src/js/main.js | 160 ----- plugins/ui/src/js/tpschart.js | 282 --------- plugins/ui/src/js/utils.js | 92 --- plugins/ui/txLog.go | 37 -- plugins/ui/ui.go | 94 --- plugins/ui/websocket.go | 45 -- plugins/zeromq/parameters.go | 13 - plugins/zeromq/plugin.go | 99 --- plugins/zeromq/publisher.go | 47 -- 24 files changed, 3101 deletions(-) delete mode 100644 plugins/dashboard/parameters.go delete mode 100644 plugins/dashboard/plugin.go delete mode 100644 plugins/dashboard/tps.go delete mode 100644 plugins/dashboard/tps_template.go delete mode 100644 plugins/ui/files.go delete mode 100644 plugins/ui/logger.go delete mode 100644 plugins/ui/nodeInfo.go delete mode 100644 plugins/ui/src/builder.js delete mode 100644 plugins/ui/src/css/styles.css delete mode 100644 plugins/ui/src/favicon.ico delete mode 100644 plugins/ui/src/index.html delete mode 100644 plugins/ui/src/js/forcegraph.js delete mode 100644 plugins/ui/src/js/icons.js delete mode 100644 plugins/ui/src/js/initials.js delete mode 100644 plugins/ui/src/js/main.js delete mode 100644 plugins/ui/src/js/tpschart.js delete mode 100644 plugins/ui/src/js/utils.js delete mode 100644 plugins/ui/txLog.go delete mode 100644 plugins/ui/ui.go delete mode 100644 plugins/ui/websocket.go delete mode 100644 plugins/zeromq/parameters.go delete mode 100644 plugins/zeromq/plugin.go delete mode 100644 plugins/zeromq/publisher.go diff --git a/main.go b/main.go index c3f42494..b047019b 100644 --- a/main.go +++ b/main.go @@ -8,7 +8,6 @@ import ( "github.com/iotaledger/goshimmer/plugins/autopeering" "github.com/iotaledger/goshimmer/plugins/bundleprocessor" "github.com/iotaledger/goshimmer/plugins/cli" - "github.com/iotaledger/goshimmer/plugins/dashboard" "github.com/iotaledger/goshimmer/plugins/gossip" "github.com/iotaledger/goshimmer/plugins/gracefulshutdown" "github.com/iotaledger/goshimmer/plugins/graph" @@ -17,7 +16,6 @@ import ( statusscreen_tps "github.com/iotaledger/goshimmer/plugins/statusscreen-tps" "github.com/iotaledger/goshimmer/plugins/tangle" "github.com/iotaledger/goshimmer/plugins/tipselection" - "github.com/iotaledger/goshimmer/plugins/ui" "github.com/iotaledger/goshimmer/plugins/webapi" webapi_broadcastData "github.com/iotaledger/goshimmer/plugins/webapi/broadcastData" webapi_findTransactionHashes "github.com/iotaledger/goshimmer/plugins/webapi/findTransactionHashes" @@ -27,7 +25,6 @@ import ( 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/zeromq" "github.com/iotaledger/hive.go/node" ) @@ -46,8 +43,6 @@ func main() { analysis.PLUGIN, gracefulshutdown.PLUGIN, tipselection.PLUGIN, - zeromq.PLUGIN, - dashboard.PLUGIN, metrics.PLUGIN, statusscreen.PLUGIN, @@ -64,8 +59,6 @@ func main() { webapi_getNeighbors.PLUGIN, webapi_spammer.PLUGIN, - ui.PLUGIN, - graph.PLUGIN, ), ) diff --git a/plugins/dashboard/parameters.go b/plugins/dashboard/parameters.go deleted file mode 100644 index 2326d843..00000000 --- a/plugins/dashboard/parameters.go +++ /dev/null @@ -1,13 +0,0 @@ -package dashboard - -import ( - flag "github.com/spf13/pflag" -) - -const ( - CFG_BIND_ADDRESS = "dashboard.bindAddress" -) - -func init() { - flag.String(CFG_BIND_ADDRESS, "127.0.0.1:8081", "the bind address for the dashboard") -} diff --git a/plugins/dashboard/plugin.go b/plugins/dashboard/plugin.go deleted file mode 100644 index bf820c55..00000000 --- a/plugins/dashboard/plugin.go +++ /dev/null @@ -1,81 +0,0 @@ -package dashboard - -import ( - "errors" - "net/http" - "time" - - "github.com/iotaledger/goshimmer/packages/parameter" - "github.com/iotaledger/goshimmer/packages/shutdown" - "github.com/iotaledger/goshimmer/plugins/metrics" - "github.com/iotaledger/hive.go/daemon" - "github.com/iotaledger/hive.go/events" - "github.com/iotaledger/hive.go/logger" - "github.com/iotaledger/hive.go/node" - "golang.org/x/net/context" -) - -var ( - log *logger.Logger - httpServer *http.Server -) - -const name = "Dashboard" - -var PLUGIN = node.NewPlugin(name, node.Disabled, configure, run) - -func configure(*node.Plugin) { - log = logger.NewLogger(name) - - router := http.NewServeMux() - - httpServer = &http.Server{ - Addr: parameter.NodeConfig.GetString(CFG_BIND_ADDRESS), - Handler: router, - } - - router.HandleFunc("/dashboard", ServeHome) - router.HandleFunc("/ws", ServeWs) - - // send the sampledTPS to client via websocket, use uint32 to save mem - metrics.Events.ReceivedTPSUpdated.Attach(events.NewClosure(func(sampledTPS uint64) { - TPSQ = append(TPSQ, uint32(sampledTPS)) - if len(TPSQ) > MAX_Q_SIZE { - TPSQ = TPSQ[1:] - } - })) -} - -func run(*node.Plugin) { - log.Infof("Starting %s ...", name) - if err := daemon.BackgroundWorker(name, workerFunc, shutdown.ShutdownPriorityDashboard); err != nil { - log.Errorf("Error starting as daemon: %s", err) - } -} - -func workerFunc(shutdownSignal <-chan struct{}) { - stopped := make(chan struct{}) - go func() { - log.Infof("Started %s: http://%s/dashboard", name, httpServer.Addr) - if err := httpServer.ListenAndServe(); err != nil { - if !errors.Is(err, http.ErrServerClosed) { - log.Errorf("Error serving: %s", err) - } - close(stopped) - } - }() - - select { - case <-shutdownSignal: - case <-stopped: - } - - log.Infof("Stopping %s ...", name) - ctx, cancel := context.WithTimeout(context.Background(), time.Second) - defer cancel() - - if err := httpServer.Shutdown(ctx); err != nil { - log.Errorf("Error stopping: %s", err) - } - log.Infof("Stopping %s ... done", name) -} diff --git a/plugins/dashboard/tps.go b/plugins/dashboard/tps.go deleted file mode 100644 index 656998c2..00000000 --- a/plugins/dashboard/tps.go +++ /dev/null @@ -1,160 +0,0 @@ -package dashboard - -import ( - "encoding/binary" - "fmt" - "html/template" - "math" - "net/http" - "strconv" - "sync" - "time" - - "github.com/iotaledger/goshimmer/plugins/autopeering/local" - - "github.com/gorilla/websocket" - "github.com/iotaledger/goshimmer/plugins/autopeering" - "github.com/iotaledger/goshimmer/plugins/metrics" - "github.com/iotaledger/hive.go/events" -) - -var ( - start = time.Now() - homeTempl, templ_err = template.New("dashboard").Parse(tpsTemplate) - upgrader = websocket.Upgrader{ - ReadBufferSize: 1024, - WriteBufferSize: 1024, - } -) - -type Status struct { - Id string `json:"Id"` - Neighbor string `json:"Neighbor"` - KnownPeer string `json:"KnownPeer"` - Uptime string `json:"Uptime"` -} - -func GetStatus() *Status { - // Get Uptime - duration := time.Since(start) - padded := false - uptime := fmt.Sprintf("Uptime: ") - if int(duration.Seconds())/(60*60*24) > 0 { - days := int(duration.Hours()) / 24 - - numberLength := int(math.Log10(float64(days))) + 1 - padLength := 31 - numberLength - - uptime += fmt.Sprintf("%*v", padLength, "") - uptime += fmt.Sprintf("%02dd ", days) - } - - if int(duration.Seconds())/(60*60) > 0 { - if !padded { - uptime += fmt.Sprintf("%29v", "") - padded = true - } - uptime += fmt.Sprintf("%02dh ", int(duration.Hours())%24) - } - - if int(duration.Seconds())/60 > 0 { - if !padded { - uptime += fmt.Sprintf("%33v", "") - padded = true - } - uptime += fmt.Sprintf("%02dm ", int(duration.Minutes())%60) - } - - if !padded { - uptime += fmt.Sprintf("%37v", "") - } - uptime += fmt.Sprintf("%02ds ", int(duration.Seconds())%60) - - outgoing := "0" - incoming := "0" - neighbors := "0" - if autopeering.Selection != nil { - outgoing = strconv.Itoa(len(autopeering.Selection.GetOutgoingNeighbors())) - incoming = strconv.Itoa(len(autopeering.Selection.GetIncomingNeighbors())) - neighbors = strconv.Itoa(len(autopeering.Selection.GetNeighbors())) - } - knownPeers := "0" - if autopeering.Discovery != nil { - knownPeers = strconv.Itoa(len(autopeering.Discovery.GetVerifiedPeers())) - } - - return &Status{ - Id: local.GetInstance().ID().String(), - Neighbor: "Neighbors: " + outgoing + " chosen / " + incoming + " accepted / " + neighbors + " total", - KnownPeer: "Known Peers: " + knownPeers + " total", - Uptime: uptime, - } -} - -// ServeWs websocket -func ServeWs(w http.ResponseWriter, r *http.Request) { - ws, err := upgrader.Upgrade(w, r, nil) - if err != nil { - return - } - - var websocketWriteMutex sync.Mutex - - notifyWebsocketClient := events.NewClosure(func(sampledTPS uint64) { - go func() { - websocketWriteMutex.Lock() - defer websocketWriteMutex.Unlock() - - p := make([]byte, 4) - binary.LittleEndian.PutUint32(p, uint32(sampledTPS)) - if err := ws.WriteMessage(websocket.BinaryMessage, p); err != nil { - return - } - - // write node status message - status := GetStatus() - if err := ws.WriteJSON(status); err != nil { - return - } - }() - }) - - metrics.Events.ReceivedTPSUpdated.Attach(notifyWebsocketClient) - - for { - if _, _, err := ws.ReadMessage(); err != nil { - break - } - } - - metrics.Events.ReceivedTPSUpdated.Detach(notifyWebsocketClient) -} - -// ServeHome registration -func ServeHome(w http.ResponseWriter, r *http.Request) { - if r.URL.Path != "/dashboard" { - http.Error(w, "Not found", http.StatusNotFound) - return - } - if r.Method != "GET" { - http.Error(w, "Method not allowed", http.StatusMethodNotAllowed) - return - } - if templ_err != nil { - panic("HTML template error") - } - - _ = homeTempl.Execute(w, &struct { - Host string - Data []uint32 - }{ - r.Host, - TPSQ, - }) -} - -var TPSQ []uint32 - -const ( - MAX_Q_SIZE int = 3600 -) diff --git a/plugins/dashboard/tps_template.go b/plugins/dashboard/tps_template.go deleted file mode 100644 index 00cc9aa8..00000000 --- a/plugins/dashboard/tps_template.go +++ /dev/null @@ -1,346 +0,0 @@ -package dashboard - -var tpsTemplate = ` -<!DOCTYPE html> -<html> - -<head> - <script src="https://code.jquery.com/jquery-3.1.1.min.js"></script> - <script src="https://code.highcharts.com/stock/highstock.js"></script> - <script src="https://code.highcharts.com/stock/modules/exporting.js"></script> - <script src="https://code.highcharts.com/stock/modules/export-data.js"></script> -</head> - -<body> - <div id="node-status" style="min-width:310px"> - <h3 id="node-id"></h3> - <h3 id="node-neighbor"></h3> - <h3 id="node-knownpeer"></h3> - <h3 id="node-uptime"></h3> - </div> - <div id="container" style="height: 400px; min-width: 310px"></div> - <script> - Highcharts.createElement('link', { - href: 'https://fonts.googleapis.com/css?family=Unica+One', - rel: 'stylesheet', - type: 'text/css' - }, null, document.getElementsByTagName('head')[0]); - - Highcharts.theme = { - colors: ['#2b908f', '#90ee7e', '#f45b5b', '#7798BF', '#aaeeee', '#ff0066', - '#eeaaee', '#55BF3B', '#DF5353', '#7798BF', '#aaeeee'], - chart: { - backgroundColor: { - linearGradient: { x1: 0, y1: 0, x2: 1, y2: 1 }, - stops: [ - [0, '#2a2a2b'], - [1, '#3e3e40'] - ] - }, - // style: { - // fontFamily: 'sans-serif' - // }, - plotBorderColor: '#606063' - }, - title: { - style: { - color: '#E0E0E3', - // textTransform: 'uppercase', - fontSize: '20px' - } - }, - subtitle: { - style: { - color: '#E0E0E3', - // textTransform: 'uppercase' - } - }, - xAxis: { - gridLineColor: '#707073', - labels: { - style: { - color: '#E0E0E3' - } - }, - lineColor: '#707073', - minorGridLineColor: '#505053', - tickColor: '#707073', - title: { - style: { - color: '#A0A0A3' - - } - } - }, - yAxis: { - gridLineColor: '#707073', - labels: { - style: { - color: '#E0E0E3' - } - }, - lineColor: '#707073', - minorGridLineColor: '#505053', - tickColor: '#707073', - tickWidth: 1, - title: { - style: { - color: '#A0A0A3' - } - } - }, - tooltip: { - backgroundColor: 'rgba(0, 0, 0, 0.85)', - style: { - color: '#F0F0F0' - } - }, - plotOptions: { - series: { - dataLabels: { - color: '#B0B0B3' - }, - marker: { - lineColor: '#333' - } - }, - boxplot: { - fillColor: '#505053' - }, - candlestick: { - lineColor: 'white' - }, - errorbar: { - color: 'white' - } - }, - legend: { - itemStyle: { - color: '#E0E0E3' - }, - itemHoverStyle: { - color: '#FFF' - }, - itemHiddenStyle: { - color: '#606063' - } - }, - credits: { - style: { - color: '#666' - } - }, - labels: { - style: { - color: '#707073' - } - }, - - drilldown: { - activeAxisLabelStyle: { - color: '#F0F0F3' - }, - activeDataLabelStyle: { - color: '#F0F0F3' - } - }, - - navigation: { - buttonOptions: { - symbolStroke: '#DDDDDD', - theme: { - fill: '#505053' - } - } - }, - - // scroll charts - rangeSelector: { - buttonTheme: { - fill: '#505053', - stroke: '#000000', - style: { - color: '#CCC' - }, - states: { - hover: { - fill: '#707073', - stroke: '#000000', - style: { - color: 'white' - } - }, - select: { - fill: '#000003', - stroke: '#000000', - style: { - color: 'white' - } - } - } - }, - inputBoxBorderColor: '#505053', - inputStyle: { - backgroundColor: '#333', - color: 'silver' - }, - labelStyle: { - color: 'silver' - } - }, - - navigator: { - handles: { - backgroundColor: '#666', - borderColor: '#AAA' - }, - outlineColor: '#CCC', - maskFill: 'rgba(255,255,255,0.1)', - series: { - color: '#7798BF', - lineColor: '#A6C7ED' - }, - xAxis: { - gridLineColor: '#505053' - } - }, - - scrollbar: { - barBackgroundColor: '#808083', - barBorderColor: '#808083', - buttonArrowColor: '#CCC', - buttonBackgroundColor: '#606063', - buttonBorderColor: '#606063', - rifleColor: '#FFF', - trackBackgroundColor: '#404043', - trackBorderColor: '#404043' - }, - - // special colors for some of the - legendBackgroundColor: 'rgba(0, 0, 0, 0.5)', - background2: '#505053', - dataLabelsColor: '#B0B0B3', - textColor: '#C0C0C0', - contrastTextColor: '#F0F0F3', - maskColor: 'rgba(255,255,255,0.3)' - }; - - // Apply the theme - Highcharts.setOptions(Highcharts.theme); - - // Start Here - var time = Date.now() - 3000; - var start_draw = time + 5000; - const update_rate = 5; - var counter = 0; - data = [[time - 5000, 0]]; - var tzoffset = new Date().getTimezoneOffset(); - var chart = Highcharts.stockChart('container', { - rangeSelector: { - selected: 1 - }, - - title: { - text: 'Transactions per second' - }, - - time: { - timezoneOffset: tzoffset - }, - - rangeSelector: { - buttons: [ - { - type: 'minute', - count: 5, - text: '5m' - }, { - type: 'minute', - count: 15, - text: '15m' - }, { - type: 'minute', - count: 30, - text: '30m' - }, { - type: 'hour', - count: 60, - text: '1h' - }], - inputEnabled: false - }, - - series: [{ - name: 'Transactions per second', - data: data, - type: 'areaspline', - threshold: null, - tooltip: { - valueDecimals: 0 - }, - fillColor: { - linearGradient: { - x1: 0, - y1: 0, - x2: 0, - y2: 1 - }, - stops: [ - [0, Highcharts.getOptions().colors[0]], - [1, Highcharts.Color(Highcharts.getOptions().colors[0]).setOpacity(0).get('rgba')] - ] - } - }] - }); - - const dataStr = '{{.Data}}' - const parsedData = JSON.parse(dataStr.replace(/ /g, ',')); - time = Date.now() - 1000 * (parsedData.length + 1); - for (let i = 0; i < parsedData.length; i++) { - chart.series[0].addPoint([time += 1000, parseInt(parsedData[i], 10)], false); - } - chart.redraw(); - console.log(parsedData); - - const conn = new WebSocket("ws://{{.Host}}/ws"); - conn.binaryType = 'arraybuffer'; - conn.onopen = evt => { - console.log("WebSocket is open now."); - console.log("WebSocket done."); - } - conn.onclose = () => { - // console.log('Connection closed'); - } - conn.onmessage = evt => { - const data = evt.data; - if(isJSON(data)) { - console.log('status updated'); - var res = JSON.parse(data); - $("#node-id").html("Node ID: " + res.Id); - $("#node-neighbor").html(res.Neighbor); - $("#node-knownpeer").html(res.KnownPeer); - $("#node-uptime").html(res.Uptime); - } else { - console.log('metric updated'); - const dv = new DataView(data); - // var value = dv.getUint32(4, true) << 32 | dv.getUint32(0, true); - const value = dv.getUint32(0, true); - chart.series[0].addPoint([time += 1000, value], true); //((counter += 1) % update_rate == 4)); - console.log(value); - console.log(dv); - } - } - - function isJSON(str) { - try { - JSON.parse(str); - } catch(e) { - return false; - } - return true; - } - </script> -</body> - -</html> -` diff --git a/plugins/ui/files.go b/plugins/ui/files.go deleted file mode 100644 index 4d32815b..00000000 --- a/plugins/ui/files.go +++ /dev/null @@ -1,995 +0,0 @@ -package ui - -var files = map[string]string{ - "css/styles.css": `/* mobile */ -html { - font-size:12px; -} -/* tablets */ -@media only screen and (min-width: 600px) { - html { - font-size:14px; - } -} -/* desktop */ -@media only screen and (min-width: 768px) { - html { - font-size:16px; - } -} -body { - opacity: 1; - transition: 0.35s opacity; -} -body.fade { - opacity: 0; - transition: none; -} - -/* bulma */ -[v-cloak] { - display: none; -} -.section { - padding: 1.8rem 1.5rem; -} -.columns { - margin-bottom: 0 !important; -} -.header{ - background:#005050; - padding-bottom: 0; -} - -/* main */ -.title{ - display: flex; - align-items: center; -} -.login{ - background:#004965; - border: 1px solid #5e6d6f; - padding:20px; - font-size: 0.9rem; - border-radius: 0.4em; - box-shadow: 0 2px 3px rgba(10, 10, 10, 0.1), 0 0 0 1px rgba(10, 10, 10, 0.1); -} -.login button{ - width:100%; - margin-top:12px; -} -.login div { - display: flex; - align-items: center; - font-size:1.2rem; -} -.login div:first-child { - margin-bottom:12px; -} -.login div span { - min-width:6.5rem; -} -.status{ - margin-left:54px; -} -.status > span { - margin-left:8px; -} -.tps.input { - width:100px; -} -.tx-toolbar { - display: flex; - justify-content: space-between; - height:50px; -} -.graph { - border: 1px solid #5e6d6f; - overflow: hidden; -} -#graph { - width:100%; - height: 100%; -} -.hovered-node{ - position: absolute; - top: 0; - font-size: 0.75rem; - padding: 5px 10px; - width: 100%; - color: #c5c5c5; -} -.chart-container { - height: calc(100% - 50px); - display: flex; - border:1px solid #5e6d6f; - overflow: hidden; -} - -/* tables */ -.info-list{ - background:#004965; - border: 1px solid #5e6d6f; - font-size: 0.9rem; -} -.info-list .list-item{ - display: flex; - justify-content: space-between; - white-space: nowrap; - overflow: hidden; -} - -.logs-container { - overflow: scroll; - display: flex; - flex-direction: column-reverse; - border:1px solid #5e6d6f; -} -.logs-list { - background:#004965; - table-layout: fixed; - width: 100%; - font-size: 0.9rem; -} -.logs-list th { - background: #00374c; -} -.logs-list td { - font-family: "Inconsolata", "Consolas", "Monaco", monospace; - padding: 0.25em 0.75em; - overflow: auto; - white-space: nowrap; -} -.logs-list td::-webkit-scrollbar { height: 0 !important } -.logs-list td:first-child { - font-weight: bold; -} -.logs-list td:last-child span { - width:35px; - text-align: center; - font-weight: bold; - display: inline-block; -} - -.tx-container { - height: 100%; - overflow: scroll; - display: flex; - flex-direction: column-reverse; - border:1px solid #5e6d6f; -} -.tx-list { - background:#004965; - table-layout: fixed; - width: 100%; - font-size: 0.9rem; -} -.tx-list th { - padding-bottom: 3px; - border-top:1px solid #5e6d6f !important; - background: #00374c; -} -.tx-list tbody tr { - cursor: pointer; -} -.tx-list tbody tr:hover { - background: #00374c; -} -.tx-list td { - font-family: "Inconsolata", "Consolas", "Monaco", monospace; - padding: 0.25em 0.75em; - overflow: auto; - white-space: nowrap; -} -.tx-list td::-webkit-scrollbar { height: 0 !important } -.tx-list td:first-child { - font-weight: bold; -} -.tx-list tr.full-tx { - display:block; - width:100%; -} -.tx-list tr.full-tx td { - padding:0; - width:100%; -} -.tx-list tr.full-tx pre:hover { - background:#232929; -} -.no-txs{ - height:100%; - width:100%; - display:flex; - align-items: center; - justify-content: center; - color:grey; - font-size: 0.8rem; -} -`, - "index.html": `<!DOCTYPE html> -<html> - -<head> - <meta charset="utf-8"> - <meta name="viewport" content="width=device-width, initial-scale=1"> - <link rel="shortcut icon" href="ui/favicon.ico"> - <title>GoShimmer UI</title> - <link rel="stylesheet" href="https://unpkg.com/bulmaswatch@0.7.5/darkly/bulmaswatch.min.css"> - <link rel="stylesheet" href="ui/css/styles.css"> -</head> - -<body class="fade"> - <section id="app"> - <section class="section header" ref="header"> - <div class="container"> - <div class="columns"> - <div class="column"> - <h1 class="title"> - <iota-icon size="42"></iota-icon> - GoShimmer - </h1> - <span v-if="loggedIn" class="status">Status:<span class="tag is-light">{{synced}}</span> - </div> - - <div v-if="!loggedIn" class="column"> - <form class="login" @submit="login"> - <div> - <span>Username:</span> - <input class="input" placeholder="Username" name="username"> - </div> - <div> - <span>Password:</span> - <input class="input" placeholder="Username" name="password"> - </div> - <button type="submit" :disabled="loginError?true:false" - :class="loginError?'button is-danger':'button is-primary'"> - {{ loginButtonText }} - </button> - </form> - </div> - - <div v-if="loggedIn" class="column"> - <div class="list info-list"> - <div v-for="(c, i) in infoKeys" class="list-item"> - <span>{{ c }}:</span> - <span v-if="infoValues[i]">{{ infoValues[i] }}</span> - </li> - </div> - </div> - </div> - </div> - <div v-if="loggedIn" class="tabs is-boxed"> - <ul> - <li v-for="t in tabs" @click="selectTab(t)" - :class="selectedTab===t?'is-active':''"> - <a>{{t}}</a> - </li> - </ul> - </div> - </section> - - <section class="section" v-if="selectedTab==='Logs'"> - <div class="container logs-container" :style="footerContainerStyle()"> - <table class="table logs-list"> - <thead v-if="logs.length>0"><tr> - <th style="width:75px;">Time</th> - <th>Message</th> - <th style="width:75px;">Status</th> - </tr></thead> - <tbody> - <tr v-for="log in logs"> - <td>{{ log.time }}</td> - <td>{{ log.source }}: {{ log.message }}</td> - <td>[<span :style="'color:'+log.color+';'">{{ log.label }}</span>]</td> - </tr> - </tbody> - </table> - </div> - </section> - - <section class="section" v-if="selectedTab==='Spammer'"> - <div class="container" :style="footerContainerStyle()"> - <div class="tx-toolbar"> - <div class="field is-grouped"> - <p class="control"> - <input ref="tpsinput" class="input tps" type="number" v-model="tpsToSpam" placeholder="TPS"> - </p> - <p class="control"> - <button class="button is-info" @click="startSpam()" :disabled="tpsToSpam<1"> - <play-icon size="19"></play-icon> - </button> - </p> - <p class="control"> - <button class="button is-primary" @click="stopSpam()" :disabled="info.receivedTps<1"> - <stop-icon size="19"></stop-icon> - </button> - </p> - </div> - <!-- <div class="field is-grouped"> - <button class="button" @click="clearTxs()" :disabled="txs.length<1"> - Clear - </button> - </div> --> - </div> - <div class="chart-container"> - <tps-chart ref="tpschart"></tps-chart> - </div> - </div> - </section> - - <section class="section" v-if="selectedTab==='Transactions'"> - <div class="container transactions" :style="footerContainerStyle()"> - <div class="tx-container"> - <table v-if="txs.length>0" class="table tx-list"> - <thead><tr> - <th style="width:50px;"><iota-icon size="20"></iota-icon></th> - <th style="line-height:21px;">Hash</th> - </tr></thead> - <tbody> - <tr v-for="tx in txs" @click="selectTxHash(tx.hash)" :class="selectedTxHash===tx.hash ? 'full-tx' : ''"> - <td v-if="selectedTxHash!==tx.hash">{{ tx.value }}</td> - <td> - <span v-if="selectedTxHash!==tx.hash">{{ tx.hash }}</span> - <pre v-if="selectedTxHash===tx.hash" :style="'width:calc('+(windowWidth-2)+'px - 3rem);'">{{ JSON.stringify(tx,null,2) }}</pre> - </td> - </tr> - </tbody> - </table> - <div v-if="txs.length===0" class="no-txs">No transactions yet</div> - </div> - </div> - </section> - - <section class="section" v-if="selectedTab==='Neighbors'"> - <div class="container graph" :style="footerContainerStyle()"> - <force-graph :neighbors="neighbors" :me="info.id"></force-graph> - </div> - </section> - - </section> - - <!-- <script src="https://unpkg.com/vue@2.5.9"></script> --> - <script src="https://unpkg.com/vue@2.6.10/dist/vue.min.js"></script> - <script src="https://unpkg.com/dayjs@1.8.15"></script> - <script src="https://unpkg.com/3d-force-graph"></script> - <script src="https://code.jquery.com/jquery-3.1.1.min.js"></script> - <script src="https://code.highcharts.com/stock/highstock.js"></script> - <script src="https://code.highcharts.com/stock/modules/exporting.js"></script> - <script src="https://code.highcharts.com/stock/modules/export-data.js"></script> - <script src="ui/js/initials.js"></script> - <script src="ui/js/utils.js"></script> - <script src="ui/js/icons.js"></script> - <script src="ui/js/forcegraph.js"></script> - <script src="ui/js/tpschart.js"></script> - <script src="ui/js/main.js"></script> -</body> - -</html>`, - "js/forcegraph.js": ` -Vue.component('force-graph', { - props:['neighbors', 'me'], - data: function() { - return { - hoveredNode: null - } - }, - watch:{ - neighbors: function (val, oldVal) { - let updateNeeded - val.forEach(node=> { - if(!oldVal.find(n=> n.id===node.id)) updateNeeded=true - }) - oldVal.forEach(node=> { - if(!val.find(n=> n.id===node.id)) updateNeeded=true - }) - if (updateNeeded) this.graph.graphData(this.makeGraph()) - }, - }, - methods:{ - makeGraph() { - return { - nodes: [{id: this.me}, ...this.neighbors], - links: this.neighbors.filter(id => id) - .map(id => ({ source: id, target: this.me })) - }; - } - }, - mounted() { - const el = document.getElementById('3d-graph') - const parentStyle = window.getComputedStyle(el.parentNode) - this.graph = ForceGraph3D()(el) - .width(parseInt(parentStyle.width)-2) - .height(parseInt(parentStyle.height)-2) - .enableNodeDrag(false) - .onNodeHover(node => { - this.hoveredNode = node - el.style.cursor = node ? 'pointer' : null - }) - .onNodeClick(node => console.log(node)) - .nodeColor(node => { - if (node.id===this.me) return 'rgba(0,200,255,1)' - return node.accepted ? 'rgba(150,255,150,1)' : 'rgba(255,255,255,1)' - }) - .linkColor('rgba(255,255,255,1)') - .linkOpacity(0.85) - .graphData(this.makeGraph()) - }, - - template: '<div style="height:100%;">'+ - '<div id="3d-graph"></div>'+ - '<div v-if="hoveredNode" class="hovered-node">'+ - 'ID: {{hoveredNode.id}} '+ - '<span v-if="hoveredNode.address">Address: {{hoveredNode.address}}</span>'+ - '</div>'+ - '</div>' -})`, - "js/icons.js": ` -Vue.component('iota-icon', { - props:['size'], - template: '<svg :height="size" :width="size" style="margin-right:10px;" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" id="Layer_1" x="0px" y="0px" viewBox="0 0 128 128" xml:space="preserve"><path d="M79.6 24.9c-.1-2.8 2.4-5.4 5.6-5.3 2.8.1 5.1 2.5 5.1 5.4 0 3-2.5 5.3-5.6 5.3-2.8 0-5.1-2.5-5.1-5.4z" fill="#FFF"/><path d="M91 95.4c3 0 5.3 2.3 5.3 5.3s-2.4 5.4-5.4 5.4c-2.9 0-5.3-2.4-5.3-5.4 0-3 2.4-5.3 5.4-5.3z" fill="#FFF"/><path d="M22.4 73.4c-3 0-5.3-2.4-5.3-5.5 0-2.9 2.4-5.2 5.4-5.2 3 0 5.3 2.4 5.3 5.5-.1 2.9-2.5 5.2-5.4 5.2z" fill="#FFF"/><path d="M81.9 39.2c0-2.6 2-4.6 4.6-4.6 2.5 0 4.6 2.1 4.6 4.6 0 2.5-2.1 4.6-4.6 4.6-2.6 0-4.6-2.1-4.6-4.6z" fill="#FFF"/><path d="M33.9 55.1c2.6 0 4.6 2 4.7 4.5 0 2.5-2.1 4.6-4.6 4.6-2.5 0-4.6-2.1-4.6-4.6-.1-2.5 2-4.5 4.5-4.5z" fill="#FFF"/><path d="M98.4 45.4c-2.5 0-4.6-2.1-4.6-4.6 0-2.6 2.1-4.6 4.6-4.6 2.5 0 4.6 2.1 4.6 4.6 0 2.6-2 4.6-4.6 4.6z" fill="#FFF"/><path d="M77.9 99.5c-2.5 0-4.6-2.1-4.6-4.6 0-2.5 2-4.5 4.6-4.6 2.5 0 4.6 2.1 4.6 4.6 0 2.5-2.1 4.6-4.6 4.6z" fill="#FFF"/><path d="M33.9 48.5c0 2.5-2.1 4.6-4.6 4.6-2.5 0-4.5-2.1-4.5-4.6 0-2.5 2.1-4.6 4.6-4.6 2.5-.1 4.6 2 4.5 4.6z" fill="#FFF"/><path d="M70.4 109c-2.5 0-4.5-2-4.5-4.6 0-2.5 2-4.5 4.6-4.6 2.5 0 4.6 2.1 4.6 4.6-.1 2.6-2.1 4.6-4.7 4.6z" fill="#FFF"/><path d="M56.9 97.1c0-2.2 1.7-3.9 3.9-3.9s3.9 1.8 3.9 4-1.8 3.9-3.9 3.9c-2.2 0-3.9-1.8-3.9-4z" fill="#FFF"/><path d="M100.9 52.9c0 2.2-1.8 3.9-3.9 3.9-2.1 0-3.9-1.8-3.9-3.9 0-2.2 1.8-4 3.9-3.9 2.1 0 3.9 1.7 3.9 3.9z" fill="#FFF"/><path d="M44.4 43.7c0 2.2-1.7 3.9-3.9 3.9s-3.9-1.7-3.9-4c0-2.2 1.7-3.9 3.9-3.9 2.3.1 4 1.8 3.9 4z" fill="#FFF"/><path d="M49 54.9c0 2.2-1.7 3.9-3.9 3.9s-3.9-1.7-3.9-3.9 1.7-4 3.9-3.9c2.2 0 3.9 1.7 3.9 3.9z" fill="#FFF"/><path d="M35 33.5c0-2.2 1.8-3.9 3.9-3.9 2.2 0 3.9 1.8 3.9 3.9 0 2.2-1.7 3.9-3.9 3.9S35 35.7 35 33.5z" fill="#FFF"/><path d="M81.1 51.3c0-2.2 1.7-3.9 3.9-3.9s4 1.8 3.9 4c0 2.2-1.8 3.9-3.9 3.9-2.2-.2-3.9-1.9-3.9-4z" fill="#FFF"/><path d="M68.2 83.7c2.1 0 3.9 1.8 3.9 3.9 0 2.2-1.8 3.9-4 3.9s-3.9-1.7-3.9-3.9c.1-2.2 1.9-3.9 4-3.9z" fill="#FFF"/><path d="M56.7 103.6c0 2.2-1.7 3.9-3.9 3.9s-3.9-1.7-3.9-3.9 1.8-4 3.9-3.9c2.2 0 3.9 1.7 3.9 3.9z" fill="#FFF"/><path d="M106.5 60.5c-2.1 0-3.8-1.8-3.9-3.9 0-2.2 1.8-3.9 4-3.9 2.1 0 3.9 1.8 3.9 3.9 0 2.2-1.8 3.9-4 3.9z" fill="#FFF"/><path d="M57.5 89.3c0 1.9-1.5 3.4-3.4 3.3-1.9 0-3.4-1.5-3.4-3.3 0-1.9 1.5-3.4 3.4-3.4s3.4 1.5 3.4 3.4z" fill="#FFF"/><path d="M50.7 38.5c1.9 0 3.3 1.5 3.3 3.3 0 1.8-1.5 3.4-3.3 3.4-1.8 0-3.4-1.5-3.4-3.4.1-1.8 1.6-3.3 3.4-3.3z" fill="#FFF"/><path d="M58.2 79.7c0-1.9 1.4-3.4 3.3-3.4s3.4 1.5 3.4 3.3c0 1.9-1.5 3.3-3.3 3.3-1.9.1-3.4-1.3-3.4-3.2z" fill="#FFF"/><path d="M46.2 99.1c-1.9 0-3.4-1.4-3.4-3.3s1.5-3.3 3.3-3.4c1.9 0 3.4 1.5 3.4 3.4 0 1.8-1.5 3.3-3.3 3.3z" fill="#FFF"/><path d="M84.7 61c0 1.8-1.4 3.3-3.3 3.3s-3.4-1.5-3.3-3.4c0-1.9 1.5-3.3 3.3-3.3 1.9 0 3.3 1.5 3.3 3.4z" fill="#FFF"/><path d="M49.1 35c-1.9 0-3.4-1.4-3.4-3.3s1.5-3.4 3.4-3.4c1.8 0 3.3 1.5 3.4 3.4 0 1.8-1.5 3.3-3.4 3.3z" fill="#FFF"/><path d="M93.4 66c-1.9 0-3.3-1.5-3.3-3.3 0-1.8 1.5-3.3 3.4-3.3s3.3 1.5 3.3 3.4c0 1.8-1.5 3.2-3.4 3.2z" fill="#FFF"/><path d="M55.2 56.4c-1.8 0-3.3-1.5-3.3-3.4 0-1.8 1.6-3.3 3.4-3.3 1.9 0 3.3 1.5 3.3 3.4s-1.5 3.3-3.4 3.3z" fill="#FFF"/><path d="M103 69.6c-1.9-.1-3.3-1.6-3.3-3.5.1-1.8 1.6-3.3 3.4-3.2 1.9.1 3.4 1.6 3.3 3.6-.1 1.8-1.6 3.2-3.4 3.1z" fill="#FFF"/><path d="M64 56.4c-1.6 0-2.9-1.3-2.9-2.9 0-1.6 1.3-2.8 2.9-2.8 1.6 0 2.9 1.3 2.8 2.9.1 1.6-1.1 2.8-2.8 2.8z" fill="#FFF"/><path d="M95.4 73.7c0-1.6 1.2-2.9 2.8-2.9 1.6 0 2.9 1.2 2.9 2.9 0 1.6-1.4 3-2.9 3-1.5-.1-2.8-1.4-2.8-3z" fill="#FFF"/><path d="M60.7 32.2c0 1.6-1.2 2.8-2.9 2.8-1.6 0-2.9-1.3-2.9-2.9 0-1.6 1.3-2.9 3-2.8 1.6 0 2.8 1.3 2.8 2.9z" fill="#FFF"/><path d="M60.4 71.9c0 1.6-1.2 2.8-2.8 2.9-1.7 0-2.9-1.3-2.9-2.9 0-1.6 1.3-2.9 2.9-2.9 1.6 0 2.8 1.3 2.8 2.9z" fill="#FFF"/><path d="M50.2 84.3c-1.6 0-2.9-1.2-2.9-2.8 0-1.6 1.3-2.9 2.9-2.9 1.5 0 2.8 1.3 2.8 2.8 0 1.6-1.2 2.9-2.8 2.9z" fill="#FFF"/><path d="M91.5 70c0 1.6-1.2 2.9-2.9 2.9-1.5 0-2.9-1.4-2.9-2.9 0-1.6 1.3-2.9 2.9-2.9 1.7 0 2.9 1.3 2.9 2.9z" fill="#FFF"/><path d="M76.7 65.5c1.7 0 2.8 1.2 2.9 2.8 0 1.6-1.2 2.9-2.9 2.9-1.6 0-2.9-1.3-2.9-2.9 0-1.6 1.2-2.8 2.9-2.8z" fill="#FFF"/><path d="M45 87.9c0 1.6-1.3 2.9-2.9 2.9-1.6 0-2.9-1.3-2.9-2.9 0-1.6 1.3-2.9 2.9-2.9 1.6 0 2.9 1.3 2.9 2.9z" fill="#FFF"/><path d="M59.5 45.2c-1.6 0-2.9-1.3-2.9-2.9 0-1.5 1.3-2.9 2.9-2.9 1.5 0 2.9 1.3 2.9 2.9 0 1.6-1.3 2.9-2.9 2.9z" fill="#FFF"/><path d="M85.8 75.1c0 1.4-1.1 2.5-2.5 2.5s-2.4-1.1-2.4-2.5 1.1-2.5 2.4-2.5c1.3.1 2.4 1.2 2.5 2.5z" fill="#FFF"/><path d="M58.2 64.6c0 1.4-1.1 2.5-2.4 2.5-1.3 0-2.5-1.2-2.5-2.5s1.2-2.5 2.5-2.5c1.3.1 2.4 1.2 2.4 2.5z" fill="#FFF"/><path d="M40.4 78.2c1.4 0 2.5 1.1 2.4 2.5 0 1.3-1.2 2.5-2.5 2.5-1.4 0-2.5-1.2-2.5-2.6.1-1.4 1.2-2.4 2.6-2.4z" fill="#FFF"/><path d="M71.2 58c-1.4 0-2.5-1-2.5-2.4s1-2.5 2.5-2.5c1.4 0 2.5 1.1 2.5 2.4 0 1.5-1.1 2.5-2.5 2.5z" fill="#FFF"/><path d="M66.7 41.9c1.4 0 2.4 1.1 2.4 2.5s-1.1 2.5-2.4 2.5c-1.4 0-2.5-1.1-2.5-2.5s1.1-2.5 2.5-2.5z" fill="#FFF"/><path d="M50.7 74.2c0 1.4-1.1 2.5-2.4 2.5-1.3 0-2.5-1.2-2.5-2.6 0-1.4 1.1-2.4 2.5-2.4s2.4 1.1 2.4 2.5z" fill="#FFF"/><path d="M71.3 71.1c1.4 0 2.4 1.1 2.4 2.5S72.6 76 71.3 76c-1.4 0-2.5-1.1-2.5-2.5.1-1.4 1.1-2.4 2.5-2.4z" fill="#FFF"/><path d="M95.3 78.8c0 1.4-1 2.5-2.5 2.5-1.4 0-2.4-1.1-2.4-2.5 0-1.3 1.1-2.5 2.4-2.5 1.4 0 2.5 1.1 2.5 2.5z" fill="#FFF"/><path d="M65.1 31.8c1.4 0 2.4 1 2.4 2.4s-1.1 2.5-2.4 2.5c-1.4 0-2.5-1.1-2.5-2.5s1.1-2.4 2.5-2.4z" fill="#FFF"/><path d="M72.7 37.3c0 1.2-1 2.1-2.2 2.1-1.2 0-2.1-1-2.1-2.1 0-1.2.9-2.1 2.1-2.1 1.3 0 2.2.9 2.2 2.1z" fill="#FFF"/><path d="M38.1 74.2c0-1.2.9-2 2.1-2 1.2 0 2.2 1 2.1 2.2 0 1.1-1 2.1-2.1 2.1-1.2 0-2.1-1-2.1-2.3z" fill="#FFF"/><path d="M89.6 82.1c0 1.2-.9 2.2-2.1 2.2-1.2 0-2.2-1-2.2-2.1 0-1.2 1-2.1 2.2-2.1 1.2-.1 2.1.8 2.1 2z" fill="#FFF"/><path d="M50.3 67.9c0 1.2-1 2.1-2.1 2.1-1.2 0-2.1-1-2.1-2.2 0-1.1 1-2.1 2.1-2.1 1.2 0 2.1 1 2.1 2.2z" fill="#FFF"/><path d="M72.2 49.5c-1.2 0-2.1-.9-2.1-2.1 0-1.2.9-2.1 2.1-2.1 1.2 0 2.1.9 2.1 2.1 0 1.3-.9 2.1-2.1 2.1z" fill="#FFF"/><path d="M77.9 76.3c1.2 0 2.1.9 2.1 2.1 0 1.2-1 2.2-2.2 2.2-1.1 0-2-1-2-2.1 0-1.3.9-2.2 2.1-2.2z" fill="#FFF"/><path d="M43.1 69.1c0 1-.8 1.8-1.8 1.8s-1.9-.9-1.9-1.9c0-1 .9-1.8 1.9-1.8 1.1.1 1.8.8 1.8 1.9z" fill="#FFF"/><path d="M84.2 83.8c0 1-.8 1.8-1.8 1.8s-1.8-.9-1.8-1.8c0-1 .8-1.8 1.9-1.8.9 0 1.7.8 1.7 1.8z" fill="#FFF"/><path d="M74.5 39.1c1.1 0 1.9.7 1.9 1.8 0 1-.8 1.8-1.8 1.8s-1.8-.7-1.8-1.8c0-1 .7-1.8 1.7-1.8z" fill="#FFF"/></svg>' -}) -Vue.component('play-circle-icon', { - props:['size'], - template: '<svg :height="size" :width="size" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M256 464c114.875 0 208-93.125 208-208S370.875 48 256 48 48 141.125 48 256s93.125 208 208 208zm-32-112V160l96 96-96 96z"/></svg>' -}) -Vue.component('play-icon', { - props:['size'], - template: '<svg :height="size" :width="size" fill="#FFF" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M96 52v408l320-204L96 52z"/></svg>' -}) -Vue.component('stop-icon', { - props:['size'], - template: '<svg :height="size" :width="size" fill="#FFF" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M405.333 64H106.667C83.198 64 64 83.198 64 106.667v298.666C64 428.802 83.198 448 106.667 448h298.666C428.802 448 448 428.802 448 405.333V106.667C448 83.198 428.802 64 405.333 64z"/></svg>' -}) -Vue.component('empty-icon', { - template: '<svg></svg>' -})`, - "js/initials.js": `var initialData = { - loggedIn: false, - connected: false, - tabs: ['Logs', 'Spammer', 'Transactions', 'Neighbors'], - selectedTab: '', - logs: [], - tpsToSpam: 1, - receivedTps:0, - txs: [], - info: {}, - selectedTxHash:null, - tps:0, - loginError:'', -} -`, - "js/main.js": `new Vue({ - el: '#app', - created() { - this.init() - window.addEventListener('resize', (e)=>{ - debounce(this.setHeaderSize, 300) - }) - }, - data: initialData, - methods: { - async login(e){ - e.preventDefault() - const formData = new FormData(e.target); - const pass = formData.get('password') - const user = formData.get('username') - try{ - const r = await api.get('login?username='+user+'&password='+pass) - if(r.token){ - this.init() - } - }catch(e){ - this.loginError = 'Not Authorized' - setTimeout(()=>this.loginError='',2000) - } - }, - async init() { - try{ - const r = await api.get('loghistory') - this.updateLogs(r) - } catch(e) { - this.show() - return - } - this.show() - this.loggedIn = true - this.selectedTab = 'Logs' - let wsProtocol = 'wss:' - if (location.protocol != 'https:') { - wsProtocol = 'ws:' - } - this.ws = new WebSocket( - api.addToken(wsProtocol+'//'+window.location.host+'/ws') - ) - this.ws.onopen = (e) => { this.connected=true } - this.ws.onclose = (e) => { this.connected=false } - this.ws.onerror = (e) => { this.connected=false } - this.ws.onmessage = (e) => { this.receive(e.data) } - }, - show() { - document.body.className = ''; - setTimeout(()=>this.setHeaderSize(),15) - }, - footerContainerStyle() { - const size = Math.max(window.innerHeight-this.headerSize, 300) - return 'height:calc('+(size-1)+'px - 3.6rem);' - }, - startSpam() { - console.log('start spam', this.tpsToSpam) - api.get('spammer?cmd=start&tps='+this.tpsToSpam) - }, - stopSpam() { - console.log('stop spam') - api.get('spammer?cmd=stop') - }, - selectTab(tab) { - if(tab==='Spammer'){ - setTimeout(()=> this.$refs.tpsinput.focus(), 1) - } - this.selectedTab=tab - }, - selectTxHash(hash) { - if(hash===this.selectedTxHash){ - this.selectedTxHash = null - } else { - this.selectedTxHash = hash - } - }, - receive(data) { - let j - try { - j = JSON.parse(data) - } catch(err){} - this.parseResponse(j) - }, - send(data) { - this.ws.send(JSON.stringify(data)) - }, - parseResponse(r) { - if(r.info){ // node info - this.info = r.info - if(this.$refs.tpschart){ - this.$refs.tpschart.addPoint(r.info.receivedTps) - } - } - if(r.txs) { - this.updateTxs(r.txs) - } - if(r.logs) { - this.updateLogs(r.logs) - } - }, - updateLogs(newLogs){ - this.logs = this.logs.concat( - newLogs.map(j=>{ - return { - message:j.message, - source:j.source, - label:logLevels[j.level].label, - color:logLevels[j.level].color, - time: dayjs(j.time).format('hh:mm:ss')} - }) - ) - }, - updateTxs(tx) { - const txs = this.txs.concat(tx).reverse() - this.txs = txs.splice(0,1000).reverse() - }, - clearTxs() { - this.txs = [] - }, - setHeaderSize() { - const h = window.getComputedStyle(this.$refs.header).height - this.headerSize = parseInt(h) - this.windowWidth = window.innerWidth - }, - }, - computed: { - synced() { return this.connected ? 'Synced':'......' }, - infoKeys() { - return ['TPS', 'Node ID', 'Neighbors', 'Peers', 'Uptime'] - }, - loginButtonText() { - return this.loginError || 'Login' - }, - infoValues() { - const i = this.info - return i.id ? [ - i.receivedTps+' received / '+i.solidTps+ 'new', - i.id, - i.chosenNeighbors.length+' chosen / '+i.acceptedNeighbors.length+' accepted', - i.knownPeers+' total / '+i.neighborhood+' neighborhood', - uptimeConverter(i.uptime) - ] : Array(5).fill('...') - }, - neighbors() { - if(this.info.chosenNeighbors && this.info.acceptedNeighbors) { - const cn = this.info.chosenNeighbors.map(s=>{ - const a = s.split(' / ') - return {id: a[1]||'', address: a[0], accepted: false} - }) - const an = this.info.acceptedNeighbors.map(s=>{ - const a = s.split(' / ') - return {id: a[1]||'', address: a[0], accepted: true} - }) - return cn.concat(an) - } - return [] - } - }, -})`, - "js/tpschart.js": `Vue.component('tps-chart', { - props: ['tps'], - watch:{ - tps: function (val, oldVal) { - console.log(val) - } - }, - methods: { - addPoint(value) { - var time = Date.now() - 1000; - this.chart.series[0].addPoint([time, value], true); - }, - }, - async created() { - const tpsqueue = await api.get('tpsqueue') - var time = Date.now() - 1000 * (tpsqueue.length + 1); - for (let i = 0; i < tpsqueue.length; i++) { - this.chart.series[0].addPoint([time += 1000, tpsqueue[i]], false); - } - this.chart.redraw(); - }, - mounted() { - Highcharts.createElement('link', { - href: 'https://fonts.googleapis.com/css?family=Unica+One', - rel: 'stylesheet', - type: 'text/css' - }, null, document.getElementsByTagName('head')[0]); - Highcharts.theme = highchartsTheme - Highcharts.setOptions(Highcharts.theme); - // Start Here - var time = Date.now() - 3000; - - data = [[time - 5000, 0]]; - var tzoffset = new Date().getTimezoneOffset(); - this.chart = Highcharts.stockChart('chart', { - rangeSelector: { - selected: 1 - }, - title: { - text: 'Transactions per second' - }, - time: { - timezoneOffset: tzoffset - }, - rangeSelector: { - buttons: [ - { - type: 'minute', - count: 5, - text: '5m' - }, { - type: 'minute', - count: 15, - text: '15m' - }, { - type: 'minute', - count: 30, - text: '30m' - }, { - type: 'hour', - count: 60, - text: '1h' - }], - inputEnabled: false - }, - series: [{ - name: 'Transactions per second', - data: data, - type: 'areaspline', - threshold: null, - tooltip: { - valueDecimals: 0 - }, - fillColor: { - linearGradient: { - x1: 0, - y1: 0, - x2: 0, - y2: 1 - }, - stops: [ - [0, Highcharts.getOptions().colors[0]], - [1, Highcharts.Color(Highcharts.getOptions().colors[0]).setOpacity(0).get('rgba')] - ] - } - }] - }); - }, - template: '<div id="chart" style="height:100%;min-width:100%"></div>' -}) - -var highchartsTheme = { - colors: ['#2b908f', '#90ee7e', '#f45b5b', '#7798BF', '#aaeeee', '#ff0066', - '#eeaaee', '#55BF3B', '#DF5353', '#7798BF', '#aaeeee'], - chart: { - backgroundColor: { - linearGradient: { x1: 0, y1: 0, x2: 1, y2: 1 }, - stops: [ - [0, '#2a2a2b'], - [1, '#3e3e40'] - ] - }, - // style: { - // fontFamily: 'sans-serif' - // }, - plotBorderColor: '#606063' - }, - title: { - style: { - color: '#E0E0E3', - // textTransform: 'uppercase', - fontSize: '20px' - } - }, - subtitle: { - style: { - color: '#E0E0E3', - // textTransform: 'uppercase' - } - }, - xAxis: { - gridLineColor: '#707073', - labels: { - style: { - color: '#E0E0E3' - } - }, - lineColor: '#707073', - minorGridLineColor: '#505053', - tickColor: '#707073', - title: { - style: { - color: '#A0A0A3' - } - } - }, - yAxis: { - gridLineColor: '#707073', - labels: { - style: { - color: '#E0E0E3' - } - }, - lineColor: '#707073', - minorGridLineColor: '#505053', - tickColor: '#707073', - tickWidth: 1, - title: { - style: { - color: '#A0A0A3' - } - } - }, - tooltip: { - backgroundColor: 'rgba(0, 0, 0, 0.85)', - style: { - color: '#F0F0F0' - } - }, - plotOptions: { - series: { - dataLabels: { - color: '#B0B0B3' - }, - marker: { - lineColor: '#333' - } - }, - boxplot: { - fillColor: '#505053' - }, - candlestick: { - lineColor: 'white' - }, - errorbar: { - color: 'white' - } - }, - legend: { - itemStyle: { - color: '#E0E0E3' - }, - itemHoverStyle: { - color: '#FFF' - }, - itemHiddenStyle: { - color: '#606063' - } - }, - credits: { - style: { - color: '#666' - } - }, - labels: { - style: { - color: '#707073' - } - }, - drilldown: { - activeAxisLabelStyle: { - color: '#F0F0F3' - }, - activeDataLabelStyle: { - color: '#F0F0F3' - } - }, - navigation: { - buttonOptions: { - symbolStroke: '#DDDDDD', - theme: { - fill: '#505053' - } - } - }, - // scroll charts - rangeSelector: { - buttonTheme: { - fill: '#505053', - stroke: '#000000', - style: { - color: '#CCC' - }, - states: { - hover: { - fill: '#707073', - stroke: '#000000', - style: { - color: 'white' - } - }, - select: { - fill: '#000003', - stroke: '#000000', - style: { - color: 'white' - } - } - } - }, - inputBoxBorderColor: '#505053', - inputStyle: { - backgroundColor: '#333', - color: 'silver' - }, - labelStyle: { - color: 'silver' - } - }, - navigator: { - handles: { - backgroundColor: '#666', - borderColor: '#AAA' - }, - outlineColor: '#CCC', - maskFill: 'rgba(255,255,255,0.1)', - series: { - color: '#7798BF', - lineColor: '#A6C7ED' - }, - xAxis: { - gridLineColor: '#505053' - } - }, - scrollbar: { - barBackgroundColor: '#808083', - barBorderColor: '#808083', - buttonArrowColor: '#CCC', - buttonBackgroundColor: '#606063', - buttonBorderColor: '#606063', - rifleColor: '#FFF', - trackBackgroundColor: '#404043', - trackBorderColor: '#404043' - }, - // special colors for some of the - legendBackgroundColor: 'rgba(0, 0, 0, 0.5)', - background2: '#505053', - dataLabelsColor: '#B0B0B3', - textColor: '#C0C0C0', - contrastTextColor: '#F0F0F3', - maskColor: 'rgba(255,255,255,0.3)' -}`, - "js/utils.js": `function uptimeConverter(seconds) { - var s = '' - var hrs = Math.floor(seconds / 3600); - if (hrs) s += hrs+'h ' - seconds -= hrs*3600; - var mnts = Math.floor(seconds / 60); - if (mnts) s += mnts+'m ' - seconds -= mnts*60; - s += seconds + 's' - return s -} - -// indexed by number -const logLevels = [{ - color: '#e74c3c', - name: 'LOG_LEVEL_FAILURE', - label: 'FAIL', -},{ - color: '#f1b70e', - name: 'LOG_LEVEL_WARNING', - label: 'WARN', -},{ - color: '#2ecc71', - name: 'LOG_LEVEL_SUCCESS', - label: 'OK', -},{ - color: '#209cee', - name: 'LOG_LEVEL_INFO', - label: 'INFO', -},{ - color: '#375a7f', - name: 'LOG_LEVEL_DEBUG', - label: 'NOTE', -}] - -const api = { - get: async function(u) { - const url = this.trim('/'+u) - try{ - const r = await fetch(this.addToken(url)) - const j = await r.json() - if (!(r.status >= 200 && r.status < 300)) { - throw new Error(j) - } - if(url.startsWith('login') && j.token) { - localStorage.setItem('token', j.token) - await sleep(1) - } - return j - } catch(e) { - throw e - } - }, - post: async function(u, data){ - const url = this.trim('/'+u) - try{ - const r = await fetch(this.addToken(url), { - method: 'POST', - headers: {'Content-Type': 'application/json'}, - data: JSON.stringify(data) - }) - const j = await r.json() - if (!(r.status >= 200 && r.status < 300)) { - throw new Error(j) - } - return j - } catch(e) { - throw e - } - }, - trim: function(s) { - return s.replace(/^\//, ''); - }, - addToken: function(s) { - const token = localStorage.getItem('token') - if (!token) return s - const char = s.includes('?') ? '&' : '?' - return s + char + 'token=' + token - } -} - -let inDebounce -function debounce(func, delay) { - const context = this - const args = arguments - clearTimeout(inDebounce) - inDebounce = setTimeout(() => func.apply(context, args), delay) -} - -function sleep(ms) { - return new Promise(resolve => setTimeout(resolve, ms)); -}`, -} diff --git a/plugins/ui/logger.go b/plugins/ui/logger.go deleted file mode 100644 index cf488427..00000000 --- a/plugins/ui/logger.go +++ /dev/null @@ -1,34 +0,0 @@ -package ui - -import ( - "sync" - "time" - - "github.com/iotaledger/hive.go/logger" -) - -var logMutex = sync.RWMutex{} -var logHistory = make([]*statusMessage, 0) - -type statusMessage struct { - Source string `json:"source"` - Level logger.Level `json:"level"` - Message string `json:"message"` - Time time.Time `json:"time"` -} - -type resp map[string]interface{} - -func storeAndSendStatusMessage(logLevel logger.Level, pluginName string, message string) { - - msg := &statusMessage{ - Source: pluginName, - Level: logLevel, - Message: message, - Time: time.Now(), - } - logMutex.Lock() - logHistory = append(logHistory, msg) - logMutex.Unlock() - ws.send(resp{"logs": []*statusMessage{msg}}) -} diff --git a/plugins/ui/nodeInfo.go b/plugins/ui/nodeInfo.go deleted file mode 100644 index 7f322623..00000000 --- a/plugins/ui/nodeInfo.go +++ /dev/null @@ -1,83 +0,0 @@ -package ui - -import ( - "sync" - "sync/atomic" - "time" - - "github.com/iotaledger/goshimmer/plugins/autopeering/local" - - "github.com/iotaledger/goshimmer/plugins/autopeering" -) - -var start = time.Now() - -var receivedTpsCounter uint64 -var solidTpsCounter uint64 - -var tpsQueue []uint32 -var tpsQueueMutex sync.RWMutex - -const maxQueueSize int = 3600 - -type nodeInfo struct { - ID string `json:"id"` - ChosenNeighbors []string `json:"chosenNeighbors"` - AcceptedNeighbors []string `json:"acceptedNeighbors"` - KnownPeersSize int `json:"knownPeers"` - NeighborhoodSize int `json:"neighborhood"` - Uptime uint64 `json:"uptime"` - ReceivedTps uint64 `json:"receivedTps"` - SolidTps uint64 `json:"solidTps"` -} - -func gatherInfo() nodeInfo { - - // update tps queue - tpsQueueMutex.Lock() - tpsQueue = append(tpsQueue, uint32(atomic.LoadUint64(&receivedTpsCounter))) - if len(tpsQueue) > maxQueueSize { - tpsQueue = tpsQueue[1:] - } - tpsQueueMutex.Unlock() - - // update neighbors - chosenNeighbors := []string{} - acceptedNeighbors := []string{} - neighbors := 0 - knownPeers := 0 - if autopeering.Selection != nil { - for _, peer := range autopeering.Selection.GetOutgoingNeighbors() { - chosenNeighbors = append(chosenNeighbors, peer.String()) - } - for _, peer := range autopeering.Selection.GetIncomingNeighbors() { - acceptedNeighbors = append(acceptedNeighbors, peer.String()) - } - neighbors = len(chosenNeighbors) + len(acceptedNeighbors) - } - if autopeering.Discovery != nil { - knownPeers = len(autopeering.Discovery.GetVerifiedPeers()) - } - - receivedTps, solidTps := updateTpsCounters() - duration := time.Since(start) / time.Second - info := nodeInfo{ - ID: local.GetInstance().ID().String(), - ChosenNeighbors: chosenNeighbors, - AcceptedNeighbors: acceptedNeighbors, - KnownPeersSize: knownPeers, - NeighborhoodSize: neighbors, - Uptime: uint64(duration), - ReceivedTps: receivedTps, - SolidTps: solidTps, - } - return info -} - -func updateTpsCounters() (uint64, uint64) { - receivedTps := atomic.LoadUint64(&receivedTpsCounter) - solidTps := atomic.LoadUint64(&solidTpsCounter) - atomic.StoreUint64(&receivedTpsCounter, 0) - atomic.StoreUint64(&solidTpsCounter, 0) - return receivedTps, solidTps -} diff --git a/plugins/ui/src/builder.js b/plugins/ui/src/builder.js deleted file mode 100644 index a3db8568..00000000 --- a/plugins/ui/src/builder.js +++ /dev/null @@ -1,58 +0,0 @@ -var fs = require('fs'); - -async function run() { - var content = 'package ui\n\nvar files = map[string]string{\n' - var files = walk('.') - var skip = ['favicon.ico','builder.js'] - await asyncForEach(files, async function(file){ - var fileName = file.substring(2, file.length) - if(skip.includes(fileName)) return - var data = await readFile(file) - content += addContent(fileName, data) - }) - content += '\n}\n' - fs.writeFile('../files.go',content,function(){ - console.log('files.go created!') - }) -} - -function addContent(fileName, data) { - return '\t"'+fileName+'":`' +data +'`,\n' -} - -function readFile(file) { - return new Promise(function(resolve,reject){ - fs.readFile(file, {encoding: 'utf-8'}, function(err,data){ - if (!err) { - resolve(data) - } else { - reject(err) - } - }); - }) -} - -var walk = function(dir) { - var results = []; - var list = fs.readdirSync(dir); - list.forEach(function(file) { - file = dir + '/' + file; - var stat = fs.statSync(file); - if (stat && stat.isDirectory()) { - /* Recurse into a subdirectory */ - results = results.concat(walk(file)); - } else { - /* Is a file */ - results.push(file); - } - }); - return results; -} - -async function asyncForEach(array, callback) { - for (let index = 0; index < array.length; index++) { - await callback(array[index], index, array); - } -} - -run() \ No newline at end of file diff --git a/plugins/ui/src/css/styles.css b/plugins/ui/src/css/styles.css deleted file mode 100644 index e78374b0..00000000 --- a/plugins/ui/src/css/styles.css +++ /dev/null @@ -1,204 +0,0 @@ -/* mobile */ -html { - font-size:12px; -} -/* tablets */ -@media only screen and (min-width: 600px) { - html { - font-size:14px; - } -} -/* desktop */ -@media only screen and (min-width: 768px) { - html { - font-size:16px; - } -} -body { - opacity: 1; - transition: 0.35s opacity; -} -body.fade { - opacity: 0; - transition: none; -} - -/* bulma */ -[v-cloak] { - display: none; -} -.section { - padding: 1.8rem 1.5rem; -} -.columns { - margin-bottom: 0 !important; -} -.header{ - background:#005050; - padding-bottom: 0; -} - -/* main */ -.title{ - display: flex; - align-items: center; -} -.login{ - background:#004965; - border: 1px solid #5e6d6f; - padding:20px; - font-size: 0.9rem; - border-radius: 0.4em; - box-shadow: 0 2px 3px rgba(10, 10, 10, 0.1), 0 0 0 1px rgba(10, 10, 10, 0.1); -} -.login button{ - width:100%; - margin-top:12px; -} -.login div { - display: flex; - align-items: center; - font-size:1.2rem; -} -.login div:first-child { - margin-bottom:12px; -} -.login div span { - min-width:6.5rem; -} -.status{ - margin-left:54px; -} -.status > span { - margin-left:8px; -} -.tps.input { - width:100px; -} -.tx-toolbar { - display: flex; - justify-content: space-between; - height:50px; -} -.graph { - border: 1px solid #5e6d6f; - overflow: hidden; -} -#graph { - width:100%; - height: 100%; -} -.hovered-node{ - position: absolute; - top: 0; - font-size: 0.75rem; - padding: 5px 10px; - width: 100%; - color: #c5c5c5; -} -.chart-container { - height: calc(100% - 50px); - display: flex; - border:1px solid #5e6d6f; - overflow: hidden; -} - -/* tables */ -.info-list{ - background:#004965; - border: 1px solid #5e6d6f; - font-size: 0.9rem; -} -.info-list .list-item{ - display: flex; - justify-content: space-between; - white-space: nowrap; - overflow: hidden; -} - -.logs-container { - overflow: scroll; - display: flex; - flex-direction: column-reverse; - border:1px solid #5e6d6f; -} -.logs-list { - background:#004965; - table-layout: fixed; - width: 100%; - font-size: 0.9rem; -} -.logs-list th { - background: #00374c; -} -.logs-list td { - font-family: "Inconsolata", "Consolas", "Monaco", monospace; - padding: 0.25em 0.75em; - overflow: auto; - white-space: nowrap; -} -.logs-list td::-webkit-scrollbar { height: 0 !important } -.logs-list td:first-child { - font-weight: bold; -} -.logs-list td:last-child span { - width:35px; - text-align: center; - font-weight: bold; - display: inline-block; -} - -.tx-container { - height: 100%; - overflow: scroll; - display: flex; - flex-direction: column-reverse; - border:1px solid #5e6d6f; -} -.tx-list { - background:#004965; - table-layout: fixed; - width: 100%; - font-size: 0.9rem; -} -.tx-list th { - padding-bottom: 3px; - border-top:1px solid #5e6d6f !important; - background: #00374c; -} -.tx-list tbody tr { - cursor: pointer; -} -.tx-list tbody tr:hover { - background: #00374c; -} -.tx-list td { - font-family: "Inconsolata", "Consolas", "Monaco", monospace; - padding: 0.25em 0.75em; - overflow: auto; - white-space: nowrap; -} -.tx-list td::-webkit-scrollbar { height: 0 !important } -.tx-list td:first-child { - font-weight: bold; -} -.tx-list tr.full-tx { - display:block; - width:100%; -} -.tx-list tr.full-tx td { - padding:0; - width:100%; -} -.tx-list tr.full-tx pre:hover { - background:#232929; -} -.no-txs{ - height:100%; - width:100%; - display:flex; - align-items: center; - justify-content: center; - color:grey; - font-size: 0.8rem; -} diff --git a/plugins/ui/src/favicon.ico b/plugins/ui/src/favicon.ico deleted file mode 100644 index 61334f976a39dfc6c85a75501d1473fd8456e341..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16958 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 CE&50R diff --git a/plugins/ui/src/index.html b/plugins/ui/src/index.html deleted file mode 100644 index a1ee5924..00000000 --- a/plugins/ui/src/index.html +++ /dev/null @@ -1,159 +0,0 @@ -<!DOCTYPE html> -<html> - -<head> - <meta charset="utf-8"> - <meta name="viewport" content="width=device-width, initial-scale=1"> - <link rel="shortcut icon" href="ui/favicon.ico"> - <title>GoShimmer UI</title> - <link rel="stylesheet" href="https://unpkg.com/bulmaswatch@0.7.5/darkly/bulmaswatch.min.css"> - <link rel="stylesheet" href="ui/css/styles.css"> -</head> - -<body class="fade"> - <section id="app"> - <section class="section header" ref="header"> - <div class="container"> - <div class="columns"> - <div class="column"> - <h1 class="title"> - <iota-icon size="42"></iota-icon> - GoShimmer - </h1> - <span v-if="loggedIn" class="status">Status:<span class="tag is-light">{{synced}}</span> - </div> - - <div v-if="!loggedIn" class="column"> - <form class="login" @submit="login"> - <div> - <span>Username:</span> - <input class="input" placeholder="Username" name="username"> - </div> - <div> - <span>Password:</span> - <input class="input" placeholder="Username" name="password"> - </div> - <button type="submit" :disabled="loginError?true:false" - :class="loginError?'button is-danger':'button is-primary'"> - {{ loginButtonText }} - </button> - </form> - </div> - - <div v-if="loggedIn" class="column"> - <div class="list info-list"> - <div v-for="(c, i) in infoKeys" class="list-item"> - <span>{{ c }}:</span> - <span v-if="infoValues[i]">{{ infoValues[i] }}</span> - </li> - </div> - </div> - </div> - </div> - <div v-if="loggedIn" class="tabs is-boxed"> - <ul> - <li v-for="t in tabs" @click="selectTab(t)" - :class="selectedTab===t?'is-active':''"> - <a>{{t}}</a> - </li> - </ul> - </div> - </section> - - <section class="section" v-if="selectedTab==='Logs'"> - <div class="container logs-container" :style="footerContainerStyle()"> - <table class="table logs-list"> - <thead v-if="logs.length>0"><tr> - <th style="width:75px;">Time</th> - <th>Message</th> - <th style="width:75px;">Status</th> - </tr></thead> - <tbody> - <tr v-for="log in logs"> - <td>{{ log.time }}</td> - <td>{{ log.source }}: {{ log.message }}</td> - <td>[<span :style="'color:'+log.color+';'">{{ log.label }}</span>]</td> - </tr> - </tbody> - </table> - </div> - </section> - - <section class="section" v-if="selectedTab==='Spammer'"> - <div class="container" :style="footerContainerStyle()"> - <div class="tx-toolbar"> - <div class="field is-grouped"> - <p class="control"> - <input ref="tpsinput" class="input tps" type="number" v-model="tpsToSpam" placeholder="TPS"> - </p> - <p class="control"> - <button class="button is-info" @click="startSpam()" :disabled="tpsToSpam<1"> - <play-icon size="19"></play-icon> - </button> - </p> - <p class="control"> - <button class="button is-primary" @click="stopSpam()" :disabled="info.receivedTps<1"> - <stop-icon size="19"></stop-icon> - </button> - </p> - </div> - <!-- <div class="field is-grouped"> - <button class="button" @click="clearTxs()" :disabled="txs.length<1"> - Clear - </button> - </div> --> - </div> - <div class="chart-container"> - <tps-chart ref="tpschart"></tps-chart> - </div> - </div> - </section> - - <section class="section" v-if="selectedTab==='Transactions'"> - <div class="container transactions" :style="footerContainerStyle()"> - <div class="tx-container"> - <table v-if="txs.length>0" class="table tx-list"> - <thead><tr> - <th style="width:50px;"><iota-icon size="20"></iota-icon></th> - <th style="line-height:21px;">Hash</th> - </tr></thead> - <tbody> - <tr v-for="tx in txs" @click="selectTxHash(tx.hash)" :class="selectedTxHash===tx.hash ? 'full-tx' : ''"> - <td v-if="selectedTxHash!==tx.hash">{{ tx.value }}</td> - <td> - <span v-if="selectedTxHash!==tx.hash">{{ tx.hash }}</span> - <pre v-if="selectedTxHash===tx.hash" :style="'width:calc('+(windowWidth-2)+'px - 3rem);'">{{ JSON.stringify(tx,null,2) }}</pre> - </td> - </tr> - </tbody> - </table> - <div v-if="txs.length===0" class="no-txs">No transactions yet</div> - </div> - </div> - </section> - - <section class="section" v-if="selectedTab==='Neighbors'"> - <div class="container graph" :style="footerContainerStyle()"> - <force-graph :neighbors="neighbors" :me="info.id"></force-graph> - </div> - </section> - - </section> - - <!-- <script src="https://unpkg.com/vue@2.5.9"></script> --> - <script src="https://unpkg.com/vue@2.6.10/dist/vue.min.js"></script> - <script src="https://unpkg.com/dayjs@1.8.15"></script> - <script src="https://unpkg.com/3d-force-graph"></script> - <script src="https://code.jquery.com/jquery-3.1.1.min.js"></script> - <script src="https://code.highcharts.com/stock/highstock.js"></script> - <script src="https://code.highcharts.com/stock/modules/exporting.js"></script> - <script src="https://code.highcharts.com/stock/modules/export-data.js"></script> - <script src="ui/js/initials.js"></script> - <script src="ui/js/utils.js"></script> - <script src="ui/js/icons.js"></script> - <script src="ui/js/forcegraph.js"></script> - <script src="ui/js/tpschart.js"></script> - <script src="ui/js/main.js"></script> -</body> - -</html> \ No newline at end of file diff --git a/plugins/ui/src/js/forcegraph.js b/plugins/ui/src/js/forcegraph.js deleted file mode 100644 index 80c0a9e6..00000000 --- a/plugins/ui/src/js/forcegraph.js +++ /dev/null @@ -1,58 +0,0 @@ - -Vue.component('force-graph', { - props:['neighbors', 'me'], - data: function() { - return { - hoveredNode: null - } - }, - watch:{ - neighbors: function (val, oldVal) { - let updateNeeded - val.forEach(node=> { - if(!oldVal.find(n=> n.id===node.id)) updateNeeded=true - }) - oldVal.forEach(node=> { - if(!val.find(n=> n.id===node.id)) updateNeeded=true - }) - if (updateNeeded) this.graph.graphData(this.makeGraph()) - }, - }, - methods:{ - makeGraph() { - return { - nodes: [{id: this.me}, ...this.neighbors], - links: this.neighbors.filter(id => id) - .map(id => ({ source: id, target: this.me })) - }; - } - }, - mounted() { - const el = document.getElementById('3d-graph') - const parentStyle = window.getComputedStyle(el.parentNode) - this.graph = ForceGraph3D()(el) - .width(parseInt(parentStyle.width)-2) - .height(parseInt(parentStyle.height)-2) - .enableNodeDrag(false) - .onNodeHover(node => { - this.hoveredNode = node - el.style.cursor = node ? 'pointer' : null - }) - .onNodeClick(node => console.log(node)) - .nodeColor(node => { - if (node.id===this.me) return 'rgba(0,200,255,1)' - return node.accepted ? 'rgba(150,255,150,1)' : 'rgba(255,255,255,1)' - }) - .linkColor('rgba(255,255,255,1)') - .linkOpacity(0.85) - .graphData(this.makeGraph()) - }, - - template: '<div style="height:100%;">'+ - '<div id="3d-graph"></div>'+ - '<div v-if="hoveredNode" class="hovered-node">'+ - 'ID: {{hoveredNode.id}} '+ - '<span v-if="hoveredNode.address">Address: {{hoveredNode.address}}</span>'+ - '</div>'+ - '</div>' -}) \ No newline at end of file diff --git a/plugins/ui/src/js/icons.js b/plugins/ui/src/js/icons.js deleted file mode 100644 index 515f7bac..00000000 --- a/plugins/ui/src/js/icons.js +++ /dev/null @@ -1,20 +0,0 @@ - -Vue.component('iota-icon', { - props:['size'], - template: '<svg :height="size" :width="size" style="margin-right:10px;" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" id="Layer_1" x="0px" y="0px" viewBox="0 0 128 128" xml:space="preserve"><path d="M79.6 24.9c-.1-2.8 2.4-5.4 5.6-5.3 2.8.1 5.1 2.5 5.1 5.4 0 3-2.5 5.3-5.6 5.3-2.8 0-5.1-2.5-5.1-5.4z" fill="#FFF"/><path d="M91 95.4c3 0 5.3 2.3 5.3 5.3s-2.4 5.4-5.4 5.4c-2.9 0-5.3-2.4-5.3-5.4 0-3 2.4-5.3 5.4-5.3z" fill="#FFF"/><path d="M22.4 73.4c-3 0-5.3-2.4-5.3-5.5 0-2.9 2.4-5.2 5.4-5.2 3 0 5.3 2.4 5.3 5.5-.1 2.9-2.5 5.2-5.4 5.2z" fill="#FFF"/><path d="M81.9 39.2c0-2.6 2-4.6 4.6-4.6 2.5 0 4.6 2.1 4.6 4.6 0 2.5-2.1 4.6-4.6 4.6-2.6 0-4.6-2.1-4.6-4.6z" fill="#FFF"/><path d="M33.9 55.1c2.6 0 4.6 2 4.7 4.5 0 2.5-2.1 4.6-4.6 4.6-2.5 0-4.6-2.1-4.6-4.6-.1-2.5 2-4.5 4.5-4.5z" fill="#FFF"/><path d="M98.4 45.4c-2.5 0-4.6-2.1-4.6-4.6 0-2.6 2.1-4.6 4.6-4.6 2.5 0 4.6 2.1 4.6 4.6 0 2.6-2 4.6-4.6 4.6z" fill="#FFF"/><path d="M77.9 99.5c-2.5 0-4.6-2.1-4.6-4.6 0-2.5 2-4.5 4.6-4.6 2.5 0 4.6 2.1 4.6 4.6 0 2.5-2.1 4.6-4.6 4.6z" fill="#FFF"/><path d="M33.9 48.5c0 2.5-2.1 4.6-4.6 4.6-2.5 0-4.5-2.1-4.5-4.6 0-2.5 2.1-4.6 4.6-4.6 2.5-.1 4.6 2 4.5 4.6z" fill="#FFF"/><path d="M70.4 109c-2.5 0-4.5-2-4.5-4.6 0-2.5 2-4.5 4.6-4.6 2.5 0 4.6 2.1 4.6 4.6-.1 2.6-2.1 4.6-4.7 4.6z" fill="#FFF"/><path d="M56.9 97.1c0-2.2 1.7-3.9 3.9-3.9s3.9 1.8 3.9 4-1.8 3.9-3.9 3.9c-2.2 0-3.9-1.8-3.9-4z" fill="#FFF"/><path d="M100.9 52.9c0 2.2-1.8 3.9-3.9 3.9-2.1 0-3.9-1.8-3.9-3.9 0-2.2 1.8-4 3.9-3.9 2.1 0 3.9 1.7 3.9 3.9z" fill="#FFF"/><path d="M44.4 43.7c0 2.2-1.7 3.9-3.9 3.9s-3.9-1.7-3.9-4c0-2.2 1.7-3.9 3.9-3.9 2.3.1 4 1.8 3.9 4z" fill="#FFF"/><path d="M49 54.9c0 2.2-1.7 3.9-3.9 3.9s-3.9-1.7-3.9-3.9 1.7-4 3.9-3.9c2.2 0 3.9 1.7 3.9 3.9z" fill="#FFF"/><path d="M35 33.5c0-2.2 1.8-3.9 3.9-3.9 2.2 0 3.9 1.8 3.9 3.9 0 2.2-1.7 3.9-3.9 3.9S35 35.7 35 33.5z" fill="#FFF"/><path d="M81.1 51.3c0-2.2 1.7-3.9 3.9-3.9s4 1.8 3.9 4c0 2.2-1.8 3.9-3.9 3.9-2.2-.2-3.9-1.9-3.9-4z" fill="#FFF"/><path d="M68.2 83.7c2.1 0 3.9 1.8 3.9 3.9 0 2.2-1.8 3.9-4 3.9s-3.9-1.7-3.9-3.9c.1-2.2 1.9-3.9 4-3.9z" fill="#FFF"/><path d="M56.7 103.6c0 2.2-1.7 3.9-3.9 3.9s-3.9-1.7-3.9-3.9 1.8-4 3.9-3.9c2.2 0 3.9 1.7 3.9 3.9z" fill="#FFF"/><path d="M106.5 60.5c-2.1 0-3.8-1.8-3.9-3.9 0-2.2 1.8-3.9 4-3.9 2.1 0 3.9 1.8 3.9 3.9 0 2.2-1.8 3.9-4 3.9z" fill="#FFF"/><path d="M57.5 89.3c0 1.9-1.5 3.4-3.4 3.3-1.9 0-3.4-1.5-3.4-3.3 0-1.9 1.5-3.4 3.4-3.4s3.4 1.5 3.4 3.4z" fill="#FFF"/><path d="M50.7 38.5c1.9 0 3.3 1.5 3.3 3.3 0 1.8-1.5 3.4-3.3 3.4-1.8 0-3.4-1.5-3.4-3.4.1-1.8 1.6-3.3 3.4-3.3z" fill="#FFF"/><path d="M58.2 79.7c0-1.9 1.4-3.4 3.3-3.4s3.4 1.5 3.4 3.3c0 1.9-1.5 3.3-3.3 3.3-1.9.1-3.4-1.3-3.4-3.2z" fill="#FFF"/><path d="M46.2 99.1c-1.9 0-3.4-1.4-3.4-3.3s1.5-3.3 3.3-3.4c1.9 0 3.4 1.5 3.4 3.4 0 1.8-1.5 3.3-3.3 3.3z" fill="#FFF"/><path d="M84.7 61c0 1.8-1.4 3.3-3.3 3.3s-3.4-1.5-3.3-3.4c0-1.9 1.5-3.3 3.3-3.3 1.9 0 3.3 1.5 3.3 3.4z" fill="#FFF"/><path d="M49.1 35c-1.9 0-3.4-1.4-3.4-3.3s1.5-3.4 3.4-3.4c1.8 0 3.3 1.5 3.4 3.4 0 1.8-1.5 3.3-3.4 3.3z" fill="#FFF"/><path d="M93.4 66c-1.9 0-3.3-1.5-3.3-3.3 0-1.8 1.5-3.3 3.4-3.3s3.3 1.5 3.3 3.4c0 1.8-1.5 3.2-3.4 3.2z" fill="#FFF"/><path d="M55.2 56.4c-1.8 0-3.3-1.5-3.3-3.4 0-1.8 1.6-3.3 3.4-3.3 1.9 0 3.3 1.5 3.3 3.4s-1.5 3.3-3.4 3.3z" fill="#FFF"/><path d="M103 69.6c-1.9-.1-3.3-1.6-3.3-3.5.1-1.8 1.6-3.3 3.4-3.2 1.9.1 3.4 1.6 3.3 3.6-.1 1.8-1.6 3.2-3.4 3.1z" fill="#FFF"/><path d="M64 56.4c-1.6 0-2.9-1.3-2.9-2.9 0-1.6 1.3-2.8 2.9-2.8 1.6 0 2.9 1.3 2.8 2.9.1 1.6-1.1 2.8-2.8 2.8z" fill="#FFF"/><path d="M95.4 73.7c0-1.6 1.2-2.9 2.8-2.9 1.6 0 2.9 1.2 2.9 2.9 0 1.6-1.4 3-2.9 3-1.5-.1-2.8-1.4-2.8-3z" fill="#FFF"/><path d="M60.7 32.2c0 1.6-1.2 2.8-2.9 2.8-1.6 0-2.9-1.3-2.9-2.9 0-1.6 1.3-2.9 3-2.8 1.6 0 2.8 1.3 2.8 2.9z" fill="#FFF"/><path d="M60.4 71.9c0 1.6-1.2 2.8-2.8 2.9-1.7 0-2.9-1.3-2.9-2.9 0-1.6 1.3-2.9 2.9-2.9 1.6 0 2.8 1.3 2.8 2.9z" fill="#FFF"/><path d="M50.2 84.3c-1.6 0-2.9-1.2-2.9-2.8 0-1.6 1.3-2.9 2.9-2.9 1.5 0 2.8 1.3 2.8 2.8 0 1.6-1.2 2.9-2.8 2.9z" fill="#FFF"/><path d="M91.5 70c0 1.6-1.2 2.9-2.9 2.9-1.5 0-2.9-1.4-2.9-2.9 0-1.6 1.3-2.9 2.9-2.9 1.7 0 2.9 1.3 2.9 2.9z" fill="#FFF"/><path d="M76.7 65.5c1.7 0 2.8 1.2 2.9 2.8 0 1.6-1.2 2.9-2.9 2.9-1.6 0-2.9-1.3-2.9-2.9 0-1.6 1.2-2.8 2.9-2.8z" fill="#FFF"/><path d="M45 87.9c0 1.6-1.3 2.9-2.9 2.9-1.6 0-2.9-1.3-2.9-2.9 0-1.6 1.3-2.9 2.9-2.9 1.6 0 2.9 1.3 2.9 2.9z" fill="#FFF"/><path d="M59.5 45.2c-1.6 0-2.9-1.3-2.9-2.9 0-1.5 1.3-2.9 2.9-2.9 1.5 0 2.9 1.3 2.9 2.9 0 1.6-1.3 2.9-2.9 2.9z" fill="#FFF"/><path d="M85.8 75.1c0 1.4-1.1 2.5-2.5 2.5s-2.4-1.1-2.4-2.5 1.1-2.5 2.4-2.5c1.3.1 2.4 1.2 2.5 2.5z" fill="#FFF"/><path d="M58.2 64.6c0 1.4-1.1 2.5-2.4 2.5-1.3 0-2.5-1.2-2.5-2.5s1.2-2.5 2.5-2.5c1.3.1 2.4 1.2 2.4 2.5z" fill="#FFF"/><path d="M40.4 78.2c1.4 0 2.5 1.1 2.4 2.5 0 1.3-1.2 2.5-2.5 2.5-1.4 0-2.5-1.2-2.5-2.6.1-1.4 1.2-2.4 2.6-2.4z" fill="#FFF"/><path d="M71.2 58c-1.4 0-2.5-1-2.5-2.4s1-2.5 2.5-2.5c1.4 0 2.5 1.1 2.5 2.4 0 1.5-1.1 2.5-2.5 2.5z" fill="#FFF"/><path d="M66.7 41.9c1.4 0 2.4 1.1 2.4 2.5s-1.1 2.5-2.4 2.5c-1.4 0-2.5-1.1-2.5-2.5s1.1-2.5 2.5-2.5z" fill="#FFF"/><path d="M50.7 74.2c0 1.4-1.1 2.5-2.4 2.5-1.3 0-2.5-1.2-2.5-2.6 0-1.4 1.1-2.4 2.5-2.4s2.4 1.1 2.4 2.5z" fill="#FFF"/><path d="M71.3 71.1c1.4 0 2.4 1.1 2.4 2.5S72.6 76 71.3 76c-1.4 0-2.5-1.1-2.5-2.5.1-1.4 1.1-2.4 2.5-2.4z" fill="#FFF"/><path d="M95.3 78.8c0 1.4-1 2.5-2.5 2.5-1.4 0-2.4-1.1-2.4-2.5 0-1.3 1.1-2.5 2.4-2.5 1.4 0 2.5 1.1 2.5 2.5z" fill="#FFF"/><path d="M65.1 31.8c1.4 0 2.4 1 2.4 2.4s-1.1 2.5-2.4 2.5c-1.4 0-2.5-1.1-2.5-2.5s1.1-2.4 2.5-2.4z" fill="#FFF"/><path d="M72.7 37.3c0 1.2-1 2.1-2.2 2.1-1.2 0-2.1-1-2.1-2.1 0-1.2.9-2.1 2.1-2.1 1.3 0 2.2.9 2.2 2.1z" fill="#FFF"/><path d="M38.1 74.2c0-1.2.9-2 2.1-2 1.2 0 2.2 1 2.1 2.2 0 1.1-1 2.1-2.1 2.1-1.2 0-2.1-1-2.1-2.3z" fill="#FFF"/><path d="M89.6 82.1c0 1.2-.9 2.2-2.1 2.2-1.2 0-2.2-1-2.2-2.1 0-1.2 1-2.1 2.2-2.1 1.2-.1 2.1.8 2.1 2z" fill="#FFF"/><path d="M50.3 67.9c0 1.2-1 2.1-2.1 2.1-1.2 0-2.1-1-2.1-2.2 0-1.1 1-2.1 2.1-2.1 1.2 0 2.1 1 2.1 2.2z" fill="#FFF"/><path d="M72.2 49.5c-1.2 0-2.1-.9-2.1-2.1 0-1.2.9-2.1 2.1-2.1 1.2 0 2.1.9 2.1 2.1 0 1.3-.9 2.1-2.1 2.1z" fill="#FFF"/><path d="M77.9 76.3c1.2 0 2.1.9 2.1 2.1 0 1.2-1 2.2-2.2 2.2-1.1 0-2-1-2-2.1 0-1.3.9-2.2 2.1-2.2z" fill="#FFF"/><path d="M43.1 69.1c0 1-.8 1.8-1.8 1.8s-1.9-.9-1.9-1.9c0-1 .9-1.8 1.9-1.8 1.1.1 1.8.8 1.8 1.9z" fill="#FFF"/><path d="M84.2 83.8c0 1-.8 1.8-1.8 1.8s-1.8-.9-1.8-1.8c0-1 .8-1.8 1.9-1.8.9 0 1.7.8 1.7 1.8z" fill="#FFF"/><path d="M74.5 39.1c1.1 0 1.9.7 1.9 1.8 0 1-.8 1.8-1.8 1.8s-1.8-.7-1.8-1.8c0-1 .7-1.8 1.7-1.8z" fill="#FFF"/></svg>' -}) -Vue.component('play-circle-icon', { - props:['size'], - template: '<svg :height="size" :width="size" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M256 464c114.875 0 208-93.125 208-208S370.875 48 256 48 48 141.125 48 256s93.125 208 208 208zm-32-112V160l96 96-96 96z"/></svg>' -}) -Vue.component('play-icon', { - props:['size'], - template: '<svg :height="size" :width="size" fill="#FFF" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M96 52v408l320-204L96 52z"/></svg>' -}) -Vue.component('stop-icon', { - props:['size'], - template: '<svg :height="size" :width="size" fill="#FFF" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M405.333 64H106.667C83.198 64 64 83.198 64 106.667v298.666C64 428.802 83.198 448 106.667 448h298.666C428.802 448 448 428.802 448 405.333V106.667C448 83.198 428.802 64 405.333 64z"/></svg>' -}) -Vue.component('empty-icon', { - template: '<svg></svg>' -}) \ No newline at end of file diff --git a/plugins/ui/src/js/initials.js b/plugins/ui/src/js/initials.js deleted file mode 100644 index d059a9d2..00000000 --- a/plugins/ui/src/js/initials.js +++ /dev/null @@ -1,14 +0,0 @@ -var initialData = { - loggedIn: false, - connected: false, - tabs: ['Logs', 'Spammer', 'Transactions', 'Neighbors'], - selectedTab: '', - logs: [], - tpsToSpam: 1, - receivedTps:0, - txs: [], - info: {}, - selectedTxHash:null, - tps:0, - loginError:'', -} diff --git a/plugins/ui/src/js/main.js b/plugins/ui/src/js/main.js deleted file mode 100644 index d6266b39..00000000 --- a/plugins/ui/src/js/main.js +++ /dev/null @@ -1,160 +0,0 @@ -new Vue({ - el: '#app', - created() { - this.init() - window.addEventListener('resize', (e)=>{ - debounce(this.setHeaderSize, 300) - }) - }, - data: initialData, - methods: { - async login(e){ - e.preventDefault() - const formData = new FormData(e.target); - const pass = formData.get('password') - const user = formData.get('username') - try{ - const r = await api.get('login?username='+user+'&password='+pass) - if(r.token){ - this.init() - } - }catch(e){ - this.loginError = 'Not Authorized' - setTimeout(()=>this.loginError='',2000) - } - }, - async init() { - try{ - const r = await api.get('loghistory') - this.updateLogs(r) - } catch(e) { - this.show() - return - } - this.show() - this.loggedIn = true - this.selectedTab = 'Logs' - let wsProtocol = 'wss:' - if (location.protocol != 'https:') { - wsProtocol = 'ws:' - } - this.ws = new WebSocket( - api.addToken(wsProtocol+'//'+window.location.host+'/ws') - ) - this.ws.onopen = (e) => { this.connected=true } - this.ws.onclose = (e) => { this.connected=false } - this.ws.onerror = (e) => { this.connected=false } - this.ws.onmessage = (e) => { this.receive(e.data) } - }, - show() { - document.body.className = ''; - setTimeout(()=>this.setHeaderSize(),15) - }, - footerContainerStyle() { - const size = Math.max(window.innerHeight-this.headerSize, 300) - return 'height:calc('+(size-1)+'px - 3.6rem);' - }, - startSpam() { - console.log('start spam', this.tpsToSpam) - api.get('spammer?cmd=start&tps='+this.tpsToSpam) - }, - stopSpam() { - console.log('stop spam') - api.get('spammer?cmd=stop') - }, - selectTab(tab) { - if(tab==='Spammer'){ - setTimeout(()=> this.$refs.tpsinput.focus(), 1) - } - this.selectedTab=tab - }, - selectTxHash(hash) { - if(hash===this.selectedTxHash){ - this.selectedTxHash = null - } else { - this.selectedTxHash = hash - } - }, - receive(data) { - let j - try { - j = JSON.parse(data) - } catch(err){} - this.parseResponse(j) - }, - send(data) { - this.ws.send(JSON.stringify(data)) - }, - parseResponse(r) { - if(r.info){ // node info - this.info = r.info - if(this.$refs.tpschart){ - this.$refs.tpschart.addPoint(r.info.receivedTps) - } - } - if(r.txs) { - this.updateTxs(r.txs) - } - if(r.logs) { - this.updateLogs(r.logs) - } - }, - updateLogs(newLogs){ - this.logs = this.logs.concat( - newLogs.map(j=>{ - return { - message:j.message, - source:j.source, - label:logLevels[j.level].label, - color:logLevels[j.level].color, - time: dayjs(j.time).format('hh:mm:ss')} - }) - ) - }, - updateTxs(tx) { - const txs = this.txs.concat(tx).reverse() - this.txs = txs.splice(0,1000).reverse() - }, - clearTxs() { - this.txs = [] - }, - setHeaderSize() { - const h = window.getComputedStyle(this.$refs.header).height - this.headerSize = parseInt(h) - this.windowWidth = window.innerWidth - }, - }, - computed: { - synced() { return this.connected ? 'Synced':'......' }, - infoKeys() { - return ['TPS', 'Node ID', 'Neighbors', 'Peers', 'Uptime'] - }, - loginButtonText() { - return this.loginError || 'Login' - }, - infoValues() { - const i = this.info - return i.id ? [ - i.receivedTps+' received / '+i.solidTps+ 'new', - i.id, - i.chosenNeighbors.length+' chosen / '+i.acceptedNeighbors.length+' accepted', - i.knownPeers+' total / '+i.neighborhood+' neighborhood', - uptimeConverter(i.uptime) - ] : Array(5).fill('...') - }, - neighbors() { - if(this.info.chosenNeighbors && this.info.acceptedNeighbors) { - const cn = this.info.chosenNeighbors.map(s=>{ - const a = s.split(' / ') - return {id: a[1]||'', address: a[0], accepted: false} - }) - const an = this.info.acceptedNeighbors.map(s=>{ - const a = s.split(' / ') - return {id: a[1]||'', address: a[0], accepted: true} - }) - return cn.concat(an) - } - return [] - } - }, -}) \ No newline at end of file diff --git a/plugins/ui/src/js/tpschart.js b/plugins/ui/src/js/tpschart.js deleted file mode 100644 index b3d89d3f..00000000 --- a/plugins/ui/src/js/tpschart.js +++ /dev/null @@ -1,282 +0,0 @@ -Vue.component('tps-chart', { - props: ['tps'], - watch:{ - tps: function (val, oldVal) { - console.log(val) - } - }, - methods: { - addPoint(value) { - var time = Date.now() - 1000; - this.chart.series[0].addPoint([time, value], true); - }, - }, - async created() { - const tpsqueue = await api.get('tpsqueue') - var time = Date.now() - 1000 * (tpsqueue.length + 1); - for (let i = 0; i < tpsqueue.length; i++) { - this.chart.series[0].addPoint([time += 1000, tpsqueue[i]], false); - } - this.chart.redraw(); - }, - mounted() { - Highcharts.createElement('link', { - href: 'https://fonts.googleapis.com/css?family=Unica+One', - rel: 'stylesheet', - type: 'text/css' - }, null, document.getElementsByTagName('head')[0]); - Highcharts.theme = highchartsTheme - Highcharts.setOptions(Highcharts.theme); - // Start Here - var time = Date.now() - 3000; - - data = [[time - 5000, 0]]; - var tzoffset = new Date().getTimezoneOffset(); - this.chart = Highcharts.stockChart('chart', { - rangeSelector: { - selected: 1 - }, - title: { - text: 'Transactions per second' - }, - time: { - timezoneOffset: tzoffset - }, - rangeSelector: { - buttons: [ - { - type: 'minute', - count: 5, - text: '5m' - }, { - type: 'minute', - count: 15, - text: '15m' - }, { - type: 'minute', - count: 30, - text: '30m' - }, { - type: 'hour', - count: 60, - text: '1h' - }], - inputEnabled: false - }, - series: [{ - name: 'Transactions per second', - data: data, - type: 'areaspline', - threshold: null, - tooltip: { - valueDecimals: 0 - }, - fillColor: { - linearGradient: { - x1: 0, - y1: 0, - x2: 0, - y2: 1 - }, - stops: [ - [0, Highcharts.getOptions().colors[0]], - [1, Highcharts.Color(Highcharts.getOptions().colors[0]).setOpacity(0).get('rgba')] - ] - } - }] - }); - }, - template: '<div id="chart" style="height:100%;min-width:100%"></div>' -}) - -var highchartsTheme = { - colors: ['#2b908f', '#90ee7e', '#f45b5b', '#7798BF', '#aaeeee', '#ff0066', - '#eeaaee', '#55BF3B', '#DF5353', '#7798BF', '#aaeeee'], - chart: { - backgroundColor: { - linearGradient: { x1: 0, y1: 0, x2: 1, y2: 1 }, - stops: [ - [0, '#2a2a2b'], - [1, '#3e3e40'] - ] - }, - // style: { - // fontFamily: 'sans-serif' - // }, - plotBorderColor: '#606063' - }, - title: { - style: { - color: '#E0E0E3', - // textTransform: 'uppercase', - fontSize: '20px' - } - }, - subtitle: { - style: { - color: '#E0E0E3', - // textTransform: 'uppercase' - } - }, - xAxis: { - gridLineColor: '#707073', - labels: { - style: { - color: '#E0E0E3' - } - }, - lineColor: '#707073', - minorGridLineColor: '#505053', - tickColor: '#707073', - title: { - style: { - color: '#A0A0A3' - } - } - }, - yAxis: { - gridLineColor: '#707073', - labels: { - style: { - color: '#E0E0E3' - } - }, - lineColor: '#707073', - minorGridLineColor: '#505053', - tickColor: '#707073', - tickWidth: 1, - title: { - style: { - color: '#A0A0A3' - } - } - }, - tooltip: { - backgroundColor: 'rgba(0, 0, 0, 0.85)', - style: { - color: '#F0F0F0' - } - }, - plotOptions: { - series: { - dataLabels: { - color: '#B0B0B3' - }, - marker: { - lineColor: '#333' - } - }, - boxplot: { - fillColor: '#505053' - }, - candlestick: { - lineColor: 'white' - }, - errorbar: { - color: 'white' - } - }, - legend: { - itemStyle: { - color: '#E0E0E3' - }, - itemHoverStyle: { - color: '#FFF' - }, - itemHiddenStyle: { - color: '#606063' - } - }, - credits: { - style: { - color: '#666' - } - }, - labels: { - style: { - color: '#707073' - } - }, - drilldown: { - activeAxisLabelStyle: { - color: '#F0F0F3' - }, - activeDataLabelStyle: { - color: '#F0F0F3' - } - }, - navigation: { - buttonOptions: { - symbolStroke: '#DDDDDD', - theme: { - fill: '#505053' - } - } - }, - // scroll charts - rangeSelector: { - buttonTheme: { - fill: '#505053', - stroke: '#000000', - style: { - color: '#CCC' - }, - states: { - hover: { - fill: '#707073', - stroke: '#000000', - style: { - color: 'white' - } - }, - select: { - fill: '#000003', - stroke: '#000000', - style: { - color: 'white' - } - } - } - }, - inputBoxBorderColor: '#505053', - inputStyle: { - backgroundColor: '#333', - color: 'silver' - }, - labelStyle: { - color: 'silver' - } - }, - navigator: { - handles: { - backgroundColor: '#666', - borderColor: '#AAA' - }, - outlineColor: '#CCC', - maskFill: 'rgba(255,255,255,0.1)', - series: { - color: '#7798BF', - lineColor: '#A6C7ED' - }, - xAxis: { - gridLineColor: '#505053' - } - }, - scrollbar: { - barBackgroundColor: '#808083', - barBorderColor: '#808083', - buttonArrowColor: '#CCC', - buttonBackgroundColor: '#606063', - buttonBorderColor: '#606063', - rifleColor: '#FFF', - trackBackgroundColor: '#404043', - trackBorderColor: '#404043' - }, - // special colors for some of the - legendBackgroundColor: 'rgba(0, 0, 0, 0.5)', - background2: '#505053', - dataLabelsColor: '#B0B0B3', - textColor: '#C0C0C0', - contrastTextColor: '#F0F0F3', - maskColor: 'rgba(255,255,255,0.3)' -} \ No newline at end of file diff --git a/plugins/ui/src/js/utils.js b/plugins/ui/src/js/utils.js deleted file mode 100644 index 5f99f30f..00000000 --- a/plugins/ui/src/js/utils.js +++ /dev/null @@ -1,92 +0,0 @@ -function uptimeConverter(seconds) { - var s = '' - var hrs = Math.floor(seconds / 3600); - if (hrs) s += hrs+'h ' - seconds -= hrs*3600; - var mnts = Math.floor(seconds / 60); - if (mnts) s += mnts+'m ' - seconds -= mnts*60; - s += seconds + 's' - return s -} - -// indexed by number -const logLevels = [{ - color: '#e74c3c', - name: 'LOG_LEVEL_FAILURE', - label: 'FAIL', -},{ - color: '#f1b70e', - name: 'LOG_LEVEL_WARNING', - label: 'WARN', -},{ - color: '#2ecc71', - name: 'LOG_LEVEL_SUCCESS', - label: 'OK', -},{ - color: '#209cee', - name: 'LOG_LEVEL_INFO', - label: 'INFO', -},{ - color: '#375a7f', - name: 'LOG_LEVEL_DEBUG', - label: 'NOTE', -}] - -const api = { - get: async function(u) { - const url = this.trim('/'+u) - try{ - const r = await fetch(this.addToken(url)) - const j = await r.json() - if (!(r.status >= 200 && r.status < 300)) { - throw new Error(j) - } - if(url.startsWith('login') && j.token) { - localStorage.setItem('token', j.token) - await sleep(1) - } - return j - } catch(e) { - throw e - } - }, - post: async function(u, data){ - const url = this.trim('/'+u) - try{ - const r = await fetch(this.addToken(url), { - method: 'POST', - headers: {'Content-Type': 'application/json'}, - data: JSON.stringify(data) - }) - const j = await r.json() - if (!(r.status >= 200 && r.status < 300)) { - throw new Error(j) - } - return j - } catch(e) { - throw e - } - }, - trim: function(s) { - return s.replace(/^\//, ''); - }, - addToken: function(s) { - const token = localStorage.getItem('token') - if (!token) return s - const char = s.includes('?') ? '&' : '?' - return s + char + 'token=' + token - } -} - -let inDebounce -function debounce(func, delay) { - const context = this - const args = arguments - clearTimeout(inDebounce) - inDebounce = setTimeout(() => func.apply(context, args), delay) -} - -function sleep(ms) { - return new Promise(resolve => setTimeout(resolve, ms)); -} \ No newline at end of file diff --git a/plugins/ui/txLog.go b/plugins/ui/txLog.go deleted file mode 100644 index d8d57932..00000000 --- a/plugins/ui/txLog.go +++ /dev/null @@ -1,37 +0,0 @@ -package ui - -import ( - "strings" - "sync" - - "github.com/iotaledger/goshimmer/packages/model/value_transaction" - "github.com/iotaledger/iota.go/transaction" -) - -// cleared every second -var transactions []transaction.Transaction -var tMutex sync.Mutex - -var emptyTag = strings.Repeat("9", 27) - -func logTransactions() interface{} { - tMutex.Lock() - defer tMutex.Unlock() - a := transactions - transactions = make([]transaction.Transaction, 0) - return a -} - -func saveTx(tx *value_transaction.ValueTransaction) { - tMutex.Lock() - defer tMutex.Unlock() - transactions = append(transactions, transaction.Transaction{ - Hash: tx.MetaTransaction.GetHash(), - Address: tx.GetAddress(), - Value: tx.GetValue(), - Timestamp: uint64(tx.GetTimestamp()), - TrunkTransaction: tx.MetaTransaction.GetTrunkTransactionHash(), - BranchTransaction: tx.MetaTransaction.GetBranchTransactionHash(), - Tag: emptyTag, - }) -} diff --git a/plugins/ui/ui.go b/plugins/ui/ui.go deleted file mode 100644 index 3c411210..00000000 --- a/plugins/ui/ui.go +++ /dev/null @@ -1,94 +0,0 @@ -package ui - -import ( - "net/http" - "strings" - "sync/atomic" - "time" - - "github.com/iotaledger/goshimmer/packages/gossip" - "github.com/iotaledger/goshimmer/packages/model/value_transaction" - "github.com/iotaledger/goshimmer/packages/shutdown" - "github.com/iotaledger/goshimmer/plugins/tangle" - "github.com/iotaledger/goshimmer/plugins/webapi" - "github.com/iotaledger/hive.go/daemon" - "github.com/iotaledger/hive.go/events" - "github.com/iotaledger/hive.go/logger" - "github.com/iotaledger/hive.go/node" - "github.com/labstack/echo" -) - -func configure(plugin *node.Plugin) { - - //webapi.Server.Static("ui", "plugins/ui/src") - webapi.Server.GET("ui", func(c echo.Context) error { - return c.HTML(http.StatusOK, files["index.html"]) - }) - webapi.Server.GET("ui/**", staticFileServer) - - webapi.Server.GET("ws", upgrader) - webapi.Server.GET("loghistory", func(c echo.Context) error { - logMutex.RLock() - defer logMutex.RUnlock() - return c.JSON(http.StatusOK, logHistory) - }) - webapi.Server.GET("tpsqueue", func(c echo.Context) error { - tpsQueueMutex.RLock() - defer tpsQueueMutex.RUnlock() - return c.JSON(http.StatusOK, tpsQueue) - }) - - gossip.Events.TransactionReceived.Attach(events.NewClosure(func(_ *gossip.TransactionReceivedEvent) { - atomic.AddUint64(&receivedTpsCounter, 1) - })) - tangle.Events.TransactionSolid.Attach(events.NewClosure(func(_ *value_transaction.ValueTransaction) { - atomic.AddUint64(&solidTpsCounter, 1) - })) - tangle.Events.TransactionStored.Attach(events.NewClosure(func(tx *value_transaction.ValueTransaction) { - go func() { - saveTx(tx) - }() - })) - - // store log messages to send them down via the websocket - anyMsgClosure := events.NewClosure(func(logLvl logger.Level, prefix string, msg string) { - storeAndSendStatusMessage(logLvl, prefix, msg) - }) - logger.Events.AnyMsg.Attach(anyMsgClosure) -} - -func staticFileServer(c echo.Context) error { - url := c.Request().URL.String() - path := url[4:] // trim off "/ui/" - res := c.Response() - header := res.Header() - if strings.HasPrefix(path, "css") { - header.Set(echo.HeaderContentType, "text/css") - } - if strings.HasPrefix(path, "js") { - header.Set(echo.HeaderContentType, "application/javascript") - } - return c.String(http.StatusOK, files[path]) -} - -func run(plugin *node.Plugin) { - - daemon.BackgroundWorker("UI Refresher", func(shutdownSignal <-chan struct{}) { - for { - select { - case <-shutdownSignal: - return - case <-time.After(1 * time.Second): - wsMutex.Lock() - ws.send(resp{ - "info": gatherInfo(), - "txs": logTransactions(), - }) - wsMutex.Unlock() - } - } - }, shutdown.ShutdownPriorityUI) -} - -// PLUGIN plugs the UI into the main program -var PLUGIN = node.NewPlugin("UI", node.Disabled, configure, run) diff --git a/plugins/ui/websocket.go b/plugins/ui/websocket.go deleted file mode 100644 index 8507f59a..00000000 --- a/plugins/ui/websocket.go +++ /dev/null @@ -1,45 +0,0 @@ -package ui - -import ( - "encoding/json" - "fmt" - "sync" - - "github.com/labstack/echo" - "golang.org/x/net/websocket" -) - -type socket struct { - conn *websocket.Conn -} - -var ws socket -var wsMutex sync.Mutex - -func (sock socket) send(msg interface{}) { - payload, err := json.Marshal(msg) - if err == nil && sock.conn != nil { - fmt.Fprint(sock.conn, string(payload)) - } -} - -func upgrader(c echo.Context) error { - - websocket.Handler(func(conn *websocket.Conn) { - wsMutex.Lock() - ws.conn = conn - wsMutex.Unlock() - defer conn.Close() - for { - msg := "" - err := websocket.Message.Receive(conn, &msg) - if err != nil { - //c.Logger().Error(err) - break - } - fmt.Printf("%s\n", msg) - } - }).ServeHTTP(c.Response(), c.Request()) - - return nil -} diff --git a/plugins/zeromq/parameters.go b/plugins/zeromq/parameters.go deleted file mode 100644 index 22850260..00000000 --- a/plugins/zeromq/parameters.go +++ /dev/null @@ -1,13 +0,0 @@ -package zeromq - -import ( - flag "github.com/spf13/pflag" -) - -const ( - ZEROMQ_PORT = "zeromq.port" -) - -func init() { - flag.Int(ZEROMQ_PORT, 5556, "tcp port used to connect to the zmq feed") -} diff --git a/plugins/zeromq/plugin.go b/plugins/zeromq/plugin.go deleted file mode 100644 index 0bf553b3..00000000 --- a/plugins/zeromq/plugin.go +++ /dev/null @@ -1,99 +0,0 @@ -package zeromq - -import ( - "strconv" - "strings" - "time" - - "github.com/iotaledger/goshimmer/packages/model/value_transaction" - "github.com/iotaledger/goshimmer/packages/parameter" - "github.com/iotaledger/goshimmer/packages/shutdown" - "github.com/iotaledger/goshimmer/plugins/tangle" - "github.com/iotaledger/hive.go/daemon" - "github.com/iotaledger/hive.go/events" - "github.com/iotaledger/hive.go/logger" - "github.com/iotaledger/hive.go/node" -) - -// zeromq logging is disabled by default -var PLUGIN = node.NewPlugin("ZeroMQ", node.Disabled, configure, run) -var log *logger.Logger -var publisher *Publisher -var emptyTag = strings.Repeat("9", 27) - -// Configure the zeromq plugin -func configure(plugin *node.Plugin) { - log = logger.NewLogger("ZeroMQ") - tangle.Events.TransactionStored.Attach(events.NewClosure(func(tx *value_transaction.ValueTransaction) { - // create goroutine for every event - go func() { - if err := publishTx(tx); err != nil { - log.Errorf("error publishing tx: %s", err.Error()) - } - }() - })) -} - -// Start the zeromq plugin -func run(plugin *node.Plugin) { - zeromqPort := parameter.NodeConfig.GetInt(ZEROMQ_PORT) - log.Infof("Starting ZeroMQ Publisher (port %d) ...", zeromqPort) - - daemon.BackgroundWorker("ZeroMQ Publisher", func(shutdownSignal <-chan struct{}) { - if err := startPublisher(plugin); err != nil { - log.Errorf("Stopping ZeroMQ Publisher: %s", err.Error()) - } else { - log.Infof("Starting ZeroMQ Publisher (port %d) ... done", zeromqPort) - } - - <-shutdownSignal - - log.Info("Stopping ZeroMQ Publisher ...") - if err := publisher.Shutdown(); err != nil { - log.Errorf("Stopping ZeroMQ Publisher: %s", err.Error()) - } else { - log.Info("Stopping ZeroMQ Publisher ... done") - } - }, shutdown.ShutdownPriorityZMQ) -} - -// Start the zmq publisher. -func startPublisher(plugin *node.Plugin) error { - pub, err := NewPublisher() - if err != nil { - return err - } - publisher = pub - - return publisher.Start(parameter.NodeConfig.GetInt(ZEROMQ_PORT)) -} - -// Publish a transaction that has recently been added to the ledger -func publishTx(tx *value_transaction.ValueTransaction) error { - - hash := tx.MetaTransaction.GetHash() - address := tx.GetAddress() - value := tx.GetValue() - timestamp := int64(tx.GetTimestamp()) - trunk := tx.MetaTransaction.GetTrunkTransactionHash() - branch := tx.MetaTransaction.GetBranchTransactionHash() - stored := time.Now().Unix() - - messages := []string{ - "tx", // ZMQ event - hash, // Transaction hash - address, // Address - strconv.FormatInt(value, 10), // Value - emptyTag, // Obsolete tag - strconv.FormatInt(timestamp, 10), // Timestamp - "0", // Index of the transaction in the bundle - "0", // Last transaction index of the bundle - hash, // Bundle hash - trunk, // Trunk transaction hash - branch, // Branch transaction hash - strconv.FormatInt(stored, 10), // Unix timestamp for when the transaction was received - emptyTag, // Tag - } - - return publisher.Send(messages) -} diff --git a/plugins/zeromq/publisher.go b/plugins/zeromq/publisher.go deleted file mode 100644 index 521a9fb3..00000000 --- a/plugins/zeromq/publisher.go +++ /dev/null @@ -1,47 +0,0 @@ -package zeromq - -import ( - "context" - "strconv" - "strings" - - zmq "github.com/go-zeromq/zmq4" -) - -// Simple zmq publisher abstraction -type Publisher struct { - socket zmq.Socket -} - -// Create a new publisher. -func NewPublisher() (*Publisher, error) { - - socket := zmq.NewPub(context.Background()) - - return &Publisher{ - socket: socket, - }, nil -} - -// Start the publisher on the given port. -func (pub *Publisher) Start(port int) error { - - return pub.socket.Listen("tcp://*:" + strconv.Itoa(port)) -} - -// Stop the publisher. -func (pub *Publisher) Shutdown() error { - - return pub.socket.Close() -} - -// Publish a new list of messages. -func (pub *Publisher) Send(messages []string) error { - if len(messages) == 0 || len(messages[0]) == 0 { - panic("zmq: invalid messages") - } - - data := strings.Join(messages, " ") - msg := zmq.NewMsgString(data) - return pub.socket.Send(msg) -} -- GitLab