From 9f651e854fc4e20c503b80bf4d3995c4052d0432 Mon Sep 17 00:00:00 2001 From: dtfiedler Date: Tue, 22 Oct 2024 14:56:02 -0500 Subject: [PATCH 1/5] fix(supply): modify the json implementation to not modify large numbers if full integers --- src/json.lua | 8 ++- src/main.lua | 14 ++-- tests/monitor/monitor.test.mjs | 124 ++++++++++++++++----------------- 3 files changed, 76 insertions(+), 70 deletions(-) diff --git a/src/json.lua b/src/json.lua index d8ee08e..c215d4c 100644 --- a/src/json.lua +++ b/src/json.lua @@ -104,7 +104,13 @@ local function encode_number(val) if val ~= val or val <= -math.huge or val >= math.huge then error("unexpected number value '" .. tostring(val) .. "'") end - return string.format("%.14g", val) + if math.floor(val) == val then + -- Large integers: avoid scientific notation and print as an integer + return string.format("%.0f", val) + else + -- Decimals: use the 'g' format to print floating point with precision, up to 14 significant digits + return string.format("%.14g", val) + end end local type_func_map = { diff --git a/src/main.lua b/src/main.lua index 837832a..927891a 100644 --- a/src/main.lua +++ b/src/main.lua @@ -1595,13 +1595,13 @@ addEventingHandler("totalTokenSupply", utils.hasMatchingTag("Action", "Total-Tok ao.send({ Target = msg.From, Action = "Total-Token-Supply-Notice", - ["Total-Token-Supply"] = totalSupply, - ["Circulating-Supply"] = circulatingSupply, - ["Locked-Supply"] = lockedSupply, - ["Staked-Supply"] = stakedSupply, - ["Delegated-Supply"] = delegatedSupply, - ["Withdraw-Supply"] = withdrawSupply, - ["Protocol-Balance"] = protocolBalance, + ["Total-Token-Supply"] = tostring(totalSupply), + ["Circulating-Supply"] = tostring(circulatingSupply), + ["Locked-Supply"] = tostring(lockedSupply), + ["Staked-Supply"] = tostring(stakedSupply), + ["Delegated-Supply"] = tostring(delegatedSupply), + ["Withdraw-Supply"] = tostring(withdrawSupply), + ["Protocol-Balance"] = tostring(protocolBalance), Data = json.encode({ -- TODO: we are losing precision on these values unexpectedly. This has been brought to the AO team - for now the tags should be correct as they are stringified total = totalSupply, diff --git a/tests/monitor/monitor.test.mjs b/tests/monitor/monitor.test.mjs index b78cc70..8f854da 100644 --- a/tests/monitor/monitor.test.mjs +++ b/tests/monitor/monitor.test.mjs @@ -174,78 +174,78 @@ describe('setup', () => { ); // TODO: there is an unknown precision loss on these values, we are discussing why with Forward. Once fixed, uncomment these tests - // const { items: balances } = await io.getBalances({ - // limit: 10_000, - // }); + const { items: balances } = await io.getBalances({ + limit: 10_000, + }); - // const protocolBalance = await io.getBalance({ - // address: processId, - // }); + const protocolBalance = await io.getBalance({ + address: processId, + }); - // assert( - // protocolBalance === supplyData.protocolBalance, - // `Protocol balance is not equal to the balance provided by the contract: ${protocolBalance} !== ${supplyData.protocolBalance}`, - // ); + assert( + protocolBalance === supplyData.protocolBalance, + `Protocol balance is not equal to the balance provided by the contract: ${protocolBalance} !== ${supplyData.protocolBalance}`, + ); - // const totalBalances = balances.reduce( - // (acc, curr) => acc + curr.balance, - // 0, - // ); - // const circulating = totalBalances - protocolBalance; - // assert( - // circulating === supplyData.circulating, - // `Circulating supply is not equal to the sum of the balances minus the protocol balance: ${circulating} !== ${supplyData.circulating}`, - // ); + const totalBalances = balances.reduce( + (acc, curr) => acc + curr.balance, + 0, + ); + const circulating = totalBalances - protocolBalance; + assert( + circulating === supplyData.circulating, + `Circulating supply is not equal to the sum of the balances minus the protocol balance: ${circulating} !== ${supplyData.circulating}`, + ); - // // get the supply staked - // const { items: gateways } = await io.getGateways({ - // limit: 1000, - // }); + // get the supply staked + const { items: gateways } = await io.getGateways({ + limit: 1000, + }); - // const staked = gateways.reduce( - // (acc, curr) => acc + curr.operatorStake, - // 0, - // ); + const staked = gateways.reduce( + (acc, curr) => acc + curr.operatorStake, + 0, + ); - // assert( - // staked === supplyData.staked, - // `Staked supply is not equal to the sum of the operator stakes: ${staked} !== ${supplyData.staked}`, - // ); + assert( + staked === supplyData.staked, + `Staked supply is not equal to the sum of the operator stakes: ${staked} !== ${supplyData.staked}`, + ); - // const delegated = gateways.reduce( - // (acc, curr) => acc + curr.totalDelegatedStake, - // 0, - // ); + const delegated = gateways.reduce( + (acc, curr) => acc + curr.totalDelegatedStake, + 0, + ); - // assert( - // delegated === supplyData.delegated, - // `Delegated supply is not equal to the sum of the total delegated stakes: ${delegated} !== ${supplyData.delegated}`, - // ); + assert( + delegated === supplyData.delegated, + `Delegated supply is not equal to the sum of the total delegated stakes: ${delegated} !== ${supplyData.delegated}`, + ); - // const computedTotal = - // supplyData.circulating + - // supplyData.locked + - // supplyData.withdrawn + - // supplyData.staked + - // supplyData.delegated + - // supplyData.protocolBalance; - // assert( - // supplyData.total === computedTotal && - // computedTotal === 1000000000 * 1000000, - // `Computed total supply (${computedTotal}) is not equal to the sum of protocol balance, circulating, locked, staked, and delegated and withdrawn provided by the contract (${supplyData.total}) and does not match the expected total of 1 billion IO`, - // ); + const computedTotal = + supplyData.circulating + + supplyData.locked + + supplyData.withdrawn + + supplyData.staked + + supplyData.delegated + + supplyData.protocolBalance; + assert( + supplyData.total === computedTotal && + computedTotal === 1000000000 * 1000000, + `Computed total supply (${computedTotal}) is not equal to the sum of protocol balance, circulating, locked, staked, and delegated and withdrawn provided by the contract (${supplyData.total}) and does not match the expected total of 1 billion IO`, + ); - // const computedCirculating = - // supplyData.total - - // supplyData.locked - - // supplyData.staked - - // supplyData.delegated - - // supplyData.withdrawn - - // supplyData.protocolBalance; - // assert( - // supplyData.circulating === computedCirculating, - // `Computed circulating supply (${computedCirculating}) is not equal to the total supply minus protocol balance, locked, staked, delegated, and withdrawn provided by the contract (${supplyData.circulating})`, - // ); + const computedCirculating = + supplyData.total - + supplyData.locked - + supplyData.staked - + supplyData.delegated - + supplyData.withdrawn - + supplyData.protocolBalance; + assert( + supplyData.circulating === computedCirculating, + `Computed circulating supply (${computedCirculating}) is not equal to the total supply minus protocol balance, locked, staked, delegated, and withdrawn provided by the contract (${supplyData.circulating})`, + ); }); }); From bd4ad5057f8d64f53ce5198acf36d443d272ce53 Mon Sep 17 00:00:00 2001 From: Ariel Melendez Date: Tue, 22 Oct 2024 17:15:59 -0700 Subject: [PATCH 2/5] feat(events): ensure withdraw supply is accounted for properly in prune PE-6796 --- src/main.lua | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main.lua b/src/main.lua index 927891a..aef3a6b 100644 --- a/src/main.lua +++ b/src/main.lua @@ -240,6 +240,9 @@ end, function(msg) lastKnownCirculatingSupply = lastKnownCirculatingSupply + (pruneGatewayResults.delegateStakeReturned or 0) + (pruneGatewayResults.gatewayStakeReturned or 0) + lastKnownWithdrawSupply = lastKnownWithdrawSupply + - (pruneGatewayResults.delegateStakeReturned or 0) + - (pruneGatewayResults.gatewayStakeReturned or 0) lastKnownStakedSupply = lastKnownStakedSupply - (pruneGatewayResults.stakeSlashed or 0) local prunedGateways = pruneGatewayResults.prunedGateways or {} From 6db5df7bdfd5dfc87f1754a352d9e273941ed0bf Mon Sep 17 00:00:00 2001 From: dtfiedler Date: Wed, 23 Oct 2024 09:12:04 -0500 Subject: [PATCH 3/5] chore(json): update json to use 20 sig digits --- src/json.lua | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/json.lua b/src/json.lua index c215d4c..af533ec 100644 --- a/src/json.lua +++ b/src/json.lua @@ -104,12 +104,12 @@ local function encode_number(val) if val ~= val or val <= -math.huge or val >= math.huge then error("unexpected number value '" .. tostring(val) .. "'") end - if math.floor(val) == val then - -- Large integers: avoid scientific notation and print as an integer - return string.format("%.0f", val) + -- Handle integer values separately to avoid floating-point conversion + if math.type(val) == "integer" then + return string.format("%d", val) -- Format as an integer else - -- Decimals: use the 'g' format to print floating point with precision, up to 14 significant digits - return string.format("%.14g", val) + -- Use 20 significant digits for non-integer numbers + return string.format("%.20g", val) end end From d3f7adddcd636031cf5e3c82b1c91b5261204cad Mon Sep 17 00:00:00 2001 From: dtfiedler Date: Wed, 23 Oct 2024 09:43:35 -0500 Subject: [PATCH 4/5] chore(arns): fix arns count test --- tests/monitor/monitor.test.mjs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/monitor/monitor.test.mjs b/tests/monitor/monitor.test.mjs index 8f854da..b13724f 100644 --- a/tests/monitor/monitor.test.mjs +++ b/tests/monitor/monitor.test.mjs @@ -484,8 +484,8 @@ describe('setup', () => { const twoWeeks = 2 * 7 * 24 * 60 * 60 * 1000; it('should not have any arns records older than two weeks', async () => { let cursor = ''; - let countedTotalArns = 0; let totalArns = 0; + const uniqueNames = new Set(); do { const { items: arns, @@ -495,8 +495,8 @@ describe('setup', () => { cursor, }); totalArns = totalItems; - countedTotalArns += arns.length; for (const arn of arns) { + uniqueNames.add(arn.name); assert(arn.processId, `ARNs name '${arn.name}' has no processId`); assert(arn.type, `ARNs name '${arn.name}' has no type`); assert( @@ -532,8 +532,8 @@ describe('setup', () => { cursor = nextCursor; } while (cursor !== undefined); assert( - countedTotalArns === totalArns, - `Counted total ARNs (${countedTotalArns}) does not match total ARNs (${totalArns})`, + uniqueNames.size === totalArns, + `Counted total ARNs (${uniqueNames.size}) does not match total ARNs (${totalArns})`, ); }); }); From 7938c807c2322b5eba109103b9ff5a4d2bdc423e Mon Sep 17 00:00:00 2001 From: dtfiedler Date: Wed, 23 Oct 2024 09:45:29 -0500 Subject: [PATCH 5/5] chore(gateways): change monitor test for gateways --- tests/monitor/monitor.test.mjs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/monitor/monitor.test.mjs b/tests/monitor/monitor.test.mjs index b13724f..642b539 100644 --- a/tests/monitor/monitor.test.mjs +++ b/tests/monitor/monitor.test.mjs @@ -365,8 +365,8 @@ describe('setup', () => { ); let cursor = ''; - let countedTotalGateways = 0; let totalGateways = 0; + const uniqueGateways = new Set(); do { const { items: gateways, @@ -376,9 +376,9 @@ describe('setup', () => { cursor, }); totalGateways = totalItems; - countedTotalGateways += gateways.length; for (const gateway of gateways) { if (gateway.status === 'joined') { + uniqueGateways.add(gateway.gatewayAddress); assert( Number.isInteger(gateway.operatorStake), `Gateway ${gateway.gatewayAddress} has an invalid operator stake: ${gateway.operatorStake}`, @@ -473,8 +473,8 @@ describe('setup', () => { cursor = nextCursor; } while (cursor !== undefined); assert( - countedTotalGateways === totalGateways, - `Counted total gateways (${countedTotalGateways}) does not match total gateways (${totalGateways})`, + uniqueGateways.size === totalGateways, + `Counted total gateways (${uniqueGateways.size}) does not match total gateways (${totalGateways})`, ); }); });