@@ -72,9 +72,105 @@ func NewCommitter(rpc rpc.IRPCClient, storage storage.IStorage, opts ...Committe
7272 opt (committer )
7373 }
7474
75+ // Clean up any stranded blocks in staging
76+ if err := committer .cleanupStrandedBlocks (); err != nil {
77+ log .Error ().Err (err ).Msg ("Failed to clean up stranded blocks during initialization" )
78+ }
79+
7580 return committer
7681}
7782
83+ func (c * Committer ) cleanupStrandedBlocks () error {
84+ // Get the current max block from main storage
85+ latestCommittedBlockNumber , err := c .storage .MainStorage .GetMaxBlockNumber (c .rpc .GetChainID ())
86+ if err != nil {
87+ return fmt .Errorf ("error getting max block number from main storage: %v" , err )
88+ }
89+
90+ if latestCommittedBlockNumber .Sign () == 0 {
91+ // No blocks in main storage yet, nothing to clean up
92+ return nil
93+ }
94+
95+ // Get block numbers from PostgreSQL that are less than or equal to the latest committed block
96+ psqlBlockNumbers , err := c .storage .StagingStorage .(* storage.PostgresConnector ).GetBlockNumbersLessThan (c .rpc .GetChainID (), latestCommittedBlockNumber )
97+ if err != nil {
98+ return fmt .Errorf ("error getting block numbers from PostgreSQL: %v" , err )
99+ }
100+
101+ if len (psqlBlockNumbers ) == 0 {
102+ // No stranded blocks in staging
103+ return nil
104+ }
105+
106+ log .Info ().
107+ Int ("block_count" , len (psqlBlockNumbers )).
108+ Str ("min_block" , psqlBlockNumbers [0 ].String ()).
109+ Str ("max_block" , psqlBlockNumbers [len (psqlBlockNumbers )- 1 ].String ()).
110+ Msg ("Found stranded blocks in staging" )
111+
112+ // Check which blocks exist in ClickHouse
113+ existsInClickHouse , err := c .storage .MainStorage .(* storage.ClickHouseConnector ).CheckBlocksExist (c .rpc .GetChainID (), psqlBlockNumbers )
114+ if err != nil {
115+ return fmt .Errorf ("error checking blocks in ClickHouse: %v" , err )
116+ }
117+
118+ // Get block data from PostgreSQL for blocks that don't exist in ClickHouse
119+ var blocksToCommit []common.BlockData
120+ for _ , blockNum := range psqlBlockNumbers {
121+ if ! existsInClickHouse [blockNum .String ()] {
122+ data , err := c .storage .StagingStorage .GetStagingData (storage.QueryFilter {
123+ BlockNumbers : []* big.Int {blockNum },
124+ ChainId : c .rpc .GetChainID (),
125+ })
126+ if err != nil {
127+ return fmt .Errorf ("error getting block data from PostgreSQL: %v" , err )
128+ }
129+ if len (data ) > 0 {
130+ blocksToCommit = append (blocksToCommit , data [0 ])
131+ }
132+ }
133+ }
134+
135+ // Insert blocks into ClickHouse
136+ if len (blocksToCommit ) > 0 {
137+ log .Info ().
138+ Int ("block_count" , len (blocksToCommit )).
139+ Str ("min_block" , blocksToCommit [0 ].Block .Number .String ()).
140+ Str ("max_block" , blocksToCommit [len (blocksToCommit )- 1 ].Block .Number .String ()).
141+ Msg ("Committing stranded blocks to ClickHouse" )
142+
143+ if err := c .storage .MainStorage .InsertBlockData (blocksToCommit ); err != nil {
144+ return fmt .Errorf ("error inserting blocks into ClickHouse: %v" , err )
145+ }
146+ }
147+
148+ // Delete all blocks from PostgreSQL that were checked (whether they existed in ClickHouse or not)
149+ var blocksToDelete []common.BlockData
150+ for _ , blockNum := range psqlBlockNumbers {
151+ blocksToDelete = append (blocksToDelete , common.BlockData {
152+ Block : common.Block {
153+ ChainId : c .rpc .GetChainID (),
154+ Number : blockNum ,
155+ },
156+ })
157+ }
158+
159+ if len (blocksToDelete ) > 0 {
160+ log .Info ().
161+ Int ("block_count" , len (blocksToDelete )).
162+ Str ("min_block" , blocksToDelete [0 ].Block .Number .String ()).
163+ Str ("max_block" , blocksToDelete [len (blocksToDelete )- 1 ].Block .Number .String ()).
164+ Msg ("Deleting stranded blocks from PostgreSQL" )
165+
166+ if err := c .storage .StagingStorage .DeleteStagingData (blocksToDelete ); err != nil {
167+ return fmt .Errorf ("error deleting blocks from PostgreSQL: %v" , err )
168+ }
169+ }
170+
171+ return nil
172+ }
173+
78174func (c * Committer ) Start (ctx context.Context ) {
79175 interval := time .Duration (c .triggerIntervalMs ) * time .Millisecond
80176
@@ -135,6 +231,68 @@ func (c *Committer) getBlockNumbersToCommit(ctx context.Context) ([]*big.Int, er
135231 }
136232 }
137233
234+ // Get block numbers from PostgreSQL that are less than or equal to the latest committed block
235+ psqlBlockNumbers , err := c .storage .StagingStorage .(* storage.PostgresConnector ).GetBlockNumbersLessThan (c .rpc .GetChainID (), latestCommittedBlockNumber )
236+ if err != nil {
237+ return nil , fmt .Errorf ("error getting block numbers from PostgreSQL: %v" , err )
238+ }
239+
240+ if len (psqlBlockNumbers ) > 0 {
241+ // Check which blocks exist in ClickHouse
242+ existsInClickHouse , err := c .storage .MainStorage .(* storage.ClickHouseConnector ).CheckBlocksExist (c .rpc .GetChainID (), psqlBlockNumbers )
243+ if err != nil {
244+ return nil , fmt .Errorf ("error checking blocks in ClickHouse: %v" , err )
245+ }
246+
247+ // Get block data from PostgreSQL for blocks that don't exist in ClickHouse
248+ var blocksToCommit []common.BlockData
249+ for _ , blockNum := range psqlBlockNumbers {
250+ if ! existsInClickHouse [blockNum .String ()] {
251+ data , err := c .storage .StagingStorage .GetStagingData (storage.QueryFilter {
252+ BlockNumbers : []* big.Int {blockNum },
253+ ChainId : c .rpc .GetChainID (),
254+ })
255+ if err != nil {
256+ return nil , fmt .Errorf ("error getting block data from PostgreSQL: %v" , err )
257+ }
258+ if len (data ) > 0 {
259+ blocksToCommit = append (blocksToCommit , data [0 ])
260+ }
261+ }
262+ }
263+
264+ // Insert blocks into ClickHouse
265+ if len (blocksToCommit ) > 0 {
266+ if err := c .storage .MainStorage .InsertBlockData (blocksToCommit ); err != nil {
267+ return nil , fmt .Errorf ("error inserting blocks into ClickHouse: %v" , err )
268+ }
269+ }
270+
271+ // Delete all blocks from PostgreSQL that were checked (whether they existed in ClickHouse or not)
272+ var blocksToDelete []common.BlockData
273+ for _ , blockNum := range psqlBlockNumbers {
274+ blocksToDelete = append (blocksToDelete , common.BlockData {
275+ Block : common.Block {
276+ ChainId : c .rpc .GetChainID (),
277+ Number : blockNum ,
278+ },
279+ })
280+ }
281+
282+ if len (blocksToDelete ) > 0 {
283+ log .Info ().
284+ Int ("block_count" , len (blocksToDelete )).
285+ Str ("min_block" , blocksToDelete [0 ].Block .Number .String ()).
286+ Str ("max_block" , blocksToDelete [len (blocksToDelete )- 1 ].Block .Number .String ()).
287+ Msg ("Deleting stranded blocks from PostgreSQL" )
288+
289+ if err := c .storage .StagingStorage .DeleteStagingData (blocksToDelete ); err != nil {
290+ log .Error ().Err (err ).Msg ("Failed to delete blocks from PostgreSQL" )
291+ }
292+ }
293+ }
294+
295+ // Continue with normal block range processing
138296 startBlock := new (big.Int ).Add (latestCommittedBlockNumber , big .NewInt (1 ))
139297 endBlock , err := c .getBlockToCommitUntil (ctx , latestCommittedBlockNumber )
140298 if err != nil {
0 commit comments