Skip to content
This repository has been archived by the owner on Dec 5, 2024. It is now read-only.

A bug on opcode CALL #1224

Open
chenjiaweiprimeledger opened this issue Nov 1, 2018 · 2 comments
Open

A bug on opcode CALL #1224

chenjiaweiprimeledger opened this issue Nov 1, 2018 · 2 comments

Comments

@chenjiaweiprimeledger
Copy link

chenjiaweiprimeledger commented Nov 1, 2018

When I executed ethereumj with a solidity program, I found that the requred gas is greater than left gas, throwing an exception.

org.ethereum.vm.VM#step

                DataWord gasLeft = program.getGas().clone();
                gasLeft.sub(new DataWord(gasCost));
                adjustedCallGas = **blockchainConfig.getCallGas(op, callGasWord, gasLeft)**;
                gasCost += adjustedCallGas.longValueSafe();

for example:
program.getGas()=100
gasCost=40
callGasWord comes from stack, it is 100 when call is contract call, and 0 when call is transfer. transfer is OK, but for contract call callGasWord is 100, gasLeft is 60, blockchainConfig.getCallGas will throw the exception.

@mkalinin
Copy link
Contributor

mkalinin commented Nov 7, 2018

The input is

gasLeft = 100; // gas left for the rest of the program execution
callGas = 100; // amount of gas that underlying call should be supplied with

The steps are

gasLeft = 100 - 40; // gasLeft is reduced by 40gas, the CALL price
if (callGas > gasLeft) throw; // program throws, cause there is not enough gas to supply underlying call

Isn't it a correct behavior?

@mitDarkMomo
Copy link

The input is

gasLeft = 100; // gas left for the rest of the program execution
callGas = 100; // amount of gas that underlying call should be supplied with

The steps are

gasLeft = 100 - 40; // gasLeft is reduced by 40gas, the CALL price
if (callGas > gasLeft) throw; // program throws, cause there is not enough gas to supply underlying call

Isn't it a correct behavior?

It's a correct behavior, but not a correct logic.

Comment on BlockchainConfig.getCallGas() says:

Calculates available gas to be passed for callee Since EIP150

But i'm afraid it's not implemented in AbstractConfig.getCallGas(), try this:

public DataWord getCallGas(OpCode op, DataWord requestedGas, DataWord availableGas) throws Program.OutOfGasException {
        // modify to apply eip150
        // if (requestedGas.compareTo(availableGas) > 0) {
        //     throw Program.Exception.notEnoughOpGas(op, requestedGas, availableGas);
        // }
        // return requestedGas;
        return availableGas.sub(availableGas.div(DataWord.of(64)));
    }

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants
@mkalinin @mitDarkMomo @chenjiaweiprimeledger and others