mirror of
https://github.com/stronk-dev/LivepeerEvents.git
synced 2025-07-05 02:35:09 +02:00
Added quiet background updates for Events and Monthly stats
Fix updating cache of monthly stats correctly Prework on getting round info in order to map Events to Rounds
This commit is contained in:
parent
e9dc60bf3c
commit
794e000c46
@ -41,6 +41,7 @@ const fs = require('fs');
|
||||
|
||||
// Used for the livepeer thegraph API
|
||||
import { request, gql } from 'graphql-request';
|
||||
import Round from "../models/Round";
|
||||
|
||||
// Gets ETH, LPT and other coin info
|
||||
let CoinMarketCap = require('coinmarketcap-api');
|
||||
@ -161,24 +162,57 @@ let lastBlockEvents = 0;
|
||||
let lastBlockTickets = 0;
|
||||
let ticketsCache = [];
|
||||
|
||||
let alreadyHasAnyRefresh = {};
|
||||
|
||||
let updateEventCache = [];
|
||||
let alreadyHasUpdateRefresh = {};
|
||||
|
||||
let rewardEventCache = [];
|
||||
let alreadyHasRewardRefresh = {};
|
||||
|
||||
let claimEventCache = [];
|
||||
let alreadyHasClaimRefresh = {};
|
||||
|
||||
let withdrawStakeEventCache = [];
|
||||
let alreadyHasWithdrawStakeRefresh = {};
|
||||
|
||||
let withdrawFeesEventCache = [];
|
||||
let alreadyHasWithdrawFeesRefresh = {};
|
||||
|
||||
let transferTicketEventCache = [];
|
||||
let alreadyHasTransferTicketRefresh = {};
|
||||
|
||||
let redeemTicketEventCache = [];
|
||||
let alreadyHasRedeemTicketRefresh = {};
|
||||
|
||||
let activateEventCache = [];
|
||||
let alreadyHasActivateRefresh = {};
|
||||
|
||||
let unbondEventCache = [];
|
||||
let alreadyHasUnbondRefresh = {};
|
||||
|
||||
let stakeEventCache = [];
|
||||
let alreadyHasStakeRefresh = {};
|
||||
|
||||
let monthlyStatCache = [];
|
||||
let alreadyHasMonthlyStatRefresh = {};
|
||||
|
||||
let commissionDataPointCache = [];
|
||||
let totalStakeDataPoint = [];
|
||||
|
||||
apiRouter.get("/getAllMonthlyStats", async (req, res) => {
|
||||
apiRouter.post("/getAllMonthlyStats", async (req, res) => {
|
||||
try {
|
||||
const { smartUpdate } = req.body;
|
||||
if (smartUpdate && req.session.user.ip) {
|
||||
if (alreadyHasMonthlyStatRefresh[req.session.user.ip]) {
|
||||
res.send({ noop: true });
|
||||
return;
|
||||
}
|
||||
}
|
||||
res.send(monthlyStatCache);
|
||||
if (req.session.user.ip) {
|
||||
alreadyHasMonthlyStatRefresh[req.session.user.ip] = true;
|
||||
}
|
||||
} catch (err) {
|
||||
res.status(400).send(err);
|
||||
}
|
||||
@ -200,81 +234,209 @@ apiRouter.get("/getAllTotalStakes", async (req, res) => {
|
||||
}
|
||||
});
|
||||
|
||||
apiRouter.get("/getAllUpdateEvents", async (req, res) => {
|
||||
apiRouter.post("/getAllUpdateEvents", async (req, res) => {
|
||||
try {
|
||||
const { smartUpdate } = req.body;
|
||||
if (smartUpdate && req.session.user.ip) {
|
||||
if (alreadyHasUpdateRefresh[req.session.user.ip]) {
|
||||
res.send({ noop: true });
|
||||
return;
|
||||
}
|
||||
}
|
||||
res.send(updateEventCache);
|
||||
if (req.session.user.ip) {
|
||||
alreadyHasAnyRefresh[req.session.user.ip] = true;
|
||||
alreadyHasUpdateRefresh[req.session.user.ip] = true;
|
||||
}
|
||||
} catch (err) {
|
||||
res.status(400).send(err);
|
||||
}
|
||||
});
|
||||
|
||||
apiRouter.get("/getAllRewardEvents", async (req, res) => {
|
||||
apiRouter.post("/getAllRewardEvents", async (req, res) => {
|
||||
try {
|
||||
const { smartUpdate } = req.body;
|
||||
if (smartUpdate && req.session.user.ip) {
|
||||
if (alreadyHasRewardRefresh[req.session.user.ip]) {
|
||||
res.send({ noop: true });
|
||||
return;
|
||||
}
|
||||
}
|
||||
res.send(rewardEventCache);
|
||||
if (req.session.user.ip) {
|
||||
alreadyHasAnyRefresh[req.session.user.ip] = true;
|
||||
alreadyHasRewardRefresh[req.session.user.ip] = true;
|
||||
}
|
||||
} catch (err) {
|
||||
res.status(400).send(err);
|
||||
}
|
||||
});
|
||||
|
||||
apiRouter.get("/getAllClaimEvents", async (req, res) => {
|
||||
apiRouter.post("/getAllClaimEvents", async (req, res) => {
|
||||
try {
|
||||
const { smartUpdate } = req.body;
|
||||
if (smartUpdate && req.session.user.ip) {
|
||||
if (alreadyHasClaimRefresh[req.session.user.ip]) {
|
||||
res.send({ noop: true });
|
||||
return;
|
||||
}
|
||||
}
|
||||
res.send(claimEventCache);
|
||||
if (req.session.user.ip) {
|
||||
alreadyHasAnyRefresh[req.session.user.ip] = true;
|
||||
alreadyHasClaimRefresh[req.session.user.ip] = true;
|
||||
}
|
||||
} catch (err) {
|
||||
res.status(400).send(err);
|
||||
}
|
||||
});
|
||||
|
||||
apiRouter.get("/getAllWithdrawStakeEvents", async (req, res) => {
|
||||
apiRouter.post("/getAllWithdrawStakeEvents", async (req, res) => {
|
||||
try {
|
||||
const { smartUpdate } = req.body;
|
||||
if (smartUpdate && req.session.user.ip) {
|
||||
if (alreadyHasWithdrawStakeRefresh[req.session.user.ip]) {
|
||||
res.send({ noop: true });
|
||||
return;
|
||||
}
|
||||
}
|
||||
res.send(withdrawStakeEventCache);
|
||||
if (req.session.user.ip) {
|
||||
alreadyHasAnyRefresh[req.session.user.ip] = true;
|
||||
alreadyHasWithdrawStakeRefresh[req.session.user.ip] = true;
|
||||
}
|
||||
} catch (err) {
|
||||
res.status(400).send(err);
|
||||
}
|
||||
});
|
||||
|
||||
apiRouter.get("/getAllWithdrawFeesEvents", async (req, res) => {
|
||||
apiRouter.post("/getAllWithdrawFeesEvents", async (req, res) => {
|
||||
try {
|
||||
const { smartUpdate } = req.body;
|
||||
if (smartUpdate && req.session.user.ip) {
|
||||
if (alreadyHasWithdrawFeesRefresh[req.session.user.ip]) {
|
||||
res.send({ noop: true });
|
||||
return;
|
||||
}
|
||||
}
|
||||
res.send(withdrawFeesEventCache);
|
||||
if (req.session.user.ip) {
|
||||
alreadyHasAnyRefresh[req.session.user.ip] = true;
|
||||
alreadyHasWithdrawFeesRefresh[req.session.user.ip] = true;
|
||||
}
|
||||
} catch (err) {
|
||||
res.status(400).send(err);
|
||||
}
|
||||
});
|
||||
|
||||
apiRouter.get("/getAllTransferTicketEvents", async (req, res) => {
|
||||
apiRouter.post("/getAllTransferTicketEvents", async (req, res) => {
|
||||
try {
|
||||
const { smartUpdate } = req.body;
|
||||
if (smartUpdate && req.session.user.ip) {
|
||||
if (alreadyHasTransferTicketRefresh[req.session.user.ip]) {
|
||||
res.send({ noop: true });
|
||||
return;
|
||||
}
|
||||
}
|
||||
res.send(transferTicketEventCache);
|
||||
if (req.session.user.ip) {
|
||||
alreadyHasAnyRefresh[req.session.user.ip] = true;
|
||||
alreadyHasTransferTicketRefresh[req.session.user.ip] = true;
|
||||
}
|
||||
} catch (err) {
|
||||
res.status(400).send(err);
|
||||
}
|
||||
});
|
||||
|
||||
apiRouter.get("/getAllRedeemTicketEvents", async (req, res) => {
|
||||
apiRouter.post("/getAllRedeemTicketEvents", async (req, res) => {
|
||||
try {
|
||||
const { smartUpdate } = req.body;
|
||||
if (smartUpdate && req.session.user.ip) {
|
||||
if (alreadyHasRedeemTicketRefresh[req.session.user.ip]) {
|
||||
res.send({ noop: true });
|
||||
return;
|
||||
}
|
||||
}
|
||||
res.send(redeemTicketEventCache);
|
||||
if (req.session.user.ip) {
|
||||
alreadyHasAnyRefresh[req.session.user.ip] = true;
|
||||
alreadyHasRedeemTicketRefresh[req.session.user.ip] = true;
|
||||
}
|
||||
} catch (err) {
|
||||
res.status(400).send(err);
|
||||
}
|
||||
});
|
||||
|
||||
apiRouter.get("/getAllActivateEvents", async (req, res) => {
|
||||
apiRouter.post("/getAllActivateEvents", async (req, res) => {
|
||||
try {
|
||||
const { smartUpdate } = req.body;
|
||||
if (smartUpdate && req.session.user.ip) {
|
||||
if (alreadyHasActivateRefresh[req.session.user.ip]) {
|
||||
res.send({ noop: true });
|
||||
return;
|
||||
}
|
||||
}
|
||||
res.send(activateEventCache);
|
||||
if (req.session.user.ip) {
|
||||
alreadyHasAnyRefresh[req.session.user.ip] = true;
|
||||
alreadyHasActivateRefresh[req.session.user.ip] = true;
|
||||
}
|
||||
} catch (err) {
|
||||
res.status(400).send(err);
|
||||
}
|
||||
});
|
||||
|
||||
apiRouter.get("/getAllUnbondEvents", async (req, res) => {
|
||||
apiRouter.post("/getAllUnbondEvents", async (req, res) => {
|
||||
try {
|
||||
const { smartUpdate } = req.body;
|
||||
if (smartUpdate && req.session.user.ip) {
|
||||
if (alreadyHasUnbondRefresh[req.session.user.ip]) {
|
||||
res.send({ noop: true });
|
||||
return;
|
||||
}
|
||||
}
|
||||
res.send(unbondEventCache);
|
||||
if (req.session.user.ip) {
|
||||
alreadyHasAnyRefresh[req.session.user.ip] = true;
|
||||
alreadyHasUnbondRefresh[req.session.user.ip] = true;
|
||||
}
|
||||
} catch (err) {
|
||||
res.status(400).send(err);
|
||||
}
|
||||
});
|
||||
|
||||
apiRouter.get("/getAllStakeEvents", async (req, res) => {
|
||||
apiRouter.post("/getAllStakeEvents", async (req, res) => {
|
||||
try {
|
||||
const { smartUpdate } = req.body;
|
||||
if (smartUpdate && req.session.user.ip) {
|
||||
if (alreadyHasStakeRefresh[req.session.user.ip]) {
|
||||
res.send({ noop: true });
|
||||
return;
|
||||
}
|
||||
}
|
||||
res.send(stakeEventCache);
|
||||
if (req.session.user.ip) {
|
||||
alreadyHasAnyRefresh[req.session.user.ip] = true;
|
||||
alreadyHasStakeRefresh[req.session.user.ip] = true;
|
||||
}
|
||||
} catch (err) {
|
||||
res.status(400).send(err);
|
||||
}
|
||||
});
|
||||
|
||||
apiRouter.get("/hasAnyRefresh", async (req, res) => {
|
||||
try {
|
||||
if (req.session.user.ip) {
|
||||
console.log(req.session.user.ip + " is checking for new Events");
|
||||
if (alreadyHasAnyRefresh[req.session.user.ip]) {
|
||||
console.log(req.session.user.ip + " is still up to date");
|
||||
res.send({ requiresRefresh: false });
|
||||
return;
|
||||
} else {
|
||||
console.log(req.session.user.ip + " requires an update");
|
||||
}
|
||||
}
|
||||
res.send({ requiresRefresh: true });
|
||||
} catch (err) {
|
||||
res.status(400).send(err);
|
||||
}
|
||||
@ -310,13 +472,22 @@ const updateMonthlyReward = async function (blockTime, amount) {
|
||||
});
|
||||
}
|
||||
// Update cached entry if it is cached
|
||||
let found = false;
|
||||
for (var idx = 0; idx < monthlyStatCache.length; idx++) {
|
||||
if (monthlyStatCache[idx].year == thisYear && monthlyStatCache[idx].month == thisMonth) {
|
||||
monthlyStatCache[idx].rewardCount += 1;
|
||||
monthlyStatCache[idx].rewardAmountSum += amount;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
const doc = await MonthlyStat.findOne({
|
||||
year: thisYear,
|
||||
month: thisMonth
|
||||
});
|
||||
monthlyStatCache.push(doc);
|
||||
}
|
||||
}
|
||||
|
||||
const updateMonthlyClaim = async function (blockTime, fees, rewards) {
|
||||
@ -344,14 +515,23 @@ const updateMonthlyClaim = async function (blockTime, fees, rewards) {
|
||||
});
|
||||
}
|
||||
// Update cached entry if it is cached
|
||||
let found = false;
|
||||
for (var idx = 0; idx < monthlyStatCache.length; idx++) {
|
||||
if (monthlyStatCache[idx].year == thisYear && monthlyStatCache[idx].month == thisMonth) {
|
||||
monthlyStatCache[idx].claimCount += 1;
|
||||
monthlyStatCache[idx].claimRewardSum += rewards;
|
||||
monthlyStatCache[idx].claimFeeSum += fees;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
const doc = await MonthlyStat.findOne({
|
||||
year: thisYear,
|
||||
month: thisMonth
|
||||
});
|
||||
monthlyStatCache.push(doc);
|
||||
}
|
||||
}
|
||||
|
||||
const updateMonthlyWithdrawStake = async function (blockTime, amount) {
|
||||
@ -378,13 +558,22 @@ const updateMonthlyWithdrawStake = async function (blockTime, amount) {
|
||||
});
|
||||
}
|
||||
// Update cached entry if it is cached
|
||||
let found = false;
|
||||
for (var idx = 0; idx < monthlyStatCache.length; idx++) {
|
||||
if (monthlyStatCache[idx].year == thisYear && monthlyStatCache[idx].month == thisMonth) {
|
||||
monthlyStatCache[idx].withdrawStakeCount += 1;
|
||||
monthlyStatCache[idx].withdrawStakeAmountSum += amount;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
const doc = await MonthlyStat.findOne({
|
||||
year: thisYear,
|
||||
month: thisMonth
|
||||
});
|
||||
monthlyStatCache.push(doc);
|
||||
}
|
||||
}
|
||||
|
||||
const updateMonthlyWithdrawFees = async function (blockTime, amount) {
|
||||
@ -411,13 +600,22 @@ const updateMonthlyWithdrawFees = async function (blockTime, amount) {
|
||||
});
|
||||
}
|
||||
// Update cached entry if it is cached
|
||||
let found = false;
|
||||
for (var idx = 0; idx < monthlyStatCache.length; idx++) {
|
||||
if (monthlyStatCache[idx].year == thisYear && monthlyStatCache[idx].month == thisMonth) {
|
||||
monthlyStatCache[idx].withdrawFeesCount += 1;
|
||||
monthlyStatCache[idx].withdrawFeesAmountSum += amount;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
const doc = await MonthlyStat.findOne({
|
||||
year: thisYear,
|
||||
month: thisMonth
|
||||
});
|
||||
monthlyStatCache.push(doc);
|
||||
}
|
||||
}
|
||||
|
||||
const updateMonthlyNewDelegator = async function (blockTime, amount) {
|
||||
@ -444,13 +642,22 @@ const updateMonthlyNewDelegator = async function (blockTime, amount) {
|
||||
});
|
||||
}
|
||||
// Update cached entry if it is cached
|
||||
let found = false;
|
||||
for (var idx = 0; idx < monthlyStatCache.length; idx++) {
|
||||
if (monthlyStatCache[idx].year == thisYear && monthlyStatCache[idx].month == thisMonth) {
|
||||
monthlyStatCache[idx].bondCount += 1;
|
||||
monthlyStatCache[idx].bondStakeSum += amount;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
const doc = await MonthlyStat.findOne({
|
||||
year: thisYear,
|
||||
month: thisMonth
|
||||
});
|
||||
monthlyStatCache.push(doc);
|
||||
}
|
||||
}
|
||||
|
||||
const updateMonthlyUnbond = async function (blockTime, amount) {
|
||||
@ -477,13 +684,22 @@ const updateMonthlyUnbond = async function (blockTime, amount) {
|
||||
});
|
||||
}
|
||||
// Update cached entry if it is cached
|
||||
let found = false;
|
||||
for (var idx = 0; idx < monthlyStatCache.length; idx++) {
|
||||
if (monthlyStatCache[idx].year == thisYear && monthlyStatCache[idx].month == thisMonth) {
|
||||
monthlyStatCache[idx].unbondCount += 1;
|
||||
monthlyStatCache[idx].unbondStakeSum += amount;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
const doc = await MonthlyStat.findOne({
|
||||
year: thisYear,
|
||||
month: thisMonth
|
||||
});
|
||||
monthlyStatCache.push(doc);
|
||||
}
|
||||
}
|
||||
|
||||
const updateMonthlyReactivated = async function (blockTime, amount) {
|
||||
@ -509,12 +725,21 @@ const updateMonthlyReactivated = async function (blockTime, amount) {
|
||||
});
|
||||
}
|
||||
// Update cached entry if it is cached
|
||||
let found = false;
|
||||
for (var idx = 0; idx < monthlyStatCache.length; idx++) {
|
||||
if (monthlyStatCache[idx].year == thisYear && monthlyStatCache[idx].month == thisMonth) {
|
||||
monthlyStatCache[idx].reactivationCount += 1;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
const doc = await MonthlyStat.findOne({
|
||||
year: thisYear,
|
||||
month: thisMonth
|
||||
});
|
||||
monthlyStatCache.push(doc);
|
||||
}
|
||||
}
|
||||
|
||||
const updateMonthlyActivation = async function (blockTime, amount) {
|
||||
@ -541,13 +766,22 @@ const updateMonthlyActivation = async function (blockTime, amount) {
|
||||
});
|
||||
}
|
||||
// Update cached entry if it is cached
|
||||
let found = false;
|
||||
for (var idx = 0; idx < monthlyStatCache.length; idx++) {
|
||||
if (monthlyStatCache[idx].year == thisYear && monthlyStatCache[idx].month == thisMonth) {
|
||||
monthlyStatCache[idx].activationCount += 1;
|
||||
monthlyStatCache[idx].activationInitialSum += amount;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
const doc = await MonthlyStat.findOne({
|
||||
year: thisYear,
|
||||
month: thisMonth
|
||||
});
|
||||
monthlyStatCache.push(doc);
|
||||
}
|
||||
}
|
||||
|
||||
const updateMonthlyMoveStake = async function (blockTime, amount) {
|
||||
@ -574,13 +808,22 @@ const updateMonthlyMoveStake = async function (blockTime, amount) {
|
||||
});
|
||||
}
|
||||
// Update cached entry if it is cached
|
||||
let found = false;
|
||||
for (var idx = 0; idx < monthlyStatCache.length; idx++) {
|
||||
if (monthlyStatCache[idx].year == thisYear && monthlyStatCache[idx].month == thisMonth) {
|
||||
monthlyStatCache[idx].moveStakeCount += 1;
|
||||
monthlyStatCache[idx].moveStakeSum += amount;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
const doc = await MonthlyStat.findOne({
|
||||
year: thisYear,
|
||||
month: thisMonth
|
||||
});
|
||||
monthlyStatCache.push(doc);
|
||||
}
|
||||
}
|
||||
|
||||
const updateMonthlyTicketReceived = async function (blockTime, amount, from, to) {
|
||||
@ -619,6 +862,8 @@ const updateMonthlyTicketReceived = async function (blockTime, amount, from, to)
|
||||
'winningTicketsReceived.$.sum': amount + eventObj.sum,
|
||||
'winningTicketsReceived.$.count': 1 + eventObj.count,
|
||||
}
|
||||
}, {
|
||||
new: true
|
||||
});
|
||||
hasModified = true;
|
||||
break;
|
||||
@ -638,6 +883,8 @@ const updateMonthlyTicketReceived = async function (blockTime, amount, from, to)
|
||||
count: 1
|
||||
}
|
||||
}
|
||||
}, {
|
||||
new: true
|
||||
});
|
||||
}
|
||||
// Check to see if the doc's embedded winningTicketsSent already contains this address
|
||||
@ -654,6 +901,8 @@ const updateMonthlyTicketReceived = async function (blockTime, amount, from, to)
|
||||
'winningTicketsSent.$.sum': amount + eventObj.sum,
|
||||
'winningTicketsSent.$.count': 1 + eventObj.count,
|
||||
}
|
||||
}, {
|
||||
new: true
|
||||
});
|
||||
hasModified = true;
|
||||
break;
|
||||
@ -673,32 +922,62 @@ const updateMonthlyTicketReceived = async function (blockTime, amount, from, to)
|
||||
count: 1
|
||||
}
|
||||
}
|
||||
}, {
|
||||
new: true
|
||||
});
|
||||
}
|
||||
}
|
||||
// Update cached entry if it is cached
|
||||
let found = false;
|
||||
for (var idx = 0; idx < monthlyStatCache.length; idx++) {
|
||||
if (monthlyStatCache[idx].year == thisYear && monthlyStatCache[idx].month == thisMonth) {
|
||||
monthlyStatCache[idx].winningTicketsReceivedCount += 1;
|
||||
monthlyStatCache[idx].winningTicketsReceivedSum += amount;
|
||||
let foundNested = false;
|
||||
// Check to see if the doc's embedded winningTicketsReceived already contains this address
|
||||
for (var idx2 = 0; idx2 < monthlyStatCache[idx].winningTicketsReceived.length; idx2++) {
|
||||
if (monthlyStatCache[idx].winningTicketsReceived[idx2].address == to) {
|
||||
monthlyStatCache[idx].winningTicketsReceived[idx2].count += 1;
|
||||
monthlyStatCache[idx].winningTicketsReceived[idx2].sum += amount;
|
||||
foundNested = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!foundNested) {
|
||||
monthlyStatCache[idx].winningTicketsReceived.push({
|
||||
address: to,
|
||||
sum: amount,
|
||||
count: 1
|
||||
});
|
||||
}
|
||||
foundNested = false;
|
||||
// Check to see if the doc's embedded winningTicketsSent already contains this address
|
||||
for (var idx2 = 0; idx2 < monthlyStatCache[idx].winningTicketsSent.length; idx2++) {
|
||||
if (monthlyStatCache[idx].winningTicketsSent[idx2].address == from) {
|
||||
monthlyStatCache[idx].winningTicketsSent[idx2].count += 1;
|
||||
monthlyStatCache[idx].winningTicketsSent[idx2].sum += amount;
|
||||
foundNested = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!foundNested) {
|
||||
monthlyStatCache[idx].winningTicketsSent.push({
|
||||
address: from,
|
||||
sum: amount,
|
||||
count: 1
|
||||
});
|
||||
}
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
const doc = await MonthlyStat.findOne({
|
||||
year: thisYear,
|
||||
month: thisMonth
|
||||
});
|
||||
monthlyStatCache.push(doc);
|
||||
}
|
||||
}
|
||||
|
||||
const updateMonthlyTicketRedeemed = async function (blockTime, amount, address) {
|
||||
@ -737,6 +1016,8 @@ const updateMonthlyTicketRedeemed = async function (blockTime, amount, address)
|
||||
'winningTicketsRedeemed.$.sum': amount + eventObj.sum,
|
||||
'winningTicketsRedeemed.$.count': 1 + eventObj.count,
|
||||
}
|
||||
}, {
|
||||
new: true
|
||||
});
|
||||
hasModified = true;
|
||||
break;
|
||||
@ -756,24 +1037,45 @@ const updateMonthlyTicketRedeemed = async function (blockTime, amount, address)
|
||||
count: 1
|
||||
}
|
||||
}
|
||||
}, {
|
||||
new: true
|
||||
});
|
||||
}
|
||||
}
|
||||
// Update cached entry if it is cached
|
||||
let found = false;
|
||||
for (var idx = 0; idx < monthlyStatCache.length; idx++) {
|
||||
if (monthlyStatCache[idx].year == thisYear && monthlyStatCache[idx].month == thisMonth) {
|
||||
monthlyStatCache[idx].winningTicketsRedeemedCount += 1;
|
||||
monthlyStatCache[idx].winningTicketsRedeemedSum += amount;
|
||||
let foundNested = false;
|
||||
// Check to see if the doc's embedded winningTicketsRedeemed already contains this address
|
||||
for (var idx2 = 0; idx2 < monthlyStatCache[idx].winningTicketsRedeemed.length; idx2++) {
|
||||
if (monthlyStatCache[idx].winningTicketsRedeemed[idx2].address == address) {
|
||||
monthlyStatCache[idx].winningTicketsRedeemed[idx2].count += 1;
|
||||
monthlyStatCache[idx].winningTicketsRedeemed[idx2].sum += amount;
|
||||
foundNested = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!foundNested) {
|
||||
monthlyStatCache[idx].winningTicketsRedeemed.push({
|
||||
address: address,
|
||||
sum: amount,
|
||||
count: 1
|
||||
});
|
||||
}
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
const doc = await MonthlyStat.findOne({
|
||||
year: thisYear,
|
||||
month: thisMonth
|
||||
});
|
||||
monthlyStatCache.push(doc);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@ -801,6 +1103,8 @@ const parseAnyEvent = async function (thisEvent) {
|
||||
}
|
||||
// No monthly stats
|
||||
updateEventCache.push(eventObj);
|
||||
alreadyHasAnyRefresh = {};
|
||||
alreadyHasUpdateRefresh = {};
|
||||
} else if (thisName === "Reward") {
|
||||
const eventObj = {
|
||||
address: thisEvent.data.transcoder.toLowerCase(),
|
||||
@ -814,7 +1118,10 @@ const parseAnyEvent = async function (thisEvent) {
|
||||
await dbObj.save();
|
||||
}
|
||||
updateMonthlyReward(eventObj.blockTime, eventObj.amount);
|
||||
alreadyHasMonthlyStatRefresh = {};
|
||||
rewardEventCache.push(eventObj);
|
||||
alreadyHasAnyRefresh = {};
|
||||
alreadyHasRewardRefresh = {};
|
||||
} else if (thisName === "EarningsClaimed") {
|
||||
const eventObj = {
|
||||
address: thisEvent.data.delegator.toLowerCase(),
|
||||
@ -831,7 +1138,10 @@ const parseAnyEvent = async function (thisEvent) {
|
||||
await dbObj.save();
|
||||
}
|
||||
updateMonthlyClaim(eventObj.blockTime, eventObj.fees, eventObj.rewards);
|
||||
alreadyHasMonthlyStatRefresh = {};
|
||||
claimEventCache.push(eventObj);
|
||||
alreadyHasAnyRefresh = {};
|
||||
alreadyHasClaimRefresh = {};
|
||||
} else if (thisName === "WithdrawStake") {
|
||||
const eventObj = {
|
||||
address: thisEvent.data.delegator.toLowerCase(),
|
||||
@ -846,7 +1156,10 @@ const parseAnyEvent = async function (thisEvent) {
|
||||
await dbObj.save();
|
||||
}
|
||||
updateMonthlyWithdrawStake(eventObj.blockTime, eventObj.amount);
|
||||
alreadyHasMonthlyStatRefresh = {};
|
||||
withdrawStakeEventCache.push(eventObj);
|
||||
alreadyHasAnyRefresh = {};
|
||||
alreadyHasWithdrawStakeRefresh = {};
|
||||
} else if (thisName === "WithdrawFees") {
|
||||
const eventObj = {
|
||||
address: thisEvent.data.delegator.toLowerCase(),
|
||||
@ -860,7 +1173,10 @@ const parseAnyEvent = async function (thisEvent) {
|
||||
await dbObj.save();
|
||||
}
|
||||
updateMonthlyWithdrawFees(eventObj.blockTime, eventObj.amount);
|
||||
alreadyHasMonthlyStatRefresh = {};
|
||||
withdrawFeesEventCache.push(eventObj);
|
||||
alreadyHasAnyRefresh = {};
|
||||
alreadyHasWithdrawFeesRefresh = {};
|
||||
} else if (thisName === "WinningTicketTransfer") {
|
||||
const eventObj = {
|
||||
address: thisEvent.data.sender.toLowerCase(),
|
||||
@ -875,7 +1191,10 @@ const parseAnyEvent = async function (thisEvent) {
|
||||
await dbObj.save();
|
||||
}
|
||||
updateMonthlyTicketReceived(eventObj.blockTime, eventObj.amount, eventObj.address, eventObj.to);
|
||||
alreadyHasMonthlyStatRefresh = {};
|
||||
transferTicketEventCache.push(eventObj);
|
||||
alreadyHasAnyRefresh = {};
|
||||
alreadyHasTransferTicketRefresh = {};
|
||||
} else if (thisName === "WinningTicketRedeemed") {
|
||||
const eventObj = {
|
||||
address: thisEvent.data.recipient.toLowerCase(),
|
||||
@ -889,7 +1208,10 @@ const parseAnyEvent = async function (thisEvent) {
|
||||
await dbObj.save();
|
||||
}
|
||||
updateMonthlyTicketRedeemed(eventObj.blockTime, eventObj.amount, eventObj.address);
|
||||
alreadyHasMonthlyStatRefresh = {};
|
||||
redeemTicketEventCache.push(eventObj);
|
||||
alreadyHasAnyRefresh = {};
|
||||
alreadyHasRedeemTicketRefresh = {};
|
||||
} else {
|
||||
console.log("Skipping unknown event of type " + thisName);
|
||||
}
|
||||
@ -981,7 +1303,10 @@ const parseSequenceEvent = async function () {
|
||||
await dbObj.save();
|
||||
}
|
||||
updateMonthlyMoveStake(eventObj.blockTime, eventObj.stake);
|
||||
alreadyHasMonthlyStatRefresh = {};
|
||||
stakeEventCache.push(eventObj);
|
||||
alreadyHasAnyRefresh = {};
|
||||
alreadyHasStakeRefresh = {};
|
||||
} else if (eventContainsBond && eventContainsTranscoderActivated) {
|
||||
console.log('Parsing TranscoderActivated sequence event');
|
||||
// Bond -> TranscoderActivated: activation in Round #
|
||||
@ -998,7 +1323,10 @@ const parseSequenceEvent = async function () {
|
||||
await dbObj.save();
|
||||
}
|
||||
updateMonthlyActivation(eventObj.blockTime, eventObj.initialStake);
|
||||
alreadyHasMonthlyStatRefresh = {};
|
||||
activateEventCache.push(eventObj);
|
||||
alreadyHasAnyRefresh = {};
|
||||
alreadyHasActivateRefresh = {};
|
||||
} else if (eventContainsTranscoderActivated) {
|
||||
console.log('Parsing lone TranscoderActivated sequence event');
|
||||
// Lone TranscoderActivated: reactivation
|
||||
@ -1014,7 +1342,10 @@ const parseSequenceEvent = async function () {
|
||||
await dbObj.save();
|
||||
}
|
||||
updateMonthlyReactivated(eventObj.blockTime);
|
||||
alreadyHasMonthlyStatRefresh = {};
|
||||
activateEventCache.push(eventObj);
|
||||
alreadyHasAnyRefresh = {};
|
||||
alreadyHasActivateRefresh = {};
|
||||
} else if (eventContainsUnbond) {
|
||||
console.log('Parsing lone unbond sequence event');
|
||||
// Lone Unbond: delegator unstaked
|
||||
@ -1032,7 +1363,10 @@ const parseSequenceEvent = async function () {
|
||||
await dbObj.save();
|
||||
}
|
||||
updateMonthlyUnbond(eventObj.blockTime, eventObj.stake);
|
||||
alreadyHasMonthlyStatRefresh = {};
|
||||
unbondEventCache.push(eventObj);
|
||||
alreadyHasAnyRefresh = {};
|
||||
alreadyHasUnbondRefresh = {};
|
||||
} else if (eventContainsBond) {
|
||||
console.log('Parsing lone bond sequence event');
|
||||
// Lone Bond: new delegator (Stake event)
|
||||
@ -1050,7 +1384,10 @@ const parseSequenceEvent = async function () {
|
||||
await dbObj.save();
|
||||
}
|
||||
updateMonthlyNewDelegator(eventObj.blockTime, eventObj.stake);
|
||||
alreadyHasMonthlyStatRefresh = {};
|
||||
stakeEventCache.push(eventObj);
|
||||
alreadyHasAnyRefresh = {};
|
||||
alreadyHasStakeRefresh = {};
|
||||
} else if (eventContainsRebond) {
|
||||
console.log('Parsing lone rebond sequence event');
|
||||
// Lone Rebond: delegator increased their stake (Stake event)
|
||||
@ -1068,6 +1405,8 @@ const parseSequenceEvent = async function () {
|
||||
// No monthly stats
|
||||
}
|
||||
stakeEventCache.push(eventObj);
|
||||
alreadyHasAnyRefresh = {};
|
||||
alreadyHasStakeRefresh = {};
|
||||
} else {
|
||||
console.log('Skipping unknown sequence event');
|
||||
}
|
||||
@ -1087,6 +1426,109 @@ const onNewEvent = async function (thisEvent) {
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
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 getRoundInfo = async function (blockNumber) {
|
||||
// Get round info from gql
|
||||
const roundQuery = gql`{
|
||||
rounds(where: {startBlock_lte: "${blockNumber}"}) {
|
||||
id
|
||||
length
|
||||
startBlock
|
||||
endBlock
|
||||
mintableTokens
|
||||
volumeETH
|
||||
volumeUSD
|
||||
totalActiveStake
|
||||
totalSupply
|
||||
participationRate
|
||||
movedStake
|
||||
newStake
|
||||
}
|
||||
}
|
||||
`;
|
||||
const roundObj = await request("https://api.thegraph.com/subgraphs/name/livepeer/arbitrum-one", roundQuery);
|
||||
// Not found
|
||||
if (!roundObj) {
|
||||
console.log("No round found at block " + blockNumber);
|
||||
return {};
|
||||
}
|
||||
console.log("This functions is not implemented yet. Logging element to console...")
|
||||
console.log(roundObj);
|
||||
// TODO filter out down to 1 round
|
||||
return roundObj;
|
||||
// Update cache
|
||||
roundCache.push(roundObj);
|
||||
// Only save if the endBlock is elapsed
|
||||
if (latestBlockInChain > roundObj.endBlock) {
|
||||
const data = {
|
||||
number: roundObj.number,
|
||||
lengthBlocks: roundObj.lengthBlocks,
|
||||
startBlock: roundObj.startBlock,
|
||||
endBlock: roundObj.endBlock,
|
||||
mintableTokens: roundObj.mintableTokens,
|
||||
volumeEth: roundObj.volumeEth,
|
||||
volumeUsd: roundObj.volumeUsd,
|
||||
totalActiveStake: roundObj.totalActiveStake,
|
||||
totalSupply: roundObj.totalSupply,
|
||||
participationRate: roundObj.participationRate,
|
||||
movedStake: roundObj.movedStake,
|
||||
newStake: roundObj.newStake
|
||||
}
|
||||
if (!CONF_DISABLE_DB) {
|
||||
// TODO only create if nonexistent (find and update with upsert or something)
|
||||
const dbObj = new Round(data);
|
||||
await dbObj.save();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
apiRouter.post("/getRoundAtBlock", async (req, res) => {
|
||||
try {
|
||||
const { blockNumber } = req.body;
|
||||
if (blockNumber) {
|
||||
console.log("Getting round info for block " + blockNumber);
|
||||
// See if it is cached
|
||||
for (const thisRound of roundCache) {
|
||||
if (thisRound.startBlock <= blockNumber && thisRound.endBlock >= blockNumber) {
|
||||
res.send(thisRound);
|
||||
return;
|
||||
}
|
||||
}
|
||||
// Get block info from thegraph
|
||||
console.log("Getting round info for block " + blockNumber);
|
||||
const thisRoundInfo = await getRoundInfo(blockNumber);
|
||||
res.send(thisRoundInfo);
|
||||
return;
|
||||
}
|
||||
} 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);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
||||
/*
|
||||
|
||||
SMART CONTRACT EVENTS - SYNC BLOCKS
|
||||
@ -1418,6 +1860,22 @@ const initSync = async function () {
|
||||
timestamp: 1,
|
||||
_id: 0
|
||||
});
|
||||
// Get all round info
|
||||
roundCache = await Round.find({}, {
|
||||
number: 1,
|
||||
lengthBlocks: 1,
|
||||
startBlock: 1,
|
||||
endBlock: 1,
|
||||
mintableTokens: 1,
|
||||
volumeEth: 1,
|
||||
volumeUsd: 1,
|
||||
totalActiveStake: 1,
|
||||
totalSupply: 1,
|
||||
participationRate: 1,
|
||||
movedStake: 1,
|
||||
newStake: 1,
|
||||
_id: 0
|
||||
})
|
||||
}
|
||||
|
||||
let cycle = 0;
|
||||
@ -1467,8 +1925,8 @@ const handleSync = async function () {
|
||||
// Then loop until we have reached the last known block
|
||||
while (isEventSyncing || isTicketSyncing || !getFinalTickets || !getFinalEvents) {
|
||||
await sleep(500);
|
||||
if (hasError){
|
||||
throw("Error while syncing");
|
||||
if (hasError) {
|
||||
throw ("Error while syncing");
|
||||
}
|
||||
if (isEventSyncing) {
|
||||
console.log("Parsed " + lastBlockEvents + " out of " + latestBlockInChain + " blocks for Event sync");
|
||||
@ -1847,6 +2305,9 @@ const mutateDynamicStatsFromDB = async function (orchestratorObj) {
|
||||
latestCommission: 1,
|
||||
latestTotalStake: 1
|
||||
});
|
||||
if (!doc){
|
||||
return;
|
||||
}
|
||||
let oldFeeCommission = -1;
|
||||
let oldRewardCommission = -1;
|
||||
let oldTotalStake = -1;
|
||||
@ -2607,69 +3068,5 @@ 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 = [];
|
||||
let highestEndblockSeen = 0;
|
||||
|
||||
const mutateRound = async function (scoreObj) {
|
||||
// Immediately mutate new object
|
||||
const doc = await MonthlyStat.findOneAndUpdate({
|
||||
year: year,
|
||||
month: month
|
||||
}, {
|
||||
testScores: scoreObj
|
||||
}, {
|
||||
upsert: true,
|
||||
new: true,
|
||||
setDefaultsOnInsert: true
|
||||
}); k
|
||||
// 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) {
|
||||
// See if it is cached
|
||||
for (const thisRound of roundCache) {
|
||||
if (thisRound.startBlock <= blockNumber && thisRound.endBlock >= blockNumber) {
|
||||
if (thisRound.endBlock > highestEndblockSeen) {
|
||||
|
||||
}
|
||||
res.send(thisAddr);
|
||||
}
|
||||
}
|
||||
// Check DB
|
||||
// If exists, mutate cache and return value
|
||||
// Get from thegraph
|
||||
console.log("Getting new Orchestrator scores for " + year + "-" + month + " @ " + url);
|
||||
// Save to DB
|
||||
mutateRound();
|
||||
}
|
||||
} 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;
|
@ -28,6 +28,8 @@ export const SET_ALL_REDEEM_TICKET_EVENTS = "SET_ALL_REDEEM_TICKET_EVENTS";
|
||||
export const SET_ALL_ACTIVATE_EVENTS = "SET_ALL_ACTIVATE_EVENTS";
|
||||
export const SET_ALL_UNBOND_EVENTS = "SET_ALL_UNBOND_EVENTS";
|
||||
export const SET_ALL_STAKE_EVENTS = "SET_ALL_STAKE_EVENTS";
|
||||
export const SET_ALL_ROUNDS = "SET_ALL_ROUNDS";
|
||||
export const SET_ADD_ROUNDS = "SET_ADD_ROUNDS";
|
||||
|
||||
const setQuotes = message => ({
|
||||
type: RECEIVE_QUOTES, message
|
||||
@ -125,6 +127,14 @@ const setAllStakeEvents = message => ({
|
||||
type: SET_ALL_STAKE_EVENTS, message
|
||||
});
|
||||
|
||||
const setAllRounds = message => ({
|
||||
type: SET_ALL_ROUNDS, message
|
||||
});
|
||||
|
||||
const setAddRound = message => ({
|
||||
type: SET_ADD_ROUNDS, message
|
||||
});
|
||||
|
||||
export const getQuotes = () => async dispatch => {
|
||||
const response = await apiUtil.getQuotes();
|
||||
const data = await response.json();
|
||||
@ -240,11 +250,13 @@ export const getAllDelInfo = () => async dispatch => {
|
||||
return dispatch(receiveErrors(data));
|
||||
};
|
||||
|
||||
export const getAllMonthlyStats = () => async dispatch => {
|
||||
const response = await apiUtil.getAllMonthlyStats();
|
||||
export const getAllMonthlyStats = (smartUpdate) => async dispatch => {
|
||||
const response = await apiUtil.getAllMonthlyStats(smartUpdate);
|
||||
const data = await response.json();
|
||||
if (response.ok) {
|
||||
return dispatch(setAllMonthlyStats(data));
|
||||
if (!data.noop) {
|
||||
return dispatch(setAllMonthlyStats(data));
|
||||
}
|
||||
}
|
||||
return dispatch(receiveErrors(data));
|
||||
};
|
||||
@ -267,112 +279,165 @@ export const getAllTotalStakes = () => async dispatch => {
|
||||
return dispatch(receiveErrors(data));
|
||||
};
|
||||
|
||||
export const getAllUpdateEvents = () => async dispatch => {
|
||||
const response = await apiUtil.getAllUpdateEvents();
|
||||
export const hasAnyRefresh = async () => {
|
||||
const response = await apiUtil.hasAnyRefresh();
|
||||
const data = await response.json();
|
||||
if (response.ok) {
|
||||
if (data && data.length){
|
||||
return dispatch(setAllUpdateEvents(data));
|
||||
if (data) {
|
||||
if (data.requiresRefresh) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
|
||||
export const getAllUpdateEvents = (smartUpdate) => async dispatch => {
|
||||
const response = await apiUtil.getAllUpdateEvents(smartUpdate);
|
||||
const data = await response.json();
|
||||
if (response.ok) {
|
||||
if (data && data.length) {
|
||||
if (!data.noop) {
|
||||
return dispatch(setAllUpdateEvents(data));
|
||||
}
|
||||
}
|
||||
}
|
||||
return dispatch(receiveErrors(data));
|
||||
};
|
||||
|
||||
export const getAllRewardEvents = () => async dispatch => {
|
||||
const response = await apiUtil.getAllRewardEvents();
|
||||
export const getAllRewardEvents = (smartUpdate) => async dispatch => {
|
||||
const response = await apiUtil.getAllRewardEvents(smartUpdate);
|
||||
const data = await response.json();
|
||||
if (response.ok) {
|
||||
if (data && data.length){
|
||||
return dispatch(setAllRewardEvents(data));
|
||||
if (data && data.length) {
|
||||
if (!data.noop) {
|
||||
return dispatch(setAllRewardEvents(data));
|
||||
}
|
||||
}
|
||||
}
|
||||
return dispatch(receiveErrors(data));
|
||||
};
|
||||
|
||||
export const getAllClaimEvents = () => async dispatch => {
|
||||
const response = await apiUtil.getAllClaimEvents();
|
||||
export const getAllClaimEvents = (smartUpdate) => async dispatch => {
|
||||
const response = await apiUtil.getAllClaimEvents(smartUpdate);
|
||||
const data = await response.json();
|
||||
if (response.ok) {
|
||||
if (data && data.length){
|
||||
return dispatch(setAllClaimEvents(data));
|
||||
if (data && data.length) {
|
||||
if (!data.noop) {
|
||||
return dispatch(setAllClaimEvents(data));
|
||||
}
|
||||
}
|
||||
}
|
||||
return dispatch(receiveErrors(data));
|
||||
};
|
||||
|
||||
export const getAllWithdrawStakeEvents = () => async dispatch => {
|
||||
const response = await apiUtil.getAllWithdrawStakeEvents();
|
||||
export const getAllWithdrawStakeEvents = (smartUpdate) => async dispatch => {
|
||||
const response = await apiUtil.getAllWithdrawStakeEvents(smartUpdate);
|
||||
const data = await response.json();
|
||||
if (response.ok) {
|
||||
if (data && data.length){
|
||||
return dispatch(setAllWithdrawStakeEvents(data));
|
||||
if (data && data.length) {
|
||||
if (!data.noop) {
|
||||
return dispatch(setAllWithdrawStakeEvents(data));
|
||||
}
|
||||
}
|
||||
}
|
||||
return dispatch(receiveErrors(data));
|
||||
};
|
||||
|
||||
export const getAllWithdrawFeesEvents = () => async dispatch => {
|
||||
const response = await apiUtil.getAllWithdrawFeesEvents();
|
||||
export const getAllWithdrawFeesEvents = (smartUpdate) => async dispatch => {
|
||||
const response = await apiUtil.getAllWithdrawFeesEvents(smartUpdate);
|
||||
const data = await response.json();
|
||||
if (response.ok) {
|
||||
if (data && data.length){
|
||||
return dispatch(setAllWithdrawFeesEvents(data));
|
||||
if (data && data.length) {
|
||||
if (!data.noop) {
|
||||
return dispatch(setAllWithdrawFeesEvents(data));
|
||||
}
|
||||
}
|
||||
}
|
||||
return dispatch(receiveErrors(data));
|
||||
};
|
||||
|
||||
export const getAllTransferTicketEvents = () => async dispatch => {
|
||||
const response = await apiUtil.getAllTransferTicketEvents();
|
||||
export const getAllTransferTicketEvents = (smartUpdate) => async dispatch => {
|
||||
const response = await apiUtil.getAllTransferTicketEvents(smartUpdate);
|
||||
const data = await response.json();
|
||||
if (response.ok) {
|
||||
if (data && data.length){
|
||||
return dispatch(setAllTransferTicketEvents(data));
|
||||
if (data && data.length) {
|
||||
if (!data.noop) {
|
||||
return dispatch(setAllTransferTicketEvents(data));
|
||||
}
|
||||
}
|
||||
}
|
||||
return dispatch(receiveErrors(data));
|
||||
};
|
||||
|
||||
export const getAllRedeemTicketEvents = () => async dispatch => {
|
||||
const response = await apiUtil.getAllRedeemTicketEvents();
|
||||
export const getAllRedeemTicketEvents = (smartUpdate) => async dispatch => {
|
||||
const response = await apiUtil.getAllRedeemTicketEvents(smartUpdate);
|
||||
const data = await response.json();
|
||||
if (response.ok) {
|
||||
if (data && data.length){
|
||||
return dispatch(setAllRedeemTicketEvents(data));
|
||||
if (data && data.length) {
|
||||
if (!data.noop) {
|
||||
return dispatch(setAllRedeemTicketEvents(data));
|
||||
}
|
||||
}
|
||||
}
|
||||
return dispatch(receiveErrors(data));
|
||||
};
|
||||
|
||||
export const getAllActivateEvents = () => async dispatch => {
|
||||
const response = await apiUtil.getAllActivateEvents();
|
||||
export const getAllActivateEvents = (smartUpdate) => async dispatch => {
|
||||
const response = await apiUtil.getAllActivateEvents(smartUpdate);
|
||||
const data = await response.json();
|
||||
if (response.ok) {
|
||||
if (data && data.length){
|
||||
return dispatch(setAllActivateEvents(data));
|
||||
if (data && data.length) {
|
||||
if (!data.noop) {
|
||||
return dispatch(setAllActivateEvents(data));
|
||||
}
|
||||
}
|
||||
}
|
||||
return dispatch(receiveErrors(data));
|
||||
};
|
||||
|
||||
export const getAllUnbondEvents = () => async dispatch => {
|
||||
const response = await apiUtil.getAllUnbondEvents();
|
||||
export const getAllUnbondEvents = (smartUpdate) => async dispatch => {
|
||||
const response = await apiUtil.getAllUnbondEvents(smartUpdate);
|
||||
const data = await response.json();
|
||||
if (response.ok) {
|
||||
if (data && data.length){
|
||||
return dispatch(setAllUnbondEvents(data));
|
||||
if (data && data.length) {
|
||||
if (!data.noop) {
|
||||
return dispatch(setAllUnbondEvents(data));
|
||||
}
|
||||
}
|
||||
}
|
||||
return dispatch(receiveErrors(data));
|
||||
};
|
||||
|
||||
export const getAllStakeEvents = () => async dispatch => {
|
||||
const response = await apiUtil.getAllStakeEvents();
|
||||
export const getAllStakeEvents = (smartUpdate) => async dispatch => {
|
||||
const response = await apiUtil.getAllStakeEvents(smartUpdate);
|
||||
const data = await response.json();
|
||||
if (response.ok) {
|
||||
if (data && data.length){
|
||||
return dispatch(setAllStakeEvents(data));
|
||||
if (data && data.length) {
|
||||
if (!data.noop) {
|
||||
return dispatch(setAllStakeEvents(data));
|
||||
}
|
||||
}
|
||||
}
|
||||
return dispatch(receiveErrors(data));
|
||||
};
|
||||
};
|
||||
|
||||
export const getAllRounds = () => async dispatch => {
|
||||
const response = await apiUtil.getAllRounds();
|
||||
const data = await response.json();
|
||||
if (response.ok) {
|
||||
return dispatch(setAllRounds(data));
|
||||
}
|
||||
return dispatch(receiveErrors(data));
|
||||
};
|
||||
|
||||
export const getRoundAtBlock = (addr) => async dispatch => {
|
||||
const response = await apiUtil.getRoundAtBlock(addr);
|
||||
const data = await response.json();
|
||||
if (response.ok) {
|
||||
return dispatch(setAddRound(data));
|
||||
}
|
||||
};
|
||||
|
@ -1,11 +1,49 @@
|
||||
import React from 'react';
|
||||
import React, { useEffect, useState } from "react";
|
||||
import {
|
||||
getRoundAtBlock
|
||||
} from "../actions/livepeer";
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
|
||||
const Block = (obj) => {
|
||||
const dispatch = useDispatch();
|
||||
const livepeer = useSelector((state) => state.livepeerstate);
|
||||
const [roundInfo, setRoundInfo] = useState(null);
|
||||
const [hasRefreshed, setRefresh] = useState(false);
|
||||
|
||||
// useEffect(() => {
|
||||
// let thisInfo = null;
|
||||
// for (const round of livepeer.rounds) {
|
||||
// if (round.startBlock <= obj.block && round.endBlock >= obj.block) {
|
||||
// thisInfo = round;
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// // If it was not cached at all
|
||||
// if (thisInfo == null && !hasRefreshed) {
|
||||
// console.log("Refresh due to non-existing round containing this block");
|
||||
// setRefresh(true);
|
||||
// dispatch(getRoundAtBlock(obj.block));
|
||||
// }
|
||||
// if (thisInfo && thisInfo != roundInfo) {
|
||||
// console.log("Setting block info obj");
|
||||
// setRoundInfo(thisInfo);
|
||||
// }
|
||||
// }, [livepeer.rounds]);
|
||||
|
||||
const thisEpoch = obj.time;
|
||||
var dateObj = new Date(0);
|
||||
dateObj.setUTCSeconds(thisEpoch);
|
||||
const thisLocalDate = dateObj.toLocaleString();
|
||||
const thisOffset = (-dateObj.getTimezoneOffset() / 60);
|
||||
|
||||
// Get round info
|
||||
let thisRoundInfo;
|
||||
if (roundInfo) {
|
||||
thisRoundInfo = <p style={{ overflowWrap: 'break-word' }}>
|
||||
Round {thisRoundInfo.number}
|
||||
</p>
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="rowAlignLeft" style={{ margin: 0, marginTop: '1em', width: '100%' }}>
|
||||
<a className="selectOrch" style={{ cursor: 'alias', margin: 0 }} target="_blank" rel="noopener noreferrer" href={obj.url}>
|
||||
@ -14,6 +52,7 @@ const Block = (obj) => {
|
||||
<a className="selectOrch" style={{ cursor: 'alias', margin: 0 }} target="_blank" rel="noopener noreferrer" href={"https://arbiscan.io/block/" + obj.block}>
|
||||
<h3 style={{ padding: '0.2em', cursor: 'alias' }}>🔗</h3>
|
||||
</a>
|
||||
{thisRoundInfo}
|
||||
<span className="rowAlignRight darkText mobileSmallerFont" style={{ margin: 0 }}>
|
||||
<p style={{ overflowWrap: 'break-word' }}>
|
||||
📅 {thisLocalDate}
|
||||
|
@ -5,11 +5,12 @@ import {
|
||||
} from "../actions/user";
|
||||
import {
|
||||
getQuotes, getBlockchainData, getCurrentOrchestratorInfo,
|
||||
getAllEnsDomains, getAllEnsInfo, getAllOrchScores, getAllOrchInfo,
|
||||
getAllEnsDomains, getAllEnsInfo, getAllOrchScores, getAllOrchInfo,
|
||||
getAllDelInfo, getAllMonthlyStats, getAllUpdateEvents, getAllRewardEvents,
|
||||
getAllClaimEvents, getAllWithdrawStakeEvents, getAllWithdrawFeesEvents,
|
||||
getAllTransferTicketEvents, getAllRedeemTicketEvents, getAllActivateEvents,
|
||||
getAllUnbondEvents, getAllStakeEvents, getAllCommissions, getAllTotalStakes
|
||||
getAllUnbondEvents, getAllStakeEvents, getAllCommissions, getAllTotalStakes,
|
||||
hasAnyRefresh
|
||||
} from "../actions/livepeer";
|
||||
import { login } from "../actions/session";
|
||||
|
||||
@ -18,6 +19,9 @@ import { login } from "../actions/session";
|
||||
// Refresh every 60 seconds
|
||||
const refreshInterval = 60000;
|
||||
|
||||
// Refresh Events every 10 seconds
|
||||
const refreshEventsInterval = 10000;
|
||||
|
||||
const Startup = (obj) => {
|
||||
const [isLoaded, setIsLoaded] = useState(false);
|
||||
const dispatch = useDispatch();
|
||||
@ -30,7 +34,28 @@ const Startup = (obj) => {
|
||||
dispatch(getCurrentOrchestratorInfo());
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
const refreshEvents = async () => {
|
||||
console.log("Checking for Events update...");
|
||||
const requiresRefresh = await hasAnyRefresh();
|
||||
if (requiresRefresh) {
|
||||
console.log("Events requires update...");
|
||||
batch(() => {
|
||||
dispatch(getAllMonthlyStats(true));
|
||||
dispatch(getAllUpdateEvents(true));
|
||||
dispatch(getAllRewardEvents(true));
|
||||
dispatch(getAllClaimEvents(true));
|
||||
dispatch(getAllWithdrawStakeEvents(true));
|
||||
dispatch(getAllWithdrawFeesEvents(true));
|
||||
dispatch(getAllTransferTicketEvents(true));
|
||||
dispatch(getAllRedeemTicketEvents(true));
|
||||
dispatch(getAllActivateEvents(true));
|
||||
dispatch(getAllUnbondEvents(true));
|
||||
dispatch(getAllStakeEvents(true));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const refreshLogin = () => {
|
||||
console.log("Logging in and getting visitor statistics...");
|
||||
batch(() => {
|
||||
@ -46,41 +71,51 @@ const Startup = (obj) => {
|
||||
dispatch(getAllEnsInfo());
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
const refreshStaticProps = () => {
|
||||
console.log("Refreshing global data...");
|
||||
batch(() => {
|
||||
dispatch(getAllOrchInfo());
|
||||
dispatch(getAllDelInfo());
|
||||
dispatch(getAllOrchScores());
|
||||
dispatch(getAllMonthlyStats());
|
||||
dispatch(getAllMonthlyStats(false));
|
||||
dispatch(getAllCommissions());
|
||||
dispatch(getAllTotalStakes());
|
||||
dispatch(getAllUpdateEvents());
|
||||
dispatch(getAllRewardEvents());
|
||||
dispatch(getAllClaimEvents());
|
||||
dispatch(getAllWithdrawStakeEvents());
|
||||
dispatch(getAllWithdrawFeesEvents());
|
||||
dispatch(getAllTransferTicketEvents());
|
||||
dispatch(getAllRedeemTicketEvents());
|
||||
dispatch(getAllActivateEvents());
|
||||
dispatch(getAllUnbondEvents());
|
||||
dispatch(getAllStakeEvents());
|
||||
dispatch(getAllUpdateEvents(false));
|
||||
dispatch(getAllRewardEvents(false));
|
||||
dispatch(getAllClaimEvents(false));
|
||||
dispatch(getAllWithdrawStakeEvents(false));
|
||||
dispatch(getAllWithdrawFeesEvents(false));
|
||||
dispatch(getAllTransferTicketEvents(false));
|
||||
dispatch(getAllRedeemTicketEvents(false));
|
||||
dispatch(getAllActivateEvents(false));
|
||||
dispatch(getAllUnbondEvents(false));
|
||||
dispatch(getAllStakeEvents(false));
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
refreshLogin();
|
||||
refreshAllZeData();
|
||||
refreshENS();
|
||||
refreshStaticProps();
|
||||
setIsLoaded(true);
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (refreshInterval) {
|
||||
const interval = setInterval(refreshAllZeData, refreshInterval);
|
||||
return () => clearInterval(interval);
|
||||
}
|
||||
}, [refreshInterval]);
|
||||
|
||||
useEffect(() => {
|
||||
if (refreshEventsInterval) {
|
||||
const intervalEvents = setInterval(refreshEvents, refreshEventsInterval);
|
||||
return () => clearInterval(intervalEvents);
|
||||
}
|
||||
}, [refreshEventsInterval]);
|
||||
|
||||
const texts = [
|
||||
"Preloading all the things...",
|
||||
"Preloading all the things...",
|
||||
@ -107,7 +142,7 @@ const Startup = (obj) => {
|
||||
</div>
|
||||
<div className="verticalDivider" />
|
||||
<div className="stroke roundedOpaque" style={{ width: 'unset', padding: '5em' }}>
|
||||
<h1>{texts[Math.floor(Math.random() * texts.length)]}</h1>
|
||||
<h1>{texts[Math.floor(Math.random() * texts.length)]}</h1>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
|
@ -25,7 +25,9 @@ import {
|
||||
SET_ALL_REDEEM_TICKET_EVENTS,
|
||||
SET_ALL_ACTIVATE_EVENTS,
|
||||
SET_ALL_UNBOND_EVENTS,
|
||||
SET_ALL_STAKE_EVENTS
|
||||
SET_ALL_STAKE_EVENTS,
|
||||
SET_ALL_ROUNDS,
|
||||
SET_ADD_ROUNDS
|
||||
} from "../../actions/livepeer";
|
||||
|
||||
export default (state = {
|
||||
@ -46,6 +48,7 @@ export default (state = {
|
||||
activateEvents: [],
|
||||
unbondEvents: [],
|
||||
stakeEvents: [],
|
||||
rounds: []
|
||||
}, { type, message }) => {
|
||||
Object.freeze(state);
|
||||
switch (type) {
|
||||
@ -132,6 +135,13 @@ export default (state = {
|
||||
return { ...state, unbondEvents: message };
|
||||
case SET_ALL_STAKE_EVENTS:
|
||||
return { ...state, stakeEvents: message };
|
||||
case SET_ALL_ROUNDS:
|
||||
return { ...state, rounds: message };
|
||||
case SET_ADD_ROUNDS:
|
||||
return {
|
||||
...state,
|
||||
rounds: [...state.rounds, message]
|
||||
};
|
||||
default:
|
||||
return { ...state };
|
||||
}
|
||||
|
@ -90,24 +90,6 @@ export const getEnsInfo = (addr) => (
|
||||
})
|
||||
);
|
||||
|
||||
export const getAllThreeBox = () => (
|
||||
fetch("api/livepeer/getAllThreeBox/", {
|
||||
method: "GET",
|
||||
headers: {
|
||||
"Content-Type": "application/json"
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
export const getThreeBox = (addr) => (
|
||||
fetch("api/livepeer/getThreeBox/" + addr, {
|
||||
method: "GET",
|
||||
headers: {
|
||||
"Content-Type": "application/json"
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
export const getOrchestratorScores = (year, month) => (
|
||||
fetch("api/livepeer/getOrchestratorScores", {
|
||||
method: "POST",
|
||||
@ -145,9 +127,10 @@ export const getAllDelInfo = () => (
|
||||
})
|
||||
);
|
||||
|
||||
export const getAllMonthlyStats = () => (
|
||||
export const getAllMonthlyStats = (smartUpdate) => (
|
||||
fetch("api/livepeer/getAllMonthlyStats", {
|
||||
method: "GET",
|
||||
method: "POST",
|
||||
body: JSON.stringify({ smartUpdate }),
|
||||
headers: {
|
||||
"Content-Type": "application/json"
|
||||
}
|
||||
@ -172,80 +155,108 @@ export const getAllTotalStakes = () => (
|
||||
})
|
||||
);
|
||||
|
||||
export const getAllUpdateEvents = () => (
|
||||
export const getAllUpdateEvents = (smartUpdate) => (
|
||||
fetch("api/livepeer/getAllUpdateEvents", {
|
||||
method: "GET",
|
||||
method: "POST",
|
||||
body: JSON.stringify({ smartUpdate }),
|
||||
headers: {
|
||||
"Content-Type": "application/json"
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
export const getAllRewardEvents = () => (
|
||||
export const getAllRewardEvents = (smartUpdate) => (
|
||||
fetch("api/livepeer/getAllRewardEvents", {
|
||||
method: "GET",
|
||||
method: "POST",
|
||||
body: JSON.stringify({ smartUpdate }),
|
||||
headers: {
|
||||
"Content-Type": "application/json"
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
export const getAllClaimEvents = () => (
|
||||
export const getAllClaimEvents = (smartUpdate) => (
|
||||
fetch("api/livepeer/getAllClaimEvents", {
|
||||
method: "GET",
|
||||
method: "POST",
|
||||
body: JSON.stringify({ smartUpdate }),
|
||||
headers: {
|
||||
"Content-Type": "application/json"
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
export const getAllWithdrawStakeEvents = () => (
|
||||
export const getAllWithdrawStakeEvents = (smartUpdate) => (
|
||||
fetch("api/livepeer/getAllWithdrawStakeEvents", {
|
||||
method: "GET",
|
||||
method: "POST",
|
||||
body: JSON.stringify({ smartUpdate }),
|
||||
headers: {
|
||||
"Content-Type": "application/json"
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
export const getAllWithdrawFeesEvents = () => (
|
||||
export const getAllWithdrawFeesEvents = (smartUpdate) => (
|
||||
fetch("api/livepeer/getAllWithdrawFeesEvents", {
|
||||
method: "GET",
|
||||
method: "POST",
|
||||
body: JSON.stringify({ smartUpdate }),
|
||||
headers: {
|
||||
"Content-Type": "application/json"
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
export const getAllTransferTicketEvents = () => (
|
||||
export const getAllTransferTicketEvents = (smartUpdate) => (
|
||||
fetch("api/livepeer/getAllTransferTicketEvents", {
|
||||
method: "GET",
|
||||
method: "POST",
|
||||
body: JSON.stringify({ smartUpdate }),
|
||||
headers: {
|
||||
"Content-Type": "application/json"
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
export const getAllRedeemTicketEvents = () => (
|
||||
export const getAllRedeemTicketEvents = (smartUpdate) => (
|
||||
fetch("api/livepeer/getAllRedeemTicketEvents", {
|
||||
method: "GET",
|
||||
method: "POST",
|
||||
body: JSON.stringify({ smartUpdate }),
|
||||
headers: {
|
||||
"Content-Type": "application/json"
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
export const getAllActivateEvents = () => (
|
||||
export const getAllActivateEvents = (smartUpdate) => (
|
||||
fetch("api/livepeer/getAllActivateEvents", {
|
||||
method: "GET",
|
||||
method: "POST",
|
||||
body: JSON.stringify({ smartUpdate }),
|
||||
headers: {
|
||||
"Content-Type": "application/json"
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
export const getAllUnbondEvents = () => (
|
||||
export const getAllUnbondEvents = (smartUpdate) => (
|
||||
fetch("api/livepeer/getAllUnbondEvents", {
|
||||
method: "POST",
|
||||
body: JSON.stringify({ smartUpdate }),
|
||||
headers: {
|
||||
"Content-Type": "application/json"
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
export const getAllStakeEvents = (smartUpdate) => (
|
||||
fetch("api/livepeer/getAllStakeEvents", {
|
||||
method: "POST",
|
||||
body: JSON.stringify({ smartUpdate }),
|
||||
headers: {
|
||||
"Content-Type": "application/json"
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
export const hasAnyRefresh = () => (
|
||||
fetch("api/livepeer/hasAnyRefresh", {
|
||||
method: "GET",
|
||||
headers: {
|
||||
"Content-Type": "application/json"
|
||||
@ -253,11 +264,21 @@ export const getAllUnbondEvents = () => (
|
||||
})
|
||||
);
|
||||
|
||||
export const getAllStakeEvents = () => (
|
||||
fetch("api/livepeer/getAllStakeEvents", {
|
||||
export const getAllRounds = () => (
|
||||
fetch("api/livepeer/getAllRounds", {
|
||||
method: "GET",
|
||||
headers: {
|
||||
"Content-Type": "application/json"
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
export const getRoundAtBlock = (blockNumber) => (
|
||||
fetch("api/livepeer/getRoundAtBlock", {
|
||||
method: "POST",
|
||||
body: JSON.stringify({ blockNumber }),
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
})
|
||||
);
|
Loading…
x
Reference in New Issue
Block a user