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: {
type: Number,
required: true
},
blockRound: {
type: Number,
required: false
}
}, { timestamps: false });

View File

@ -1259,6 +1259,7 @@ const initSync = async function () {
transactionHash: 1,
blockNumber: 1,
blockTime: 1,
blockRound: 1,
_id: 0
});
// Get all parsed reward events and cache them
@ -1268,6 +1269,7 @@ const initSync = async function () {
transactionHash: 1,
blockNumber: 1,
blockTime: 1,
blockRound: 1,
_id: 0
});
// Get all parsed claim events and cache them
@ -1280,6 +1282,7 @@ const initSync = async function () {
transactionHash: 1,
blockNumber: 1,
blockTime: 1,
blockRound: 1,
_id: 0
});
// Get all parsed withdraw fees events and cache them
@ -1289,6 +1292,7 @@ const initSync = async function () {
transactionHash: 1,
blockNumber: 1,
blockTime: 1,
blockRound: 1,
_id: 0
});
// Get all parsed withdraw stake events and cache them
@ -1299,6 +1303,7 @@ const initSync = async function () {
transactionHash: 1,
blockNumber: 1,
blockTime: 1,
blockRound: 1,
_id: 0
});
// Get all parsed transfer winning ticket events and cache them
@ -1309,6 +1314,7 @@ const initSync = async function () {
transactionHash: 1,
blockNumber: 1,
blockTime: 1,
blockRound: 1,
_id: 0
});
// Get all parsed redeem winning ticket events and cache them
@ -1318,6 +1324,7 @@ const initSync = async function () {
transactionHash: 1,
blockNumber: 1,
blockTime: 1,
blockRound: 1,
_id: 0
});
// Get all parsed orchestrator activation events and cache them
@ -1328,6 +1335,7 @@ const initSync = async function () {
transactionHash: 1,
blockNumber: 1,
blockTime: 1,
blockRound: 1,
_id: 0
});
// Get all parsed unbond events and cache them
@ -1339,6 +1347,7 @@ const initSync = async function () {
transactionHash: 1,
blockNumber: 1,
blockTime: 1,
blockRound: 1,
_id: 0
});
// Get all parsed stake events and cache them
@ -1350,6 +1359,7 @@ const initSync = async function () {
transactionHash: 1,
blockNumber: 1,
blockTime: 1,
blockRound: 1,
_id: 0
});
// 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;

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++;
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
while (ticketIdx2 >= 0) {
const currentOrch = tmpCopy[ticketIdx2];
let thisVal = currentOrch.bondedAmount;
let thisVal = parseFloat(currentOrch.bondedAmount);
if (thisVal > largestValue) {
largestIdx = ticketIdx2;

View File

@ -1,8 +1,9 @@
import React, { useState, useRef } from "react";
import EventButton from "./eventButton";
import ScrollContainer from 'react-indiana-drag-scroll';
import { Pagination } from "@mantine/core";
import { Pagination, Title } from "@mantine/core";
import Filter from './filterComponent';
import { Dialog, Stack, Button, Group } from '@mantine/core';
const thresholdStaking = 0.001;
const thresholdFees = 0.00009;
@ -444,19 +445,31 @@ const EventViewer = (obj) => {
let filterBit;
if (obj.showFilter) {
filterBit =
<div className="strokeSmollLeft roundedOpaque" style={{ borderTopLeftRadius: 0, borderTopRightRadius: 0, borderBottomLeftRadius: 0, width: '100%' }}>
<div className="row">
<span>Showing {hidden + unfiltered} out of {limitShown} results</span>
</div>
<Filter amountFilter={obj.amountFilter} setAmountFilter={obj.setAmountFilter}
searchTerm={obj.searchTerm} setSearchTerm={obj.setSearchTerm} />
</div>
<Dialog
opened={obj.showFilter}
withCloseButton
onClose={() => obj.setShowFilter(false)}
size="xl"
shadow="xl"
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 (
<div className="strokeSmollLeft" style={{ height: 'calc( 100vh - 50px)' }}>
{filterBit}
<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%' }}>
<ScrollContainer activationDistance={1} className="overflow-container" hideScrollbars={false} style={{ width: '100%', overflowX: 'hidden' }}>
<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 Orchestrator from "../components/orchestratorViewer";
import ContractPrices from '../components/ContractPrices';
import { Dialog } from '@mantine/core';
// Shows the EventViewer and other Livepeer related info
const defaultMaxShown = 50;
@ -19,6 +20,7 @@ const Livepeer = (obj) => {
const livepeer = useSelector((state) => state.livepeerstate);
const [redirectToHome, setRedirectToHome] = useState(false);
const [showFilter, setShowFilter] = useState(false);
const [opened, setOpened] = useState(false);
const [showSidebar, setShowSidebar] = useState(true);
console.log("Rendering Livepeer");
@ -44,7 +46,7 @@ const Livepeer = (obj) => {
}
let sidebar;
if (showSidebar) {
if (showSidebar && false) {
sidebar = <div id='sideContent'>
<div className="verticalDivider" />
<div className="strokeSmollLeft sideMargin">
@ -82,7 +84,7 @@ const Livepeer = (obj) => {
}}>
<h4> Clear</h4>
</button>
<p>Sidebar</p>
<p>Detail</p>
<div className="toggle-container" onClick={() => setShowSidebar(!showSidebar)}>
<div className={`dialog-button ${showSidebar ? "" : "disabled"}`}>
{showSidebar ? "Show" : "Hide"}
@ -97,10 +99,37 @@ const Livepeer = (obj) => {
</div>
</div>
<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}
<div className="mainContent">
<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}
updateEvents={livepeer.updateEvents}
rewardEvents={livepeer.rewardEvents}
@ -113,7 +142,7 @@ const Livepeer = (obj) => {
unbondEvents={livepeer.unbondEvents}
stakeEvents={livepeer.stakeEvents}
monthlyStats={livepeer.monthlyStats}
/>
/>
</div>
</div>
</div >