Merge pull request #1014 from nspcc-dev/mpt-fixes

Mpt fixes
This commit is contained in:
Roman Khimov 2020-06-04 19:04:02 +03:00 committed by GitHub
commit 0b87a68210
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 18 additions and 8 deletions

View file

@ -835,7 +835,7 @@ func (bc *Blockchain) storeBlock(block *block.Block) error {
if err != nil {
return errors.WithMessagef(err, "can't get previous state root")
}
prevHash = prev.Root
prevHash = hash.DoubleSha256(prev.GetSignedPart())
}
err := bc.AddStateRoot(&state.MPTRoot{
MPTRootBase: state.MPTRootBase{
@ -859,6 +859,12 @@ func (bc *Blockchain) storeBlock(block *block.Block) error {
return err
}
bc.dao.MPT.Flush()
// Every persist cycle we also compact our in-memory MPT.
persistedHeight := atomic.LoadUint32(&bc.persistedHeight)
if persistedHeight == block.Index-1 {
// 10 is good and roughly estimated to fit remaining trie into 1M of memory.
bc.dao.MPT.Collapse(10)
}
bc.topBlock.Store(block)
atomic.StoreUint32(&bc.blockHeight, block.Index)
bc.memPool.RemoveStale(bc.isTxStillRelevant)
@ -1803,7 +1809,7 @@ func (bc *Blockchain) verifyStateRoot(r *state.MPTRoot) error {
prev, err := bc.GetStateRoot(r.Index - 1)
if err != nil {
return errors.New("can't get previous state root")
} else if !prev.Root.Equals(r.PrevHash) {
} else if !r.PrevHash.Equals(hash.DoubleSha256(prev.GetSignedPart())) {
return errors.New("previous hash mismatch")
} else if prev.Version != r.Version {
return errors.New("version mismatch")

View file

@ -245,6 +245,7 @@ func (cd *Cached) FlushStorage() error {
return err
}
}
ti.State |= flushedState
}
}
return nil
@ -275,7 +276,7 @@ func (cd *Cached) getStorageItemNoCache(scripthash util.Uint160, key []byte) *st
func (cd *Cached) getStorageItemInt(scripthash util.Uint160, key []byte, putToCache bool) *state.StorageItem {
ti := cd.storage.getItem(scripthash, key)
if ti != nil {
if ti.State == delOp {
if ti.State&delOp != 0 {
return nil
}
return copyItem(&ti.StorageItem)
@ -303,8 +304,10 @@ func (cd *Cached) PutStorageItem(scripthash util.Uint160, key []byte, si *state.
item := copyItem(si)
ti := cd.storage.getItem(scripthash, key)
if ti != nil {
if ti.State == delOp || ti.State == getOp {
if ti.State&(delOp|getOp) != 0 {
ti.State = putOp
} else {
ti.State = addOp
}
ti.StorageItem = *item
return nil
@ -357,7 +360,7 @@ func (cd *Cached) GetStorageItemsIterator(hash util.Uint160, prefix []byte) (Sto
for ; keyIndex < len(cd.storage.keys[hash]); keyIndex++ {
k := cd.storage.keys[hash][keyIndex]
v := cache[k]
if v.State != delOp && bytes.HasPrefix([]byte(k), prefix) {
if v.State&delOp == 0 && bytes.HasPrefix([]byte(k), prefix) {
val := make([]byte, len(v.StorageItem.Value))
copy(val, v.StorageItem.Value)
return []byte(k), val, nil
@ -404,7 +407,7 @@ func (cd *Cached) GetStorageItems(hash util.Uint160, prefix []byte) ([]StorageIt
for _, k := range cd.storage.keys[hash] {
v := cache[k]
if v.State != delOp {
if v.State&delOp == 0 {
val := make([]byte, len(v.StorageItem.Value))
copy(val, v.StorageItem.Value)
result = append(result, StorageItemWithKey{

View file

@ -475,7 +475,7 @@ func (dao *Simple) PutStorageItem(scripthash util.Uint160, key []byte, si *state
if err := dao.MPT.Put(k, v); err != nil && err != mpt.ErrNotFound {
return err
}
return dao.Put(si, stKey)
return dao.Store.Put(stKey, v[1:])
}
// DeleteStorageItem drops storage item for the given script with the

View file

@ -24,6 +24,7 @@ const (
delOp
addOp
putOp
flushedState
)
func newItemCache() *itemCache {

View file

@ -261,7 +261,6 @@ func (t *Trie) deleteFromExtension(n *ExtensionNode, path []byte) (Node, error)
case *ExtensionNode:
n.key = append(n.key, nxt.key...)
n.next = nxt.next
n.invalidateCache()
case *HashNode:
if nxt.IsEmpty() {
return nxt, nil
@ -269,6 +268,7 @@ func (t *Trie) deleteFromExtension(n *ExtensionNode, path []byte) (Node, error)
default:
n.next = r
}
n.invalidateCache()
return n, nil
}