Skip to content

Commit

Permalink
fix: remove supply view, calculate supply as we mint
Browse files Browse the repository at this point in the history
  • Loading branch information
rafaelcr committed Aug 30, 2023
1 parent 1621fb4 commit 36addce
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 27 deletions.
36 changes: 36 additions & 0 deletions migrations/1693428793416_brc20-minted-supply-column.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/* eslint-disable @typescript-eslint/naming-convention */
import { MigrationBuilder, ColumnDefinitions } from 'node-pg-migrate';

export const shorthands: ColumnDefinitions | undefined = undefined;

export function up(pgm: MigrationBuilder): void {
pgm.addColumn('brc20_deploys', {
minted_supply: {
type: 'numeric',
default: 0,
},
});
pgm.sql(`
UPDATE brc20_deploys AS d
SET minted_supply = (
SELECT COALESCE(SUM(amount), 0) AS minted_supply
FROM brc20_mints
WHERE brc20_deploy_id = d.id
)
`);
pgm.dropMaterializedView('brc20_supplies');
}

export function down(pgm: MigrationBuilder): void {
pgm.dropColumn('brc20_deploys', ['minted_supply']);
pgm.createMaterializedView(
'brc20_supplies',
{ data: true },
`
SELECT brc20_deploy_id, SUM(amount) as minted_supply, MAX(block_height) as block_height
FROM brc20_mints
GROUP BY brc20_deploy_id
`
);
pgm.createIndex('brc20_supplies', ['brc20_deploy_id'], { unique: true });
}
45 changes: 19 additions & 26 deletions src/pg/brc20/brc20-pg-store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,12 +86,11 @@ export class Brc20PgStore extends BasePgStoreModule {
const results = await this.sql<(DbBrc20Token & { total: number })[]>`
SELECT
d.id, i.genesis_id, i.number, d.block_height, d.tx_id, d.address, d.ticker, d.max, d.limit,
d.decimals, l.timestamp as deploy_timestamp, COALESCE(s.minted_supply, 0) as minted_supply, COUNT(*) OVER() as total
d.decimals, l.timestamp as deploy_timestamp, d.minted_supply, COUNT(*) OVER() as total
FROM brc20_deploys AS d
INNER JOIN inscriptions AS i ON i.id = d.inscription_id
INNER JOIN genesis_locations AS g ON g.inscription_id = d.inscription_id
INNER JOIN locations AS l ON l.id = g.location_id
LEFT JOIN brc20_supplies AS s ON d.id = s.brc20_deploy_id
${tickerPrefixCondition ? this.sql`WHERE ${tickerPrefixCondition}` : this.sql``}
OFFSET ${args.offset}
LIMIT ${args.limit}
Expand Down Expand Up @@ -144,13 +143,8 @@ export class Brc20PgStore extends BasePgStoreModule {
const deploy = await this.getDeploy(args);
if (!deploy) return;

const supplyPromise = sql<{ max: string }[]>`
SELECT max FROM brc20_deploys WHERE id = ${deploy.id}
`;
const mintedPromise = sql<{ minted_supply: string }[]>`
SELECT minted_supply
FROM brc20_supplies
WHERE brc20_deploy_id = ${deploy.id}
const supplyPromise = sql<{ max: string; minted_supply: string }[]>`
SELECT max, minted_supply FROM brc20_deploys WHERE id = ${deploy.id}
`;
const holdersPromise = sql<{ count: string }[]>`
SELECT COUNT(*) AS count
Expand All @@ -159,11 +153,11 @@ export class Brc20PgStore extends BasePgStoreModule {
GROUP BY address
HAVING SUM(avail_balance + trans_balance) > 0
`;
const settles = await Promise.allSettled([supplyPromise, holdersPromise, mintedPromise]);
const [supply, holders, minted] = throwOnFirstRejected(settles);
const settles = await Promise.allSettled([supplyPromise, holdersPromise]);
const [supply, holders] = throwOnFirstRejected(settles);
return {
max_supply: supply[0].max,
minted_supply: minted[0]?.minted_supply ?? '0',
minted_supply: supply[0]?.minted_supply ?? '0',
holders: holders[0]?.count ?? '0',
};
});
Expand Down Expand Up @@ -283,23 +277,17 @@ export class Brc20PgStore extends BasePgStoreModule {
// * Does the mint amount exceed remaining supply?
const mintRes = await this.sql`
WITH mint_data AS (
SELECT
d.id, d.decimals, d.limit, d.max,
COALESCE(SUM(amount), 0) AS minted_supply
FROM brc20_deploys AS d
LEFT JOIN brc20_mints AS m ON m.brc20_deploy_id = d.id
WHERE d.ticker_lower = LOWER(${mint.op.tick})
GROUP BY d.id
SELECT id, decimals, "limit", max, minted_supply
FROM brc20_deploys
WHERE ticker_lower = LOWER(${mint.op.tick}) AND minted_supply < max
),
validated_mint AS (
SELECT
m.id AS brc20_deploy_id,
LEAST(${mint.op.amt}::numeric, m.max - m.minted_supply) AS real_mint_amount
FROM mint_data AS m
WHERE
(m.minted_supply < m.max)
AND (m.limit IS NULL OR ${mint.op.amt}::numeric <= m.limit)
AND (SCALE(${mint.op.amt}::numeric) <= m.decimals)
id AS brc20_deploy_id,
LEAST(${mint.op.amt}::numeric, max - minted_supply) AS real_mint_amount
FROM mint_data
WHERE ("limit" IS NULL OR ${mint.op.amt}::numeric <= "limit")
AND (SCALE(${mint.op.amt}::numeric) <= decimals)
),
mint_insert AS (
INSERT INTO brc20_mints
Expand All @@ -310,6 +298,11 @@ export class Brc20PgStore extends BasePgStoreModule {
FROM validated_mint
)
ON CONFLICT (inscription_id) DO NOTHING
),
supply_update AS (
UPDATE brc20_deploys
SET minted_supply = minted_supply + (SELECT real_mint_amount FROM validated_mint)
WHERE id = (SELECT brc20_deploy_id FROM validated_mint)
)
INSERT INTO brc20_balances
(inscription_id, location_id, brc20_deploy_id, address, avail_balance, trans_balance, type)
Expand Down
1 change: 0 additions & 1 deletion src/pg/pg-store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,6 @@ export class PgStore extends BasePgStore {
// We'll issue materialized view refreshes in parallel. We will not wait for them to finish so
// we can respond to the chainhook node with a `200` HTTP code as soon as possible.
const views = [this.normalizeInscriptionCount({ min_block_height: updatedBlockHeightMin })];
if (ENV.BRC20_BLOCK_SCAN_ENABLED) views.push(this.refreshMaterializedView('brc20_supplies'));
const viewRefresh = Promise.allSettled(views);
// Only wait for these on tests.
if (isTestEnv) await viewRefresh;
Expand Down

0 comments on commit 36addce

Please sign in to comment.