From 1957dea0be9561039bd658487a1ecea45139e4e4 Mon Sep 17 00:00:00 2001 From: JacobDenver007 Date: Thu, 9 May 2019 18:05:00 +0800 Subject: [PATCH] Vm delegate (#243) * assetamount push amount and assetName length into stack * assetamount push amount and assetName length into stack * cost more gas when receipt first receive assetID * cost more gas when receipt first receive assetID --- processor/transition.go | 1 + processor/vm/instructions.go | 5 +++++ processor/vm/vm.go | 30 ++++++++++++++++++++++++++++++ 3 files changed, 36 insertions(+) diff --git a/processor/transition.go b/processor/transition.go index ea6dc1fd..91a33047 100644 --- a/processor/transition.go +++ b/processor/transition.go @@ -116,6 +116,7 @@ func (st *StateTransition) TransitionDb() (ret []byte, usedGas uint64, failed bo if err != nil { return nil, 0, true, err, vmerr } + intrinsicGas += st.evm.CheckReceipt(st.action) if err := st.useGas(intrinsicGas); err != nil { return nil, 0, true, err, vmerr } diff --git a/processor/vm/instructions.go b/processor/vm/instructions.go index 45df125d..fbbb7239 100644 --- a/processor/vm/instructions.go +++ b/processor/vm/instructions.go @@ -1425,6 +1425,11 @@ func opCallEx(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *S action := types.NewAction(types.CallContract, contract.Name(), toName, 0, assetID, 0, value, nil, nil) + if !contract.UseGas(evm.CheckReceipt(action)) { + stack.push(evm.interpreter.intPool.getZero()) + return nil, nil + } + err = evm.AccountDB.TransferAsset(action.Sender(), action.Recipient(), action.AssetID(), action.Value()) //distribute gas var assetName common.Name diff --git a/processor/vm/vm.go b/processor/vm/vm.go index 0476bec8..53ea2f83 100644 --- a/processor/vm/vm.go +++ b/processor/vm/vm.go @@ -152,6 +152,24 @@ func (evm *EVM) Cancel() { atomic.StoreInt32(&evm.abort, 1) } +func (evm *EVM) CheckReceipt(action *types.Action) uint64 { + toAcct, err := evm.AccountDB.GetAccountByName(action.Recipient()) + if err != nil { + return 0 + } + if toAcct == nil { + return 0 + } + if toAcct.IsDestroyed() { + return 0 + } + _, err = toAcct.GetBalanceByID(action.AssetID()) + if err == accountmanager.ErrAccountAssetNotExist { + return params.CallValueTransferGas + } + return 0 +} + func (evm *EVM) distributeContractGas(runGas uint64, contractName common.Name, callerName common.Name) { if runGas > 0 && len(contractName.String()) > 0 { contratFounderRatio := evm.chainConfig.ChargeCfg.ContractRatio @@ -246,6 +264,12 @@ func (evm *EVM) Call(caller ContractRef, action *types.Action, gas uint64) (ret snapshot = evm.StateDB.Snapshot() ) + receiptGas := evm.CheckReceipt(action) + if gas < receiptGas { + return nil, gas, ErrInsufficientBalance + } else { + gas -= receiptGas + } if err := evm.AccountDB.TransferAsset(action.Sender(), action.Recipient(), action.AssetID(), action.Value()); err != nil { return nil, gas, err } @@ -504,6 +528,12 @@ func (evm *EVM) Create(caller ContractRef, action *types.Action, gas uint64) (re return nil, 0, ErrContractCodeCollision } + receiptGas := evm.CheckReceipt(action) + if gas < receiptGas { + return nil, gas, ErrInsufficientBalance + } else { + gas -= receiptGas + } if err := evm.AccountDB.TransferAsset(action.Sender(), action.Recipient(), evm.AssetID, action.Value()); err != nil { evm.StateDB.RevertToSnapshot(snapshot) return nil, gas, err