You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

83 lines
2.2 KiB

package light
import (
"encoding/hex"
"sort"
lightErr "github.com/tendermint/tendermint/light/errors"
)
type memStoreProvider struct {
// byHeight is always sorted by Height... need to support range search (nil, h]
// btree would be more efficient for larger sets
byHeight fullCommits
byHash map[string]FullCommit
}
// fullCommits just exists to allow easy sorting
type fullCommits []FullCommit
func (s fullCommits) Len() int { return len(s) }
func (s fullCommits) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
func (s fullCommits) Less(i, j int) bool {
return s[i].Height() < s[j].Height()
}
// NewMemStoreProvider returns a new in-memory provider.
func NewMemStoreProvider() Provider {
return &memStoreProvider{
byHeight: fullCommits{},
byHash: map[string]FullCommit{},
}
}
func (m *memStoreProvider) encodeHash(hash []byte) string {
return hex.EncodeToString(hash)
}
// StoreCommit stores a FullCommit after verifying it.
func (m *memStoreProvider) StoreCommit(fc FullCommit) error {
// make sure the fc is self-consistent before saving
err := fc.ValidateBasic(fc.Commit.Header.ChainID)
if err != nil {
return err
}
// store the valid fc
key := m.encodeHash(fc.ValidatorsHash())
m.byHash[key] = fc
m.byHeight = append(m.byHeight, fc)
sort.Sort(m.byHeight)
return nil
}
// GetByHeight returns the FullCommit for height h or an error if the commit is not found.
func (m *memStoreProvider) GetByHeight(h int) (FullCommit, error) {
// search from highest to lowest
for i := len(m.byHeight) - 1; i >= 0; i-- {
fc := m.byHeight[i]
if fc.Height() <= h {
return fc, nil
}
}
return FullCommit{}, lightErr.ErrCommitNotFound()
}
// GetByHash returns the FullCommit for the hash or an error if the commit is not found.
func (m *memStoreProvider) GetByHash(hash []byte) (FullCommit, error) {
var err error
fc, ok := m.byHash[m.encodeHash(hash)]
if !ok {
err = lightErr.ErrCommitNotFound()
}
return fc, err
}
// LatestCommit returns the latest FullCommit or an error if no commits exist.
func (m *memStoreProvider) LatestCommit() (FullCommit, error) {
l := len(m.byHeight)
if l == 0 {
return FullCommit{}, lightErr.ErrCommitNotFound()
}
return m.byHeight[l-1], nil
}