func ListSnapshots(logger *logger.SugarLogger, snapDir string) []uint64 {
	dir, err := os.Open(snapDir)
	if err != nil {
		logger.Errorf("Failed to open snapshot directory %s: %s", snapDir, err)
		return nil
	}
	defer dir.Close()
	filenames, err := dir.Readdirnames(-1)
	if err != nil {
		logger.Errorf("Failed to read snapshot files: %s", err)
		return nil
	}
	snapfiles := []string{}
	for i := range filenames {
		if strings.HasSuffix(filenames[i], ".snap") {
			snapfiles = append(snapfiles, filenames[i])
		}
	}
	sort.Strings(snapfiles)
	var snapshots []uint64
	for _, snapfile := range snapfiles {
		fpath := filepath.Join(snapDir, snapfile)
		s, err := snap.Read(logger.Desugar(), fpath)
		if err != nil {
			logger.Errorf("Snapshot file %s is corrupted: %s", fpath, err)
			broken := fpath + ".broken"
			if err = os.Rename(fpath, broken); err != nil {
				logger.Errorf("Failed to rename corrupted snapshot file %s to %s: %s", fpath, broken, err)
			} else {
				logger.Debugf("Renaming corrupted snapshot file %s to %s", fpath, broken)
			}
			continue
		}
		snapshots = append(snapshots, s.Metadata.Index)
	}
	return snapshots
}
ListSnapshots returns a list of RaftIndex of snapshots stored on disk.
If a file is corrupted, rename the file.
package replication
import (
	"fmt"
	"io"
	"os"
	"path/filepath"
	"sort"
	"strings"
	"github.com/hyperledger-labs/orion-server/pkg/logger"
	"github.com/pkg/errors"
	"go.etcd.io/etcd/etcdserver/api/snap"
	"go.etcd.io/etcd/pkg/fileutil"
	"go.etcd.io/etcd/raft"
	"go.etcd.io/etcd/raft/raftpb"
	"go.etcd.io/etcd/wal"
	"go.etcd.io/etcd/wal/walpb"
)
var MaxSnapshotFiles = 4
type RaftStorage struct {
	SnapshotCatchUpEntries uint64
	walDir  string
	snapDir string
	lg *logger.SugarLogger
	MemoryStorage *raft.MemoryStorage
	wal           *wal.WAL
	snap          *snap.Snapshotter
	snapshotIndex []uint64
}
func CreateStorage(lg *logger.SugarLogger, walDir string, snapDir string) (*RaftStorage, error) {
	sn, err := createSnapshotter(lg, snapDir)
	if err != nil {
		return nil, err
	}
	snapshot, err := sn.Load()
	if err != nil {
		if err == snap.ErrNoSnapshot {
			lg.Debugf("No snapshot found at %s", snapDir)
		} else {
			return nil, errors.Errorf("failed to load snapshot: %s", err)
		}
	} else {
		lg.Debugf("Loaded snapshot at Term %d and Index %d, ConfState: %+v",
			snapshot.Metadata.Term, snapshot.Metadata.Index, snapshot.Metadata.ConfState)
	}
	w, st, ents, err := createOrReadWAL(lg, walDir, snapshot)
	if err != nil {
		return nil, errors.Errorf("failed to create or read WAL: %s", err)
	}
	ms := raft.NewMemoryStorage()
	if snapshot != nil {
		lg.Debugf("Applying snapshot to raft MemoryStorage")
		if err := ms.ApplySnapshot(*snapshot); err != nil {
			return nil, errors.Errorf("Failed to apply snapshot to memory: %s", err)
		}
	}
	lg.Debugf("Setting HardState to {Term: %d, Commit: %d}", st.Term, st.Commit)
	ms.SetHardState(st)  
	lg.Debugf("Appending %d entries to memory storage", len(ents))
	ms.Append(ents)  
	return &RaftStorage{
		lg:            lg,
		MemoryStorage: ms,
		wal:           w,
		snap:          sn,
		walDir:        walDir,
		snapDir:       snapDir,
		snapshotIndex: ListSnapshots(lg, snapDir),
	}, nil
}