core: wrap dao in GetTestVM

MPT must not be shared to the test VM.
Fix DATA RACE between `Collapse()` and RPC calls.
This commit is contained in:
Evgenii Stratonikov 2020-09-04 16:45:31 +03:00
parent e0f406fd3a
commit bff67c921a
2 changed files with 11 additions and 5 deletions

View file

@ -1455,7 +1455,9 @@ func (bc *Blockchain) GetEnrollments() ([]state.Validator, error) {
// GetTestVM returns a VM and a Store setup for a test run of some sort of code. // GetTestVM returns a VM and a Store setup for a test run of some sort of code.
func (bc *Blockchain) GetTestVM(tx *transaction.Transaction) *vm.VM { func (bc *Blockchain) GetTestVM(tx *transaction.Transaction) *vm.VM {
systemInterop := bc.newInteropContext(trigger.Application, bc.dao, nil, tx) d := bc.dao.GetWrapped().(*dao.Simple)
d.MPT = nil
systemInterop := bc.newInteropContext(trigger.Application, d, nil, tx)
vm := systemInterop.SpawnVM() vm := systemInterop.SpawnVM()
vm.SetPriceGetter(getPrice) vm.SetPriceGetter(getPrice)
return vm return vm

View file

@ -367,9 +367,11 @@ func (dao *Simple) PutStorageItem(id int32, key []byte, si *state.StorageItem) e
return buf.Err return buf.Err
} }
v := buf.Bytes() v := buf.Bytes()
if dao.MPT != nil {
if err := dao.MPT.Put(stKey[1:], v); err != nil && err != mpt.ErrNotFound { if err := dao.MPT.Put(stKey[1:], v); err != nil && err != mpt.ErrNotFound {
return err return err
} }
}
return dao.Store.Put(stKey, v) return dao.Store.Put(stKey, v)
} }
@ -377,9 +379,11 @@ func (dao *Simple) PutStorageItem(id int32, key []byte, si *state.StorageItem) e
// given key from the store. // given key from the store.
func (dao *Simple) DeleteStorageItem(id int32, key []byte) error { func (dao *Simple) DeleteStorageItem(id int32, key []byte) error {
stKey := makeStorageItemKey(id, key) stKey := makeStorageItemKey(id, key)
if dao.MPT != nil {
if err := dao.MPT.Delete(stKey[1:]); err != nil && err != mpt.ErrNotFound { if err := dao.MPT.Delete(stKey[1:]); err != nil && err != mpt.ErrNotFound {
return err return err
} }
}
return dao.Store.Delete(stKey) return dao.Store.Delete(stKey)
} }