func (p *snapshotPool) GetPeers(snapshot *snapshot) []types.NodeID {
	key := snapshot.Key()
	p.Lock()
	defer p.Unlock()
	peers := make([]types.NodeID, 0, len(p.snapshotPeers[key]))
	for _, peer := range p.snapshotPeers[key] {
		peers = append(peers, peer)
	}
	sort.Slice(peers, func(a int, b int) bool {
		return strings.Compare(string(peers[a]), string(peers[b])) < 0
	})
	return peers
}
GetPeers returns the peers for a snapshot.
package statesync
import (
	"crypto/sha256"
	"fmt"
	"math/rand"
	"sort"
	"strings"
	tmsync "github.com/tendermint/tendermint/internal/libs/sync"
	"github.com/tendermint/tendermint/types"
)
type snapshotKey [sha256.Size]byte
type snapshot struct {
	Height   uint64
	Format   uint32
	Chunks   uint32
	Hash     []byte
	Metadata []byte
	trustedAppHash []byte  
}
func (s *snapshot) Key() snapshotKey {
	hasher := sha256.New()
	hasher.Write([]byte(fmt.Sprintf("%v:%v:%v", s.Height, s.Format, s.Chunks)))
	hasher.Write(s.Hash)
	hasher.Write(s.Metadata)
	var key snapshotKey
	copy(key[:], hasher.Sum(nil))
	return key
}
type snapshotPool struct {
	tmsync.Mutex
	snapshots     map[snapshotKey]*snapshot
	snapshotPeers map[snapshotKey]map[types.NodeID]types.NodeID
	formatIndex map[uint32]map[snapshotKey]bool
	heightIndex map[uint64]map[snapshotKey]bool
	peerIndex   map[types.NodeID]map[snapshotKey]bool
	formatBlacklist   map[uint32]bool
	peerBlacklist     map[types.NodeID]bool
	snapshotBlacklist map[snapshotKey]bool
}
func newSnapshotPool() *snapshotPool {
	return &snapshotPool{
		snapshots:         make(map[snapshotKey]*snapshot),
		snapshotPeers:     make(map[snapshotKey]map[types.NodeID]types.NodeID),
		formatIndex:       make(map[uint32]map[snapshotKey]bool),
		heightIndex:       make(map[uint64]map[snapshotKey]bool),
		peerIndex:         make(map[types.NodeID]map[snapshotKey]bool),
		formatBlacklist:   make(map[uint32]bool),
		peerBlacklist:     make(map[types.NodeID]bool),
		snapshotBlacklist: make(map[snapshotKey]bool),
	}
}
func (p *snapshotPool) Add(peerID types.NodeID, snapshot *snapshot) (bool, error) {
	key := snapshot.Key()
	p.Lock()
	defer p.Unlock()
	switch {
	case p.formatBlacklist[snapshot.Format]:
		return false, nil
	case p.peerBlacklist[peerID]:
		return false, nil
	case p.snapshotBlacklist[key]:
		return false, nil
	case len(p.peerIndex[peerID]) >= recentSnapshots:
		return false, nil
	}
	if p.snapshotPeers[key] == nil {
		p.snapshotPeers[key] = make(map[types.NodeID]types.NodeID)
	}
	p.snapshotPeers[key][peerID] = peerID
	if p.peerIndex[peerID] == nil {
		p.peerIndex[peerID] = make(map[snapshotKey]bool)
	}
	p.peerIndex[peerID][key] = true
	if p.snapshots[key] != nil {
		return false, nil
	}
	p.snapshots[key] = snapshot
	if p.formatIndex[snapshot.Format] == nil {
		p.formatIndex[snapshot.Format] = make(map[snapshotKey]bool)
	}
	p.formatIndex[snapshot.Format][key] = true
	if p.heightIndex[snapshot.Height] == nil {
		p.heightIndex[snapshot.Height] = make(map[snapshotKey]bool)
	}
	p.heightIndex[snapshot.Height][key] = true
	return true, nil
}
func (p *snapshotPool) Best() *snapshot {
	ranked := p.Ranked()
	if len(ranked) == 0 {
		return nil
	}
	return ranked[0]
}
func (p *snapshotPool) GetPeer(snapshot *snapshot) types.NodeID {
	peers := p.GetPeers(snapshot)
	if len(peers) == 0 {
		return ""
	}
	return peers[rand.Intn(len(peers))]  
}