@render-foundation/utils 0.0.237 → 0.0.238
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/cjs/burn/burnCalculations.js +140 -0
- package/lib/cjs/burn/burnCalculations.js.map +1 -0
- package/lib/cjs/client/pg/v2Client.js +120 -1
- package/lib/cjs/client/pg/v2Client.js.map +1 -1
- package/lib/cjs/index.js +3 -1
- package/lib/cjs/index.js.map +1 -1
- package/lib/esm/src/burn/burnCalculations.js +124 -0
- package/lib/esm/src/burn/burnCalculations.js.map +1 -0
- package/lib/esm/src/client/pg/v2Client.js +116 -0
- package/lib/esm/src/client/pg/v2Client.js.map +1 -1
- package/lib/esm/src/index.js +1 -0
- package/lib/esm/src/index.js.map +1 -1
- package/lib/esm/tsconfig.esm.tsbuildinfo +1 -1
- package/lib/types/src/burn/burnCalculations.d.ts +52 -0
- package/lib/types/src/burn/burnCalculations.d.ts.map +1 -0
- package/lib/types/src/client/pg/v2Client.d.ts +39 -0
- package/lib/types/src/client/pg/v2Client.d.ts.map +1 -1
- package/lib/types/src/index.d.ts +2 -1
- package/lib/types/src/index.d.ts.map +1 -1
- package/package.json +1 -1
- package/lib/cjs/tsconfig.cjs.tsbuildinfo +0 -1
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
3
|
+
var t = {};
|
|
4
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
5
|
+
t[p] = s[p];
|
|
6
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
7
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
8
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
9
|
+
t[p[i]] = s[p[i]];
|
|
10
|
+
}
|
|
11
|
+
return t;
|
|
12
|
+
};
|
|
13
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
+
exports.calculateBurnAmounts = exports.batchFinishedAtMedian = void 0;
|
|
15
|
+
const spl_utils_1 = require("@render-foundation/spl-utils");
|
|
16
|
+
const logger_1 = require("../logger");
|
|
17
|
+
// Utility function copied from cron-server
|
|
18
|
+
const batchFinishedAtMedian = (jobs) => {
|
|
19
|
+
const pricedAt = jobs.length % 2 == 0
|
|
20
|
+
? new Date(Math.trunc((Date.parse(jobs[jobs.length / 2].finishedAt) +
|
|
21
|
+
Date.parse(jobs[jobs.length / 2 - 1].finishedAt)) /
|
|
22
|
+
2))
|
|
23
|
+
: new Date(Date.parse(jobs[Math.floor(jobs.length / 2)].finishedAt));
|
|
24
|
+
return pricedAt;
|
|
25
|
+
};
|
|
26
|
+
exports.batchFinishedAtMedian = batchFinishedAtMedian;
|
|
27
|
+
/**
|
|
28
|
+
* Pure function that calculates burn amounts without side effects
|
|
29
|
+
* This is the core logic extracted from consumeIncrBuyAndBurnRenderPG
|
|
30
|
+
*/
|
|
31
|
+
const calculateBurnAmounts = (input, opts = {
|
|
32
|
+
perpetual: true,
|
|
33
|
+
}, log = logger_1.consoleLogger) => {
|
|
34
|
+
const { jobs, userGrantSpends, burnAdjustments, params, decimals, priceAtDate, eurToUSDC, } = input;
|
|
35
|
+
// Apply grant/buy split logic to jobs
|
|
36
|
+
const processedJobs = jobs.map((j) => {
|
|
37
|
+
const { buyRenderAmt, grantRenderAmt } = j, rest = __rest(j, ["buyRenderAmt", "grantRenderAmt"]);
|
|
38
|
+
return rest;
|
|
39
|
+
}); // Deep copy to avoid mutations
|
|
40
|
+
for (const j of processedJobs) {
|
|
41
|
+
const userGrantSpend = userGrantSpends[j.userId];
|
|
42
|
+
if (userGrantSpend) {
|
|
43
|
+
if (opts.perpetual ||
|
|
44
|
+
userGrantSpend.userGrantSpend.perpetual ||
|
|
45
|
+
j.rndrUsed <= userGrantSpend.currAllot) {
|
|
46
|
+
j.grantRenderAmt = Number(j.rndrUsed);
|
|
47
|
+
log.debug(`job ${j.id} grant split: ${j.rndrUsed}`);
|
|
48
|
+
userGrantSpend.currAllot -= BigInt(j.rndrUsed);
|
|
49
|
+
}
|
|
50
|
+
else if (userGrantSpend.currAllot <= BigInt(0)) {
|
|
51
|
+
log.debug(`job ${j.id} buy split: ${j.rndrUsed}`);
|
|
52
|
+
j.buyRenderAmt = Number(j.rndrUsed);
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
log.debug(`job ${j.id} buy + grant split: ${j.rndrUsed} grant: ${Number(userGrantSpend.currAllot)} buy: ${Number(j.rndrUsed) - Number(userGrantSpend.currAllot)}`);
|
|
56
|
+
j.grantRenderAmt = Number(userGrantSpend.currAllot);
|
|
57
|
+
j.buyRenderAmt = Number(j.rndrUsed) - Number(userGrantSpend.currAllot);
|
|
58
|
+
userGrantSpend.currAllot = BigInt(0);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
log.debug(`job ${j.id} no grant split: ${j.rndrUsed}`);
|
|
63
|
+
j.buyRenderAmt = Number(j.rndrUsed);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
const totalRenderUsed = processedJobs.reduce((tot, job) => tot + Number(job.rndrUsed.toString()), 0);
|
|
67
|
+
log.debug(`jobs buy + grant split: ${JSON.stringify(processedJobs)}`);
|
|
68
|
+
// Check minimum threshold
|
|
69
|
+
if (totalRenderUsed < (0, spl_utils_1.toBN)(params.minTotalRndrThreshold, decimals).toNumber()) {
|
|
70
|
+
throw new Error(`totalRenderUsed ${totalRenderUsed / Math.pow(10, decimals)} < total threshold ${params.minTotalRndrThreshold}`);
|
|
71
|
+
}
|
|
72
|
+
const totalRenderBuyAndBurn = processedJobs.reduce((tot, job) => { var _a; return tot + Number((_a = job.buyRenderAmt) !== null && _a !== void 0 ? _a : 0); }, 0);
|
|
73
|
+
const totalRender = processedJobs.reduce((tot, job) => tot + Number(job.rndrUsed.toString()), 0);
|
|
74
|
+
log.debug(`Burn calculation inputs:`);
|
|
75
|
+
log.debug(` totalRenderUsed: ${totalRenderUsed}`);
|
|
76
|
+
log.debug(` totalRenderBuyAndBurn: ${totalRenderBuyAndBurn}`);
|
|
77
|
+
log.debug(` totalRender: ${totalRender}`);
|
|
78
|
+
log.debug(` priceAtDate: ${priceAtDate}`);
|
|
79
|
+
log.debug(` eurToUSDC: ${eurToUSDC}`);
|
|
80
|
+
const pricedAt = (0, exports.batchFinishedAtMedian)(processedJobs.map((job) => ({
|
|
81
|
+
finishedAt: job.completedAt.toISOString(),
|
|
82
|
+
jobId: job.id,
|
|
83
|
+
rndrUsed: Number(job.rndrUsed.toString()),
|
|
84
|
+
})));
|
|
85
|
+
// Core burn calculation logic
|
|
86
|
+
const toBurn = Math.trunc((totalRender / priceAtDate / 4) * 0.95 * eurToUSDC);
|
|
87
|
+
let renderToBuyAndBurn = Math.trunc((totalRenderBuyAndBurn / totalRender) * toBurn);
|
|
88
|
+
const origRenderToBuyAndBurn = renderToBuyAndBurn;
|
|
89
|
+
log.debug(`Core burn calculation:`);
|
|
90
|
+
log.debug(` toBurn: ${toBurn}`);
|
|
91
|
+
log.debug(` renderToBuyAndBurn: ${renderToBuyAndBurn}`);
|
|
92
|
+
log.debug(` origRenderToBuyAndBurn: ${origRenderToBuyAndBurn}`);
|
|
93
|
+
let burnAdjustmentId = undefined;
|
|
94
|
+
// Apply burn adjustments
|
|
95
|
+
if (burnAdjustments.length > 0) {
|
|
96
|
+
const adjustment = burnAdjustments[0];
|
|
97
|
+
burnAdjustmentId = adjustment.id;
|
|
98
|
+
const adjLeft = adjustment.downAdjToBurn - adjustment.adjusted;
|
|
99
|
+
const minBurnRndrThreshold = (0, spl_utils_1.toBN)(params.minBurnRndrThreshold, decimals).toNumber();
|
|
100
|
+
const available = renderToBuyAndBurn - minBurnRndrThreshold;
|
|
101
|
+
if (adjLeft > available) {
|
|
102
|
+
renderToBuyAndBurn = minBurnRndrThreshold;
|
|
103
|
+
}
|
|
104
|
+
else {
|
|
105
|
+
renderToBuyAndBurn -= adjLeft;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
// Validate burn thresholds
|
|
109
|
+
const toBuyAndBurnUI = renderToBuyAndBurn / Math.pow(10, decimals);
|
|
110
|
+
if (renderToBuyAndBurn != 0) {
|
|
111
|
+
if (toBuyAndBurnUI > params.maxBurnRndrThreshold) {
|
|
112
|
+
throw new Error(`buy and burn RENDER ${toBuyAndBurnUI} too high`);
|
|
113
|
+
}
|
|
114
|
+
if (toBuyAndBurnUI < params.minBurnRndrThreshold) {
|
|
115
|
+
throw new Error(`buy and burn RENDER ${toBuyAndBurnUI} too low < ${params.minBurnRndrThreshold}`);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
const renderToBurnFromEmissions = toBurn - origRenderToBuyAndBurn;
|
|
119
|
+
const totalToBurn = renderToBuyAndBurn + renderToBurnFromEmissions;
|
|
120
|
+
log.debug(`Final burn calculation results:`);
|
|
121
|
+
log.debug(` renderToBuyAndBurn: ${renderToBuyAndBurn}`);
|
|
122
|
+
log.debug(` renderToBurnFromEmissions: ${renderToBurnFromEmissions}`);
|
|
123
|
+
log.debug(` totalToBurn: ${totalToBurn}`);
|
|
124
|
+
log.debug(` toBurn: ${toBurn}`);
|
|
125
|
+
return {
|
|
126
|
+
totalRenderUsed,
|
|
127
|
+
totalRenderBuyAndBurn,
|
|
128
|
+
totalRender,
|
|
129
|
+
renderToBuyAndBurn,
|
|
130
|
+
renderToBurnFromEmissions,
|
|
131
|
+
totalToBurn,
|
|
132
|
+
toBurn,
|
|
133
|
+
origRenderToBuyAndBurn,
|
|
134
|
+
burnAdjustmentId,
|
|
135
|
+
pricedAt,
|
|
136
|
+
processedJobs,
|
|
137
|
+
};
|
|
138
|
+
};
|
|
139
|
+
exports.calculateBurnAmounts = calculateBurnAmounts;
|
|
140
|
+
//# sourceMappingURL=burnCalculations.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"burnCalculations.js","sourceRoot":"","sources":["../../../src/burn/burnCalculations.ts"],"names":[],"mappings":"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"}
|
|
@@ -35,7 +35,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
35
35
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
36
36
|
};
|
|
37
37
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
38
|
-
exports.pgClient = exports.batchFinishedAtMedian = exports.DISPERSED_BURN_CORRECTION_TABLE = exports.DISPERSED_SETTLEMENT_TABLE = exports.GRANT_BURN_TABLE = exports.GRANT_BURN_ID_TABLE = exports.USER_GRANT_SPEND_TABLE = exports.CURRENT_USER_GRANT_SPEND_TABLE = exports.POLYGON_UPGRADE_TABLE = exports.ENTITY_EPOCH_INFO_TABLE = exports.BURN_CORRECTION_TABLE = exports.NETWORK_REVENUE_TABLE = exports.BRIDGE_TRANSFER_TABLE = exports.BURN_TABLE = exports.JOB_TABLE = exports.JOB_ID_TABLE = exports.LIABILITY_ADJUSTMENT_BATCH_TABLE = exports.LIABILITY_ADJUSTMENT_TABLE = exports.LIABILITY_TABLE = exports.SOL_TRANSFER_TABLE = exports.ENTITY_TABLE = exports.MANUAL_BURN_TABLE = exports.EPOCH_TABLE = exports.SOL_TX_TABLE = void 0;
|
|
38
|
+
exports.pgClient = exports.batchFinishedAtMedian = exports.foldGrantAllotment = exports.CREDIT_DECIMALS = exports.EUR_TO_CREDITS = exports.DISPERSED_BURN_CORRECTION_TABLE = exports.DISPERSED_SETTLEMENT_TABLE = exports.GRANT_BURN_TABLE = exports.GRANT_BURN_ID_TABLE = exports.OTOY_GRANT_TABLE = exports.USER_GRANT_SPEND_TABLE = exports.CURRENT_USER_GRANT_SPEND_TABLE = exports.POLYGON_UPGRADE_TABLE = exports.ENTITY_EPOCH_INFO_TABLE = exports.BURN_CORRECTION_TABLE = exports.NETWORK_REVENUE_TABLE = exports.BRIDGE_TRANSFER_TABLE = exports.BURN_TABLE = exports.JOB_TABLE = exports.JOB_ID_TABLE = exports.LIABILITY_ADJUSTMENT_BATCH_TABLE = exports.LIABILITY_ADJUSTMENT_TABLE = exports.LIABILITY_TABLE = exports.SOL_TRANSFER_TABLE = exports.ENTITY_TABLE = exports.MANUAL_BURN_TABLE = exports.EPOCH_TABLE = exports.SOL_TX_TABLE = void 0;
|
|
39
39
|
const kysely_1 = require("kysely");
|
|
40
40
|
const logger_1 = require("../../logger");
|
|
41
41
|
const pg_1 = require("pg");
|
|
@@ -59,6 +59,7 @@ exports.ENTITY_EPOCH_INFO_TABLE = 'entity_epoch_info';
|
|
|
59
59
|
exports.POLYGON_UPGRADE_TABLE = 'polygon_upgrade';
|
|
60
60
|
exports.CURRENT_USER_GRANT_SPEND_TABLE = 'current_user_grant_spend';
|
|
61
61
|
exports.USER_GRANT_SPEND_TABLE = 'user_grant_spend';
|
|
62
|
+
exports.OTOY_GRANT_TABLE = 'otoy_grant';
|
|
62
63
|
exports.GRANT_BURN_ID_TABLE = 'grant_burn_id';
|
|
63
64
|
exports.GRANT_BURN_TABLE = 'grant_burn';
|
|
64
65
|
exports.DISPERSED_SETTLEMENT_TABLE = 'dispersed_settlement';
|
|
@@ -66,6 +67,40 @@ exports.DISPERSED_BURN_CORRECTION_TABLE = 'dispersed_burn_correction';
|
|
|
66
67
|
BigInt.prototype.toJSON = function () {
|
|
67
68
|
return this.toString();
|
|
68
69
|
};
|
|
70
|
+
// EUR -> render credits. OTOY issues grants in EUR (otoy_grant.amount_credits holds the raw OTOY
|
|
71
|
+
// confirmed_amount = EUR, despite the column name); 1 render credit = EUR 0.25, so credits = EUR x 4.
|
|
72
|
+
// job.render_amt / user_grant_spend.render_spent_delta are credits x 1e8.
|
|
73
|
+
exports.EUR_TO_CREDITS = BigInt(4);
|
|
74
|
+
exports.CREDIT_DECIMALS = BigInt(100000000); // 1e8
|
|
75
|
+
/**
|
|
76
|
+
* Pure core of the grant allotment: fold a user's OTOY grants against what's already been spent.
|
|
77
|
+
*
|
|
78
|
+
* consumed = attributedSpend (spend already stamped with an otoy_grant_id)
|
|
79
|
+
* + correctionSettled (jobs whose grant is already being settled by a burn_correction)
|
|
80
|
+
*
|
|
81
|
+
* The correctionSettled term is the DOUBLE-SPEND GUARD: an escrow_credit correction means we're
|
|
82
|
+
* recovering that job's dollars from escrow, so its grant is already committed. Counting it here stops
|
|
83
|
+
* the same grant from also funding a future emissions burn.
|
|
84
|
+
*
|
|
85
|
+
* fifoGrantId = the oldest grant still holding room, i.e. the one the next spend draws from.
|
|
86
|
+
*/
|
|
87
|
+
const foldGrantAllotment = (grants, attributedSpend, correctionSettled) => {
|
|
88
|
+
const granted = grants.reduce((s, g) => s + g.amountCredits, BigInt(0));
|
|
89
|
+
const consumed = (attributedSpend > BigInt(0) ? attributedSpend : BigInt(0)) +
|
|
90
|
+
(correctionSettled > BigInt(0) ? correctionSettled : BigInt(0));
|
|
91
|
+
const avail = granted > consumed ? granted - consumed : BigInt(0);
|
|
92
|
+
let drawn = consumed;
|
|
93
|
+
let fifoGrantId;
|
|
94
|
+
for (const g of grants) {
|
|
95
|
+
if (drawn < g.amountCredits) {
|
|
96
|
+
fifoGrantId = g.id;
|
|
97
|
+
break;
|
|
98
|
+
}
|
|
99
|
+
drawn -= g.amountCredits;
|
|
100
|
+
}
|
|
101
|
+
return { granted, consumed, avail, fifoGrantId };
|
|
102
|
+
};
|
|
103
|
+
exports.foldGrantAllotment = foldGrantAllotment;
|
|
69
104
|
const base_2 = require("./base");
|
|
70
105
|
const moment_1 = __importDefault(require("moment"));
|
|
71
106
|
pg.types.setTypeParser(1114, (str) => moment_1.default.utc(str).toDate());
|
|
@@ -190,6 +225,73 @@ const pgClient = (config) => {
|
|
|
190
225
|
}
|
|
191
226
|
: undefined;
|
|
192
227
|
});
|
|
228
|
+
// Spendable grant per user, straight off otoy_grant (FIFO), net of what's already been spent or
|
|
229
|
+
// already settled by a burn correction. See GrantAllotment for the units + the double-spend guard.
|
|
230
|
+
const getGrantAllotments = (db, p, log = logger_1.consoleLogger) => __awaiter(void 0, void 0, void 0, function* () {
|
|
231
|
+
var _b, _c, _d;
|
|
232
|
+
const out = {};
|
|
233
|
+
if (!p.userIds.length)
|
|
234
|
+
return out;
|
|
235
|
+
const grants = yield db
|
|
236
|
+
.selectFrom(exports.OTOY_GRANT_TABLE)
|
|
237
|
+
.select(['id', 'user_id', 'amount_credits', 'otoy_created_at'])
|
|
238
|
+
.where('user_id', 'in', p.userIds)
|
|
239
|
+
.orderBy('otoy_created_at', 'asc')
|
|
240
|
+
.orderBy('id', 'asc')
|
|
241
|
+
.execute();
|
|
242
|
+
if (!grants.length)
|
|
243
|
+
return out;
|
|
244
|
+
// Anything already booked against a pool grant, in EITHER direction:
|
|
245
|
+
// - negative delta = spend drawn from the grant (this mechanism)
|
|
246
|
+
// - positive delta = the grant was CREDITED into current_user_grant_spend (the one-off canary
|
|
247
|
+
// route). That balance is already handed to the caller separately, so leaving it in the pool too
|
|
248
|
+
// would hand out the same grant twice.
|
|
249
|
+
// Hence abs(): both directions retire pool capacity.
|
|
250
|
+
const spent = yield db
|
|
251
|
+
.selectFrom(exports.USER_GRANT_SPEND_TABLE)
|
|
252
|
+
.select((eb) => [
|
|
253
|
+
'user_id',
|
|
254
|
+
eb.fn.sum((0, kysely_1.sql) `abs(render_spent_delta)`).as('net'),
|
|
255
|
+
])
|
|
256
|
+
.where('user_id', 'in', p.userIds)
|
|
257
|
+
.where('otoy_grant_id', 'is not', null)
|
|
258
|
+
.groupBy('user_id')
|
|
259
|
+
.execute();
|
|
260
|
+
// jobs already settled by a burn correction — their grant is spoken for (double-spend guard)
|
|
261
|
+
const corrected = yield db
|
|
262
|
+
.selectFrom(`${exports.JOB_TABLE} as j`)
|
|
263
|
+
.innerJoin(`${exports.BURN_CORRECTION_TABLE} as bc`, 'bc.job_id', 'j.id')
|
|
264
|
+
.select((eb) => ['j.user_id as user_id', eb.fn.sum('j.render_amt').as('amt')])
|
|
265
|
+
.where('j.user_id', 'in', p.userIds)
|
|
266
|
+
.groupBy('j.user_id')
|
|
267
|
+
.execute();
|
|
268
|
+
const spentBy = new Map(spent.map((r) => { var _a; return [r.user_id, BigInt((_a = r.net) !== null && _a !== void 0 ? _a : 0)]; }));
|
|
269
|
+
const corrBy = new Map(corrected.map((r) => { var _a; return [r.user_id, BigInt((_a = r.amt) !== null && _a !== void 0 ? _a : 0)]; }));
|
|
270
|
+
for (const g of grants) {
|
|
271
|
+
const u = g.user_id;
|
|
272
|
+
const cur = (_b = out[u]) !== null && _b !== void 0 ? _b : (out[u] = { userId: u, granted: BigInt(0), consumed: BigInt(0), avail: BigInt(0), grants: [] });
|
|
273
|
+
// amount_credits is numeric EUR — truncate to whole base units after the x4 conversion
|
|
274
|
+
const credits = (BigInt(Math.round(Number(g.amount_credits) * 1e8)) * exports.EUR_TO_CREDITS);
|
|
275
|
+
cur.granted += credits;
|
|
276
|
+
cur.grants.push({
|
|
277
|
+
id: Number(g.id),
|
|
278
|
+
amountCredits: credits,
|
|
279
|
+
createdAt: g.otoy_created_at ? new Date(g.otoy_created_at) : null,
|
|
280
|
+
});
|
|
281
|
+
}
|
|
282
|
+
for (const u of Object.keys(out)) {
|
|
283
|
+
const attributed = (_c = spentBy.get(u)) !== null && _c !== void 0 ? _c : BigInt(0); // abs() — spend drawn or grant already credited
|
|
284
|
+
const viaCorrection = (_d = corrBy.get(u)) !== null && _d !== void 0 ? _d : BigInt(0);
|
|
285
|
+
const f = (0, exports.foldGrantAllotment)(out[u].grants, attributed, viaCorrection);
|
|
286
|
+
out[u].granted = f.granted;
|
|
287
|
+
out[u].consumed = f.consumed;
|
|
288
|
+
out[u].avail = f.avail;
|
|
289
|
+
if (viaCorrection > BigInt(0)) {
|
|
290
|
+
log.info(`grant allotment ${u}: granted ${f.granted} - attributed ${attributed} - correction-settled ${viaCorrection} = ${f.avail}`);
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
return out;
|
|
294
|
+
});
|
|
193
295
|
const updateTotalRndr = (db, p, totalRndr, savedAt, log) => __awaiter(void 0, void 0, void 0, function* () {
|
|
194
296
|
const res = (yield db
|
|
195
297
|
.updateTable(exports.EPOCH_TABLE)
|
|
@@ -1081,11 +1183,23 @@ const pgClient = (config) => {
|
|
|
1081
1183
|
return;
|
|
1082
1184
|
}
|
|
1083
1185
|
}
|
|
1186
|
+
// FIFO-attribute this spend to the user's oldest OTOY grant that still has room. Stamping
|
|
1187
|
+
// otoy_grant_id is what makes getGrantAllotments count it as consumed — an unattributed row
|
|
1188
|
+
// would leave the grant looking unspent and let it fund a second burn.
|
|
1189
|
+
let otoyGrantId = p.otoyGrantId;
|
|
1190
|
+
if (otoyGrantId === undefined && p.renderSpentDelta < BigInt(0)) {
|
|
1191
|
+
const allots = yield getGrantAllotments(db.trx, { userIds: [p.userId] }, log);
|
|
1192
|
+
const a = allots[p.userId];
|
|
1193
|
+
if (a) {
|
|
1194
|
+
otoyGrantId = (0, exports.foldGrantAllotment)(a.grants, a.consumed, BigInt(0)).fifoGrantId;
|
|
1195
|
+
}
|
|
1196
|
+
}
|
|
1084
1197
|
const v = {
|
|
1085
1198
|
user_id: p.userId,
|
|
1086
1199
|
render_spent_delta: p.renderSpentDelta,
|
|
1087
1200
|
grant_burn_id: p.grantBurnId,
|
|
1088
1201
|
job_id: p.jobId,
|
|
1202
|
+
otoy_grant_id: otoyGrantId,
|
|
1089
1203
|
};
|
|
1090
1204
|
const res = yield db.trx
|
|
1091
1205
|
.insertInto(exports.USER_GRANT_SPEND_TABLE)
|
|
@@ -2134,6 +2248,11 @@ const pgClient = (config) => {
|
|
|
2134
2248
|
return yield getCurrentUserGrantSpend(db.trx, f, log);
|
|
2135
2249
|
});
|
|
2136
2250
|
},
|
|
2251
|
+
getGrantAllotments(db, f, log = logger_1.consoleLogger) {
|
|
2252
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
2253
|
+
return yield getGrantAllotments(db.trx, f, log);
|
|
2254
|
+
});
|
|
2255
|
+
},
|
|
2137
2256
|
deleteAll(log = logger_1.consoleLogger) {
|
|
2138
2257
|
return __awaiter(this, void 0, void 0, function* () {
|
|
2139
2258
|
if (config.database.includes('render')) {
|