Browse Source

Merge pull request #1192 from chriseth/stopinvalidcall

STOP for invalid call.
cl-refactor
Gav Wood 10 years ago
parent
commit
6f1e7cbea2
  1. 9
      alethzero/MainWin.cpp
  2. 17
      libsolidity/ExpressionCompiler.cpp
  3. 4
      libwhisper/WhisperHost.cpp
  4. 11
      test/SolidityEndToEndTest.cpp

9
alethzero/MainWin.cpp

@ -1382,11 +1382,16 @@ void Main::on_blocks_currentItemChanged()
s << "<br/>Pre: <b>" << BlockInfo(ethereum()->blockChain().block(info.parentHash)).stateRoot << "</b>";
else
s << "<br/>Pre: <i>Nothing is before Phil</i>";
BlockReceipts receipts = ethereum()->blockChain().receipts(h);
unsigned ii = 0;
for (auto const& i: block[1])
s << "<br/>" << sha3(i.data()).abridged();// << ": <b>" << i[1].toHash<h256>() << "</b> [<b>" << i[2].toInt<u256>() << "</b> used]";
{
s << "<br/>" << sha3(i.data()).abridged() << ": <b>" << receipts.receipts[ii].stateRoot() << "</b> [<b>" << receipts.receipts[ii].gasUsed() << "</b> used]";
++ii;
}
s << "<br/>Post: <b>" << info.stateRoot << "</b>";
s << "<br/>Dump: " Span(Mono) << toHex(block[0].data()) << "</span>";
s << "<div>Receipts-Hex: " Span(Mono) << toHex(ethereum()->blockChain().receipts(h).rlp()) << "</span></div>";
s << "<div>Receipts-Hex: " Span(Mono) << toHex(receipts.rlp()) << "</span></div>";
}
else
{

17
libsolidity/ExpressionCompiler.cpp

@ -984,9 +984,10 @@ void ExpressionCompiler::appendExternalFunctionCall(FunctionType const& _functio
m_context << eth::dupInstruction(m_context.baseToCurrentStackOffset(gasStackPos));
else
// send all gas except for the 21 needed to execute "SUB" and "CALL"
m_context << u256(21) << eth::Instruction::GAS << eth::Instruction::SUB;
m_context << eth::Instruction::CALL
<< eth::Instruction::POP; // @todo do not ignore failure indicator
m_context << u256(_functionType.valueSet() ? 6741 : 41) << eth::Instruction::GAS << eth::Instruction::SUB;
m_context << eth::Instruction::CALL;
auto tag = m_context.appendConditionalJump();
m_context << eth::Instruction::STOP << tag; // STOP if CALL leaves 0.
if (_functionType.valueSet())
m_context << eth::Instruction::POP;
if (_functionType.gasSet())
@ -999,10 +1000,12 @@ void ExpressionCompiler::appendExternalFunctionCall(FunctionType const& _functio
CompilerUtils(m_context).loadFromMemory(0, *firstType, false, true);
}
void ExpressionCompiler::appendArgumentsCopyToMemory(vector<ASTPointer<Expression const>> const& _arguments,
TypePointers const& _types,
bool _padToWordBoundaries,
bool _padExceptionIfFourBytes)
void ExpressionCompiler::appendArgumentsCopyToMemory(
vector<ASTPointer<Expression const>> const& _arguments,
TypePointers const& _types,
bool _padToWordBoundaries,
bool _padExceptionIfFourBytes
)
{
solAssert(_types.empty() || _types.size() == _arguments.size(), "");
for (size_t i = 0; i < _arguments.size(); ++i)

4
libwhisper/WhisperHost.cpp

@ -58,7 +58,7 @@ void WhisperHost::inject(Envelope const& _m, WhisperPeer* _p)
{
cnote << this << ": inject: " << _m.expiry() << _m.ttl() << _m.topic() << toHex(_m.data());
if (_m.expiry() <= time(0))
if (_m.expiry() <= (unsigned)time(0))
return;
auto h = _m.sha3();
@ -171,7 +171,7 @@ void WhisperHost::cleanup()
{
// remove old messages.
// should be called every now and again.
auto now = time(0);
unsigned now = (unsigned)time(0);
WriteGuard l(x_messages);
for (auto it = m_expiryQueue.begin(); it != m_expiryQueue.end() && it->first <= now; it = m_expiryQueue.erase(it))
m_messages.erase(it->second);

11
test/SolidityEndToEndTest.cpp

@ -1619,9 +1619,11 @@ BOOST_AUTO_TEST_CASE(gas_and_value_basic)
function sendAmount(uint amount) returns (uint256 bal) {
return h.getBalance.value(amount)();
}
function outOfGas() returns (bool flagBefore, bool flagAfter, uint myBal) {
flagBefore = h.getFlag();
h.setFlag.gas(2)(); // should fail due to OOG, return value can be garbage
function outOfGas() returns (bool ret) {
h.setFlag.gas(2)(); // should fail due to OOG
return true;
}
function checkState() returns (bool flagAfter, uint myBal) {
flagAfter = h.getFlag();
myBal = this.balance;
}
@ -1630,7 +1632,8 @@ BOOST_AUTO_TEST_CASE(gas_and_value_basic)
compileAndRun(sourceCode, 20);
BOOST_REQUIRE(callContractFunction("sendAmount(uint256)", 5) == encodeArgs(5));
// call to helper should not succeed but amount should be transferred anyway
BOOST_REQUIRE(callContractFunction("outOfGas()", 5) == encodeArgs(false, false, 20 - 5));
BOOST_REQUIRE(callContractFunction("outOfGas()", 5) == bytes());
BOOST_REQUIRE(callContractFunction("checkState()", 5) == encodeArgs(false, 20 - 5));
}
BOOST_AUTO_TEST_CASE(value_complex)

Loading…
Cancel
Save