neo-go/pkg/core/stateroot/store.go
Roman Khimov d143696328 stateroot: try to fix MPT caching/updating
It was completely ruined by bf20db09e0. MPT was
updating bc.dao directly which shouldn't ever happen, it must write into the
same cache and then Persist these KVs as usual.
2021-03-27 00:33:11 +03:00

80 lines
1.9 KiB
Go

package stateroot
import (
"encoding/binary"
"github.com/nspcc-dev/neo-go/pkg/core/state"
"github.com/nspcc-dev/neo-go/pkg/core/storage"
"github.com/nspcc-dev/neo-go/pkg/io"
)
const (
prefixGC = 0x01
prefixLocal = 0x02
prefixValidated = 0x03
)
func (s *Module) addLocalStateRoot(store *storage.MemCachedStore, sr *state.MPTRoot) error {
key := makeStateRootKey(sr.Index)
if err := putStateRoot(store, key, sr); err != nil {
return err
}
data := make([]byte, 4)
binary.LittleEndian.PutUint32(data, sr.Index)
return store.Put([]byte{byte(storage.DataMPT), prefixLocal}, data)
}
func putStateRoot(store *storage.MemCachedStore, key []byte, sr *state.MPTRoot) error {
w := io.NewBufBinWriter()
sr.EncodeBinary(w.BinWriter)
return store.Put(key, w.Bytes())
}
func (s *Module) getStateRoot(key []byte) (*state.MPTRoot, error) {
data, err := s.Store.Get(key)
if err != nil {
return nil, err
}
sr := &state.MPTRoot{}
r := io.NewBinReaderFromBuf(data)
sr.DecodeBinary(r)
return sr, r.Err
}
func makeStateRootKey(index uint32) []byte {
key := make([]byte, 5)
key[0] = byte(storage.DataMPT)
binary.BigEndian.PutUint32(key, index)
return key
}
// AddStateRoot adds validated state root provided by network.
func (s *Module) AddStateRoot(sr *state.MPTRoot) error {
if err := s.VerifyStateRoot(sr); err != nil {
return err
}
key := makeStateRootKey(sr.Index)
local, err := s.getStateRoot(key)
if err != nil {
return err
}
if len(local.Witness) != 0 {
return nil
}
if err := putStateRoot(s.Store, key, sr); err != nil {
return err
}
data := make([]byte, 4)
binary.LittleEndian.PutUint32(data, sr.Index)
if err := s.Store.Put([]byte{byte(storage.DataMPT), prefixValidated}, data); err != nil {
return err
}
s.validatedHeight.Store(sr.Index)
if !s.bc.GetConfig().StateRootInHeader {
updateStateHeightMetric(sr.Index)
}
return nil
}