@@ -182,23 +182,37 @@ func (s *Store) Prune(ctx context.Context, height uint64) error {
182182 return nil
183183 }
184184
185+ // Use a batch to atomically delete all per-height ABCI metadata and
186+ // update the last pruned height in a single transaction. This avoids
187+ // leaving the store in a partially pruned state if an error occurs
188+ // midway through the operation.
189+ batch , err := s .prefixedStore .Batch (ctx )
190+ if err != nil {
191+ return fmt .Errorf ("failed to create batch for pruning: %w" , err )
192+ }
193+
185194 // Delete per-height ABCI metadata (block IDs and block responses) for
186195 // heights in (lastPruned, height]. Missing keys are ignored.
187196 for h := lastPruned + 1 ; h <= height ; h ++ {
188- bidKey := ds .NewKey (blockIDKey ).ChildString (strconv .FormatUint (h , 10 ))
189- if err := s .prefixedStore .Delete (ctx , bidKey ); err != nil && ! errors .Is (err , ds .ErrNotFound ) {
190- return fmt .Errorf ("failed to delete block ID at height %d during pruning: %w" , h , err )
197+ hStr := strconv .FormatUint (h , 10 )
198+ bidKey := ds .NewKey (blockIDKey ).ChildString (hStr )
199+ if err := batch .Delete (ctx , bidKey ); err != nil && ! errors .Is (err , ds .ErrNotFound ) {
200+ return fmt .Errorf ("failed to add block ID deletion to batch at height %d: %w" , h , err )
191201 }
192202
193- brKey := ds .NewKey (blockResponseKey ).ChildString (strconv . FormatUint ( h , 10 ) )
194- if err := s . prefixedStore .Delete (ctx , brKey ); err != nil && ! errors .Is (err , ds .ErrNotFound ) {
195- return fmt .Errorf ("failed to delete block response at height %d during pruning : %w" , h , err )
203+ brKey := ds .NewKey (blockResponseKey ).ChildString (hStr )
204+ if err := batch .Delete (ctx , brKey ); err != nil && ! errors .Is (err , ds .ErrNotFound ) {
205+ return fmt .Errorf ("failed to add block response deletion to batch at height %d: %w" , h , err )
196206 }
197207 }
198208
199- // Persist the updated last pruned height.
200- if err := s .prefixedStore .Put (ctx , ds .NewKey (lastPrunedHeightKey ), []byte (strconv .FormatUint (height , 10 ))); err != nil {
201- return fmt .Errorf ("failed to update last pruned height: %w" , err )
209+ // Persist the updated last pruned height in the same batch.
210+ if err := batch .Put (ctx , ds .NewKey (lastPrunedHeightKey ), []byte (strconv .FormatUint (height , 10 ))); err != nil {
211+ return fmt .Errorf ("failed to add last pruned height update to batch: %w" , err )
212+ }
213+
214+ if err := batch .Commit (ctx ); err != nil {
215+ return fmt .Errorf ("failed to commit pruning batch: %w" , err )
202216 }
203217
204218 return nil
0 commit comments