Prework for displaying round numbers with events, make filterr and inspector view modal windows

This commit is contained in:
Marco van Dijk 2022-04-23 21:02:29 +02:00
parent 6fba12ec1f
commit 55ade43bbe
7 changed files with 187 additions and 23 deletions

View File

@ -0,0 +1,55 @@
import mongoose from 'mongoose';
const RoundSchema = new mongoose.Schema({
number: {
type: Number,
required: true
},
lengthBlocks: {
type: Number,
required: true
},
startBlock: {
type: Number,
required: true
},
endBlock: {
type: Number,
required: true
},
mintableTokens: {
type: Number,
required: true
},
volumeEth: {
type: Number,
required: true
},
volumeUsd: {
type: Number,
required: true
},
totalActiveStake: {
type: Number,
required: true
},
totalSupply: {
type: Number,
required: true
},
participationRate: {
type: Number,
required: true
},
movedStake: {
type: Number,
required: true
},
newStake: {
type: Number,
required: true
}
}, { timestamps: false });
const Round = mongoose.model('RoundSchema', RoundSchema);
export default Round;

View File

@ -8,10 +8,6 @@ const BlockSchema = new mongoose.Schema({
blockTime: { blockTime: {
type: Number, type: Number,
required: true required: true
},
blockRound: {
type: Number,
required: false
} }
}, { timestamps: false }); }, { timestamps: false });

View File

