-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathsyncFrontendMove.go
More file actions
110 lines (93 loc) · 3.17 KB
/
syncFrontendMove.go
File metadata and controls
110 lines (93 loc) · 3.17 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
package handler
import (
"fmt"
"time"
"github.com/optimism-java/dispute-explorer/internal/schema"
"github.com/optimism-java/dispute-explorer/internal/svc"
"github.com/optimism-java/dispute-explorer/pkg/log"
)
func SyncFrontendMoveTransactions(ctx *svc.ServiceContext) {
log.Infof("[Handler.SyncFrontendMoveTransactions] Starting sync frontend move transactions...")
for {
select {
case <-ctx.Context.Done():
log.Infof("[Handler.SyncFrontendMoveTransactions] Context canceled, stopping...")
return
default:
err := processFrontendMoveTransactions(ctx)
if err != nil {
log.Errorf("[Handler.SyncFrontendMoveTransactions] Process error: %s", err)
}
time.Sleep(30 * time.Second)
}
}
}
// processFrontendMoveTransactions
func processFrontendMoveTransactions(ctx *svc.ServiceContext) error {
var unsyncedTransactions []schema.FrontendMoveTransaction
err := ctx.DB.Where("is_synced = ?", false).Order("id").Limit(10).Find(&unsyncedTransactions).Error
if err != nil {
return err
}
if len(unsyncedTransactions) == 0 {
log.Debugf("[Handler.SyncFrontendMoveTransactions] No unsynced transactions found")
return nil
}
log.Infof("[Handler.SyncFrontendMoveTransactions] Found %d unsynced transactions", len(unsyncedTransactions))
for i := range unsyncedTransactions {
transaction := &unsyncedTransactions[i]
if transaction.Status == schema.FrontendMoveStatusConfirmed {
err := syncSingleTransaction(ctx, transaction)
if err != nil {
log.Errorf("[Handler.SyncFrontendMoveTransactions] Failed to sync transaction %s: %s", transaction.TxHash, err)
continue
}
}
}
return nil
}
// syncSingleTransaction
func syncSingleTransaction(ctx *svc.ServiceContext, transaction *schema.FrontendMoveTransaction) error {
tx := ctx.DB.Begin()
defer func() {
if r := recover(); r != nil {
tx.Rollback()
}
}()
// 1. update dispute_game has_frontend_move column to true
err := tx.Model(&schema.DisputeGame{}).
Where("game_contract = ?", transaction.GameContract).
Update("has_frontend_move", true).Error
if err != nil {
tx.Rollback()
return err
}
// 2. update game_claim_data is_from_frontend column to true
result := tx.Model(&schema.GameClaimData{}).
Where("game_contract = ? AND parent_index = ?", transaction.GameContract, transaction.ParentIndex).
Update("is_from_frontend", true)
if result.Error != nil {
tx.Rollback()
return result.Error
}
if result.RowsAffected == 0 {
tx.Rollback()
log.Warnf("[Handler.SyncFrontendMoveTransactions] No matching game_claim_data found for transaction %s (game: %s, parent_index: %s), will retry later",
transaction.TxHash, transaction.GameContract, transaction.ParentIndex)
return fmt.Errorf("no matching game_claim_data found, will retry later")
}
// 3. update frontend_move_transactions is_synced column to true
err = tx.Model(transaction).Update("is_synced", true).Error
if err != nil {
tx.Rollback()
return err
}
// tx commit
err = tx.Commit().Error
if err != nil {
return err
}
log.Infof("[Handler.SyncFrontendMoveTransactions] Successfully synced transaction %s (game: %s, parent_index: %s)",
transaction.TxHash, transaction.GameContract, transaction.ParentIndex)
return nil
}