Skip to content

Commit

Permalink
inline call to CallExpert
Browse files Browse the repository at this point in the history
  • Loading branch information
darioush committed Sep 18, 2024
1 parent e1702c0 commit 0dbb579
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 19 deletions.
18 changes: 0 additions & 18 deletions core/vm/evm.go
Original file line number Diff line number Diff line change
Expand Up @@ -345,24 +345,6 @@ func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas
return ret, gas, err
}

// This allows the user transfer balance of a specified coinId in addition to a normal Call().
func (evm *EVM) CallExpert(caller ContractRef, addr common.Address, input []byte, gas uint64, value *uint256.Int, coinID common.Hash, value2 *big.Int) (ret []byte, leftOverGas uint64, err error) {
transfer := evm.Context.Transfer
defer func() { evm.Context.Transfer = transfer }()

evm.Context.Transfer = func(db StateDB, from, to common.Address, amount *uint256.Int) {
// Restore the original function after this is called once
defer func() { evm.Context.Transfer = transfer }()
transfer(db, from, to, amount)
evm.Context.TransferMultiCoin(db, from, to, coinID, value2)
}

if value2.Sign() != 0 && !evm.Context.CanTransferMC(evm.StateDB, caller.Address(), addr, coinID, value2) {
return nil, gas, vmerrs.ErrInsufficientBalance
}
return evm.Call(caller, addr, input, gas, value)
}

// CallCode executes the contract associated with the addr with the given input
// as parameters. It also handles any necessary value transfer required and takes
// the necessary steps to create accounts and reverses the state in case of an
Expand Down
23 changes: 22 additions & 1 deletion core/vm/instructions.go
Original file line number Diff line number Diff line change
Expand Up @@ -732,7 +732,28 @@ func opCallExpert(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext)
if !value.IsZero() {
gas += params.CallStipend
}
ret, returnGas, err := interpreter.evm.CallExpert(scope.Contract, toAddr, args, gas, &value, coinID, bigVal2)

evm := interpreter.evm
transfer := evm.Context.Transfer
defer func() { evm.Context.Transfer = transfer }()

evm.Context.Transfer = func(db StateDB, from, to common.Address, amount *uint256.Int) {
// Restore the original function after this is called once
defer func() { evm.Context.Transfer = transfer }()
transfer(db, from, to, amount)
evm.Context.TransferMultiCoin(db, from, to, coinID, bigVal2)
}

var (
ret []byte
returnGas uint64
err error
)
if value2.Sign() != 0 && !evm.Context.CanTransferMC(evm.StateDB, scope.Contract.Address(), toAddr, coinID, bigVal2) {
ret, returnGas, err = nil, gas, vmerrs.ErrInsufficientBalance
} else {
ret, returnGas, err = evm.Call(scope.Contract, toAddr, args, gas, &value)
}
if err != nil {
temp.Clear()
} else {
Expand Down

0 comments on commit 0dbb579

Please # to comment.