Skip to content

Commit bf0eebd

Browse files
committed
fix: creationtime value of coinbase transactions
1 parent 15e4e3d commit bf0eebd

File tree

6 files changed

+131
-6
lines changed

6 files changed

+131
-6
lines changed

backfill/Dockerfile.creationtime

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
FROM golang:1.23.7 AS builder
2+
WORKDIR /app
3+
COPY . .
4+
RUN go mod download
5+
RUN CGO_ENABLED=0 GOOS=linux GOARCH=arm64 go build -o fix-creationtime ./fix-creationtime/fix-creationtime.go
6+
7+
FROM scratch
8+
WORKDIR /app
9+
COPY ./global-bundle.pem ./global-bundle.pem
10+
COPY --from=builder /app/fix-creationtime .
11+
CMD ["./fix-creationtime"]
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
package main
2+
3+
import (
4+
"context"
5+
"flag"
6+
"fmt"
7+
"go-backfill/config"
8+
"log"
9+
"time"
10+
11+
"github.com/jackc/pgx/v5"
12+
)
13+
14+
const (
15+
batchSize = 1000
16+
lastId = 105126770
17+
)
18+
19+
func fixBatchCreationTime(conn *pgx.Conn, lastId int64) (bool, int64, error) {
20+
startTime := time.Now()
21+
22+
// Start transaction for writes
23+
tx, err := conn.Begin(context.Background())
24+
if err != nil {
25+
return false, lastId, fmt.Errorf("failed to begin transaction: %v", err)
26+
}
27+
defer tx.Rollback(context.Background())
28+
29+
// Update creation time for coinbase transactions in batch
30+
updateQuery := `
31+
WITH OrderedUpdates AS (
32+
SELECT id
33+
FROM "Transactions"
34+
WHERE id > $1 AND sender = 'coinbase'
35+
ORDER BY id ASC
36+
LIMIT $2
37+
)
38+
UPDATE "Transactions"
39+
SET creationtime = (CAST(creationtime AS BIGINT) / 1000000)::TEXT
40+
FROM OrderedUpdates
41+
WHERE "Transactions".id = OrderedUpdates.id
42+
RETURNING "Transactions".id, "Transactions".creationtime
43+
`
44+
45+
rows, err := tx.Query(context.Background(), updateQuery, lastId, batchSize)
46+
if err != nil {
47+
return false, lastId, fmt.Errorf("failed to execute update: %v", err)
48+
}
49+
defer rows.Close()
50+
51+
var updatedCount int
52+
var lastProcessedId int64
53+
var lastCreationTime string
54+
for rows.Next() {
55+
if err := rows.Scan(&lastProcessedId, &lastCreationTime); err != nil {
56+
return false, lastId, fmt.Errorf("failed to scan row: %v", err)
57+
}
58+
updatedCount++
59+
60+
}
61+
62+
if err := tx.Commit(context.Background()); err != nil {
63+
return false, lastId, fmt.Errorf("failed to commit transaction: %v", err)
64+
}
65+
66+
elapsed := time.Since(startTime)
67+
log.Printf("Fixed creation time for %d coinbase transactions. Batch time: %.2fs", updatedCount, elapsed.Seconds())
68+
69+
return updatedCount == batchSize, lastProcessedId, nil
70+
}
71+
72+
func main() {
73+
envFile := flag.String("env", ".env", "Path to the .env file")
74+
flag.Parse()
75+
76+
config.InitEnv(*envFile)
77+
env := config.GetConfig()
78+
79+
// Database connection
80+
connStr := fmt.Sprintf("host=%s port=%s user=%s password=%s dbname=%s sslmode=disable",
81+
env.DbHost, env.DbPort, env.DbUser, env.DbPassword, env.DbName)
82+
83+
conn, err := pgx.Connect(context.Background(), connStr)
84+
if err != nil {
85+
log.Fatalf("Failed to connect to database: %v", err)
86+
}
87+
defer conn.Close(context.Background())
88+
89+
log.Println("Connected to database")
90+
91+
lastId := int64(0)
92+
hasMore := true
93+
processedTransactions := int64(0)
94+
95+
for hasMore {
96+
var err error
97+
hasMore, lastId, err = fixBatchCreationTime(conn, lastId)
98+
if err != nil {
99+
log.Fatalf("Error during batch processing: %v", err)
100+
}
101+
processedTransactions += batchSize
102+
progress := float64(processedTransactions) / float64(105126770) * 100
103+
104+
if hasMore {
105+
log.Printf("Progress: %.2f%% (%d/%d transactions processed)", progress, processedTransactions, lastId)
106+
} else {
107+
log.Printf("Progress: 100.00%%")
108+
}
109+
110+
time.Sleep(100 * time.Millisecond)
111+
}
112+
113+
log.Println("Creation time fix completed successfully")
114+
}

