Skip to content

Commit c2c4ce7

Browse files
committed
refactor: added a total gas counter for a specific block and for each chain
1 parent 3343a87 commit c2c4ce7

File tree

8 files changed

+117
-20
lines changed

8 files changed

+117
-20
lines changed

backfill/process/save_payloads.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"go-backfill/fetch"
88
"go-backfill/repository"
99
"log"
10+
"strconv"
1011
"time"
1112

1213
"github.com/jackc/pgx/v5/pgxpool"
@@ -72,6 +73,7 @@ func savePayloads(network string, chainId int, processedPayloads []fetch.Process
7273
}
7374

7475
var transactionIdsToSave [][]int64
76+
var totalGasUsedInChain float64 = 0
7577
for index, processedPayload := range processedPayloads {
7678
var blockId = blockIds[index]
7779
var currBlock = blocks[index]
@@ -90,6 +92,22 @@ func savePayloads(network string, chainId int, processedPayloads []fetch.Process
9092
return Counters{}, DataSizeTracker{}, fmt.Errorf("saving transaction details for block %d -> %w", currBlock.Height, err)
9193
}
9294

95+
var totalGasUsedInBlock float64 = 0
96+
for _, txDetail := range txDetails {
97+
gas, err := strconv.ParseFloat(txDetail.Gas, 64)
98+
if err != nil {
99+
return Counters{}, DataSizeTracker{}, fmt.Errorf("parsing gas for block %d: %w", currBlock.Height, err)
100+
}
101+
gasPrice, err := strconv.ParseFloat(txDetail.GasPrice, 64)
102+
if err != nil {
103+
return Counters{}, DataSizeTracker{}, fmt.Errorf("parsing gas price for block %d: %w", currBlock.Height, err)
104+
}
105+
totalGasUsedInBlock += gas * gasPrice
106+
}
107+
108+
repository.SaveTotalGasUsed(tx, totalGasUsedInBlock, blockId)
109+
totalGasUsedInChain += totalGasUsedInBlock
110+
93111
txsSize := approximateSize(txs)
94112
dataSizeTracker.TransactionsKB += txsSize
95113
transactionIdsToSave = append(transactionIdsToSave, transactionIds)
@@ -158,6 +176,7 @@ func savePayloads(network string, chainId int, processedPayloads []fetch.Process
158176

159177
repository.SaveCounters(tx, repository.CounterAttributes{
160178
ChainId: chainId,
179+
TotalGasUsed: totalGasUsedInChain,
161180
CanonicalBlocksCount: len(blocks),
162181
// ignore coinbase transactions on the canonical transaction counter
163182
CanonicalTransactionsCount: counters.Transactions - len(blocks),

backfill/repository/counters_repository.go

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package repository
22

33
import (
44
"context"
5+
"fmt"
56

67
"github.com/jackc/pgx/v5"
78
)
@@ -10,25 +11,35 @@ type CounterAttributes struct {
1011
ChainId int
1112
CanonicalBlocksCount int
1213
CanonicalTransactionsCount int
14+
TotalGasUsed float64
15+
}
16+
17+
func SaveTotalGasUsed(tx pgx.Tx, totalGasUsed float64, blockId int64) error {
18+
query := `
19+
UPDATE "Blocks"
20+
SET "totalGasUsed" = $1
21+
WHERE "id" = $2
22+
`
23+
24+
_, err := tx.Exec(context.Background(), query, totalGasUsed, blockId)
25+
if err != nil {
26+
return fmt.Errorf("saving total gas used: %w", err)
27+
}
28+
29+
return nil
1330
}
1431

1532
func SaveCounters(tx pgx.Tx, counters CounterAttributes) error {
1633
query := `
1734
UPDATE "Counters"
18-
SET "canonicalBlocks" = "canonicalBlocks" + $1, "canonicalTransactions" = "canonicalTransactions" + $2
19-
WHERE "chainId" = $3
35+
SET "canonicalBlocks" = "canonicalBlocks" + $1, "canonicalTransactions" = "canonicalTransactions" + $2, "totalGasUsed" = "totalGasUsed" + $3
36+
WHERE "chainId" = $4
2037
`
2138

22-
batch := &pgx.Batch{}
23-
batch.Queue(
24-
query,
25-
counters.CanonicalBlocksCount,
26-
counters.CanonicalTransactionsCount,
27-
counters.ChainId,
28-
)
29-
30-
br := tx.SendBatch(context.Background(), batch)
31-
defer br.Close()
39+
_, err := tx.Exec(context.Background(), query, counters.CanonicalBlocksCount, counters.CanonicalTransactionsCount, counters.TotalGasUsed, counters.ChainId)
40+
if err != nil {
41+
return fmt.Errorf("saving counters: %w", err)
42+
}
3243

3344
return nil
3445
}

indexer/migrations/20250722170139-create-counter-table.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,10 @@ module.exports = {
2424
type: Sequelize.INTEGER,
2525
allowNull: false,
2626
},
27+
totalGasUsed: {
28+
type: Sequelize.DECIMAL(20, 10),
29+
allowNull: false,
30+
},
2731
});
2832

2933
const chainIds = Array.from({ length: 20 }, (_, i) => ({
@@ -32,6 +36,7 @@ module.exports = {
3236
orphansBlocks: 0,
3337
canonicalTransactions: 0,
3438
orphanTransactions: 0,
39+
totalGasUsed: 0,
3540
}));
3641

3742
await queryInterface.bulkInsert('Counters', chainIds);
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
'use strict';
2+
3+
/** @type {import('sequelize-cli').Migration} */
4+
module.exports = {
5+
async up(queryInterface, Sequelize) {
6+
await queryInterface.addColumn('Blocks', 'totalGasUsed', {
7+
type: Sequelize.DECIMAL(20, 10),
8+
});
9+
},
10+
11+
async down(queryInterface) {
12+
await queryInterface.removeColumn('Blocks', 'totalGasUsed');
13+
},
14+
};

indexer/src/models/block.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ export interface BlockAttributes {
3535
coinbase: object;
3636
canonical?: boolean;
3737
transactionsCount: number;
38+
totalGasUsed: number;
3839
}
3940

4041
/**
@@ -102,6 +103,9 @@ class Block extends Model<BlockAttributes> implements BlockAttributes {
102103

103104
/** The number of transactions in the block. */
104105
declare transactionsCount: number;
106+
107+
/** The total gas used in the block. */
108+
declare totalGasUsed: number;
105109
}
106110

107111
/**
@@ -202,6 +206,10 @@ Block.init(
202206
defaultValue: 0,
203207
comment: 'The number of transactions in the block.',
204208
},
209+
totalGasUsed: {
210+
type: DataTypes.DECIMAL(20, 10),
211+
comment: 'The total gas used in the block.',
212+
},
205213
},
206214
{
207215
sequelize,

indexer/src/models/counter.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ class Counter extends Model {
88
public orphansBlocks!: number;
99
public canonicalTransactions!: number;
1010
public orphanTransactions!: number;
11+
public totalGasUsed!: number;
1112
}
1213

1314
Counter.init(
@@ -32,6 +33,10 @@ Counter.init(
3233
type: DataTypes.INTEGER,
3334
allowNull: false,
3435
},
36+
totalGasUsed: {
37+
type: DataTypes.DECIMAL(20, 10),
38+
allowNull: false,
39+
},
3540
},
3641
{
3742
sequelize,

indexer/src/services/counters.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,15 @@ export async function increaseCounters({
77
canonicalTransactionsCount,
88
orphanTransactionsCount,
99
chainId,
10+
totalGasUsed = 0,
1011
tx,
1112
}: {
1213
canonicalBlocksCount: number;
1314
orphansBlocksCount: number;
1415
canonicalTransactionsCount: number;
1516
orphanTransactionsCount: number;
1617
chainId: number;
18+
totalGasUsed?: number;
1719
tx?: Transaction;
1820
}) {
1921
await Counter.increment('canonicalBlocks', {
@@ -36,4 +38,11 @@ export async function increaseCounters({
3638
transaction: tx,
3739
where: { chainId: { [Op.eq]: chainId } },
3840
});
41+
if (totalGasUsed > 0) {
42+
await Counter.increment('totalGasUsed', {
43+
by: totalGasUsed,
44+
transaction: tx,
45+
where: { chainId: { [Op.eq]: chainId } },
46+
});
47+
}
3948
}

indexer/src/services/payload.ts

Lines changed: 34 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,12 @@
1414
* 6. Extracting guard information for security validation
1515
*/
1616

17-
import { BlockAttributes } from '@/models/block';
17+
import Block, { BlockAttributes } from '@/models/block';
1818
import TransactionModel, { TransactionAttributes } from '@/models/transaction';
1919
import Event, { EventAttributes } from '@/models/event';
2020
import Transfer, { TransferAttributes } from '@/models/transfer';
2121
import { getNftTransfers, getCoinTransfers } from './transfers';
22-
import { Transaction } from 'sequelize';
22+
import { Op, Transaction } from 'sequelize';
2323
import Signer from '@/models/signer';
2424
import Guard from '@/models/guard';
2525
import { handleSingleQuery } from '@/utils/raw-query';
@@ -74,11 +74,9 @@ export async function processPayloadKey(
7474
const transactions = payloadData.transactions || [];
7575

7676
// Process all regular transactions in parallel
77-
const transactionPromises: Array<
78-
Promise<{ events: EventAttributes[]; transfers: TransferAttributes[] }>
79-
> = transactions.map((transactionInfo: any) => {
80-
return processTransaction(transactionInfo, block, tx);
81-
});
77+
const transactionPromises: Array<Promise<TransactionResult>> = transactions.map(
78+
(transactionInfo: any) => processTransaction(transactionInfo, block, tx),
79+
);
8280

8381
const transactionResults = await Promise.all(transactionPromises);
8482
const normalEvents = transactionResults.map(t => t.events).flat();
@@ -87,15 +85,31 @@ export async function processPayloadKey(
8785
const coinbaseResult = await addCoinbaseTransactions([block], tx!);
8886
const coinbaseEvents = coinbaseResult.events;
8987

88+
const totalGasUsed = transactionResults.reduce((acc, t) => {
89+
const gasUsed = new Decimal(t.gas).mul(t.gasprice).toNumber();
90+
return acc.plus(gasUsed);
91+
}, new Decimal(0));
92+
9093
await increaseCounters({
9194
canonicalBlocksCount: 1,
9295
orphansBlocksCount: 0,
9396
canonicalTransactionsCount: transactionPromises.length,
9497
orphanTransactionsCount: 0,
9598
chainId: block.chainId,
99+
totalGasUsed: totalGasUsed.toNumber(),
96100
tx,
97101
});
98102

103+
await Block.update(
104+
{
105+
totalGasUsed: sequelize.literal(`COALESCE("totalGasUsed", 0) + ${totalGasUsed}`),
106+
},
107+
{
108+
transaction: tx,
109+
where: { id: { [Op.eq]: block.id } },
110+
},
111+
);
112+
99113
// Combine all events from both transaction types
100114
return [...normalEvents, ...coinbaseEvents];
101115
}
@@ -118,11 +132,19 @@ export async function processPayloadKey(
118132
* TODO: [OPTIMIZATION] The balance insert operation uses a raw SQL query which could potentially
119133
* be vulnerable to SQL injection. Consider using parameterized queries or ORM methods.
120134
*/
135+
136+
export interface TransactionResult {
137+
events: EventAttributes[];
138+
transfers: TransferAttributes[];
139+
gas: string;
140+
gasprice: string;
141+
}
142+
121143
export async function processTransaction(
122144
transactionArray: any,
123145
block: BlockAttributes,
124146
tx?: Transaction,
125-
): Promise<{ events: EventAttributes[]; transfers: TransferAttributes[] }> {
147+
): Promise<TransactionResult> {
126148
const transactionInfo = transactionArray[TRANSACTION_INDEX];
127149
const receiptInfo = transactionArray[RECEIPT_INDEX];
128150

@@ -312,6 +334,8 @@ export async function processTransaction(
312334
return {
313335
events: eventsWithTransactionId,
314336
transfers: transfersWithTransactionId,
337+
gas: transactionDetailsAttributes.gas,
338+
gasprice: transactionDetailsAttributes.gasprice,
315339
};
316340
}
317341

@@ -338,6 +362,8 @@ export async function processTransaction(
338362
return {
339363
events: eventsWithTransactionId,
340364
transfers: transfersWithTransactionId,
365+
gas: transactionDetailsAttributes.gas,
366+
gasprice: transactionDetailsAttributes.gasprice,
341367
};
342368
} catch (error) {
343369
console.error(

0 commit comments

Comments
 (0)