New Readme

Added config for default O to backend
Modified grafana scaling
This commit is contained in:
Marco van Dijk 2022-03-06 14:16:10 +01:00
parent 9f1a06a1c6
commit 1eb2d709d2
4 changed files with 153 additions and 41 deletions

175
README
View File

@ -1,36 +1,151 @@
Setup VPS What
Install pm2, nodejs, nginx, certbot, certbot-nginx, npm This project shows a live feed of events happening on the Livepeer BondingManager smart contract. This way it is able to track:
git clone https://github.com/stronk-dev/LivepeerEvents.git /var/www - (De)activations of Orchestrators on the Livepeer network
cd /var/www - Orchestrators calling reward
npm install - Orchestrators updating their commission rates
cd /var/www/backend - Delegators earning staking and fee rewards
npm install - Delegators delegating or moving their delegated stake
nano /var/www/backend/src/config.js to your liking - Delegators unbonding their stake
replace /etc/nginx/nginx.conf with supplied one, certbot will upgrade it to HTTPS
systemctl enable --now nginx.service
certbot --nginx
Connect Backend Orchestrators can be inspected by clicking on their address, showing all of their delegators, earned fees and stake
cd /var/www/backend
pm2 start ecosystem.config.js --env production
pm2 save
pm2 startup
Monitor Backend
pm2 log backend
pm2 stop backend
pm2 start backend
Run in test environment: API endpoints:
Run backend as 'npm run dev' - https://nframe.nl/api/livepeer/grafana
Run frontend as 'npm start' - Returns a JSON object of top 200 coin data, as well as gas fees and contract prices
- https://nframe.nl/api/livepeer/cmc
- Returns a JSON object of the raw data of the top 200 coins
- https://nframe.nl/api/livepeer/blockchains
- Returns a JSON object of gas fees and livepeer contract fees on L1 and L2
- https://nframe.nl/api/livepeer/quotes
- Returns a JSON object of top 200 coint data by coin symbol
- https://nframe.nl/api/livepeer/getEvents
- Returns a JSON object of the raw data of all events on the Livepeer BondingManager contract
- https://nframe.nl/api/livepeer/getEvents
- Returns a JSON object of the raw data of all events on the Livepeer BondingManager contract
- https://nframe.nl/api/livepeer/getEvents
- POST request with orchAddr in the body
- https://www.nframe.nl/livepeer?orchAddr=0x847791cbf03be716a7fe9dc8c9affe17bd49ae5e
- GET requests with the orchAddr as URL parameter
- Returns a JSON object of the current data on the given Orchestrator
- https://www.nframe.nl/livepeer/
- Returns a JSON object of the Orchestrator selected in the backend
Update frontend production: How
cd /var/www
git pull
npm run build
Update backend production
pm2 restart backend
pm2 start ecosystem.config.js --env production
Frontend
The frontend can be used on it's own as a basis for hosting your own Orchestrator website
By default the website will forward all API requests to http://localhost:42609
Meaning, it will look for the backend at the same place where the website is running!
If you want to run this frontend without running your own backend, you have to configure it to always pull it's data from the existing API at https://nframe.nl/
Modify package.json to do this
- Edit the line containing "proxy": "http://localhost:42609" and replace "http://localhost:42609" with "http://localhost:42609"
Dependencies
nginx, certbot, certbot-nginx, npm
HTTPS using nginx
- replace /etc/nginx/nginx.conf with supplied one, certbot will upgrade it to HTTPS
- systemctl enable --now nginx.service
- certbot --nginx
Initial Config
Download copy of repository and change directory to it
- git clone https://github.com/stronk-dev/LivepeerEvents.git /var/www
- cd /var/www
Download all external dependencies we are using
- npm install
Edit default Orchestrator Address
If you are not running your own backend, by default the backend will return my Orchestrator
In order to show your own Orchestrator on the Grafana page, you need to edit src/util/livepeer.js
Edit the line containing:
export const getCurrentOrchestratorInfo = () => (
fetch("api/livepeer/getOrchestrator", {
method: "GET",
headers: {
"Content-Type": "application/json"
}
})
);
And change this to (replace with your own address):
export const getCurrentOrchestratorInfo = () => (
fetch("api/livepeer/getOrchestrator/0x847791cbf03be716a7fe9dc8c9affe17bd49ae5e", {
method: "GET",
headers: {
"Content-Type": "application/json"
}
})
);
All Grafana panels point towards where I am hosting my own Grafana dashboard. You need to edit this to pull the panels from your own Grafana instance
For each panel you want to replace:
- Open your own Grafana page
- Click on the menu of any Panel and click share
- Open the Embed tab
- Copy the entire Embed HTML bit
- Edit src/grafana.js:
- Replace any <iframe/> block with the one you copied and edit the height to your liking. The width parameter can be left out so that they scale to the width of the parent element
Note that you can specify the timerange and update frequency in the URL by using URL parameters, like
- from=now-2d&to=now&refresh=5s
Developing
Open the directory of your frontend and run
- npm start
Your local environtment is available at http://localhost:3000/
Running or updating in Production
- cd /var/www
- npm run build
(Optional) Run your own Backend
Note that running your own backend is not required, since you can also use the existing API at nframe.nl
Nonetheless, running your own backend is recommended so you can make changes as well as keep things quick if you are far away from Western Europe, where nframe.nl is hosted
Dependencies
nodejs, npm, pm2
Initial Config
Download copy of repository and change directory to it
- git clone https://github.com/stronk-dev/LivepeerEvents.git /var/www
- cd /var/www/backend
Download all external dependencies we are using
- npm install
Set configuration variables
- nano /var/www/backend/src/config.js
- PORT can be left as is, defines at what port the backend will accept API requests
- NODE_ENV can be left as is, defines the default way to connect to the database
- MONGO_URI should be edited to the URL of your MongoDB instance. This is where the backend stores it's data when it is running in production mode
- MONGO_URI_DEV should be edited to the URL of your MongoDB instance. This is where the backend stores it's data when it is running in development mode
- MONGO_URI_LOCAL can be left as is, this is where the backend stores it's data when it is running in local mode
- API_CMC should be edited to contain your own coinmarketcap api key
- API_L1_HTTP should be edited to the HTTP url of a L1 ethereum node
- API_L2_HTTP should be edited to the HTTP url of a L2 ethereum node
- API_L2_WS should be edited to the WS url of an Arbitrum mainnet Alchemy node
- CONF_DEFAULT_ORCH should be edited to the public address of your own Orchestrator. This is the default Orchestrator the backend will return
Developing
Open the directory of your backend and run
- npm run dev
Running in Production
Open the directory of your backend and run the backend using pm2
- cd /var/www/backend
- pm2 start ecosystem.config.js --env production
Save the current pm2 process list configuration
- pm2 save
Automatically start the backend when the server reboots
- pm2 startup
Updating in Production
- pm2 restart backend
Other commands
View logs
- pm2 log backend
Stop the entire thing
- pm2 stop backend