backfill/process/coinbase.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ func ProcessCoinbaseTransaction(coinbase string, blockId int64, creationTime int
4040
txAttribute := repository.TransactionAttributes{
4141
BlockId: blockId,
4242
ChainId: int(chainId),
43-
CreationTime: strconv.FormatInt(creationTime, 10),
43+
CreationTime: strconv.FormatInt(creationTime/1000000, 10),
4444
Hash: coinbaseDecoded.ReqKey,
4545
Result: coinbaseDecoded.Result,
4646
Logs: coinbaseDecoded.Logs,

indexer/src/kadena-server/repository/infra/repository/transaction-db-repository.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ export default class TransactionDbRepository implements TransactionRepository {
203203
JOIN "Transactions" t ON b.id = t."blockId"
204204
LEFT JOIN "TransactionDetails" td ON t.id = td."transactionId"
205205
${transactionsConditions}
206-
ORDER BY t.id ${order}
206+
ORDER BY t.creationtime ${order}
207207
LIMIT $1
208208
`;
209209
} else {
@@ -212,7 +212,7 @@ export default class TransactionDbRepository implements TransactionRepository {
212212
SELECT t.id, t."blockId", t.hash, t.num_events, t.txid, t.logs, t.result, t.requestkey, t."chainId"
213213
FROM "Transactions" t
214214
${transactionsConditions}
215-
ORDER BY t.id ${order}
215+
ORDER BY t.creationtime ${order}
216216
LIMIT $1
217217
)
218218
SELECT
@@ -425,7 +425,7 @@ export default class TransactionDbRepository implements TransactionRepository {
425425
) filtered_signers ON t.id = filtered_signers."transactionId"
426426
LEFT JOIN "TransactionDetails" td on t.id = td."transactionId"
427427
${cursorCondition}
428-
ORDER BY t.id ${order}
428+
ORDER BY t.creationtime ${order}
429429
LIMIT $1;
430430
`;
431431

indexer/src/kadena-server/repository/infra/schema-validator/transaction-meta-schema-validator.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ function validate(row: any): TransactionMetaOutput {
1414
const res = schema.parse(row);
1515
return {
1616
chainId: res.chainId,
17-
creationTime: new Date(Number(res.creationTime) / 1000),
17+
creationTime: new Date(Number(res.creationTime) * 1000),
1818
gasLimit: res.gasLimit ?? 0,
1919
gasPrice: Number(res.gasPrice) ?? 0,
2020
sender: res.sender,

indexer/src/services/sync/coinbase.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ export async function processCoinbaseTransaction(
122122
const transactionAttributes = {
123123
blockId: block.id,
124124
chainId: block.chainId,
125-
creationtime: block.creationTime.toString(),
125+
creationtime: Math.trunc(Number(block.creationTime) / 1000000).toString(),
126126
hash: coinbase.reqKey,
127127
result: coinbase.result,
128128
logs: coinbase.logs,

0 commit comments

Comments
 (0)