core: get data from dao in interops
It's more logically correct as Blockchain can be several transactions behind in terms of its state.
This commit is contained in:
parent
0abd55c2c2
commit
212cf44e26
3 changed files with 33 additions and 36 deletions
|
@ -1336,8 +1336,8 @@ func (bc *Blockchain) GetScriptHashesForVerifying(t *transaction.Transaction) ([
|
|||
func (bc *Blockchain) spawnVMWithInterops(interopCtx *interopContext) *vm.VM {
|
||||
vm := vm.New()
|
||||
vm.SetScriptGetter(func(hash util.Uint160) []byte {
|
||||
cs := bc.GetContractState(hash)
|
||||
if cs == nil {
|
||||
cs, err := interopCtx.dao.GetContractState(hash)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
return cs.Script
|
||||
|
|
|
@ -172,8 +172,8 @@ func (ic *interopContext) txGetUnspentCoins(v *vm.VM) error {
|
|||
if !ok {
|
||||
return errors.New("value is not a transaction")
|
||||
}
|
||||
ucs := ic.bc.GetUnspentCoinState(tx.Hash())
|
||||
if ucs == nil {
|
||||
ucs, err := ic.dao.GetUnspentCoinState(tx.Hash())
|
||||
if err != nil {
|
||||
return errors.New("no unspent coin state found")
|
||||
}
|
||||
v.Estack().PushVal(vm.NewInteropItem(ucs))
|
||||
|
@ -200,10 +200,7 @@ func (ic *interopContext) txGetWitnesses(v *vm.VM) error {
|
|||
|
||||
// bcGetValidators returns validators.
|
||||
func (ic *interopContext) bcGetValidators(v *vm.VM) error {
|
||||
validators, err := ic.bc.GetValidators()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
validators := ic.dao.GetValidators()
|
||||
v.Estack().PushVal(validators)
|
||||
return nil
|
||||
}
|
||||
|
@ -315,9 +312,9 @@ func (ic *interopContext) bcGetAccount(v *vm.VM) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
acc := ic.bc.GetAccountState(acchash)
|
||||
if acc == nil {
|
||||
acc = state.NewAccount(acchash)
|
||||
acc, err := ic.dao.GetAccountStateOrNew(acchash)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
v.Estack().PushVal(vm.NewInteropItem(acc))
|
||||
return nil
|
||||
|
@ -330,8 +327,8 @@ func (ic *interopContext) bcGetAsset(v *vm.VM) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
as := ic.bc.GetAssetState(ashash)
|
||||
if as == nil {
|
||||
as, err := ic.dao.GetAssetState(ashash)
|
||||
if err != nil {
|
||||
return errors.New("asset not found")
|
||||
}
|
||||
v.Estack().PushVal(vm.NewInteropItem(as))
|
||||
|
@ -394,8 +391,8 @@ func (ic *interopContext) accountIsStandard(v *vm.VM) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
contract := ic.bc.GetContractState(acchash)
|
||||
res := contract == nil || vm.IsStandardContract(contract.Script)
|
||||
contract, err := ic.dao.GetContractState(acchash)
|
||||
res := err != nil || vm.IsStandardContract(contract.Script)
|
||||
v.Estack().PushVal(res)
|
||||
return nil
|
||||
}
|
||||
|
@ -413,7 +410,7 @@ func (ic *interopContext) storageFind(v *vm.VM) error {
|
|||
return err
|
||||
}
|
||||
prefix := string(v.Estack().Pop().Bytes())
|
||||
siMap, err := ic.bc.GetStorageItems(stc.ScriptHash)
|
||||
siMap, err := ic.dao.GetStorageItems(stc.ScriptHash)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -488,8 +485,8 @@ func (ic *interopContext) contractCreate(v *vm.VM) error {
|
|||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
contract := ic.bc.GetContractState(newcontract.ScriptHash())
|
||||
if contract == nil {
|
||||
contract, err := ic.dao.GetContractState(newcontract.ScriptHash())
|
||||
if err != nil {
|
||||
contract = newcontract
|
||||
err := ic.dao.PutContractState(contract)
|
||||
if err != nil {
|
||||
|
@ -528,8 +525,8 @@ func (ic *interopContext) contractMigrate(v *vm.VM) error {
|
|||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
contract := ic.bc.GetContractState(newcontract.ScriptHash())
|
||||
if contract == nil {
|
||||
contract, err := ic.dao.GetContractState(newcontract.ScriptHash())
|
||||
if err != nil {
|
||||
contract = newcontract
|
||||
err := ic.dao.PutContractState(contract)
|
||||
if err != nil {
|
||||
|
@ -537,7 +534,7 @@ func (ic *interopContext) contractMigrate(v *vm.VM) error {
|
|||
}
|
||||
if contract.HasStorage() {
|
||||
hash := getContextScriptHash(v, 0)
|
||||
siMap, err := ic.bc.GetStorageItems(hash)
|
||||
siMap, err := ic.dao.GetStorageItems(hash)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -729,8 +726,8 @@ func (ic *interopContext) assetRenew(v *vm.VM) error {
|
|||
}
|
||||
years := byte(v.Estack().Pop().BigInt().Int64())
|
||||
// Not sure why C# code regets an asset from the Store, but we also do it.
|
||||
asset := ic.bc.GetAssetState(as.ID)
|
||||
if asset == nil {
|
||||
asset, err := ic.dao.GetAssetState(as.ID)
|
||||
if err != nil {
|
||||
return errors.New("can't renew non-existent asset")
|
||||
}
|
||||
if asset.Expiration < ic.bc.BlockHeight()+1 {
|
||||
|
@ -741,7 +738,7 @@ func (ic *interopContext) assetRenew(v *vm.VM) error {
|
|||
expiration = math.MaxUint32
|
||||
}
|
||||
asset.Expiration = uint32(expiration)
|
||||
err := ic.dao.PutAssetState(asset)
|
||||
err = ic.dao.PutAssetState(asset)
|
||||
if err != nil {
|
||||
return gherr.Wrap(err, "failed to store asset")
|
||||
}
|
||||
|
|
|
@ -68,8 +68,8 @@ func (ic *interopContext) bcGetContract(v *vm.VM) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cs := ic.bc.GetContractState(hash)
|
||||
if cs == nil {
|
||||
cs, err := ic.dao.GetContractState(hash)
|
||||
if err != nil {
|
||||
v.Estack().PushVal([]byte{})
|
||||
} else {
|
||||
v.Estack().PushVal(vm.NewInteropItem(cs))
|
||||
|
@ -100,18 +100,18 @@ func (ic *interopContext) bcGetHeight(v *vm.VM) error {
|
|||
|
||||
// getTransactionAndHeight gets parameter from the vm evaluation stack and
|
||||
// returns transaction and its height if it's present in the blockchain.
|
||||
func getTransactionAndHeight(bc Blockchainer, v *vm.VM) (*transaction.Transaction, uint32, error) {
|
||||
func getTransactionAndHeight(cd *cachedDao, v *vm.VM) (*transaction.Transaction, uint32, error) {
|
||||
hashbytes := v.Estack().Pop().Bytes()
|
||||
hash, err := util.Uint256DecodeBytesLE(hashbytes)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
return bc.GetTransaction(hash)
|
||||
return cd.GetTransaction(hash)
|
||||
}
|
||||
|
||||
// bcGetTransaction returns transaction.
|
||||
func (ic *interopContext) bcGetTransaction(v *vm.VM) error {
|
||||
tx, _, err := getTransactionAndHeight(ic.bc, v)
|
||||
tx, _, err := getTransactionAndHeight(ic.dao, v)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -121,7 +121,7 @@ func (ic *interopContext) bcGetTransaction(v *vm.VM) error {
|
|||
|
||||
// bcGetTransactionHeight returns transaction height.
|
||||
func (ic *interopContext) bcGetTransactionHeight(v *vm.VM) error {
|
||||
_, h, err := getTransactionAndHeight(ic.bc, v)
|
||||
_, h, err := getTransactionAndHeight(ic.dao, v)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -383,8 +383,8 @@ func (ic *interopContext) runtimeDeserialize(v *vm.VM) error {
|
|||
}
|
||||
*/
|
||||
func (ic *interopContext) checkStorageContext(stc *StorageContext) error {
|
||||
contract := ic.bc.GetContractState(stc.ScriptHash)
|
||||
if contract == nil {
|
||||
contract, err := ic.dao.GetContractState(stc.ScriptHash)
|
||||
if err != nil {
|
||||
return errors.New("no contract found")
|
||||
}
|
||||
if !contract.HasStorage() {
|
||||
|
@ -535,16 +535,16 @@ func (ic *interopContext) contractDestroy(v *vm.VM) error {
|
|||
return errors.New("can't destroy contract when not triggered by application")
|
||||
}
|
||||
hash := getContextScriptHash(v, 0)
|
||||
cs := ic.bc.GetContractState(hash)
|
||||
if cs == nil {
|
||||
cs, err := ic.dao.GetContractState(hash)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
err := ic.dao.DeleteContractState(hash)
|
||||
err = ic.dao.DeleteContractState(hash)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if cs.HasStorage() {
|
||||
siMap, err := ic.bc.GetStorageItems(hash)
|
||||
siMap, err := ic.dao.GetStorageItems(hash)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue