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:
Marco van Dijk 2022-05-06 17:16:51 +02:00
parent e9dc60bf3c
commit 794e000c46
6 changed files with 746 additions and 179 deletions

View File

@ -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;

View File

@ -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));
}
};

View File

@ -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' }}>
📅&nbsp;{thisLocalDate}

View File

@ -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>
)

View File

@ -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 };
}

View File

@ -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'
}
})
);