@ -1259,6 +1259,7 @@ const initSync = async function () {
transactionHash: 1, transactionHash: 1,
blockNumber: 1, blockNumber: 1,
blockTime: 1, blockTime: 1,
blockRound: 1,
_id: 0 _id: 0
}); });
// Get all parsed reward events and cache them // Get all parsed reward events and cache them
@ -1268,6 +1269,7 @@ const initSync = async function () {
transactionHash: 1, transactionHash: 1,
blockNumber: 1, blockNumber: 1,
blockTime: 1, blockTime: 1,
blockRound: 1,
_id: 0 _id: 0
}); });
// Get all parsed claim events and cache them // Get all parsed claim events and cache them
@ -1280,6 +1282,7 @@ const initSync = async function () {
transactionHash: 1, transactionHash: 1,
blockNumber: 1, blockNumber: 1,
blockTime: 1, blockTime: 1,
blockRound: 1,
_id: 0 _id: 0
}); });
// Get all parsed withdraw fees events and cache them // Get all parsed withdraw fees events and cache them
@ -1289,6 +1292,7 @@ const initSync = async function () {
transactionHash: 1, transactionHash: 1,
blockNumber: 1, blockNumber: 1,
blockTime: 1, blockTime: 1,
blockRound: 1,
_id: 0 _id: 0
}); });
// Get all parsed withdraw stake events and cache them // Get all parsed withdraw stake events and cache them
@ -1299,6 +1303,7 @@ const initSync = async function () {
transactionHash: 1, transactionHash: 1,
blockNumber: 1, blockNumber: 1,
blockTime: 1, blockTime: 1,
blockRound: 1,
_id: 0 _id: 0
}); });
// Get all parsed transfer winning ticket events and cache them // Get all parsed transfer winning ticket events and cache them
@ -1309,6 +1314,7 @@ const initSync = async function () {
transactionHash: 1, transactionHash: 1,
blockNumber: 1, blockNumber: 1,
blockTime: 1, blockTime: 1,
blockRound: 1,
_id: 0 _id: 0
}); });
// Get all parsed redeem winning ticket events and cache them // Get all parsed redeem winning ticket events and cache them
@ -1318,6 +1324,7 @@ const initSync = async function () {
transactionHash: 1, transactionHash: 1,
blockNumber: 1, blockNumber: 1,
blockTime: 1, blockTime: 1,
blockRound: 1,
_id: 0 _id: 0
}); });
// Get all parsed orchestrator activation events and cache them // Get all parsed orchestrator activation events and cache them
@ -1328,6 +1335,7 @@ const initSync = async function () {
transactionHash: 1, transactionHash: 1,
blockNumber: 1, blockNumber: 1,
blockTime: 1, blockTime: 1,
blockRound: 1,
_id: 0 _id: 0
}); });
// Get all parsed unbond events and cache them // Get all parsed unbond events and cache them
@ -1339,6 +1347,7 @@ const initSync = async function () {
transactionHash: 1, transactionHash: 1,
blockNumber: 1, blockNumber: 1,
blockTime: 1, blockTime: 1,
blockRound: 1,
_id: 0 _id: 0
}); });
// Get all parsed stake events and cache them // Get all parsed stake events and cache them
@ -1350,6 +1359,7 @@ const initSync = async function () {
transactionHash: 1, transactionHash: 1,
blockNumber: 1, blockNumber: 1,
blockTime: 1, blockTime: 1,
blockRound: 1,
_id: 0 _id: 0
}); });
// Get all parsed monthly stats and cache them // Get all parsed monthly stats and cache them
@ -2632,6 +2642,72 @@ apiRouter.get("/getAllOrchScores", async (req, res) => {
} }
}); });
/*
BLOCKS - LIVEPEER ROUNDS
Gets livepeer round number for a given block number
Gets entire round details if the round does not exist yet
Saves entire round details as separate data point as well
Mutates roundCache to contain the new round
Mutates the Event in the database to contain the round number
*/
let roundCache = [];
const mutateRoundToDB = async function (scoreObj) {
// Immediately mutate new object
const doc = await MonthlyStat.findOneAndUpdate({
year: year,
month: month
}, {
testScores: scoreObj
}, {
upsert: true,
new: true,
setDefaultsOnInsert: true
});
// Then find and mutate all Event objects which fall in this round
}
apiRouter.post("/getRoundAtBlock", async (req, res) => {
try {
const { blockNumber } = req.body;
if (blockNumber) {
// Since months get counted starting at 0
const now = new Date().getTime();
let wasInCache = false;
// See if it is cached
for (const thisAddr of orchScoreCache) {
if (thisAddr.year === year && thisAddr.month === month) {
// Check timeout
if (now - thisAddr.timestamp < 360000) {
res.send(thisAddr);
return;
}
wasInCache = true;
}
}
// Check DB
// Get from thegraph
console.log("Getting new Orchestrator scores for " + year + "-" + month + " @ " + url);
// Save to DB
mutateRoundToDB();
}
} catch (err) {
console.log(err);
res.status(400).send(err);
}
});
// Returns entire orch score mapping cache
apiRouter.get("/getAllRounds", async (req, res) => {
try {
res.send(roundCache);
} catch (err) {
res.status(400).send(err);
}
});
export default apiRouter; export default apiRouter;

View File

@ -253,11 +253,6 @@ const MonthlyGraphs = (obj) => {
}); });
} }
console.log("+1 for tickets");
console.log(obj.data.winningTicketsSent);
console.log(obj.data.winningTicketsReceivedSum);
console.log(pieList);
totalGraphs++; totalGraphs++;
broadcasterObj = <div className="stroke" style={{ width: 'unset' }}> broadcasterObj = <div className="stroke" style={{ width: 'unset' }}>

View File

