Keep qualification and matrix state live between snapshots
The tail added new members but never updated the referrer's directCount, the parent's matrix slots, or the recipient's earnedPol — so a member who qualified mid-day kept showing 1/2 in tree views until the next daily snapshot (hit live: #63 joined under #35 at 22:56 UTC and #35 still displayed unqualified). Registrations now increment the referrer's count and wire the new member into the parent's l/r; payouts bump the recipient's earnedPol. One-time re-snapshot on deploy trues up the stale state. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -55,6 +55,8 @@ function loadState() {
|
|||||||
}
|
}
|
||||||
// income rows saved before desc-classification existed: re-snapshot to backfill
|
// income rows saved before desc-classification existed: re-snapshot to backfill
|
||||||
if (state.payouts.some(p => p.kind === 'income' && !p.desc)) state.snapshotAt = 0;
|
if (state.payouts.some(p => p.kind === 'income' && !p.desc)) state.snapshotAt = 0;
|
||||||
|
// one-time true-up: earlier tail code didn't maintain directCount/matrix slots live
|
||||||
|
if (!state.migratedLiveCounts) { state.snapshotAt = 0; state.migratedLiveCounts = true; }
|
||||||
}
|
}
|
||||||
function saveState() {
|
function saveState() {
|
||||||
try {
|
try {
|
||||||
@@ -221,7 +223,10 @@ async function processRange(fromBlock, toBlock) {
|
|||||||
if (l.topics[0] === T_REGISTERED) {
|
if (l.topics[0] === T_REGISTERED) {
|
||||||
const id = topicInt(l.topics[1]);
|
const id = topicInt(l.topics[1]);
|
||||||
if (!state.members[id]) {
|
if (!state.members[id]) {
|
||||||
state.members[id] = { account: topicAddr(l.topics[2]), referrerId: topicInt(l.topics[3]), tier: wInt(l.data, 0), joinedAt: ts };
|
state.members[id] = { account: topicAddr(l.topics[2]), referrerId: topicInt(l.topics[3]), tier: wInt(l.data, 0), joinedAt: ts, level: 1, directCount: 0, earnedPol: 0 };
|
||||||
|
// keep the referrer's qualification progress live between snapshots
|
||||||
|
const ref = state.members[topicInt(l.topics[3])];
|
||||||
|
if (ref) ref.directCount = (ref.directCount || 0) + 1;
|
||||||
newIds.push(id);
|
newIds.push(id);
|
||||||
emit({ type: 'registered', id, referrerId: topicInt(l.topics[3]), tierName: tierName(wInt(l.data, 0)), tx, ts });
|
emit({ type: 'registered', id, referrerId: topicInt(l.topics[3]), tierName: tierName(wInt(l.data, 0)), tx, ts });
|
||||||
}
|
}
|
||||||
@@ -249,13 +254,22 @@ async function processRange(fromBlock, toBlock) {
|
|||||||
if (twinIdx >= 0) state.payouts[twinIdx] = p;
|
if (twinIdx >= 0) state.payouts[twinIdx] = p;
|
||||||
else {
|
else {
|
||||||
state.payouts.push(p); state.totals.count++; state.totals.pol = +(state.totals.pol + p.pol).toFixed(6);
|
state.payouts.push(p); state.totals.count++; state.totals.pol = +(state.totals.pol + p.pol).toFixed(6);
|
||||||
|
const rcpt = state.members[p.toId];
|
||||||
|
if (rcpt) rcpt.earnedPol = +((rcpt.earnedPol || 0) + p.pol).toFixed(6);
|
||||||
emit({ type: 'payout', kind: p.kind, toId: p.toId, fromId: p.fromId, pol: p.pol, levelName: levelName(p.level), upgrade: p.upgrade, tx, ts });
|
emit({ type: 'payout', kind: p.kind, toId: p.toId, fromId: p.fromId, pol: p.pol, levelName: levelName(p.level), upgrade: p.upgrade, tx, ts });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (const id of newIds) {
|
for (const id of newIds) {
|
||||||
try { const m = await fetchMember(id); if (m) Object.assign(state.members[id], { uplineId: m.uplineId, level: m.level }); }
|
try {
|
||||||
catch (e) { /* picked up by next snapshot */ }
|
const m = await fetchMember(id);
|
||||||
|
if (m) {
|
||||||
|
Object.assign(state.members[id], { uplineId: m.uplineId, level: m.level });
|
||||||
|
// wire the new member into the parent's matrix slots so trees update live
|
||||||
|
const par = state.members[m.uplineId];
|
||||||
|
if (par) { if (!par.l) par.l = id; else if (!par.r && par.l !== id) par.r = id; }
|
||||||
|
}
|
||||||
|
} catch (e) { /* picked up by next snapshot */ }
|
||||||
}
|
}
|
||||||
state.payouts.sort((a, b) => (a.ts || 0) - (b.ts || 0));
|
state.payouts.sort((a, b) => (a.ts || 0) - (b.ts || 0));
|
||||||
if (state.payouts.length > KEEP_PAYOUTS) state.payouts = state.payouts.slice(-KEEP_PAYOUTS);
|
if (state.payouts.length > KEEP_PAYOUTS) state.payouts = state.payouts.slice(-KEEP_PAYOUTS);
|
||||||
|
|||||||
Reference in New Issue
Block a user