Skip to content

Commit 7c3652b

Browse files
mergify[bot]yihuangtac0turtle
authored andcommitted
feat: save restored snapshot locally (backport cosmos#16060) (cosmos#16262)
Co-authored-by: yihuang <[email protected]> Co-authored-by: marbar3778 <[email protected]>
1 parent a2e83e2 commit 7c3652b

File tree

4 files changed

+24
-8
lines changed

4 files changed

+24
-8
lines changed

CHANGELOG.md

+4
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,10 @@ Ref: https://keepachangelog.com/en/1.0.0/
3838

3939
## [Unreleased]
4040

41+
## Features
42+
43+
* [#16060](https://github.com/cosmos/cosmos-sdk/pull/16060) Support saving restoring snapshot locally.
44+
4145
### Improvements
4246

4347
* (deps) [#15973](https://github.com/cosmos/cosmos-sdk/pull/15973) Bump CometBFT to [v0.34.28](https://github.com/cometbft/cometbft/blob/v0.34.28/CHANGELOG.md#v03428).

store/snapshots/manager.go

+7-8
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ type Manager struct {
5959
opts types.SnapshotOptions
6060
// multistore is the store from which snapshots are taken.
6161
multistore types.Snapshotter
62-
logger storetypes.Logger
62+
logger log.Logger
6363

6464
mtx sync.Mutex
6565
operation operation
@@ -319,7 +319,7 @@ func (m *Manager) Restore(snapshot types.Snapshot) error {
319319

320320
dir := m.store.pathSnapshot(snapshot.Height, snapshot.Format)
321321
if err := os.MkdirAll(dir, 0o750); err != nil {
322-
return errorsmod.Wrapf(err, "failed to create snapshot directory %q", dir)
322+
return sdkerrors.Wrapf(err, "failed to create snapshot directory %q", dir)
323323
}
324324

325325
chChunks := m.loadChunkStream(snapshot.Height, snapshot.Format, chChunkIDs)
@@ -362,10 +362,9 @@ func (m *Manager) loadChunkStream(height uint64, format uint32, chunkIDs <-chan
362362
func (m *Manager) doRestoreSnapshot(snapshot types.Snapshot, chChunks <-chan io.ReadCloser) error {
363363
dir := m.store.pathSnapshot(snapshot.Height, snapshot.Format)
364364
if err := os.MkdirAll(dir, 0o750); err != nil {
365-
return errorsmod.Wrapf(err, "failed to create snapshot directory %q", dir)
365+
return sdkerrors.Wrapf(err, "failed to create snapshot directory %q", dir)
366366
}
367367

368-
var nextItem types.SnapshotItem
369368
streamReader, err := NewStreamReader(chChunks)
370369
if err != nil {
371370
return err
@@ -431,7 +430,7 @@ func (m *Manager) RestoreChunk(chunk []byte) (bool, error) {
431430
}
432431

433432
if int(m.restoreChunkIndex) >= len(m.restoreSnapshot.Metadata.ChunkHashes) {
434-
return false, errorsmod.Wrap(storetypes.ErrLogic, "received unexpected chunk")
433+
return false, sdkerrors.Wrap(sdkerrors.ErrLogic, "received unexpected chunk")
435434
}
436435

437436
// Check if any errors have occurred yet.
@@ -454,7 +453,7 @@ func (m *Manager) RestoreChunk(chunk []byte) (bool, error) {
454453
}
455454

456455
if err := m.store.saveChunkContent(chunk, m.restoreChunkIndex, m.restoreSnapshot); err != nil {
457-
return false, errorsmod.Wrapf(err, "save chunk content %d", m.restoreChunkIndex)
456+
return false, sdkerrors.Wrapf(err, "save chunk content %d", m.restoreChunkIndex)
458457
}
459458

460459
// Pass the chunk to the restore, and wait for completion if it was the final one.
@@ -468,7 +467,7 @@ func (m *Manager) RestoreChunk(chunk []byte) (bool, error) {
468467
// the chunks are all written into files, we can save the snapshot to the db,
469468
// even if the restoration may not completed yet.
470469
if err := m.store.saveSnapshot(m.restoreSnapshot); err != nil {
471-
return false, errorsmod.Wrap(err, "save restoring snapshot")
470+
return false, sdkerrors.Wrap(err, "save restoring snapshot")
472471
}
473472

474473
done := <-m.chRestoreDone
@@ -505,7 +504,7 @@ func (m *Manager) RestoreLocalSnapshot(height uint64, format uint32) error {
505504
}
506505
defer m.endLocked()
507506

508-
return m.restoreSnapshot(*snapshot, ch)
507+
return m.doRestoreSnapshot(*snapshot, ch)
509508
}
510509

511510
// sortedExtensionNames sort extension names for deterministic iteration.

store/snapshots/manager_test.go

+7
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,13 @@ func TestManager_Restore(t *testing.T) {
214214
assert.Equal(t, expectItems, target.items)
215215
assert.Equal(t, 10, len(extSnapshotter.state))
216216

217+
// The snapshot is saved in local snapshot store
218+
snapshots, err := store.List()
219+
require.NoError(t, err)
220+
snapshot := snapshots[0]
221+
require.Equal(t, uint64(3), snapshot.Height)
222+
require.Equal(t, types.CurrentFormat, snapshot.Format)
223+
217224
// Starting a new restore should fail now, because the target already has contents.
218225
err = manager.Restore(types.Snapshot{
219226
Height: 3,

store/snapshots/store.go

+6
Original file line numberDiff line numberDiff line change
@@ -315,6 +315,12 @@ func (s *Store) saveChunk(chunkBody io.ReadCloser, index uint32, snapshot *types
315315
return nil
316316
}
317317

318+
// saveChunkContent save the chunk to disk
319+
func (s *Store) saveChunkContent(chunk []byte, index uint32, snapshot *types.Snapshot) error {
320+
path := s.PathChunk(snapshot.Height, snapshot.Format, index)
321+
return os.WriteFile(path, chunk, 0o600)
322+
}
323+
318324
// saveSnapshot saves snapshot metadata to the database.
319325
func (s *Store) saveSnapshot(snapshot *types.Snapshot) error {
320326
value, err := proto.Marshal(snapshot)

0 commit comments

Comments
 (0)