diff --git a/core/store/statestore/state_batch.go b/core/store/statestore/state_batch.go index d81141d27b..8c93148292 100644 --- a/core/store/statestore/state_batch.go +++ b/core/store/statestore/state_batch.go @@ -43,7 +43,7 @@ func NewStateStoreBatch(memoryStore common.MemoryCacheStore, store common.Persis } func (self *StateBatch) Find(prefix common.DataEntryPrefix, key []byte) ([]*common.StateItem, error) { - var states []*common.StateItem + var sts []*common.StateItem bp := []byte{byte(prefix)} iter := self.store.NewIterator(append(bp, key...)) defer iter.Release() @@ -56,16 +56,16 @@ func (self *StateBatch) Find(prefix common.DataEntryPrefix, key []byte) ([]*comm if err != nil { return nil, err } - states = append(states, &common.StateItem{Key: string(keyV), Value: state}) + sts = append(sts, &common.StateItem{Key: string(keyV), Value: state}) } } keyP := string(append(bp, key...)) for _, v := range self.memoryStore.Find() { if v.State != common.Deleted && strings.HasPrefix(v.Key, keyP) { - states = append(states, v.Copy()) + sts = append(sts, v.Copy()) } } - return states, nil + return sts, nil } func (self *StateBatch) TryAdd(prefix common.DataEntryPrefix, key []byte, value states.StateValue) { @@ -73,51 +73,59 @@ func (self *StateBatch) TryAdd(prefix common.DataEntryPrefix, key []byte, value } func (self *StateBatch) TryGetOrAdd(prefix common.DataEntryPrefix, key []byte, value states.StateValue) error { - state := self.memoryStore.Get(byte(prefix), key) + bPrefix := byte(prefix) + aPrefix := []byte{bPrefix} + state := self.memoryStore.Get(bPrefix, key) if state != nil { if state.State == common.Deleted { - self.setStateObject(byte(prefix), key, value, common.Changed) + self.setStateObject(bPrefix, key, value, common.Changed) return nil } return nil } - item, err := self.store.Get(append([]byte{byte(prefix)}, key...)) - if err != nil && err != leveldb.ErrNotFound { + _, err := self.store.Get(append(aPrefix, key...)) + if err != nil { + if err == leveldb.ErrNotFound { + return nil + } return errors.NewDetailErr(err, errors.ErrNoCode, "[TryGetOrAdd], leveldb store get data failed.") } - if item != nil { - return nil - } - self.setStateObject(byte(prefix), key, value, common.Changed) + + self.setStateObject(bPrefix, key, value, common.Changed) return nil } func (self *StateBatch) TryGet(prefix common.DataEntryPrefix, key []byte) (*common.StateItem, error) { - state := self.memoryStore.Get(byte(prefix), key) + bPrefix := byte(prefix) + aPrefix := []byte{bPrefix} + pk := append(aPrefix, key...) + state := self.memoryStore.Get(bPrefix, key) if state != nil { if state.State == common.Deleted { return nil, nil } return state, nil } - enc, err := self.store.Get(append([]byte{byte(prefix)}, key...)) - if err != nil && err != leveldb.ErrNotFound { + enc, err := self.store.Get(pk) + if err != nil { + if err == leveldb.ErrNotFound { + return nil, nil + } return nil, errors.NewDetailErr(err, errors.ErrNoCode, "[TryGet], leveldb store get data failed.") } - if enc == nil { - return nil, nil - } stateVal, err := getStateObject(prefix, enc) if err != nil { return nil, err } - self.setStateObject(byte(prefix), key, stateVal, common.None) - return &common.StateItem{Key: string(append([]byte{byte(prefix)}, key...)), Value: stateVal, State: common.None}, nil + self.setStateObject(bPrefix, key, stateVal, common.None) + return &common.StateItem{Key: string(pk), Value: stateVal, State: common.None}, nil } func (self *StateBatch) TryGetAndChange(prefix common.DataEntryPrefix, key []byte) (states.StateValue, error) { - state := self.memoryStore.Get(byte(prefix), key) + bPrefix := byte(prefix) + aPrefix := []byte{bPrefix} + state := self.memoryStore.Get(bPrefix, key) if state != nil { if state.State == common.Deleted { return nil, nil @@ -126,21 +134,20 @@ func (self *StateBatch) TryGetAndChange(prefix common.DataEntryPrefix, key []byt } return state.Value, nil } - k := append([]byte{byte(prefix)}, key...) + k := append(aPrefix, key...) enc, err := self.store.Get(k) - if err != nil && err != leveldb.ErrNotFound { + if err != nil { + if err == leveldb.ErrNotFound { + return nil, nil + } return nil, errors.NewDetailErr(err, errors.ErrNoCode, "[TryGetAndChange], leveldb store get data failed.") } - if enc == nil { - return nil, nil - } - val, err := getStateObject(prefix, enc) if err != nil { return nil, err } - self.setStateObject(byte(prefix), key, val, common.Changed) + self.setStateObject(bPrefix, key, val, common.Changed) return val, nil } diff --git a/smartcontract/storage/dbcache.go b/smartcontract/storage/dbcache.go index b0aa0dfc48..b0f754c862 100644 --- a/smartcontract/storage/dbcache.go +++ b/smartcontract/storage/dbcache.go @@ -51,17 +51,19 @@ func NewCloneCache(store common.StateStore) *CloneCache { // Commit current transaction cache to block cache func (cloneCache *CloneCache) Commit() { for _, v := range cloneCache.Memory { + vk := []byte(v.Key) if v.State == common.Deleted { - cloneCache.Store.TryDelete(v.Prefix, []byte(v.Key)) + cloneCache.Store.TryDelete(v.Prefix, vk) } else if v.State == common.Changed { - cloneCache.Store.TryAdd(v.Prefix, []byte(v.Key), v.Value) + cloneCache.Store.TryAdd(v.Prefix, vk, v.Value) } } } // Add item to cache func (cloneCache *CloneCache) Add(prefix common.DataEntryPrefix, key []byte, value states.StateValue) { - cloneCache.Memory[string(append([]byte{byte(prefix)}, key...))] = &StateItem{ + pk := string(append([]byte{byte(prefix)}, key...)) + cloneCache.Memory[pk] = &StateItem{ Prefix: prefix, Key: string(key), Value: value, @@ -73,9 +75,10 @@ func (cloneCache *CloneCache) Add(prefix common.DataEntryPrefix, key []byte, val // If item has existed, return it // Else add it to cache func (cloneCache *CloneCache) GetOrAdd(prefix common.DataEntryPrefix, key []byte, value states.StateValue) (states.StateValue, error) { - if v, ok := cloneCache.Memory[string(append([]byte{byte(prefix)}, key...))]; ok { + pk := string(append([]byte{byte(prefix)}, key...)) + if v, ok := cloneCache.Memory[pk]; ok { if v.State == common.Deleted { - cloneCache.Memory[string(append([]byte{byte(prefix)}, key...))] = &StateItem{Prefix: prefix, Key: string(key), Value: value, State: common.Changed} + cloneCache.Memory[pk] = &StateItem{Prefix: prefix, Key: string(key), Value: value, State: common.Changed} return value, nil } return v.Value, nil @@ -87,13 +90,14 @@ func (cloneCache *CloneCache) GetOrAdd(prefix common.DataEntryPrefix, key []byte if item != nil && item.State != common.Deleted { return item.Value, nil } - cloneCache.Memory[string(append([]byte{byte(prefix)}, key...))] = &StateItem{Prefix: prefix, Key: string(key), Value: value, State: common.Changed} + cloneCache.Memory[pk] = &StateItem{Prefix: prefix, Key: string(key), Value: value, State: common.Changed} return value, nil } // Get item by key func (cloneCache *CloneCache) Get(prefix common.DataEntryPrefix, key []byte) (states.StateValue, error) { - if v, ok := cloneCache.Memory[string(append([]byte{byte(prefix)}, key...))]; ok { + pk := string(append([]byte{byte(prefix)}, key...)) + if v, ok := cloneCache.Memory[pk]; ok { if v.State == common.Deleted { return nil, nil } @@ -111,10 +115,11 @@ func (cloneCache *CloneCache) Get(prefix common.DataEntryPrefix, key []byte) (st // Delete item from cache func (cloneCache *CloneCache) Delete(prefix common.DataEntryPrefix, key []byte) { - if v, ok := cloneCache.Memory[string(append([]byte{byte(prefix)}, key...))]; ok { + pk := string(append([]byte{byte(prefix)}, key...)) + if v, ok := cloneCache.Memory[pk]; ok { v.State = common.Deleted } else { - cloneCache.Memory[string(append([]byte{byte(prefix)}, key...))] = &StateItem{ + cloneCache.Memory[pk] = &StateItem{ Prefix: prefix, Key: string(key), State: common.Deleted,