@ -19,7 +19,7 @@ const OrchDelegatorViewer = (obj) => {
// Find current O with most ticket wins in Eth // Find current O with most ticket wins in Eth
while (ticketIdx2 >= 0) { while (ticketIdx2 >= 0) {
const currentOrch = tmpCopy[ticketIdx2]; const currentOrch = tmpCopy[ticketIdx2];
let thisVal = currentOrch.bondedAmount; let thisVal = parseFloat(currentOrch.bondedAmount);
if (thisVal > largestValue) { if (thisVal > largestValue) {
largestIdx = ticketIdx2; largestIdx = ticketIdx2;

View File

@ -1,8 +1,9 @@
import React, { useState, useRef } from "react"; import React, { useState, useRef } from "react";
import EventButton from "./eventButton"; import EventButton from "./eventButton";
import ScrollContainer from 'react-indiana-drag-scroll'; import ScrollContainer from 'react-indiana-drag-scroll';
import { Pagination } from "@mantine/core"; import { Pagination, Title } from "@mantine/core";
import Filter from './filterComponent'; import Filter from './filterComponent';
import { Dialog, Stack, Button, Group } from '@mantine/core';
const thresholdStaking = 0.001; const thresholdStaking = 0.001;
const thresholdFees = 0.00009; const thresholdFees = 0.00009;
@ -444,19 +445,31 @@ const EventViewer = (obj) => {
let filterBit; let filterBit;
if (obj.showFilter) { if (obj.showFilter) {
filterBit = filterBit =
<div className="strokeSmollLeft roundedOpaque" style={{ borderTopLeftRadius: 0, borderTopRightRadius: 0, borderBottomLeftRadius: 0, width: '100%' }}> <Dialog
<div className="row"> opened={obj.showFilter}
<span>Showing {hidden + unfiltered} out of {limitShown} results</span> withCloseButton
</div> onClose={() => obj.setShowFilter(false)}
<Filter amountFilter={obj.amountFilter} setAmountFilter={obj.setAmountFilter} size="xl"
searchTerm={obj.searchTerm} setSearchTerm={obj.setSearchTerm} /> shadow="xl"
</div> position={{ bottom: 20, left: 20 }}
radius="md"
styles={{
root: { backgroundColor: 'rgba(214, 214, 214, 0.90)' },
closeButton: {},
}}
>
<Stack>
<Title order={3}>Showing {hidden + unfiltered} out of {limitShown} results</Title>
<Filter amountFilter={obj.amountFilter} setAmountFilter={obj.setAmountFilter}
searchTerm={obj.searchTerm} setSearchTerm={obj.setSearchTerm} />
</Stack>
</Dialog>
} }
return ( return (
<div className="strokeSmollLeft" style={{ height: 'calc( 100vh - 50px)' }}> <div className="strokeSmollLeft" style={{ height: 'calc( 100vh - 50px)' }}>
{filterBit} {filterBit}
<div className="row" style={{ width: '100%', height: '100%' }}> <div className="row" style={{ width: '100%', height: '100%' }}>
<div className="stroke roundedOpaque onlyVerticalScroll" style={{ width: '40vw', minWidth: '400px', height: 'calc( 100vh - 50px - 2em)', marginTop: '2em' }}> <div className="stroke roundedOpaque onlyVerticalScroll" style={{ width: '40vw', maxWidth: '600px', minWidth: '300px', height: 'calc( 100vh - 50px - 2em)', marginTop: '2em' }}>
<div className="content-wrapper" style={{ width: '100%' }}> <div className="content-wrapper" style={{ width: '100%' }}>
<ScrollContainer activationDistance={1} className="overflow-container" hideScrollbars={false} style={{ width: '100%', overflowX: 'hidden' }}> <ScrollContainer activationDistance={1} className="overflow-container" hideScrollbars={false} style={{ width: '100%', overflowX: 'hidden' }}>
<div className="overflow-content" style={{ cursor: 'grab', padding: 0, width: '100%' }}> <div className="overflow-content" style={{ cursor: 'grab', padding: 0, width: '100%' }}>

View File

@ -6,6 +6,7 @@ import { getOrchestratorInfo, clearOrchestrator } from "../actions/livepeer";
import EventViewer from "../components/eventViewer"; import EventViewer from "../components/eventViewer";
import Orchestrator from "../components/orchestratorViewer"; import Orchestrator from "../components/orchestratorViewer";
import ContractPrices from '../components/ContractPrices'; import ContractPrices from '../components/ContractPrices';
import { Dialog } from '@mantine/core';
// Shows the EventViewer and other Livepeer related info // Shows the EventViewer and other Livepeer related info
const defaultMaxShown = 50; const defaultMaxShown = 50;
@ -19,6 +20,7 @@ const Livepeer = (obj) => {
const livepeer = useSelector((state) => state.livepeerstate); const livepeer = useSelector((state) => state.livepeerstate);
const [redirectToHome, setRedirectToHome] = useState(false); const [redirectToHome, setRedirectToHome] = useState(false);
const [showFilter, setShowFilter] = useState(false); const [showFilter, setShowFilter] = useState(false);
const [opened, setOpened] = useState(false);
const [showSidebar, setShowSidebar] = useState(true); const [showSidebar, setShowSidebar] = useState(true);
console.log("Rendering Livepeer"); console.log("Rendering Livepeer");
@ -44,7 +46,7 @@ const Livepeer = (obj) => {
} }
let sidebar; let sidebar;
if (showSidebar) { if (showSidebar && false) {
sidebar = <div id='sideContent'> sidebar = <div id='sideContent'>
<div className="verticalDivider" /> <div className="verticalDivider" />
<div className="strokeSmollLeft sideMargin"> <div className="strokeSmollLeft sideMargin">
@ -82,7 +84,7 @@ const Livepeer = (obj) => {
}}> }}>
<h4> Clear</h4> <h4> Clear</h4>
</button> </button>
<p>Sidebar</p> <p>Detail</p>
<div className="toggle-container" onClick={() => setShowSidebar(!showSidebar)}> <div className="toggle-container" onClick={() => setShowSidebar(!showSidebar)}>
<div className={`dialog-button ${showSidebar ? "" : "disabled"}`}> <div className={`dialog-button ${showSidebar ? "" : "disabled"}`}>
{showSidebar ? "Show" : "Hide"} {showSidebar ? "Show" : "Hide"}
@ -97,10 +99,37 @@ const Livepeer = (obj) => {
</div> </div>
</div> </div>
<div id='bodyContent'> <div id='bodyContent'>
<Dialog
opened={showSidebar}
withCloseButton
onClose={() => setShowSidebar(false)}
size="xl"
shadow="xl"
radius="md"
styles={{
root: { backgroundColor: 'rgba(214, 214, 214, 0.90)' },
closeButton: { },
}}
>
<div className='stroke'>
<div className="verticalDivider" />
<div className="strokeSmollLeft sideMargin">
<div className="row">
<div className="row">
<Orchestrator thisOrchestrator={thisOrchObj} rootOnly={false} forceVertical={true} />
</div>
</div>
<div className="verticalDivider" />
<div className="row">
<ContractPrices quotes={livepeer.quotes} blockchains={livepeer.blockchains} />
</div>
</div>
</div >
</Dialog>
{sidebar} {sidebar}
<div className="mainContent"> <div className="mainContent">
<EventViewer searchTerm={searchTerm} setSearchTerm={setSearchTerm} <EventViewer searchTerm={searchTerm} setSearchTerm={setSearchTerm}
forceVertical={true} showFilter={showFilter} setAmountFilter={setAmountFilter} amountFilter={amountFilter} forceVertical={true} setShowFilter={setShowFilter} showFilter={showFilter} setAmountFilter={setAmountFilter} amountFilter={amountFilter}
maxAmount={maxAmount} setMaxAmount={setMaxAmount} maxAmount={maxAmount} setMaxAmount={setMaxAmount}
updateEvents={livepeer.updateEvents} updateEvents={livepeer.updateEvents}
rewardEvents={livepeer.rewardEvents} rewardEvents={livepeer.rewardEvents}
@ -113,7 +142,7 @@ const Livepeer = (obj) => {
unbondEvents={livepeer.unbondEvents} unbondEvents={livepeer.unbondEvents}
stakeEvents={livepeer.stakeEvents} stakeEvents={livepeer.stakeEvents}
monthlyStats={livepeer.monthlyStats} monthlyStats={livepeer.monthlyStats}
/> />
</div> </div>
</div> </div>
</div > </div >