From ac1a11634edaacfdbc198df4ed4078ac4c141af7 Mon Sep 17 00:00:00 2001 From: chriseth Date: Tue, 28 Jul 2015 13:37:38 +0200 Subject: [PATCH] Improved gas computation for CALLCODE. --- ExpressionCompiler.cpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/ExpressionCompiler.cpp b/ExpressionCompiler.cpp index 470fd7c58..786d386d9 100644 --- a/ExpressionCompiler.cpp +++ b/ExpressionCompiler.cpp @@ -1072,6 +1072,7 @@ void ExpressionCompiler::appendExternalFunctionCall( using FunctionKind = FunctionType::Location; FunctionKind funKind = _functionType.getLocation(); bool returnSuccessCondition = funKind == FunctionKind::Bare || funKind == FunctionKind::BareCallCode; + bool isCallCode = funKind == FunctionKind::BareCallCode || funKind == FunctionKind::CallCode; //@todo only return the first return value for now Type const* firstReturnType = @@ -1158,13 +1159,20 @@ void ExpressionCompiler::appendExternalFunctionCall( if (_functionType.gasSet()) m_context << eth::dupInstruction(m_context.baseToCurrentStackOffset(gasStackPos)); else + { // send all gas except the amount needed to execute "SUB" and "CALL" // @todo this retains too much gas for now, needs to be fine-tuned. + u256 gasNeededByCaller = eth::c_callGas + 10; + if (_functionType.valueSet()) + gasNeededByCaller += eth::c_callValueTransferGas; + if (!isCallCode) + gasNeededByCaller += eth::c_callNewAccountGas; // we never know m_context << - u256(eth::c_callGas + 10 + (_functionType.valueSet() ? eth::c_callValueTransferGas : 0) + eth::c_callNewAccountGas) << + gasNeededByCaller << eth::Instruction::GAS << eth::Instruction::SUB; - if (funKind == FunctionKind::CallCode || funKind == FunctionKind::BareCallCode) + } + if (isCallCode) m_context << eth::Instruction::CALLCODE; else m_context << eth::Instruction::CALL;