Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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 join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants
@mkalinin @mitDarkMomo @chenjiaweiprimeledger and others