Save thegraph commission and total stake data as well as monthly stat and separate

This commit is contained in:
Marco van Dijk 2022-04-19 15:30:51 +02:00
parent d32e42a926
commit 63a97ecaff
4 changed files with 245 additions and 2 deletions

View File

@ -0,0 +1,23 @@
import mongoose from 'mongoose';
const CommissionDataPointSchema = new mongoose.Schema({
address: {
type: String,
required: true
},
feeCommission: {
type: Number,
required: true
},
rewardCommission: {
type: Number,
required: true
},
timestamp: {
type: Number,
required: true
}
}, { timestamps: false });
const CommissionDataPoint = mongoose.model('CommissionDataPoint', CommissionDataPointSchema);
export default CommissionDataPoint;

View File

@ -0,0 +1,19 @@
import mongoose from 'mongoose';
const TotalStakeDataPointSchema = new mongoose.Schema({
address: {
type: String,
required: true
},
totalStake: {
type: Number,
required: true
},
timestamp: {
type: Number,
required: true
}
}, { timestamps: false });
const TotalStakeDataPoint = mongoose.model('TotalStakeDataPoint', TotalStakeDataPointSchema);
export default TotalStakeDataPoint;

View File

@ -148,8 +148,13 @@ const MonthlyStatSchema = new mongoose.Schema({
required: false, required: false,
default: [] default: []
}, },
// Dynamic stats (until the month has passed) containing latest commission, latest totalStake // History for theGraph current data for that month
orchestratorStats: { latestCommission: {
type: [Object],
required: false,
default: null
},
latestTotalStake: {
type: [Object], type: [Object],
required: false, required: false,
default: null default: null

View File

@ -491,6 +491,8 @@ const updateMonthlyTicketReceived = async function (blockTime, amount, from, to)
// If so, update that entry in winningTicketsReceived // If so, update that entry in winningTicketsReceived
if (eventObj.address == to) { if (eventObj.address == to) {
await MonthlyStat.updateOne({ await MonthlyStat.updateOne({
year: thisYear,
month: thisMonth,
'winningTicketsReceived.address': { '$ne': to } 'winningTicketsReceived.address': { '$ne': to }
}, { }, {
$inc: { $inc: {
@ -507,6 +509,8 @@ const updateMonthlyTicketReceived = async function (blockTime, amount, from, to)
// Else push new data to winningTicketsReceived // Else push new data to winningTicketsReceived
if (!hasModified) { if (!hasModified) {
await MonthlyStat.updateOne({ await MonthlyStat.updateOne({
year: thisYear,
month: thisMonth,
'winningTicketsReceived.address': { '$ne': to } 'winningTicketsReceived.address': { '$ne': to }
}, { }, {
$push: { $push: {
@ -524,6 +528,8 @@ const updateMonthlyTicketReceived = async function (blockTime, amount, from, to)
// If so, update that entry in winningTicketsSent // If so, update that entry in winningTicketsSent
if (eventObj.address == from) { if (eventObj.address == from) {
await MonthlyStat.updateOne({ await MonthlyStat.updateOne({
year: thisYear,
month: thisMonth,
'winningTicketsSent.address': { '$ne': from } 'winningTicketsSent.address': { '$ne': from }
}, { }, {
$inc: { $inc: {
@ -540,6 +546,8 @@ const updateMonthlyTicketReceived = async function (blockTime, amount, from, to)
// Else push new data to winningTicketsSent // Else push new data to winningTicketsSent
if (!hasModified) { if (!hasModified) {
await MonthlyStat.updateOne({ await MonthlyStat.updateOne({
year: thisYear,
month: thisMonth,
'winningTicketsSent.address': { '$ne': from } 'winningTicketsSent.address': { '$ne': from }
}, { }, {
$push: { $push: {
@ -605,6 +613,8 @@ const updateMonthlyTicketRedeemed = async function (blockTime, amount, address)
// If so, update that entry in winningTicketsReceived // If so, update that entry in winningTicketsReceived
if (eventObj.address == address) { if (eventObj.address == address) {
await MonthlyStat.updateOne({ await MonthlyStat.updateOne({
year: thisYear,
month: thisMonth,
'winningTicketsRedeemed.address': { '$ne': address } 'winningTicketsRedeemed.address': { '$ne': address }
}, { }, {
$inc: { $inc: {
@ -621,6 +631,8 @@ const updateMonthlyTicketRedeemed = async function (blockTime, amount, address)
// Else push new data to winningTicketsReceived // Else push new data to winningTicketsReceived
if (!hasModified) { if (!hasModified) {
await MonthlyStat.updateOne({ await MonthlyStat.updateOne({
year: thisYear,
month: thisMonth,
'winningTicketsRedeemed.address': { '$ne': address } 'winningTicketsRedeemed.address': { '$ne': address }
}, { }, {
$push: { $push: {
@ -1438,6 +1450,188 @@ Latest commission and totalStake stored in mongoDB (monthlyStat.js) and all in l
let orchestratorCache = []; let orchestratorCache = [];
const mutateNewCommissionRates = async function (address, feeCommission, rewardCommission) {
const now = new Date().getTime();
const thisMonth = dateObj.getMonth();
const thisYear = dateObj.getFullYear();
// Convert weird format to actual percentages
rewardCommission = (rewardCommission / 10000).toFixed(2);
feeCommission = (100 - (feeCommission / 10000)).toFixed(2);
// Create new data point
if (!CONF_DISABLE_DB) {
const dbObj = new Event({
address: address,
feeCommission: feeCommission,
rewardCommission: rewardCommission,
timestamp: now
});
await dbObj.save();
}
// Mutate monthly stats
// Get DB entry
const doc = await MonthlyStat.findOne({
year: thisYear,
month: thisMonth
}, {
latestCommission: 1
});
// Check to see if the doc's embedded latestCommission already contains this address
let hasModified = false;
for (const eventObj of doc.latestCommission) {
// If so, update existing entry
if (eventObj.address == address) {
await MonthlyStat.updateOne({
year: thisYear,
month: thisMonth,
'latestCommission.address': { '$ne': address }
}, {
$set: {
'latestCommission': {
feeCommission: feeCommission,
rewardCommission: rewardCommission,
timestamp: now
}
}
});
hasModified = true;
break;
}
}
// Else push new data to latestCommission
if (!hasModified) {
await MonthlyStat.updateOne({
year: thisYear,
month: thisMonth,
'latestCommission.address': { '$ne': address }
}, {
$push: {
'latestCommission': {
address: address,
feeCommission: feeCommission,
rewardCommission: rewardCommission,
timestamp: now
}
}
});
}
}
const mutateNewGlobalStake = async function (address, globalStake) {
const now = new Date().getTime();
const thisMonth = dateObj.getMonth();
const thisYear = dateObj.getFullYear();
// Create new data point
if (!CONF_DISABLE_DB) {
const dbObj = new Event({
address: address,
totalStake: globalStake,
timestamp: now
});
await dbObj.save();
}
// Mutate monthly stats
// Get DB entry
const doc = await MonthlyStat.findOne({
year: thisYear,
month: thisMonth
}, {
latestTotalStake: 1
});
// Check to see if the doc's embedded latestTotalStake already contains this address
let hasModified = false;
for (const eventObj of doc.latestTotalStake) {
// If so, update existing entry
if (eventObj.address == address) {
await MonthlyStat.updateOne({
year: thisYear,
month: thisMonth,
'latestTotalStake.address': { '$ne': address }
}, {
$set: {
'latestTotalStake': {
totalStake: globalStake,
timestamp: now
}
}
});
hasModified = true;
break;
}
}
// Else push new data to latestTotalStake
if (!hasModified) {
await MonthlyStat.updateOne({
year: thisYear,
month: thisMonth,
'latestTotalStake.address': { '$ne': address }
}, {
$push: {
'latestTotalStake': {
address: address,
totalStake: globalStake,
timestamp: now
}
}
});
}
}
const mutateDynamicStatsFromDB = async function (orchestratorObj) {
const now = new Date().getTime();
const thisMonth = dateObj.getMonth();
const thisYear = dateObj.getFullYear();
// Compare with latest entry in monthly statistics for the current month
const doc = await MonthlyStat.findOne({
year: thisYear,
month: thisMonth
}, {
latestCommission: 1,
latestTotalStake: 1
});
let oldFeeCommission = -1;
let oldRewardCommission = -1;
let oldTotalStake = -1;
// Determine latest commission rates
for (var orch of doc.latestCommission) {
if (orch.address == orchestratorObj.id) {
oldFeeCommission = orch.feeCommission;
oldRewardCommission = orch.rewardCommission;
break;
}
}
// Determine latest total stake
for (var orch of doc.latestTotalStake) {
if (orch.address == orchestratorObj.id) {
oldTotalStake = orch.totalStake;
break;
}
}
// Convert weird format to actual percentages
let newRewardCommission = (orchestratorObj.rewardCut / 10000).toFixed(2);
let newFeeCommission = (100 - (orchestratorObj.feeShare / 10000)).toFixed(2);
// If data changed, mutate
if (oldRewardCommission != newRewardCommission) {
mutateNewCommissionRates(orchestratorObj.id, orchestratorObj.feeShare, orchestratorObj.rewardCut);
} else if (oldFeeCommission != newFeeCommission) {
mutateNewCommissionRates(orchestratorObj.id, orchestratorObj.feeShare, orchestratorObj.rewardCut);
}
if (oldTotalStake != orchestratorObj.totalStake) {
mutateNewGlobalStake(orchestratorObj.id, orchestratorObj.totalStake);
}
}
const mutateDynamicStatsFromCache = async function (oldOrchestratorObj, newOrchestratorObj) {
// Check with monthly stats in cache to see if it differs
if (oldOrchestratorObj.rewardCut != newOrchestratorObj.rewardCut) {
mutateNewCommissionRates(newOrchestratorObj.id, newOrchestratorObj.feeShare, newOrchestratorObj.rewardCut);
} else if (oldOrchestratorObj.feeShare != newOrchestratorObj.feeShare) {
mutateNewCommissionRates(newOrchestratorObj.id, newOrchestratorObj.feeShare, newOrchestratorObj.rewardCut);
}
if (oldOrchestratorObj.totalStake != newOrchestratorObj.totalStake) {
mutateNewGlobalStake(newOrchestratorObj.id, newOrchestratorObj.totalStake);
}
}
// Gets info on a given Orchestrator // Gets info on a given Orchestrator
const parseOrchestrator = async function (reqAddr) { const parseOrchestrator = async function (reqAddr) {
try { try {
@ -1514,12 +1708,14 @@ const parseOrchestrator = async function (reqAddr) {
for (var idx = 0; idx < orchestratorCache.length; idx++) { for (var idx = 0; idx < orchestratorCache.length; idx++) {
if (orchestratorCache[idx].id == reqAddr) { if (orchestratorCache[idx].id == reqAddr) {
console.log("Updating outdated orchestrator " + orchestratorObj.id + " @ " + now); console.log("Updating outdated orchestrator " + orchestratorObj.id + " @ " + now);
mutateDynamicStatsFromCache(orchestratorObj, orchestratorCache[idx]);
orchestratorCache[idx] = orchestratorObj; orchestratorCache[idx] = orchestratorObj;
break; break;
} }
} }
} else { } else {
console.log("Pushing new orchestrator " + orchestratorObj.id + " @ " + now); console.log("Pushing new orchestrator " + orchestratorObj.id + " @ " + now);
mutateDynamicStatsFromDB(orchestratorObj);
orchestratorCache.push(orchestratorObj); orchestratorCache.push(orchestratorObj);
} }
} }