Merge pull request #1011 from tendermint/1006-panic-on-light-client-startup

protect memStoreProvider#byHash map by mutex
This commit is contained in:
Ethan Buchman
2017-12-27 15:30:59 -05:00
committed by GitHub

View File

@@ -3,11 +3,13 @@ package lite
import (
"encoding/hex"
"sort"
"sync"
liteErr "github.com/tendermint/tendermint/lite/errors"
)
type memStoreProvider struct {
mtx sync.RWMutex
// byHeight is always sorted by Height... need to support range search (nil, h]
// btree would be more efficient for larger sets
byHeight fullCommits
@@ -45,6 +47,9 @@ func (m *memStoreProvider) StoreCommit(fc FullCommit) error {
// store the valid fc
key := m.encodeHash(fc.ValidatorsHash())
m.mtx.Lock()
defer m.mtx.Unlock()
m.byHash[key] = fc
m.byHeight = append(m.byHeight, fc)
sort.Sort(m.byHeight)
@@ -53,6 +58,9 @@ func (m *memStoreProvider) StoreCommit(fc FullCommit) error {
// GetByHeight returns the FullCommit for height h or an error if the commit is not found.
func (m *memStoreProvider) GetByHeight(h int64) (FullCommit, error) {
m.mtx.RLock()
defer m.mtx.RUnlock()
// search from highest to lowest
for i := len(m.byHeight) - 1; i >= 0; i-- {
fc := m.byHeight[i]
@@ -65,16 +73,21 @@ func (m *memStoreProvider) GetByHeight(h int64) (FullCommit, error) {
// 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
m.mtx.RLock()
defer m.mtx.RUnlock()
fc, ok := m.byHash[m.encodeHash(hash)]
if !ok {
err = liteErr.ErrCommitNotFound()
return fc, liteErr.ErrCommitNotFound()
}
return fc, err
return fc, nil
}
// LatestCommit returns the latest FullCommit or an error if no commits exist.
func (m *memStoreProvider) LatestCommit() (FullCommit, error) {
m.mtx.RLock()
defer m.mtx.RUnlock()
l := len(m.byHeight)
if l == 0 {
return FullCommit{}, liteErr.ErrCommitNotFound()