View File

@ -3,7 +3,7 @@ import Event from '../models/event';
import Block from '../models/block'; import Block from '../models/block';
const apiRouter = express.Router(); const apiRouter = express.Router();
import { import {
API_CMC, API_L1_HTTP, API_L2_HTTP, API_L2_WS API_CMC, API_L1_HTTP, API_L2_HTTP, API_L2_WS, CONF_DEFAULT_ORCH
} from "../config"; } from "../config";
// Do API requests to other API's // Do API requests to other API's
const https = require('https'); const https = require('https');
@ -61,8 +61,6 @@ let serviceUriFeeCostL2 = 0;
// Update O info from thegraph every 1 minute // Update O info from thegraph every 1 minute
const timeoutTheGraph = 60000; const timeoutTheGraph = 60000;
// Address of O info we are want to display
const defaultOrch = "0x847791cbf03be716a7fe9dc8c9affe17bd49ae5e";
// Will contain addr, lastGet, and obj of any requested O's // Will contain addr, lastGet, and obj of any requested O's
let orchestratorCache = []; let orchestratorCache = [];
@ -486,7 +484,7 @@ apiRouter.get("/getOrchestrator", async (req, res) => {
try { try {
let reqOrch = req.query.orch; let reqOrch = req.query.orch;
if (!reqOrch || reqOrch == "") { if (!reqOrch || reqOrch == "") {
reqOrch = defaultOrch; reqOrch = CONF_DEFAULT_ORCH;
} }
const reqObj = await parseOrchestrator(reqOrch); const reqObj = await parseOrchestrator(reqOrch);
res.send(reqObj); res.send(reqObj);

View File

@ -63,16 +63,16 @@ const Grafana = (obj) => {
<div className="flexContainer" style={{ justifyContent: "center" }}> <div className="flexContainer" style={{ justifyContent: "center" }}>
<Orchestrator thisOrchestrator={livepeer.thisOrchestrator} rootOnly={true} /> <Orchestrator thisOrchestrator={livepeer.thisOrchestrator} rootOnly={true} />
</div> </div>
<div className="flexContainer" style={{ justifyContent: "center" }}> <div className="flexContainer" style={{ justifyContent: "stretch", padding: '20px', width: '100%' }}>
<iframe className="fullGrafana" src="https://grafana.stronk.tech/d-solo/71b6OZ0Gz/orchestrator-overview?orgId=1&refresh=5s&theme=dark&panelId=23763572056" height="200" frameBorder="0"></iframe> <iframe className="fullGrafana" src="https://grafana.stronk.tech/d-solo/71b6OZ0Gz/orchestrator-overview?orgId=1&refresh=5s&theme=dark&panelId=23763572056" height="200" frameBorder="0"></iframe>
</div> </div>
<div className="flexContainer" style={{ justifyContent: "center" }}> <div className="flexContainer" style={{ justifyContent: "stretch", padding: '20px', width: '100%' }}>
<iframe className="fullGrafana" src="https://grafana.stronk.tech/d-solo/71b6OZ0Gz/orchestrator-overview?orgId=1&refresh=5s&theme=dark&panelId=23763572077" height="400" frameBorder="0"></iframe> <iframe className="fullGrafana" src="https://grafana.stronk.tech/d-solo/71b6OZ0Gz/orchestrator-overview?orgId=1&refresh=5s&theme=dark&panelId=23763572077" height="400" frameBorder="0"></iframe>
</div> </div>
<div className="flexContainer" style={{ justifyContent: "center" }}> <div className="flexContainer" style={{ justifyContent: "stretch", padding: '20px', width: '100%' }}>
<iframe className="fullGrafana" src="https://grafana.stronk.tech/d-solo/71b6OZ0Gz/orchestrator-overview?orgId=1&refresh=5s&theme=dark&panelId=23763572032" height="200" frameBorder="0"></iframe> <iframe className="fullGrafana" src="https://grafana.stronk.tech/d-solo/71b6OZ0Gz/orchestrator-overview?orgId=1&refresh=5s&theme=dark&panelId=23763572032" height="200" frameBorder="0"></iframe>
</div> </div>
<div className="flexContainer" style={{ justifyContent: "center" }}> <div className="flexContainer" style={{ justifyContent: "stretch", padding: '20px', width: '100%' }}>
<iframe className="fullGrafana" src="https://grafana.stronk.tech/d-solo/71b6OZ0Gz/orchestrator-overview?orgId=1&from=now-2d&to=now&refresh=5s&theme=dark&panelId=23763572040" height="400" frameBorder="0"></iframe> <iframe className="fullGrafana" src="https://grafana.stronk.tech/d-solo/71b6OZ0Gz/orchestrator-overview?orgId=1&from=now-2d&to=now&refresh=5s&theme=dark&panelId=23763572040" height="400" frameBorder="0"></iframe>
</div> </div>
<div className="row"> <div className="row">

View File

@ -146,10 +146,10 @@ svg {
} }
.fullGrafana { .fullGrafana {
width: 900px; width: 100%;
} }
.halfGrafana { .halfGrafana {
width: 450px; width: 50%;
} }
.lightText { .lightText {
@ -167,7 +167,6 @@ svg {
cursor: default; cursor: default;
text-align: start; text-align: start;
padding: 0; padding: 0;
padding-left: 1em;
margin: 0; margin: 0;
user-select: text; user-select: text;
font-size: small; font-size: small;