diff --git a/.env b/.env index aad71e2..efb135f 100644 --- a/.env +++ b/.env @@ -3,7 +3,34 @@ DOMAIN=your-domain.xmr.example TRAEFIK_TAG=2.7 TRAEFIK_ACME_EMAIL=your-email@xmr.example TRAEFIK_LOGLEVEL=DEBUG +TRAEFIK_TLS_PORT=443 +TRAEFIK_HTTP_PORT=80 MONEROD_TAG=latest +MONEROD_RPC_PORT=18081 +MONEROD_RESTRICTED_RPC_PORT=18089 +MONEROD_P2P_PORT=18080 +MONEROD_ZMQ_RPC_PORT=18082 +MONEROD_ZMQ_PUB_PORT=18083 +MONEROD_EXTRA_PARAMS= +MONEROD_accessControlAllowOriginList=* -THS_TAG=latest +LWS_TAG=v0.2_0.18 +LWS_PORT=8000 +LWS_EXTRA_PARAMS= + +#TOR_TAG=latest +TOR_TAG=v0.4.7.8-57f8867 +TOR_HTTP_PORT=80 + +EXPLORER_TAG=v0.18 +EXPLORER_PORT=8081 + +P2POOL_WALLET=changeme +P2POOL_STRATUM_PORT=3333 +P2POOL_P2P_PORT=37889 +P2POOL_PEERS=65.21.227.114:37889,node.sethforprivacy.com:37889 + +GRAFANA_TAG=8.5.4 +GF_SECURITY_ADMIN_PASSWORD=xmrsh-admin +PROMETHEUS_TAG=v2.36.0 diff --git a/README.md b/README.md index fa43135..a8fa7b9 100644 --- a/README.md +++ b/README.md @@ -1,19 +1,50 @@ # xmr.sh -A Monero node installer in a single command +**xmr.sh** script wizard sets up a new server running a monero node daemon with Docker compose, with your choice of SSL certificates for your domain, network selection, a Tor hidden service, Grafana dashboard and more. -Tested in: +## Distribution support + +Compatible and tested on: - Debian 11 - Ubuntu Focal - Fedora 36 -- CentOS 10 Stream -ToDo: +Other distributions with docker pre-installed would probably be compatible as well. -[ ] Add wizard for DNS domain selection. -[ ] Status and node info at finish. -[ ] Make tor service optional -[ ] Optional block explorer -[ ] Grafana with stats -[ ] Add monerod-proxy +## Demo + +[![asciicast](https://asciinema.org/a/1gL7tNhb3XgPUr26losgZaeCJ.svg)](https://asciinema.org/a/1gL7tNhb3XgPUr26losgZaeCJ) + +## FAQ + +Check the [wiki](https://github.com/vdo/xmr.sh/wiki/FAQ) + +## ToDo + +- [x] Add wizard for DNS domain selection. +- [x] Status and node info at finish. +- [x] Mainnet / Stagenet / Testnet selection +- [x] Pruning enabled +- [x] Clearnet TLS port selection +- [x] Uninstall script +- [x] Make tor service optional +- [x] Block explorer (disabled) +- [x] Grafana dashboard +- [x] arm64 support for all images +- [x] monerod-lws support (experimental) +- [ ] Shellcheck via Github Actions +- [ ] Documentation +- [ ] monerod-proxy support for random node forwarding +- [ ] i2p service +- [ ] p2pool mining + +# Credits + +[@cirocosta](https://github.com/cirocosta) for the metrics exporter and grafana dashboard. + +[@sethforprivacy](https://github.com/sethforprivacy) for providing and maintaining Monero Docker images. + +# Donate XMR 🍕 + +86GwmtuKWtjJBWT8Srn4oqZHbP41k2kpG79xXKKgauJzCmZkFJ5ihwjVnRodVbVjAx64JeB7VyGbF6hEdwpcPcR7Go8x2YZ diff --git a/config/grafana/dashboards/monero.json b/config/grafana/dashboards/monero.json new file mode 100644 index 0000000..373654c --- /dev/null +++ b/config/grafana/dashboards/monero.json @@ -0,0 +1,5408 @@ +{ + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": "-- Grafana --", + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "description": "", + "editable": true, + "gnetId": null, + "graphTooltip": 0, + "id": 1, + "iteration": 1628030532187, + "links": [], + "panels": [ + { + "datasource": null, + "description": "Whether the node is running against mainnet or not.", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [ + { + "options": { + "0": { + "index": 1, + "text": "no" + }, + "1": { + "index": 0, + "text": "yes" + } + }, + "type": "value" + } + ], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 2, + "w": 3, + "x": 0, + "y": 0 + }, + "id": 68, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "text": {}, + "textMode": "auto" + }, + "pluginVersion": "8.0.6", + "targets": [ + { + "exemplar": true, + "expr": "monero_info_mainnet", + "instant": false, + "interval": "", + "legendFormat": "mainnet", + "refId": "A" + } + ], + "title": "Main network", + "transparent": true, + "type": "stat" + }, + { + "datasource": null, + "description": "Whether the node is fully in sync with the network or not.", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [ + { + "options": { + "0": { + "index": 1, + "text": "no" + }, + "1": { + "index": 0, + "text": "yes" + } + }, + "type": "value" + } + ], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 2, + "w": 3, + "x": 3, + "y": 0 + }, + "id": 69, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "text": {}, + "textMode": "auto" + }, + "pluginVersion": "8.0.6", + "targets": [ + { + "exemplar": true, + "expr": "monero_info_synchronized", + "instant": true, + "interval": "", + "legendFormat": "mainnet", + "refId": "A" + } + ], + "title": "Synchronized", + "transparent": true, + "type": "stat" + }, + { + "collapsed": true, + "datasource": null, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 2 + }, + "id": 62, + "panels": [ + { + "datasource": null, + "description": "Current chain's block height vs node's current height. When syncing, let's one quickly tell how far the node is from being synchronized with the network.", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": -1, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "stepBefore", + "lineWidth": 1, + "pointSize": 6, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "decimals": 0, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "none" + }, + "overrides": [] + }, + "gridPos": { + "h": 7, + "w": 8, + "x": 0, + "y": 3 + }, + "id": 71, + "options": { + "legend": { + "calcs": [], + "displayMode": "hidden", + "placement": "bottom" + }, + "tooltip": { + "mode": "multi" + } + }, + "targets": [ + { + "exemplar": true, + "expr": "monero_info_height", + "interval": "", + "legendFormat": "height", + "refId": "A" + }, + { + "exemplar": true, + "expr": "monero_info_target_height", + "hide": false, + "interval": "", + "legendFormat": "target", + "refId": "B" + } + ], + "title": "Height and Target", + "transparent": true, + "type": "graph" + }, + { + "datasource": null, + "description": "Maximum hard limit for block size scaling, as well as median used for scaling factor", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "axisSoftMin": 0, + "barAlignment": -1, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "stepBefore", + "lineWidth": 1, + "pointSize": 6, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "decimals": 0, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "decbytes" + }, + "overrides": [] + }, + "gridPos": { + "h": 7, + "w": 8, + "x": 8, + "y": 3 + }, + "id": 65, + "options": { + "legend": { + "calcs": [], + "displayMode": "hidden", + "placement": "bottom" + }, + "tooltip": { + "mode": "multi" + } + }, + "targets": [ + { + "exemplar": true, + "expr": "monero_info_block_size_limit_bytes", + "interval": "", + "legendFormat": "limit", + "refId": "A" + }, + { + "exemplar": true, + "expr": "monero_info_block_size_median_bytes", + "hide": false, + "interval": "", + "legendFormat": "median", + "refId": "B" + } + ], + "title": "Block size median and limit", + "transparent": true, + "type": "graph" + }, + { + "datasource": null, + "description": "For how long this node has been up.", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": -1, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "stepBefore", + "lineWidth": 1, + "pointSize": 6, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "dtdhms" + }, + "overrides": [] + }, + "gridPos": { + "h": 7, + "w": 8, + "x": 16, + "y": 3 + }, + "id": 66, + "options": { + "legend": { + "calcs": [], + "displayMode": "hidden", + "placement": "bottom" + }, + "tooltip": { + "mode": "multi" + } + }, + "targets": [ + { + "exemplar": true, + "expr": "monero_info_uptime_seconds_total", + "interval": "", + "legendFormat": "limit", + "refId": "A" + } + ], + "title": "Uptime", + "transparent": true, + "type": "graph" + }, + { + "datasource": null, + "description": "Number of blocks alternative to the longest chain", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "axisSoftMin": 0, + "barAlignment": -1, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "stepBefore", + "lineWidth": 1, + "pointSize": 6, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "decimals": 0, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "short" + }, + "overrides": [] + }, + "gridPos": { + "h": 7, + "w": 8, + "x": 0, + "y": 10 + }, + "id": 64, + "options": { + "legend": { + "calcs": [], + "displayMode": "hidden", + "placement": "bottom" + }, + "tooltip": { + "mode": "multi" + } + }, + "targets": [ + { + "exemplar": true, + "expr": "monero_info_alternative_blocks", + "interval": "", + "legendFormat": "alternative blocks", + "refId": "A" + } + ], + "title": "Alternative blocks", + "transparent": true, + "type": "graph" + }, + { + "datasource": null, + "description": "Amount of free space in the partition where the Monero database is located at.", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": -1, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "stepBefore", + "lineWidth": 1, + "pointSize": 6, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "decimals": 3, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "decbytes" + }, + "overrides": [] + }, + "gridPos": { + "h": 7, + "w": 8, + "x": 8, + "y": 10 + }, + "id": 74, + "options": { + "legend": { + "calcs": [], + "displayMode": "hidden", + "placement": "bottom" + }, + "tooltip": { + "mode": "multi" + } + }, + "targets": [ + { + "exemplar": true, + "expr": "monero_info_free_space_bytes", + "interval": "", + "legendFormat": "free space", + "refId": "A" + } + ], + "title": "Free space", + "transparent": true, + "type": "graph" + }, + { + "datasource": null, + "description": "Size of Monero's database on disk.", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": -1, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "stepBefore", + "lineWidth": 1, + "pointSize": 6, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "decimals": 3, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "decbytes" + }, + "overrides": [] + }, + "gridPos": { + "h": 7, + "w": 8, + "x": 16, + "y": 10 + }, + "id": 75, + "options": { + "legend": { + "calcs": [], + "displayMode": "hidden", + "placement": "bottom" + }, + "tooltip": { + "mode": "multi" + } + }, + "targets": [ + { + "exemplar": true, + "expr": "monero_info_database_size_bytes", + "interval": "", + "legendFormat": "size", + "refId": "A" + } + ], + "title": "Database Size", + "transparent": true, + "type": "graph" + } + ], + "title": "Overall", + "type": "row" + }, + { + "collapsed": true, + "datasource": null, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 3 + }, + "id": 44, + "panels": [ + { + "datasource": null, + "description": "The distribution of how long ago peers in the whitelist have been seen.\n", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": -1, + "drawStyle": "points", + "fillOpacity": 26, + "gradientMode": "opacity", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 3, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "s" + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "1" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "dark-purple", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "0.99" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "dark-blue", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "0.95" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "dark-green", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "0.9" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "dark-yellow", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "0.75" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "dark-orange", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "0.5" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "dark-red", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "0.25" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "light-red", + "mode": "fixed" + } + } + ] + } + ] + }, + "gridPos": { + "h": 7, + "w": 8, + "x": 0, + "y": 4 + }, + "id": 55, + "options": { + "legend": { + "calcs": [], + "displayMode": "hidden", + "placement": "bottom" + }, + "tooltip": { + "mode": "multi" + } + }, + "targets": [ + { + "exemplar": true, + "expr": "monero_peerlist_lastseen{quantile=~\"$quantile\"}", + "interval": "", + "legendFormat": "{{ quantile }}", + "refId": "A" + } + ], + "title": "White Peerlist last seen distribution", + "transparent": true, + "type": "graph" + }, + { + "datasource": null, + "description": "Number of peers in each peer list.", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": -1, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "stepBefore", + "lineWidth": 1, + "pointSize": 6, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "short" + }, + "overrides": [] + }, + "gridPos": { + "h": 7, + "w": 8, + "x": 8, + "y": 4 + }, + "id": 57, + "options": { + "legend": { + "calcs": [], + "displayMode": "hidden", + "placement": "bottom" + }, + "tooltip": { + "mode": "multi" + } + }, + "targets": [ + { + "exemplar": true, + "expr": "monero_peerlist", + "interval": "", + "legendFormat": "{{ type }}", + "refId": "A" + } + ], + "title": "Peerlists' count", + "transparent": true, + "type": "graph" + }, + { + "datasource": null, + "description": "Rate of data transmission in and out from this node (p2p and rpc).", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": -1, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "stepBefore", + "lineWidth": 1, + "pointSize": 6, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "Bps" + }, + "overrides": [] + }, + "gridPos": { + "h": 7, + "w": 8, + "x": 16, + "y": 4 + }, + "id": 58, + "options": { + "legend": { + "calcs": [], + "displayMode": "hidden", + "placement": "bottom" + }, + "tooltip": { + "mode": "multi" + } + }, + "targets": [ + { + "exemplar": true, + "expr": "rate(monero_net_rx_bytes[1m])", + "interval": "", + "legendFormat": "rx", + "refId": "A" + }, + { + "exemplar": true, + "expr": "rate(monero_net_tx_bytes[1m])", + "hide": false, + "interval": "", + "legendFormat": "tx", + "refId": "B" + } + ], + "title": "Data rate", + "transparent": true, + "type": "graph" + }, + { + "datasource": null, + "description": "Number of connections based on their direction (incoming/outgoing)", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": -1, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "stepBefore", + "lineWidth": 1, + "pointSize": 6, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "short" + }, + "overrides": [] + }, + "gridPos": { + "h": 7, + "w": 8, + "x": 0, + "y": 11 + }, + "id": 46, + "options": { + "legend": { + "calcs": [], + "displayMode": "hidden", + "placement": "bottom" + }, + "tooltip": { + "mode": "multi" + } + }, + "targets": [ + { + "exemplar": true, + "expr": "sum(monero_p2p_connections) by (type)", + "interval": "", + "legendFormat": "{{ type }}", + "refId": "A" + } + ], + "title": "Connections by direction (in/out)", + "transparent": true, + "type": "graph" + }, + { + "datasource": null, + "description": "Number of connections based on their connection state.", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": -1, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "stepBefore", + "lineWidth": 1, + "pointSize": 6, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "short" + }, + "overrides": [] + }, + "gridPos": { + "h": 7, + "w": 8, + "x": 8, + "y": 11 + }, + "id": 47, + "options": { + "legend": { + "calcs": [], + "displayMode": "hidden", + "placement": "bottom" + }, + "tooltip": { + "mode": "multi" + } + }, + "targets": [ + { + "exemplar": true, + "expr": "sum(monero_p2p_connections) by (state)", + "interval": "", + "legendFormat": "{{ type }}", + "refId": "A" + } + ], + "title": "Connections by connection state", + "transparent": true, + "type": "graph" + }, + { + "datasource": null, + "description": "Total amount of data sent and received by this node.", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": -1, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "stepBefore", + "lineWidth": 1, + "pointSize": 6, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "decbytes" + }, + "overrides": [] + }, + "gridPos": { + "h": 7, + "w": 8, + "x": 16, + "y": 11 + }, + "id": 59, + "options": { + "legend": { + "calcs": [], + "displayMode": "hidden", + "placement": "bottom" + }, + "tooltip": { + "mode": "multi" + } + }, + "targets": [ + { + "exemplar": true, + "expr": "monero_net_rx_bytes", + "interval": "", + "legendFormat": "rx", + "refId": "A" + }, + { + "exemplar": true, + "expr": "monero_net_tx_bytes", + "hide": false, + "interval": "", + "legendFormat": "tx", + "refId": "B" + } + ], + "title": "Data", + "transparent": true, + "type": "graph" + }, + { + "datasource": null, + "description": "The distribution of data retrieval from our connected peers.\n", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": -1, + "drawStyle": "points", + "fillOpacity": 26, + "gradientMode": "opacity", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 3, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "Bps" + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "1" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "dark-purple", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "0.99" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "dark-blue", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "0.95" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "dark-green", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "0.9" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "dark-yellow", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "0.75" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "dark-orange", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "0.5" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "dark-red", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "0.25" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "light-red", + "mode": "fixed" + } + } + ] + } + ] + }, + "gridPos": { + "h": 7, + "w": 8, + "x": 0, + "y": 18 + }, + "id": 50, + "options": { + "legend": { + "calcs": [], + "displayMode": "hidden", + "placement": "bottom" + }, + "tooltip": { + "mode": "multi" + } + }, + "targets": [ + { + "exemplar": true, + "expr": "monero_p2p_connections_rx_rate_bps{quantile=~\"$quantile\"}", + "interval": "", + "legendFormat": "{{ quantile }}", + "refId": "A" + } + ], + "title": "P2P Peers Data Receive Rate", + "transparent": true, + "type": "graph" + }, + { + "datasource": null, + "description": "The distribution of data transmission to our connected peers.\n", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": -1, + "drawStyle": "points", + "fillOpacity": 26, + "gradientMode": "opacity", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 3, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "Bps" + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "1" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "dark-purple", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "0.99" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "dark-blue", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "0.95" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "dark-green", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "0.9" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "dark-yellow", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "0.75" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "dark-orange", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "0.5" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "dark-red", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "0.25" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "light-red", + "mode": "fixed" + } + } + ] + } + ] + }, + "gridPos": { + "h": 7, + "w": 8, + "x": 8, + "y": 18 + }, + "id": 60, + "options": { + "legend": { + "calcs": [], + "displayMode": "hidden", + "placement": "bottom" + }, + "tooltip": { + "mode": "multi" + } + }, + "targets": [ + { + "exemplar": true, + "expr": "monero_p2p_connections_tx_rate_bps{quantile=~\"$quantile\"}", + "interval": "", + "legendFormat": "{{ quantile }}", + "refId": "A" + } + ], + "title": "P2P Peers Data Transmission Rate", + "transparent": true, + "type": "graph" + }, + { + "datasource": null, + "description": "The distribution of the heights of our peers\n", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": -1, + "drawStyle": "points", + "fillOpacity": 26, + "gradientMode": "opacity", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 3, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "short" + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "1" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "dark-purple", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "0.99" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "dark-blue", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "0.95" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "dark-green", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "0.9" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "dark-yellow", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "0.75" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "dark-orange", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "0.5" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "dark-red", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "0.25" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "light-red", + "mode": "fixed" + } + } + ] + } + ] + }, + "gridPos": { + "h": 7, + "w": 8, + "x": 16, + "y": 18 + }, + "id": 49, + "options": { + "legend": { + "calcs": [], + "displayMode": "hidden", + "placement": "bottom" + }, + "tooltip": { + "mode": "multi" + } + }, + "targets": [ + { + "exemplar": true, + "expr": "monero_p2p_connections_height{quantile=~\"$quantile\"}", + "interval": "", + "legendFormat": "{{ quantile }}", + "refId": "A" + } + ], + "title": "Connected Peers' Height", + "transparent": true, + "type": "graph" + }, + { + "datasource": null, + "description": "The distribution of the age of the connections established to/from our nodes.\n", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": -1, + "drawStyle": "points", + "fillOpacity": 26, + "gradientMode": "opacity", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 3, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "s" + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "1" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "dark-purple", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "0.99" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "dark-blue", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "0.95" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "dark-green", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "0.9" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "dark-yellow", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "0.75" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "dark-orange", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "0.5" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "dark-red", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "0.25" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "light-red", + "mode": "fixed" + } + } + ] + } + ] + }, + "gridPos": { + "h": 7, + "w": 8, + "x": 0, + "y": 25 + }, + "id": 51, + "options": { + "legend": { + "calcs": [], + "displayMode": "hidden", + "placement": "bottom" + }, + "tooltip": { + "mode": "multi" + } + }, + "targets": [ + { + "exemplar": true, + "expr": "monero_p2p_connections_age{quantile=~\"$quantile\"}", + "interval": "", + "legendFormat": "{{ quantile }}", + "refId": "A" + } + ], + "title": "Connections' Age", + "transparent": true, + "type": "graph" + } + ], + "title": "Networking", + "type": "row" + }, + { + "collapsed": true, + "datasource": null, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 4 + }, + "id": 38, + "panels": [ + { + "datasource": null, + "description": "Average number of RPC requests served over the past minute.\n\nps.: this includes the calls made by the stats collector too.", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": -1, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "stepBefore", + "lineStyle": { + "fill": "solid" + }, + "lineWidth": 1, + "pointSize": 6, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "short" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 5 + }, + "id": 40, + "options": { + "legend": { + "calcs": [], + "displayMode": "hidden", + "placement": "bottom" + }, + "tooltip": { + "mode": "multi" + } + }, + "targets": [ + { + "exemplar": true, + "expr": "increase(monero_rpc_hits_total[1m])", + "interval": "", + "legendFormat": "{{method}}", + "refId": "A" + } + ], + "title": "RPC hits per minute", + "transparent": true, + "type": "graph" + }, + { + "datasource": null, + "description": "Average amount of time spent serving RPC methods over that past minute.\n\nps.: this includes the calls made by the stats collector too.", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": -1, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "stepBefore", + "lineWidth": 1, + "pointSize": 6, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "s" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 5 + }, + "id": 42, + "options": { + "legend": { + "calcs": [], + "displayMode": "hidden", + "placement": "bottom" + }, + "tooltip": { + "mode": "multi" + } + }, + "targets": [ + { + "exemplar": true, + "expr": "rate(monero_rpc_seconds_total[1m])", + "interval": "", + "legendFormat": "{{method}}", + "refId": "A" + } + ], + "title": "Time spent serving RPC methods", + "transparent": true, + "type": "graph" + }, + { + "datasource": null, + "description": "Number of RPC connections being served.", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "axisSoftMin": 0, + "barAlignment": -1, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "stepBefore", + "lineWidth": 1, + "pointSize": 6, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "decimals": 0, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "short" + }, + "overrides": [] + }, + "gridPos": { + "h": 7, + "w": 8, + "x": 0, + "y": 13 + }, + "id": 73, + "options": { + "legend": { + "calcs": [], + "displayMode": "hidden", + "placement": "bottom" + }, + "tooltip": { + "mode": "multi" + } + }, + "targets": [ + { + "exemplar": true, + "expr": "monero_info_rpc_connections", + "interval": "", + "legendFormat": "connections", + "refId": "A" + } + ], + "title": "RPC Connections", + "transparent": true, + "type": "graph" + } + ], + "title": "RPC", + "type": "row" + }, + { + "collapsed": true, + "datasource": null, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 5 + }, + "id": 16, + "panels": [ + { + "datasource": null, + "description": "Total number of key images spent across all transactions that are still in the pool", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": -1, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "stepBefore", + "lineWidth": 1, + "pointSize": 6, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "short" + }, + "overrides": [] + }, + "gridPos": { + "h": 7, + "w": 8, + "x": 0, + "y": 6 + }, + "id": 21, + "options": { + "legend": { + "calcs": [], + "displayMode": "hidden", + "placement": "bottom" + }, + "tooltip": { + "mode": "multi" + } + }, + "targets": [ + { + "exemplar": true, + "expr": "monero_transaction_pool_spent_key_images", + "interval": "", + "legendFormat": "spent key images", + "refId": "A" + } + ], + "title": "Spent Key Images", + "transparent": true, + "type": "graph" + }, + { + "datasource": null, + "description": "Total size of the block", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": -1, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "stepBefore", + "lineWidth": 1, + "pointSize": 6, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "decbytes" + }, + "overrides": [] + }, + "gridPos": { + "h": 7, + "w": 8, + "x": 8, + "y": 6 + }, + "id": 23, + "options": { + "legend": { + "calcs": [], + "displayMode": "hidden", + "placement": "bottom" + }, + "tooltip": { + "mode": "multi" + } + }, + "targets": [ + { + "exemplar": true, + "expr": "monero_transaction_pool_size_bytes", + "interval": "", + "legendFormat": "size", + "refId": "A" + } + ], + "title": "Size", + "transparent": true, + "type": "graph" + }, + { + "datasource": null, + "description": "Number of transactions in the transaction pool.", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": -1, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "stepBefore", + "lineWidth": 1, + "pointSize": 6, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "short" + }, + "overrides": [] + }, + "gridPos": { + "h": 7, + "w": 8, + "x": 16, + "y": 6 + }, + "id": 18, + "options": { + "legend": { + "calcs": [], + "displayMode": "hidden", + "placement": "bottom" + }, + "tooltip": { + "mode": "multi" + } + }, + "targets": [ + { + "exemplar": true, + "expr": "monero_transaction_pool_transactions", + "interval": "", + "legendFormat": "fee", + "refId": "A" + } + ], + "title": "Transactions", + "transparent": true, + "type": "graph" + }, + { + "datasource": null, + "description": "The distribution of the sizes of the transactions in the pool.\n", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": -1, + "drawStyle": "points", + "fillOpacity": 26, + "gradientMode": "opacity", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 3, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "decbytes" + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "1" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "dark-purple", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "0.99" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "dark-blue", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "0.95" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "dark-green", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "0.9" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "dark-yellow", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "0.75" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "dark-orange", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "0.5" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "dark-red", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "0.25" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "light-red", + "mode": "fixed" + } + } + ] + } + ] + }, + "gridPos": { + "h": 7, + "w": 8, + "x": 0, + "y": 13 + }, + "id": 26, + "options": { + "legend": { + "calcs": [], + "displayMode": "hidden", + "placement": "bottom" + }, + "tooltip": { + "mode": "multi" + } + }, + "targets": [ + { + "exemplar": true, + "expr": "monero_transaction_pool_transactions_size_bytes{quantile=~\"$quantile\"}", + "interval": "", + "legendFormat": "{{ quantile }}", + "refId": "A" + } + ], + "title": "Transaction Size", + "transparent": true, + "type": "graph" + }, + { + "datasource": null, + "description": "The distribution fees (in micronero) per kB for the transactions still in the transaction pool.\n", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": -1, + "drawStyle": "points", + "fillOpacity": 26, + "gradientMode": "opacity", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 3, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "µɱ" + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "1" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "dark-purple", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "0.99" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "dark-blue", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "0.95" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "dark-green", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "0.9" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "dark-yellow", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "0.75" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "dark-orange", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "0.5" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "dark-red", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "0.25" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "light-red", + "mode": "fixed" + } + } + ] + } + ] + }, + "gridPos": { + "h": 7, + "w": 8, + "x": 8, + "y": 13 + }, + "id": 20, + "options": { + "legend": { + "calcs": [], + "displayMode": "hidden", + "placement": "bottom" + }, + "tooltip": { + "mode": "multi" + } + }, + "targets": [ + { + "exemplar": true, + "expr": "monero_transaction_pool_fees_micronero_per_kb{quantile=~\"$quantile\"}", + "interval": "", + "legendFormat": "{{ quantile }}", + "refId": "A" + } + ], + "title": "Transaction Fees Distribution (per kB)", + "transparent": true, + "type": "graph" + }, + { + "datasource": null, + "description": "Total amount of fees (in Monero) for the transactions in the transaction pool.", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": -1, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "stepBefore", + "lineWidth": 1, + "pointSize": 6, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "ɱ" + }, + "overrides": [] + }, + "gridPos": { + "h": 7, + "w": 8, + "x": 16, + "y": 13 + }, + "id": 24, + "options": { + "legend": { + "calcs": [], + "displayMode": "hidden", + "placement": "bottom" + }, + "tooltip": { + "mode": "multi" + } + }, + "targets": [ + { + "exemplar": true, + "expr": "monero_transaction_pool_fees_monero", + "interval": "", + "legendFormat": "fee", + "refId": "A" + } + ], + "title": "Fees", + "transparent": true, + "type": "graph" + }, + { + "datasource": null, + "description": "The distribution of the amount of inputs used in transactions still in the transaction pool. \n", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": -1, + "drawStyle": "points", + "fillOpacity": 26, + "gradientMode": "opacity", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 3, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "1" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "dark-purple", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "0.99" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "dark-blue", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "0.95" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "dark-green", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "0.9" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "dark-yellow", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "0.75" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "dark-orange", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "0.5" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "dark-red", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "0.25" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "light-red", + "mode": "fixed" + } + } + ] + } + ] + }, + "gridPos": { + "h": 7, + "w": 8, + "x": 0, + "y": 20 + }, + "id": 28, + "options": { + "legend": { + "calcs": [], + "displayMode": "hidden", + "placement": "bottom" + }, + "tooltip": { + "mode": "multi" + } + }, + "targets": [ + { + "exemplar": true, + "expr": "monero_transaction_pool_transactions_inputs{quantile=~\"$quantile\"}", + "interval": "", + "legendFormat": "{{ quantile }}", + "refId": "A" + } + ], + "title": "Transaction Inputs", + "transparent": true, + "type": "graph" + }, + { + "datasource": null, + "description": "The distribution of the amount of outputs used in transactions still in the transaction pool. \n", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": -1, + "drawStyle": "points", + "fillOpacity": 26, + "gradientMode": "opacity", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 3, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "1" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "dark-purple", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "0.99" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "dark-blue", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "0.95" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "dark-green", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "0.9" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "dark-yellow", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "0.75" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "dark-orange", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "0.5" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "dark-red", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "0.25" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "light-red", + "mode": "fixed" + } + } + ] + } + ] + }, + "gridPos": { + "h": 7, + "w": 8, + "x": 8, + "y": 20 + }, + "id": 29, + "options": { + "legend": { + "calcs": [], + "displayMode": "hidden", + "placement": "bottom" + }, + "tooltip": { + "mode": "multi" + } + }, + "targets": [ + { + "exemplar": true, + "expr": "monero_transaction_pool_transactions_outputs{quantile=~\"$quantile\"}", + "interval": "", + "legendFormat": "{{ quantile }}", + "refId": "A" + } + ], + "title": "Transaction Outputs", + "transparent": true, + "type": "graph" + }, + { + "datasource": null, + "description": "Total number of inputs and outputs from the transactions still in the pool.", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": -1, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "stepBefore", + "lineWidth": 1, + "pointSize": 6, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "short" + }, + "overrides": [] + }, + "gridPos": { + "h": 7, + "w": 8, + "x": 16, + "y": 20 + }, + "id": 31, + "options": { + "legend": { + "calcs": [], + "displayMode": "hidden", + "placement": "bottom" + }, + "tooltip": { + "mode": "multi" + } + }, + "targets": [ + { + "exemplar": true, + "expr": "monero_transaction_pool_transactions_inputs_sum", + "interval": "", + "legendFormat": "inputs", + "refId": "A" + }, + { + "exemplar": true, + "expr": "monero_transaction_pool_transactions_outputs_sum", + "hide": false, + "interval": "", + "legendFormat": "outputs", + "refId": "B" + } + ], + "title": "Inputs and Outputs", + "transparent": true, + "type": "graph" + }, + { + "datasource": null, + "description": "A couple of statistics that reveals weird scenarios found in the transaction pool.", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": -1, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "stepBefore", + "lineWidth": 1, + "pointSize": 6, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "short" + }, + "overrides": [] + }, + "gridPos": { + "h": 7, + "w": 8, + "x": 0, + "y": 27 + }, + "id": 32, + "options": { + "legend": { + "calcs": [], + "displayMode": "hidden", + "placement": "bottom" + }, + "tooltip": { + "mode": "multi" + } + }, + "targets": [ + { + "exemplar": true, + "expr": "monero_transaction_pool_double_spends", + "interval": "", + "legendFormat": "double spends", + "refId": "A" + }, + { + "exemplar": true, + "expr": "monero_transaction_pool_older_than_10m", + "hide": false, + "interval": "", + "legendFormat": "older than 10m", + "refId": "B" + }, + { + "exemplar": true, + "expr": "monero_transaction_pool_failing_transactions", + "hide": false, + "interval": "", + "legendFormat": "failing transactions", + "refId": "C" + }, + { + "exemplar": true, + "expr": "monero_transaction_pool_not_relayed", + "hide": false, + "interval": "", + "legendFormat": "not relayed", + "refId": "D" + } + ], + "title": "Weird cases", + "transparent": true, + "type": "graph" + }, + { + "datasource": null, + "description": "Distribution of for how long transactions have been sitting in the pool.", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": -1, + "drawStyle": "points", + "fillOpacity": 26, + "gradientMode": "opacity", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 3, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "s" + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "1" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "dark-purple", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "0.99" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "dark-blue", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "0.95" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "dark-green", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "0.9" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "dark-yellow", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "0.75" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "dark-orange", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "0.5" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "dark-red", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "0.25" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "light-red", + "mode": "fixed" + } + } + ] + } + ] + }, + "gridPos": { + "h": 7, + "w": 8, + "x": 8, + "y": 27 + }, + "id": 34, + "options": { + "legend": { + "calcs": [], + "displayMode": "hidden", + "placement": "bottom" + }, + "tooltip": { + "mode": "multi" + } + }, + "targets": [ + { + "exemplar": true, + "expr": "monero_transaction_pool_transactions_age{quantile=~\"$quantile\"}", + "interval": "", + "legendFormat": "{{ quantile }}", + "refId": "A" + } + ], + "title": "Transaction Age", + "transparent": true, + "type": "graph" + } + ], + "title": "Transaction Pool", + "type": "row" + }, + { + "collapsed": true, + "datasource": null, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 6 + }, + "id": 2, + "panels": [ + { + "datasource": null, + "description": "Height of the last block in the chain.", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": -1, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "stepBefore", + "lineWidth": 1, + "pointSize": 6, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "none" + }, + "overrides": [] + }, + "gridPos": { + "h": 7, + "w": 8, + "x": 0, + "y": 7 + }, + "id": 36, + "options": { + "legend": { + "calcs": [], + "displayMode": "hidden", + "placement": "bottom" + }, + "tooltip": { + "mode": "multi" + } + }, + "targets": [ + { + "exemplar": true, + "expr": "monero_lastblock_height", + "interval": "", + "legendFormat": "transactions", + "refId": "A" + } + ], + "title": "Height", + "transparent": true, + "type": "graph" + }, + { + "datasource": null, + "description": "Total amount of fees (in Monero) included in the last block.", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": -1, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "stepBefore", + "lineWidth": 1, + "pointSize": 6, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "ɱ" + }, + "overrides": [] + }, + "gridPos": { + "h": 7, + "w": 8, + "x": 8, + "y": 7 + }, + "id": 4, + "options": { + "legend": { + "calcs": [], + "displayMode": "hidden", + "placement": "bottom" + }, + "tooltip": { + "mode": "multi" + } + }, + "targets": [ + { + "exemplar": true, + "expr": "monero_lastblock_fees_monero", + "interval": "", + "legendFormat": "fee", + "refId": "A" + } + ], + "title": "Fees", + "transparent": true, + "type": "graph" + }, + { + "datasource": null, + "description": "Newly amount of Monero created in this block as a miner subsidy. ", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": -1, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "stepBefore", + "lineWidth": 1, + "pointSize": 6, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "decimals": 6, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "ɱ" + }, + "overrides": [] + }, + "gridPos": { + "h": 7, + "w": 8, + "x": 16, + "y": 7 + }, + "id": 7, + "options": { + "legend": { + "calcs": [], + "displayMode": "hidden", + "placement": "bottom" + }, + "tooltip": { + "mode": "multi" + } + }, + "targets": [ + { + "exemplar": true, + "expr": "monero_lastblock_subsidy_monero", + "interval": "", + "legendFormat": "block subsidy", + "refId": "A" + } + ], + "title": "Subsidy", + "transparent": true, + "type": "graph" + }, + { + "datasource": null, + "description": "The distribution fees (in micronero) per kB for the transactions included in the block seen as last at the time.\n", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": -1, + "drawStyle": "points", + "fillOpacity": 26, + "gradientMode": "opacity", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 3, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "µɱ" + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "1" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "dark-purple", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "0.99" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "dark-blue", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "0.95" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "dark-green", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "0.9" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "dark-yellow", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "0.75" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "dark-orange", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "0.5" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "dark-red", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "0.25" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "light-red", + "mode": "fixed" + } + } + ] + } + ] + }, + "gridPos": { + "h": 7, + "w": 8, + "x": 0, + "y": 14 + }, + "id": 5, + "options": { + "legend": { + "calcs": [], + "displayMode": "hidden", + "placement": "bottom" + }, + "tooltip": { + "mode": "multi" + } + }, + "targets": [ + { + "exemplar": true, + "expr": "monero_lastblock_fees_micronero_per_kb{quantile=~\"$quantile\"}", + "interval": "", + "legendFormat": "{{ quantile }}", + "refId": "A" + } + ], + "title": "Transaction Fees Distribution (per kB)", + "transparent": true, + "type": "graph" + }, + { + "datasource": null, + "description": "Total block rewards granted to the miner of this block (transaction fees + block subsidy).", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": -1, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "stepBefore", + "lineWidth": 1, + "pointSize": 6, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "ɱ" + }, + "overrides": [] + }, + "gridPos": { + "h": 7, + "w": 8, + "x": 8, + "y": 14 + }, + "id": 6, + "options": { + "legend": { + "calcs": [], + "displayMode": "hidden", + "placement": "bottom" + }, + "tooltip": { + "mode": "multi" + } + }, + "targets": [ + { + "exemplar": true, + "expr": "monero_lastblock_reward_monero", + "interval": "", + "legendFormat": "total rewards", + "refId": "A" + } + ], + "title": "Rewards", + "transparent": true, + "type": "graph" + }, + { + "datasource": null, + "description": "Total size of the block", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": -1, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "stepBefore", + "lineWidth": 1, + "pointSize": 6, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "decbytes" + }, + "overrides": [] + }, + "gridPos": { + "h": 7, + "w": 8, + "x": 16, + "y": 14 + }, + "id": 11, + "options": { + "legend": { + "calcs": [], + "displayMode": "hidden", + "placement": "bottom" + }, + "tooltip": { + "mode": "multi" + } + }, + "targets": [ + { + "exemplar": true, + "expr": "monero_lastblock_size_bytes", + "interval": "", + "legendFormat": "size", + "refId": "A" + } + ], + "title": "Size", + "transparent": true, + "type": "graph" + }, + { + "datasource": null, + "description": "Number of transactions included in the block", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": -1, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "stepBefore", + "lineWidth": 1, + "pointSize": 6, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "short" + }, + "overrides": [] + }, + "gridPos": { + "h": 7, + "w": 8, + "x": 0, + "y": 21 + }, + "id": 10, + "options": { + "legend": { + "calcs": [], + "displayMode": "hidden", + "placement": "bottom" + }, + "tooltip": { + "mode": "multi" + } + }, + "targets": [ + { + "exemplar": true, + "expr": "monero_lastblock_transactions", + "interval": "", + "legendFormat": "transactions", + "refId": "A" + } + ], + "title": "Transactions", + "transparent": true, + "type": "graph" + }, + { + "datasource": null, + "description": "Number of transactions included in the block", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": -1, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "stepBefore", + "lineWidth": 1, + "pointSize": 6, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "short" + }, + "overrides": [] + }, + "gridPos": { + "h": 7, + "w": 8, + "x": 8, + "y": 21 + }, + "id": 14, + "options": { + "legend": { + "calcs": [], + "displayMode": "hidden", + "placement": "bottom" + }, + "tooltip": { + "mode": "multi" + } + }, + "targets": [ + { + "exemplar": true, + "expr": "monero_lastblock_transactions_inputs_sum", + "interval": "", + "legendFormat": "inputs", + "refId": "A" + }, + { + "exemplar": true, + "expr": "monero_lastblock_transactions_outputs_sum", + "hide": false, + "interval": "", + "legendFormat": "outputs", + "refId": "B" + } + ], + "title": "Inputs and Outputs", + "transparent": true, + "type": "graph" + }, + { + "datasource": null, + "description": "The distribution of sizes of the transactions included in this block.\n", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": -1, + "drawStyle": "points", + "fillOpacity": 26, + "gradientMode": "opacity", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 3, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "decbytes" + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "1" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "dark-purple", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "0.99" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "dark-blue", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "0.95" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "dark-green", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "0.9" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "dark-yellow", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "0.75" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "dark-orange", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "0.5" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "dark-red", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "0.25" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "light-red", + "mode": "fixed" + } + } + ] + } + ] + }, + "gridPos": { + "h": 7, + "w": 8, + "x": 16, + "y": 21 + }, + "id": 13, + "options": { + "legend": { + "calcs": [], + "displayMode": "hidden", + "placement": "bottom" + }, + "tooltip": { + "mode": "multi" + } + }, + "targets": [ + { + "exemplar": true, + "expr": "monero_lastblock_transactions_size_bytes{quantile=~\"$quantile\"}", + "interval": "", + "legendFormat": "{{ quantile }}", + "refId": "A" + } + ], + "title": "Transaction Size Distribution", + "transparent": true, + "type": "graph" + }, + { + "datasource": null, + "description": "The distribution of the amount of inputs used in transactions included in this block. \n", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": -1, + "drawStyle": "points", + "fillOpacity": 26, + "gradientMode": "opacity", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 3, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "1" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "dark-purple", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "0.99" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "dark-blue", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "0.95" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "dark-green", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "0.9" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "dark-yellow", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "0.75" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "dark-orange", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "0.5" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "dark-red", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "0.25" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "light-red", + "mode": "fixed" + } + } + ] + } + ] + }, + "gridPos": { + "h": 7, + "w": 8, + "x": 0, + "y": 28 + }, + "id": 8, + "options": { + "legend": { + "calcs": [], + "displayMode": "hidden", + "placement": "bottom" + }, + "tooltip": { + "mode": "multi" + } + }, + "targets": [ + { + "exemplar": true, + "expr": "monero_lastblock_transactions_inputs{quantile=~\"$quantile\"}", + "interval": "", + "legendFormat": "{{ quantile }}", + "refId": "A" + } + ], + "title": "Transaction Inputs", + "transparent": true, + "type": "graph" + }, + { + "datasource": null, + "description": "The distribution of the amount of outputs used in transactions included in this block. \n", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": -1, + "drawStyle": "points", + "fillOpacity": 26, + "gradientMode": "opacity", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 3, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "1" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "dark-purple", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "0.99" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "dark-blue", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "0.95" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "dark-green", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "0.9" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "dark-yellow", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "0.75" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "dark-orange", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "0.5" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "dark-red", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "0.25" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "light-red", + "mode": "fixed" + } + } + ] + } + ] + }, + "gridPos": { + "h": 7, + "w": 8, + "x": 8, + "y": 28 + }, + "id": 9, + "options": { + "legend": { + "calcs": [], + "displayMode": "hidden", + "placement": "bottom" + }, + "tooltip": { + "mode": "multi" + } + }, + "targets": [ + { + "exemplar": true, + "expr": "monero_lastblock_transactions_outputs{quantile=~\"$quantile\"}", + "interval": "", + "legendFormat": "{{ quantile }}", + "refId": "A" + } + ], + "title": "Transaction Outputs", + "transparent": true, + "type": "graph" + }, + { + "datasource": null, + "description": "Difficulty used for mining the last block", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": -1, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "stepBefore", + "lineWidth": 1, + "pointSize": 6, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "sci" + }, + "overrides": [] + }, + "gridPos": { + "h": 7, + "w": 8, + "x": 16, + "y": 28 + }, + "id": 12, + "options": { + "legend": { + "calcs": [], + "displayMode": "hidden", + "placement": "bottom" + }, + "tooltip": { + "mode": "multi" + } + }, + "targets": [ + { + "exemplar": true, + "expr": "monero_lastblock_difficulty", + "interval": "", + "legendFormat": "size", + "refId": "A" + } + ], + "title": "Difficulty", + "transparent": true, + "type": "graph" + } + ], + "title": "Last Block", + "type": "row" + } + ], + "refresh": "1m", + "schemaVersion": 30, + "style": "dark", + "tags": [], + "templating": { + "list": [ + { + "allValue": null, + "current": {}, + "datasource": "prometheus", + "definition": "", + "hide": 0, + "includeAll": false, + "index": -1, + "label": "Quantile", + "multi": false, + "name": "quantile", + "options": [], + "query": "label_values(monero_peerlist_lastseen,quantile)", + "refresh": 1, + "regex": "", + "skipUrlSync": false, + "sort": 1, + "tagValuesQuery": "", + "tags": [], + "tagsQuery": "", + "type": "query", + "useTags": false + } + ] + }, + "time": { + "from": "now-3h", + "to": "now" + }, + "timepicker": { + "refresh_intervals": [ + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ] + }, + "timezone": "", + "title": "Monero", + "uid": "K9dtfZG7z", + "version": 1 +} diff --git a/config/grafana/grafana.ini b/config/grafana/grafana.ini new file mode 100644 index 0000000..bb46eea --- /dev/null +++ b/config/grafana/grafana.ini @@ -0,0 +1,29 @@ +[analytics] +reporting_enabled = false +check_for_updates = false + +[auth] +disable_login_form = false + +; [auth.anonymous] +; enabled = true +; org_role = Admin + +[dashboards] +min_refresh_interval = 1m +default_home_dashboard_path = /var/lib/grafana/dashboards/monero.json + +[paths] +provisioning = /etc/grafana/provisioning + +[server] +root_url = https://127.0.0.1/grafana +enable_gzip = true +read_timeout = 2m + +[snapshots] +external_enabled = false + +[security] +admin_user = admin +admin_password = xmrsh-admin \ No newline at end of file diff --git a/config/grafana/provisioning/dashboards/all.yaml b/config/grafana/provisioning/dashboards/all.yaml new file mode 100644 index 0000000..5a31c91 --- /dev/null +++ b/config/grafana/provisioning/dashboards/all.yaml @@ -0,0 +1,12 @@ +apiVersion: 1 + +providers: + - name: 'fs' + orgId: 1 + folder: '' + type: 'file' + updateIntervalSeconds: 30 + allowUiUpdates: true + options: + path: '/var/lib/grafana/dashboards' + foldersFromFilesStructure: true diff --git a/config/grafana/provisioning/datasources/all.yaml b/config/grafana/provisioning/datasources/all.yaml new file mode 100644 index 0000000..10d9ced --- /dev/null +++ b/config/grafana/provisioning/datasources/all.yaml @@ -0,0 +1,12 @@ +apiVersion: 1 + +datasources: + - name: prometheus + type: prometheus + access: proxy + orgId: 1 + url: http://prometheus:9090 + isDefault: true + version: 1 + editable: false + timeInterval: 30s diff --git a/config/prometheus/config.yaml b/config/prometheus/config.yaml new file mode 100644 index 0000000..555e9e4 --- /dev/null +++ b/config/prometheus/config.yaml @@ -0,0 +1,8 @@ +global: + scrape_interval: "10s" + evaluation_interval: "10s" +scrape_configs: + - job_name: "monerod" + static_configs: + - targets: + - "monero-exporter:9000" diff --git a/data/grafana/.gitignore b/data/grafana/.gitignore new file mode 100644 index 0000000..5e7d273 --- /dev/null +++ b/data/grafana/.gitignore @@ -0,0 +1,4 @@ +# Ignore everything in this directory +* +# Except this file +!.gitignore diff --git a/data/letsencrypt/.gitignore b/data/letsencrypt/.gitignore new file mode 100644 index 0000000..5e7d273 --- /dev/null +++ b/data/letsencrypt/.gitignore @@ -0,0 +1,4 @@ +# Ignore everything in this directory +* +# Except this file +!.gitignore diff --git a/data/monero-lws/.gitignore b/data/monero-lws/.gitignore new file mode 100644 index 0000000..5e7d273 --- /dev/null +++ b/data/monero-lws/.gitignore @@ -0,0 +1,4 @@ +# Ignore everything in this directory +* +# Except this file +!.gitignore diff --git a/data/monero/.gitignore b/data/monero/.gitignore new file mode 100644 index 0000000..5e7d273 --- /dev/null +++ b/data/monero/.gitignore @@ -0,0 +1,4 @@ +# Ignore everything in this directory +* +# Except this file +!.gitignore diff --git a/data/prometheus/.gitignore b/data/prometheus/.gitignore new file mode 100644 index 0000000..5e7d273 --- /dev/null +++ b/data/prometheus/.gitignore @@ -0,0 +1,4 @@ +# Ignore everything in this directory +* +# Except this file +!.gitignore diff --git a/data/tor/.gitignore b/data/tor/.gitignore new file mode 100644 index 0000000..5e7d273 --- /dev/null +++ b/data/tor/.gitignore @@ -0,0 +1,4 @@ +# Ignore everything in this directory +* +# Except this file +!.gitignore diff --git a/docker-compose.le.yml b/docker-compose.le.yml deleted file mode 100644 index 90c7895..0000000 --- a/docker-compose.le.yml +++ /dev/null @@ -1,59 +0,0 @@ -version: "3.7" - -services: - traefik: - image: traefik:${TRAEFIK_TAG} - container_name: traefik - ports: - - 80:80 - - 443:443 - volumes: - - "./letsencrypt:/letsencrypt" - - "/var/run/docker.sock:/var/run/docker.sock:ro" - command: - - "--log.level=${TRAEFIK_LOGLEVEL}" - - "--providers.docker=true" - - "--providers.docker.exposedbydefault=false" - - "--entrypoints.web.address=:80" - - "--entrypoints.web.http.redirections.entryPoint.to=websecure" - - "--entrypoints.web.http.redirections.entryPoint.scheme=https" - - "--entrypoints.web.http.redirections.entrypoint.permanent=true" - - "--entrypoints.websecure.address=:443" - - "--certificatesresolvers.le.acme.httpchallenge=true" - - "--certificatesresolvers.le.acme.httpchallenge.entrypoint=web" - - "--certificatesresolvers.le.acme.email=${TRAEFIK_ACME_EMAIL}" - - "--certificatesresolvers.le.acme.storage=/letsencrypt/acme.json" - restart: always - monerod: - container_name: monerod - image: sethsimmons/simple-monerod:${MONEROD_TAG} - command: >- - --restricted-rpc --public-node --no-igd --no-zmq - --enable-dns-blocklist --rpc-restricted-bind-ip=0.0.0.0 --rpc-restricted-bind-port=18089 --confirm-external-bind - --prune-blockchain - ports: - - "18080:18080" # Exposes P2P port - - "18089" - volumes: - - "monerod-data:/home/monero/.bitmonero" - labels: - - "traefik.enable=true" - - "traefik.http.routers.monerod.rule=(Host(`${DOMAIN}`))" - - "traefik.http.routers.monerod.entrypoints=websecure" - - "traefik.http.routers.monerod.tls.certresolver=le" - - "traefik.http.routers.monerod.service=monerod" - - "traefik.http.services.monerod.loadbalancer.server.port=18089" - - "traefik.http.middlewares.corsheader.headers.accessControlAllowOriginList=*" - - "traefik.http.routers.monerod.middlewares=corsheader" - restart: unless-stopped - - watchtower: - container_name: watchtower - image: containrrr/watchtower - volumes: - - /var/run/docker.sock:/var/run/docker.sock - labels: - - com.centurylinklabs.watchtower.enable="false" - command: --interval 360 --include-stopped -volumes: - monerod-data: {} diff --git a/docker-compose.nole.yml b/docker-compose.nole.yml deleted file mode 100644 index 5a5754d..0000000 --- a/docker-compose.nole.yml +++ /dev/null @@ -1,56 +0,0 @@ -services: - traefik: - image: traefik:${TRAEFIK_TAG} - container_name: traefik - ports: - - 80:80 - - 443:443 - volumes: - - "./letsencrypt:/letsencrypt" - - "/var/run/docker.sock:/var/run/docker.sock:ro" - command: - - "--log.level=${TRAEFIK_LOGLEVEL}" - - "--providers.docker=true" - - "--providers.docker.exposedbydefault=false" - - "--entrypoints.web.address=:80" - - "--entrypoints.web.http.redirections.entryPoint.to=websecure" - - "--entrypoints.web.http.redirections.entryPoint.scheme=https" - - "--entrypoints.web.http.redirections.entrypoint.permanent=true" - - "--entrypoints.websecure.address=:443" - restart: always - monerod: - container_name: monerod - image: sethsimmons/simple-monerod:${MONEROD_TAG} - command: >- - --restricted-rpc --public-node --no-igd --no-zmq - --enable-dns-blocklist --rpc-restricted-bind-ip=0.0.0.0 --rpc-restricted-bind-port=18089 --confirm-external-bind - --prune-blockchain - ports: - - "18080:18080" # Exposes P2P port - - "18089" - volumes: - - "monerod-data:/home/monero/.bitmonero" - labels: - - "traefik.enable=true" - - "traefik.http.routers.monerod.rule=(PathPrefix(`/`))" - - "traefik.http.routers.monerod.entrypoints=websecure" - - "traefik.http.routers.monerod.tls" - - "traefik.http.routers.monerod.service=monerod" - - "traefik.http.services.monerod.loadbalancer.server.port=18089" - - "traefik.http.middlewares.corsheader.headers.accessControlAllowOriginList=*" - - "traefik.http.routers.monerod.middlewares=corsheader" - restart: unless-stopped - - watchtower: - image: containrrr/watchtower - volumes: - - /var/run/docker.sock:/var/run/docker.sock - labels: - - com.centurylinklabs.watchtower.enable="false" - command: --interval 360 --include-stopped -volumes: - monerod-data: {} - -networks: - xmrsh: - name: xmrsh diff --git a/docker-compose.tor.yml b/docker-compose.tor.yml deleted file mode 100644 index 5ff1a71..0000000 --- a/docker-compose.tor.yml +++ /dev/null @@ -1,26 +0,0 @@ -version: "3.7" - -services: - tor: - container_name: tor - image: goldy/tor-hidden-service:${THS_TAG} - links: - - monerod - environment: - MONEROD_TOR_SERVICE_HOSTS: "80:monerod:18089" - volumes: - - tor-keys:/var/lib/tor/hidden_service/ - # secrets: - # - monerod - -volumes: - tor-keys: - {} - # driver: local - -# secrets: -# monerod: -# file: ./private_key_monerod_v3 -networks: - default: - name: ${NETWORK:-xmrsh_default} diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..368b5c4 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,237 @@ +version: "3.7" + +x-log-config: &log-config + logging: + driver: json-file + options: + max-size: "50m" + max-file: "20" + +x-traefik-command-le: &traefik-command-le + command: + - "--log.level=${TRAEFIK_LOGLEVEL}" + - "--providers.docker=true" + - "--providers.docker.exposedbydefault=false" + - "--entrypoints.web.address=:${TRAEFIK_HTTP_PORT}" + - "--entrypoints.web.http.redirections.entryPoint.to=websecure" + - "--entrypoints.web.http.redirections.entryPoint.scheme=https" + - "--entrypoints.web.http.redirections.entrypoint.permanent=true" + - "--entrypoints.websecure.address=:${TRAEFIK_TLS_PORT}" + - "--certificatesresolvers.le.acme.httpchallenge=true" + - "--certificatesresolvers.le.acme.httpchallenge.entrypoint=web" + - "--certificatesresolvers.le.acme.email=${TRAEFIK_ACME_EMAIL}" + - "--certificatesresolvers.le.acme.storage=/letsencrypt/acme.json" + +x-traefik-command-nole: &traefik-command-nole + command: + - "--log.level=${TRAEFIK_LOGLEVEL}" + - "--providers.docker=true" + - "--providers.docker.exposedbydefault=false" + - "--entrypoints.web.address=:${TRAEFIK_HTTP_PORT}" + - "--entrypoints.web.http.redirections.entryPoint.to=websecure" + - "--entrypoints.web.http.redirections.entryPoint.scheme=https" + - "--entrypoints.web.http.redirections.entrypoint.permanent=true" + - "--entrypoints.websecure.address=:${TRAEFIK_TLS_PORT}" + +x-monerod-command: &monerod-command + command: >- + --public-node --no-igd + --enable-dns-blocklist --rpc-restricted-bind-ip=0.0.0.0 + --rpc-restricted-bind-port=${MONEROD_RESTRICTED_RPC_PORT} --confirm-external-bind + --zmq-pub tcp://0.0.0.0:${MONEROD_ZMQ_PUB_PORT} --zmq-rpc-bind-port=${MONEROD_ZMQ_RPC_PORT} --zmq-rpc-bind-ip=0.0.0.0 + --rpc-bind-port=${MONEROD_RPC_PORT} --rpc-bind-ip=0.0.0.0 + ${MONEROD_EXTRA_PARAMS} + +x-tor-service: &tor-service + tor: + container_name: tor + image: vdo1138/tor-hidden-service:${TOR_TAG} + restart: unless-stopped + links: + - monerod + environment: + MONEROD_TOR_SERVICE_HOSTS: "${TOR_HTTP_PORT}:monerod:${MONEROD_RESTRICTED_RPC_PORT}" + volumes: + - ./data/tor:/var/lib/tor/hidden_service/ + <<: *log-config + +x-explorer-service: &explorer-service + explorer: + image: vdo1138/xmrblocks:${EXPLORER_TAG} + container_name: explorer + restart: unless-stopped + volumes: + - ./data/monero:/home/monero/.bitmonero + ports: + - ${EXPLORER_PORT} + depends_on: + - monerod + labels: + - "traefik.enable=true" + - "traefik.http.routers.explorer.rule=(PathPrefix(`/explorer`) )" #!nole + # - "traefik.http.routers.explorer.rule=(Host(`${DOMAIN}`) && PathPrefix(`/explorer`) )" #!le + # - "traefik.http.routers.explorer.tls.certresolver=le" #!le + - "traefik.http.middlewares.stripprefix-explorer.stripprefix.prefixes=/explorer" + - "traefik.http.routers.explorer.middlewares=stripprefix-explorer" + - "traefik.http.routers.explorer.entrypoints=websecure" + - "traefik.http.routers.explorer.tls" + - "traefik.http.routers.explorer.service=explorer" + - "traefik.http.services.explorer.loadbalancer.server.port=${EXPLORER_PORT}" + <<: *log-config + +x-monero-lws-service: &monero-lws-service + monero-lws: + image: vdo1138/monero-lws:${LWS_TAG} + container_name: monero-lws + restart: unless-stopped + security_opt: + - "no-new-privileges:true" + command: >- + --rest-server http://0.0.0.0:8000 --daemon=tcp://monerod:${MONEROD_ZMQ_RPC_PORT} + --sub=tcp://monerod:${MONEROD_ZMQ_PUB_PORT} --log-level=4 + --confirm-external-bind ${LWS_EXTRA_PARAMS} + volumes: + - ./data/monero-lws:/home/monero-lws/.bitmonero/ + depends_on: + - monerod + labels: + - "traefik.enable=true" + - "traefik.http.routers.monero-lws.rule=(PathPrefix(`/lws`) )" #!nole + # - "traefik.http.routers.monero-lws.rule=(Host(`${DOMAIN}`) && PathPrefix(`/lws`) )" #!le + # - "traefik.http.routers.monero-lws.tls.certresolver=le" #!le + - "traefik.http.middlewares.stripprefix-monero-lws.stripprefix.prefixes=/lws" + - "traefik.http.routers.monero-lws.middlewares=stripprefix-monero-lws" + - "traefik.http.routers.monero-lws.entrypoints=websecure" + - "traefik.http.routers.monero-lws.tls" + - "traefik.http.routers.monero-lws.service=monero-lws" + - "traefik.http.services.monero-lws.loadbalancer.server.port=${LWS_PORT}" + <<: *log-config + +x-monero-exporter-service: &monero-exporter-service + monero-exporter: + command: + - --monero-addr=http://monerod:${MONEROD_RPC_PORT} + container_name: monero-exporter + restart: unless-stopped + image: vdo1138/monero-exporter:0.0.2 + <<: *log-config + +x-p2pool-service: &p2pool-service + p2pool: + image: sethsimmons/p2pool:latest + restart: unless-stopped + container_name: p2pool + #tty: true + #stdin_open: true + volumes: + - ./data/p2pool:/home/p2pool + # - /dev/hugepages:/dev/hugepages:rw + ports: + - ${P2POOL_STRATUM_PORT}:${P2POOL_STRATUM_PORT} + - ${P2POOL_P2P_PORT}:${P2POOL_P2P_PORT} + command: >- + --wallet "${P2POOL_WALLET}" + --stratum "0.0.0.0:${P2POOL_STRATUM_PORT}" --p2p "0.0.0.0:${P2POOL_P2P_PORT}" --rpc-port "${MONEROD_RPC_PORT}" + --addpeers "P2POOL_PEERS" --host "monerod" --no-randomx + +x-grafana-service: &grafana-service + grafana: + user: "1000" + command: + - -config=/etc/grafana/grafana.ini + container_name: grafana + restart: unless-stopped + image: grafana/grafana:${GRAFANA_TAG} + ports: + - 3000 + volumes: + - ./data/grafana:/var/lib/grafana + - ./config/grafana/grafana.ini:/etc/grafana/grafana.ini:ro + - ./config/grafana/provisioning:/etc/grafana/provisioning:ro + - ./config/grafana/dashboards:/var/lib/grafana/dashboards:ro + environment: + GF_SECURITY_ADMIN_PASSWORD: ${GF_SECURITY_ADMIN_PASSWORD} + labels: + - "traefik.enable=true" + - "traefik.http.routers.grafana.rule=(PathPrefix(`/grafana`) )" #!nole + # - "traefik.http.routers.grafana.rule=(Host(`${DOMAIN}`) && PathPrefix(`/grafana`) )" #!le + # - "traefik.http.routers.grafana.tls.certresolver=le" #!le + - "traefik.http.middlewares.stripprefix-grafana.stripprefix.prefixes=/grafana" + - "traefik.http.routers.grafana.middlewares=stripprefix-grafana" + - "traefik.http.routers.grafana.entrypoints=websecure" + - "traefik.http.routers.grafana.tls" + - "traefik.http.routers.grafana.service=grafana" + - "traefik.http.services.grafana.loadbalancer.server.port=3000" + <<: *log-config + +x-prometheus-service: &prometheus-service + prometheus: + user: "1000" + command: + - --config.file=/etc/prometheus/config.yaml + - --storage.tsdb.path=/data + - --storage.tsdb.retention.time=30d + container_name: prometheus + restart: unless-stopped + image: prom/prometheus:${PROMETHEUS_TAG} + volumes: + - ./data/prometheus:/data + - ./config/prometheus/config.yaml:/etc/prometheus/config.yaml:ro + <<: *log-config + +x-watchtower-service: &watchtower-service + watchtower: + container_name: watchtower + restart: unless-stopped + image: containrrr/watchtower:latest + volumes: + - /var/run/docker.sock:/var/run/docker.sock + labels: + - com.centurylinklabs.watchtower.enable="false" + command: --interval 360 --include-stopped + <<: *log-config + +services: + traefik: + image: traefik:${TRAEFIK_TAG} + container_name: traefik + ports: + - ${TRAEFIK_HTTP_PORT}:${TRAEFIK_HTTP_PORT} + - ${TRAEFIK_TLS_PORT}:${TRAEFIK_TLS_PORT} + volumes: + - "./data/letsencrypt:/letsencrypt" #!le + - "/var/run/docker.sock:/var/run/docker.sock:ro" + <<: *traefik-command-nole #!traefik-command + restart: always + <<: *log-config + + monerod: + container_name: monerod + image: sethsimmons/simple-monerod:${MONEROD_TAG} + <<: *monerod-command + ports: + - "${MONEROD_P2P_PORT}:${MONEROD_P2P_PORT}" # Exposes P2P port + volumes: + - "./data/monero:/home/monero/.bitmonero" + labels: + - "traefik.enable=true" + # - "traefik.http.routers.monerod.rule=(Host(`${DOMAIN}`) && PathPrefix(`/`))" #!le + # - "traefik.http.routers.monerod.tls.certresolver=le" #!le + - "traefik.http.routers.monerod.rule=(PathPrefix(`/`))" #!nole + - "traefik.http.routers.monerod.entrypoints=websecure" + - "traefik.http.routers.monerod.tls" + - "traefik.http.routers.monerod.service=monerod" + - "traefik.http.services.monerod.loadbalancer.server.port=${MONEROD_RESTRICTED_RPC_PORT}" + # - "traefik.http.middlewares.corsheader.headers.accessControlAllowOriginList=${MONEROD_accessControlAllowOriginList}" #!cors + # - "traefik.http.routers.monerod.middlewares=corsheader" #!cors + restart: unless-stopped + <<: *log-config + + # <<: *tor-service #!tor + # <<: *explorer-service #!explorer + # <<: *monero-lws-service #!lws + # <<: *monero-exporter-service #!monero-exporter + # <<: *p2pool-service #!p2pool + # <<: *grafana-service #!grafana + # <<: *prometheus-service #!prometheus + # <<: *watchtower-service #!watchtower diff --git a/install b/install new file mode 100755 index 0000000..aca7cb7 --- /dev/null +++ b/install @@ -0,0 +1,480 @@ +#!/bin/bash + +################################################################ +# Colors # +################################################################ +# Reset +Off='\033[0m' # Text Reset + +# Regular Colors +Red='\033[0;31m' # Red +Green='\033[0;32m' # Green +Yellow='\033[0;33m' # Yellow +Purple='\033[0;35m' # Purple +White='\033[0;37m' # White + +# Background +On_Black='\033[40m' # Black + +OkBullet="${Green}${On_Black}:: ${White}${On_Black}" +WarnBullet="${Yellow}${On_Black}:: ${White}${On_Black}" +ErrBullet="${Red}${On_Black}:: ${White}${On_Black}" +Ok="${Green}${On_Black} ok.${Off}" +Fail="${Red}${On_Black} failed!${Off}" +Nok="${Yellow}${On_Black} nok.${Off}" +Stat="${Purple}${On_Black}" +StatInfo="${White}${On_Black}" + +################################################################ +# Vars # +################################################################ +VERSION="v0.4.0" +XMRSH_INSTALL_CMD="sudo bash -c \"\$(curl -sLSf https://get.xmr.sh)\"" +XMRSH_DIR="/opt/xmr.sh" +XMRSH_BRANCH="main" +XMRSH_URL="https://github.com/vdo/xmr.sh" +XMRSH_LOG_FILE="/tmp/xmr.sh-$(date +%Y%m%d-%H%M%S).log" +DOCKER_INSTALLED=false +DOCKER_COMPOSE_INSTALLED=false +DOCKER_COMPOSE_VERSION="v2.5.0" +DEPENDENCIES="git curl" +ONION="Not Available" +TLS_PORT="443" +TLS_DOMAIN="" +TLS_EMAIL="" +NETWORK="mainnet" +ENABLE_GRAFANA="" + +################################################################ +# Functions # +################################################################ + +header() { + echo -e "${Red}${On_Black} _ " + echo -e "__ ___ __ ___ _ __ ___| |__ " + echo -e "\ \/ / '_ ' _ \| '__/ __| '_ \ " + echo -e " > <| | | | | | | _\__ \ | | |" + echo -e "/_/\_\_| |_| |_|_|(_)___/_| |_|" + echo -e " Version ${VERSION}${Off}\n" +} + +detect_root() { + echo -ne "${OkBullet}Checking root... ${Off}" + if [[ $EUID -ne 0 ]]; then + echo -e "${Fail}" + echo -e "${ErrBullet}You need to run this script as root (UID=0).${Off}" + exit 1 + fi + echo -e "${Ok}" +} + +detect_pipe() { + echo -ne "${OkBullet}Checking script execution... ${Off}" + if [ -p /dev/stdin ]; then + echo -e "${Fail}" + echo -e "${ErrBullet}This script can't be piped! Instead, use the command: ${XMRSH_INSTALL_CMD}${Off}" + exit 1 + fi + echo -e "${Ok}" +} + +check_deps() { + echo -ne "${OkBullet}Checking and installing dependencies... ${Off}" + # shellcheck disable=SC2068 + for pkg in ${DEPENDENCIES[@]}; do + if ! command -v "${pkg}" >>"${XMRSH_LOG_FILE}" 2>&1; then + install_pkg "${pkg}" + check_return $? + fi + done + echo -e "${Ok}" +} + +install_pkg() { + # This detects both ubuntu and debian + if grep -q "debian" /etc/os-release; then + apt-get update >>"${XMRSH_LOG_FILE}" 2>&1 + apt-get install -y "$1" >>"${XMRSH_LOG_FILE}" 2>&1 + elif grep -q "fedora" /etc/os-release || grep -q "centos" /etc/os-release; then + dnf install -y "$1" >>"${XMRSH_LOG_FILE}" 2>&1 + else + echo -e "${ErrBullet}Cannot detect your distribution package manager.${Off}" + exit 1 + fi +} + +detect_curl() { + echo -ne "${OkBullet}Checking curl... ${Off}" + # docker --version >>"${XMRSH_LOG_FILE}" 2>&1 | grep -q "Docker version" + if curl --version >>"${XMRSH_LOG_FILE}" 2>&1; then + echo -e "${Ok}" + else + echo -e "${Nok}" + echo -e "${ErrBullet}Please install curl first.${Off}" + exit 1 + fi +} + +detect_docker() { + echo -ne "${OkBullet}Checking docker... ${Off}" + if docker --version >>"${XMRSH_LOG_FILE}" 2>&1; then + DOCKER_INSTALLED=true + echo -e "${Ok}" + else + echo -e "${Nok}" + fi +} + +detect_docker_compose() { + echo -ne "${OkBullet}Checking docker compose... ${Off}" + if docker-compose --version >>"${XMRSH_LOG_FILE}" 2>&1; then + DOCKER_COMPOSE_INSTALLED=true + echo -e "${Ok}" + else + echo -e "${Nok}" + fi +} + +install_docker() { + echo -ne "${OkBullet}Installing docker... ${Off}" + # Docker Installer as provided in + curl -fsSL https://get.docker.com -o - | bash >>"${XMRSH_LOG_FILE}" 2>&1 + check_return $? + # Fedora and Centos need to enable & start the daemon + if grep -q "fedora" /etc/os-release || grep -q "centos" /etc/os-release; then + systemctl enable docker >>"${XMRSH_LOG_FILE}" 2>&1 + systemctl start docker >>"${XMRSH_LOG_FILE}" 2>&1 + fi + echo -e "${Ok}" +} + +install_docker_compose() { + echo -ne "${OkBullet}Installing compose... ${Off}" + # Install docker-compose binary, even if "docker compose" exists, for consistency. + curl -SL "https://github.com/docker/compose/releases/download/${DOCKER_COMPOSE_VERSION}/docker-compose-linux-$(uname -m)" -o /usr/local/bin/docker-compose >>"${XMRSH_LOG_FILE}" 2>&1 + check_return $? + chmod +x /usr/local/bin/docker-compose >>"${XMRSH_LOG_FILE}" 2>&1 + check_return $? + echo -e "${Ok}" +} + +install_xmrsh() { + echo -ne "${OkBullet}Installing xmr.sh... ${Off}" + if [ ! -d "$XMRSH_DIR" ]; then + git clone -b "${XMRSH_BRANCH}" "${XMRSH_URL}" "${XMRSH_DIR}" >>"${XMRSH_LOG_FILE}" 2>&1 + check_return $? + pushd "${XMRSH_DIR}" >>"${XMRSH_LOG_FILE}" 2>&1 || return + chown -R "1000:1000" ./data >>"${XMRSH_LOG_FILE}" 2>&1 + check_return $? + else + echo -e "${Ok}" + echo -e "${ErrBullet}Error: xmr.sh already present in ${XMRSH_DIR}. Run the uninstall script first." + exit 1 + fi + echo -e "${Ok}" +} + +configure_network() { + echo -e "${OkBullet}Select the desired node network (mainnet, testnet, stagenet)" + PS3=":: Enter a number: " + options=("mainnet" "testnet" "stagenet") + select opt in "${options[@]}"; do + case $opt in + "mainnet") + break + ;; + "testnet") + NETWORK="testnet" + sed -i "s/MONEROD_P2P_PORT=.*/MONEROD_P2P_PORT=28080/g" .env + sed -i "/MONEROD_EXTRA_PARAMS/s/$/ --testnet/g" .env + sed -i "/LWS_EXTRA_PARAMS/s/$/ --network test/g" .env + break + ;; + "stagenet") + NETWORK="stagenet" + sed -i "s/MONEROD_P2P_PORT=.*/MONEROD_P2P_PORT=38080/g" .env + sed -i "/MONEROD_EXTRA_PARAMS/s/$/ --stagenet/g" .env + sed -i "/LWS_EXTRA_PARAMS/s/$/ --network stage/g" .env + break + ;; + *) echo "Invalid network choice!" ;; + esac + done +} + +configure_tls_domain() { + echo -e "${OkBullet}Enter the desired domain for the Let's Encrypt SSL certificate." + read -r -e -p " Leave empty to use a self signed certificate []: " TLS_DOMAIN + if [ -n "${TLS_DOMAIN}" ]; then + while ! echo "${TLS_DOMAIN}" | grep -qP '(?=^.{5,254}$)(^(?:(?!\d+\.)[a-zA-Z0-9_\-]{1,63}\.?)+(?:[a-zA-Z]{2,})$)'; do + echo -e "${WarnBullet}Domain not valid." + read -r -p " Enter again your desired domain []: " TLS_DOMAIN + done + echo -e "${OkBullet}Enter the desired email for the Let's Encrypt SSL certificate." + read -r -e -p " Enter a valid email. Let's Encrypt validates it! []: " TLS_EMAIL + while ! echo "${TLS_EMAIL}" | grep -qP '^[A-Za-z0-9+._-]+@([a-zA-Z0-9-]+\.)+[a-zA-Z]{2,6}$'; do + echo -e "${WarnBullet}Email not valid." + read -r -p " Enter again your desired email []: " TLS_EMAIL + done + # Set domain and email address in vars + sed -i "s/DOMAIN=.*/DOMAIN=${TLS_DOMAIN}/g" .env + sed -i "s/TRAEFIK_ACME_EMAIL=.*/TRAEFIK_ACME_EMAIL=${TLS_EMAIL}/g" .env + # Enable Let's Encrypt settings in compose + sed -i '/#!le/s/# //g' docker-compose.yml + sed -i '/#!nole/s/- /# - /g' docker-compose.yml + sed -i "/#\!traefik-command/s/\*traefik-command-nole/\*traefik-command-le/g" docker-compose.yml + fi +} + +configure_tls_port() { + echo -e "${OkBullet}Enter the desired TLS/HTTPS port." + read -r -e -p " Leave empty to use the default [443]: " TLS_PORT + if [ -n "${TLS_PORT}" ]; then + while ! echo "${TLS_PORT}" | grep -qP '^([1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])$'; do + echo -e "${WarnBullet}Port not valid." + read -r -p " Enter again your desired port: " TLS_PORT + done + # Set port in vars + sed -i "s/TRAEFIK_TLS_PORT=.*/TRAEFIK_TLS_PORT=${TLS_PORT}/g" .env + else + TLS_PORT="443" + fi +} + +configure_pruning() { + echo -e "${OkBullet}Configuring pruning..." + while true; do + read -r -e -p " Do you want to enable blockchain pruning? [y/n]: " yn + case $yn in + [Yy]*) + sed -i "/MONEROD_EXTRA_PARAMS/s/$/ --prune-blockchain/g" .env + break + ;; + [Nn]*) break ;; + *) echo " Please answer yes or no." ;; + esac + done +} + +configure_cors() { + echo -e "${OkBullet}Configuring CORS..." + while true; do + read -r -e -p " Do you want to enable CORS headers so the node can be used in web apps? [y/n]: " yn + case $yn in + [Yy]*) + sed -i '/#!cors/s/# //g' docker-compose.yml + break + ;; + [Nn]*) break ;; + *) echo " Please answer yes or no." ;; + esac + done +} + +configure_tor() { + echo -e "${OkBullet}Configuring tor..." + while true; do + read -r -e -p " Do you want to enable a Tor hidden service? [y/n]: " yn + case $yn in + [Yy]*) + sed -i '/#!tor/s/# //g' docker-compose.yml + ENABLE_TOR=true + break + ;; + [Nn]*) break ;; + *) echo " Please answer yes or no." ;; + esac + done +} + +configure_explorer() { + echo -e "${OkBullet}Configuring explorer..." + while true; do + read -r -e -p " Do you want to enable an explorer service? [y/n]: " yn + case $yn in + [Yy]*) + sed -i '/#!explorer/s/# //g' docker-compose.yml + ENABLE_EXPLORER=true + break + ;; + [Nn]*) break ;; + *) echo " Please answer yes or no." ;; + esac + done +} + +configure_lws() { + echo -e "${OkBullet}Configuring LWS..." + while true; do + read -r -e -p " Do you want to enable the light wallet service (experimental)? [y/n]: " yn + case $yn in + [Yy]*) + sed -i '/#!lws/s/# //g' docker-compose.yml + ENABLE_LWS=true + break + ;; + [Nn]*) break ;; + *) echo " Please answer yes or no." ;; + esac + done +} + +configure_p2pool() { + echo -e "${OkBullet}Configuring p2pool..." + while true; do + read -r -e -p " Do you want to enable the p2pool service? [y/n]: " yn + case $yn in + [Yy]*) + read -r -e -p " Enter the desired primary address which will recieve the rewards. []: " P2P_ADDRESS + while ! echo "${P2P_ADDRESS}" | grep -qP '(4|5|9|A)[a-zA-Z|\d]{94}'; do + echo -e "${WarnBullet}Address is not valid. Remember: subaddresses are not supported by p2pool." + read -r -p " Enter again your primary address: " P2P_ADDRESS + done + sed -i "s/P2POOL_WALLET=.*/P2POOL_WALLET=${P2P_ADDRESS}/g" .env + sed -i '/#!p2pool/s/# //g' docker-compose.yml + ENABLE_P2POOL=true + break + ;; + [Nn]*) break ;; + *) echo " Please answer yes or no." ;; + esac + done +} + +configure_grafana() { + echo -e "${OkBullet}Configuring grafana..." + while true; do + read -r -e -p " Do you want to enable a grafana monitoring dashboard? [y/n]: " yn + case $yn in + [Yy]*) + ENABLE_GRAFANA=true + sed -i '/#!monero-exporter/s/# //g' docker-compose.yml + sed -i '/#!grafana/s/# //g' docker-compose.yml + sed -i '/#!prometheus/s/# //g' docker-compose.yml + GRAFANA_PASSWORD="$(openssl rand -base64 9 | tr '\/' '-')" + sed -i "s/GF_SECURITY_ADMIN_PASSWORD=.*/GF_SECURITY_ADMIN_PASSWORD=${GRAFANA_PASSWORD}/g" .env + break + ;; + [Nn]*) break ;; + *) echo " Please answer yes or no." ;; + esac + done +} + +configure_watchtower() { + echo -e "${OkBullet}Configuring watchtower..." + while true; do + read -r -e -p " Do you want to enable automatic node updates using watchtower? [y/n]: " yn + case $yn in + [Yy]*) + sed -i '/#!watchtower/s/# //g' docker-compose.yml + break + ;; + [Nn]*) break ;; + *) echo " Please answer yes or no." ;; + esac + done +} + +# get_public_ip() { +# # Using dig: +# # dig +short txt ch whoami.cloudflare @1.0.0.1 +# PUBLIC_IP=$(curl -s ifconfig.co) +# } + +start_xmrsh() { + echo -ne "${OkBullet}Starting monero node and services... ${Off}" + docker-compose pull >>"${XMRSH_LOG_FILE}" 2>&1 + check_return $? + docker-compose up -d >>"${XMRSH_LOG_FILE}" 2>&1 + check_return $? + if [[ $ENABLE_TOR == true ]]; then + sleep 4 + ONION=$(docker logs tor 2>&1 | grep Entrypoint | cut -d " " -f 8) + fi + echo -e "${Ok}" +} + +check_return() { + if [ "$1" -ne 0 ]; then + echo -e "${Fail}" + echo -e "${ErrBullet}Installation failed. Check the logs in ${XMRSH_LOG_FILE}${Off}" + exit "$1" + fi +} + +completed() { + echo -e "${OkBullet}Deployment complete.${Off}" + PUBLIC_IP=$(curl -4 -s ifconfig.co 2>>"${XMRSH_LOG_FILE}") + if [ -n "$TLS_DOMAIN" ]; then + HOST="${TLS_DOMAIN}" + else + HOST="${PUBLIC_IP}" + fi + if [[ $TLS_PORT == "443" ]]; then + PORT_SUFF="" + else + PORT_SUFF=":${TLS_PORT}" + fi + echo + echo -e " ${Red}┌───────────────────────────────────────────────────────────────────────────[info]──" + echo -e " ${Red}│${Stat} Network: ${StatInfo}${NETWORK}" + echo -e " ${Red}│${Stat} Public URL: ${StatInfo}https://${HOST}${PORT_SUFF}" + + echo -e " ${Red}│${Stat} Public IP: ${StatInfo}${PUBLIC_IP}" + if [ "$ENABLE_TOR" = true ]; then + echo -e " ${Red}│${Stat} Onion Service: ${StatInfo}$ONION" + fi + if [ "$ENABLE_EXPLORER" = true ]; then + echo -e " ${Red}│${Stat} Explorer URL: ${StatInfo}https://${HOST}${PORT_SUFF}/explorer" + fi + if [ "$ENABLE_LWS" = true ]; then + echo -e " ${Red}│${Stat} LWS URL: ${StatInfo}https://${HOST}${PORT_SUFF}/lws" + fi + if [ "$ENABLE_P2POOL" = true ]; then + echo -e " ${Red}│${Stat} P2Pool stratum: ${StatInfo}${HOST}:3333" + fi + if [ "$ENABLE_GRAFANA" = true ]; then + echo -e " ${Red}│${Stat} Grafana URL: ${StatInfo}https://${HOST}${PORT_SUFF}/grafana" + echo -e " ${Red}│${Stat} Grafana user: ${StatInfo}admin" + echo -e " ${Red}│${Stat} Grafana password: ${StatInfo}${GRAFANA_PASSWORD}" + fi + echo -e " ${Red}│${Stat} Project files installed in: ${StatInfo}${XMRSH_DIR}" + echo -e " ${Red}│${Off}" + echo +} + +header +detect_root +detect_pipe +check_deps +detect_docker +detect_docker_compose + +if [ $DOCKER_INSTALLED = false ]; then + install_docker + install_docker_compose +fi + +if [ $DOCKER_INSTALLED = true ] && [ $DOCKER_COMPOSE_INSTALLED = false ]; then + install_docker_compose +fi + +install_xmrsh +configure_network +configure_tls_domain +configure_tls_port +configure_pruning +configure_cors +configure_tor +configure_lws +configure_p2pool +# Deployment of explorer disabled until it's stable. +# configure_explorer +configure_grafana +configure_watchtower + +start_xmrsh +completed + +exit 0 diff --git a/installer.sh b/installer.sh deleted file mode 100755 index e06ba92..0000000 --- a/installer.sh +++ /dev/null @@ -1,239 +0,0 @@ -#!/bin/bash - -################################################################ -# Color Aliases # -################################################################ -# Reset -Off='\033[0m' # Text Reset - -# Regular Colors -Black='\033[0;30m' # Black -Red='\033[0;31m' # Red -Green='\033[0;32m' # Green -Yellow='\033[0;33m' # Yellow -Blue='\033[0;34m' # Blue -Purple='\033[0;35m' # Purple -Cyan='\033[0;36m' # Cyan -White='\033[0;37m' # White - -# Bold -BBlack='\033[1;30m' # Black -BRed='\033[1;31m' # Red -BGreen='\033[1;32m' # Green -BYellow='\033[1;33m' # Yellow -BBlue='\033[1;34m' # Blue -BPurple='\033[1;35m' # Purple -BCyan='\033[1;36m' # Cyan -BWhite='\033[1;37m' # White - -# Underline -UBlack='\033[4;30m' # Black -URed='\033[4;31m' # Red -UGreen='\033[4;32m' # Green -UYellow='\033[4;33m' # Yellow -UBlue='\033[4;34m' # Blue -UPurple='\033[4;35m' # Purple -UCyan='\033[4;36m' # Cyan -UWhite='\033[4;37m' # White - -# Background -On_Black='\033[40m' # Black -On_Red='\033[41m' # Red -On_Green='\033[42m' # Green -On_Yellow='\033[43m' # Yellow -On_Blue='\033[44m' # Blue -On_Purple='\033[45m' # Purple -On_Cyan='\033[46m' # Cyan -On_White='\033[47m' # White - -OkBullet="${OnBlack}${Green}:: ${White}" -WarnBullet="${OnBlack}${Yellow}:: ${White}" -ErrBullet="${OnBlack}${Red}:: ${White}" -Ok="${OnBlack}${Green} ok.${Off}" -Fail="${OnBlack}${Red} failed!${Off}" -Nok="${OnBlack}${Yellow} nok.${Off}" - -################################################################ -# Vars # -################################################################ -VERSION="v0.1.0" -XMRSH_DIR="/opt/xmr.sh" -XMRSH_LOG_FILE="/tmp/xmr.sh-$(date +%Y%m%d-%H%M%S).log" -DOCKER_INSTALLED=false -DOCKER_COMPOSE_INSTALLED=false -DOCKER_COMPOSE_VERSION="v2.5.0" -DEPENDENCIES="git curl" - -################################################################ -# Functions # -################################################################ - -header() { - echo -e "${OnBlack}${Red} _ " - echo -e "__ ___ __ ___ _ __ ___| |__ " - echo -e "\ \/ / '_ ' _ \| '__/ __| '_ \ " - echo -e " > <| | | | | | | _\__ \ | | |" - echo -e "/_/\_\_| |_| |_|_|(_)___/_| |_|" - echo -e " Version ${VERSION}${Off}\n" -} - -detect_root() { - echo -ne "${OkBullet}Checking root... ${Off}" - if [[ $EUID -ne 0 ]]; then - echo -e "${Fail}" - echo -e "${ErrBullet}You need to run this script as root (UID=0).${Off}" - exit 1 - fi - echo -e "${Ok}" -} - -check_deps() { - echo -ne "${OkBullet}Checking and installing dependencies... ${Off}" - for pkg in ${DEPENDENCIES[@]}; do - if ! which ${pkg} >>"${XMRSH_LOG_FILE}" 2>&1; then - install_pkg ${pkg} - check_return $? - fi - done - echo -e "${Ok}" -} - -install_pkg() { - # This detects both ubuntu and debian - if grep -q "debian" /etc/os-release; then - apt-get update >>"${XMRSH_LOG_FILE}" 2>&1 - apt-get install -y $1 >>"${XMRSH_LOG_FILE}" 2>&1 - elif grep -q "fedora" /etc/os-release || grep -q "centos" /etc/os-release; then - dnf install -y $1 >>"${XMRSH_LOG_FILE}" 2>&1 - else - echo -e "${ErrBullet}Cannot detect your distribution package manager.${Off}" - exit 1 - fi -} - -detect_curl() { - echo -ne "${OkBullet}Checking curl... ${Off}" - # docker --version >>"${XMRSH_LOG_FILE}" 2>&1 | grep -q "Docker version" - if curl --version >>"${XMRSH_LOG_FILE}" 2>&1; then - echo -e "${Ok}" - else - echo -e "${Nok}" - echo -e "${ErrBullet}Please install curl first.${Off}" - exit 1 - fi -} - -detect_docker() { - echo -ne "${OkBullet}Checking docker... ${Off}" - # docker --version >>"${XMRSH_LOG_FILE}" 2>&1 | grep -q "Docker version" - if docker --version >>"${XMRSH_LOG_FILE}" 2>&1; then - DOCKER_INSTALLED=true - echo -e "${Ok}" - else - echo -e "${Nok}" - fi -} - -detect_docker_compose() { - echo -ne "${OkBullet}Checking docker compose... ${Off}" - #docker-compose --version >>"${XMRSH_LOG_FILE}" 2>&1 | grep -q "Docker Compose version" - if docker-compose --version >>"${XMRSH_LOG_FILE}" 2>&1; then - DOCKER_COMPOSE_INSTALLED=true - echo -e "${Ok}" - else - echo -e "${Nok}" - fi -} - -install_docker() { ( - echo -ne "${OkBullet}Installing docker... ${Off}" - # Docker Installer as provided in - curl -fsSL https://get.docker.com -o - | bash >>"${XMRSH_LOG_FILE}" 2>&1 - check_return $? - # Fedora and Centos need to enable & start the daemon - if grep -q "fedora" /etc/os-release || grep -q "centos" /etc/os-release; then - systemctl enable docker >>"${XMRSH_LOG_FILE}" 2>&1 - systemctl start docker >>"${XMRSH_LOG_FILE}" 2>&1 - fi - echo -e "${Ok}" -); } - -install_docker_compose() { - echo -ne "${OkBullet}Installing compose... ${Off}" - # Install docker-compose binary, even if "docker compose" exists, for consistency. - curl -SL "https://github.com/docker/compose/releases/download/${DOCKER_COMPOSE_VERSION}/docker-compose-linux-$(uname -m)" -o /usr/local/bin/docker-compose >>"${XMRSH_LOG_FILE}" 2>&1 - check_return $? - chmod +x /usr/local/bin/docker-compose >>"${XMRSH_LOG_FILE}" 2>&1 - check_return $? - echo -e "${Ok}" -} - -install_xmrsh() { - echo -ne "${OkBullet}Installing xmr.sh... ${Off}" - if [ ! -d "$XMRSH_DIR" ]; then - git clone https://github.com/vdo/xmr.sh "${XMRSH_DIR}" >>"${XMRSH_LOG_FILE}" 2>&1 - check_return $? - else - echo -e "${Ok}" - echo -e "${WarnBullet}Warning: xmr.sh already present in ${XMRSH_DIR}" - return - fi - echo -e "${Ok}" -} - -start_xmrsh() { - pushd "${XMRSH_DIR}" >>"${XMRSH_LOG_FILE}" 2>&1 - cp docker-compose.nole.yml docker-compose.yml ## FIXME: Temporal deploy w/o Let's Encrypt - echo -ne "${OkBullet}Starting monero node... ${Off}" - docker-compose pull >>"${XMRSH_LOG_FILE}" 2>&1 - check_return $? - docker-compose up -d >>"${XMRSH_LOG_FILE}" 2>&1 - check_return $? - echo -e "${Ok}" -} - -start_xmrsh_tor() { - pushd "${XMRSH_DIR}" >>"${XMRSH_LOG_FILE}" 2>&1 - echo -ne "${OkBullet}Starting tor hidden service... ${Off}" - docker-compose -f docker-compose.yml -f docker-compose.tor.yml up -d >>"${XMRSH_LOG_FILE}" 2>&1 - check_return $? - sleep 3 - ONION=$(docker logs tor 2>&1 | grep Entrypoint | cut -d " " -f 8) - echo -e "${Ok}" - echo -e "${OkBullet}Tor hidden service ready at: ${ONION} ${Off}" -} - -check_return() { - if [ $1 -ne 0 ]; then - echo -e "${Fail}" - echo -e "${ErrBullet}Installation failed. Check the logs in ${XMRSH_LOG_FILE}${Off}" - exit "$1" - fi -} - -completed() { - # FIXME: Show domain / public IP - echo -e "${OkBullet}Deployment complete!!${Off}" -} - -header -detect_root -check_deps -detect_docker -detect_docker_compose - -if [ $DOCKER_INSTALLED = false ]; then - install_docker - install_docker_compose -fi - -if [ $DOCKER_INSTALLED = true ] && [ $DOCKER_COMPOSE_INSTALLED = false ]; then - install_docker_compose -fi - -install_xmrsh -start_xmrsh -start_xmrsh_tor -completed - -exit 0 diff --git a/monero-lws-admin b/monero-lws-admin new file mode 100755 index 0000000..4627df9 --- /dev/null +++ b/monero-lws-admin @@ -0,0 +1,2 @@ +#!/bin/bash +docker exec -ti monero-lws /usr/local/bin/monero-lws-admin ${@} diff --git a/uninstall b/uninstall new file mode 100755 index 0000000..47c79ff --- /dev/null +++ b/uninstall @@ -0,0 +1,86 @@ +#!/bin/bash + +################################################################ +# Colors # +################################################################ +# Reset +Off='\033[0m' # Text Reset + +# Regular Colors +Red='\033[0;31m' # Red +Green='\033[0;32m' # Green +#Yellow='\033[0;33m' # Yellow +#Purple='\033[0;35m' # Purple +White='\033[0;37m' # White + +# Background +On_Black='\033[40m' # Black + +OkBullet="${Green}${On_Black}:: ${White}${On_Black}" +#WarnBullet="${Yellow}${On_Black}:: ${White}${On_Black}" +ErrBullet="${Red}${On_Black}:: ${White}${On_Black}" +Ok="${Green}${On_Black} ok.${Off}" +Fail="${Red}${On_Black} failed!${Off}" +#Nok="${Yellow}${On_Black} nok.${Off}" + +################################################################ +# Vars # +################################################################ + +XMRSH_DIR="/opt/xmr.sh" +XMRSH_LOG_FILE="/tmp/xmr.sh-$(date +%Y%m%d-%H%M%S).log" + +################################################################ +# Functions # +################################################################ + +check_root() { + echo -ne "${OkBullet}Checking root... ${Off}" + if [[ $EUID -ne 0 ]]; then + echo -e "${Fail}" + echo -e "${ErrBullet}You need to run this script as root (UID=0).${Off}" + exit 1 + fi + echo -e "${Ok}" +} + +check_return() { + if [ "$1" -ne 0 ]; then + echo -e "${Fail}" + echo -e "${ErrBullet}Installation failed. Check the logs in ${XMRSH_LOG_FILE}${Off}" + exit "$1" + fi +} + +uninstall() { + pushd $XMRSH_DIR >>"${XMRSH_LOG_FILE}" 2>&1 || check_return $? + echo -e "${OkBullet}Uninstalling xmr.sh..." + if [ -f docker-compose.yml ]; then + docker-compose down >>"${XMRSH_LOG_FILE}" 2>&1 + fi + check_return $? + while true; do + read -r -e -p " Do you want to keep the data directory with the blockchain and other data files? [y/n]: " yn + case $yn in + [Yy]*) + find . -type f -not -name 'data' -print0 | xargs -0 -I {} rm {} + check_return $? + popd >>"${XMRSH_LOG_FILE}" 2>&1 || check_return $? + break + ;; + [Nn]*) + popd >>"${XMRSH_LOG_FILE}" 2>&1 || check_return $? + rm -rf "${XMRSH_DIR}" + check_return $? + break + ;; + *) echo " Please answer yes or no." ;; + esac + done + echo -e "${OkBullet}Uninstall complete." +} + +check_root +uninstall + +exit 0