diff --git a/libevm/VM.h b/libevm/VM.h index 2eb34ed04..ce8001bbf 100644 --- a/libevm/VM.h +++ b/libevm/VM.h @@ -110,6 +110,7 @@ template dev::bytesConstRef dev::eth::VM::go(Ext& _ext, OnOpFunc con break; case Instruction::SUICIDE: + require(1); runGas = 0; break; @@ -124,6 +125,7 @@ template dev::bytesConstRef dev::eth::VM::go(Ext& _ext, OnOpFunc con break; case Instruction::SLOAD: + require(1); runGas = c_sloadGas; break; @@ -163,15 +165,11 @@ template dev::bytesConstRef dev::eth::VM::go(Ext& _ext, OnOpFunc con break; case Instruction::BALANCE: + require(1); runGas = c_balanceGas; break; case Instruction::CALL: - require(7); - runGas = c_callGas + m_stack[m_stack.size() - 1]; - newTempSize = std::max(memNeed(m_stack[m_stack.size() - 6], m_stack[m_stack.size() - 7]), memNeed(m_stack[m_stack.size() - 4], m_stack[m_stack.size() - 5])); - break; - case Instruction::CALLCODE: require(7); runGas = c_callGas + m_stack[m_stack.size() - 1]; @@ -188,35 +186,16 @@ template dev::bytesConstRef dev::eth::VM::go(Ext& _ext, OnOpFunc con break; } - case Instruction::ADD: - case Instruction::MUL: - case Instruction::SUB: - case Instruction::DIV: - case Instruction::SDIV: - case Instruction::MOD: - case Instruction::SMOD: - case Instruction::EXP: - case Instruction::NEG: - case Instruction::LT: - case Instruction::GT: - case Instruction::SLT: - case Instruction::SGT: - case Instruction::EQ: - case Instruction::NOT: - case Instruction::AND: - case Instruction::OR: - case Instruction::XOR: - case Instruction::BYTE: - case Instruction::ADDMOD: - case Instruction::MULMOD: + case Instruction::PC: + case Instruction::MSIZE: + case Instruction::GAS: + case Instruction::JUMPDEST: case Instruction::ADDRESS: case Instruction::ORIGIN: case Instruction::CALLER: case Instruction::CALLVALUE: - case Instruction::CALLDATALOAD: case Instruction::CALLDATASIZE: case Instruction::CODESIZE: - case Instruction::EXTCODESIZE: case Instruction::GASPRICE: case Instruction::PREVHASH: case Instruction::COINBASE: @@ -256,7 +235,39 @@ template dev::bytesConstRef dev::eth::VM::go(Ext& _ext, OnOpFunc con case Instruction::PUSH30: case Instruction::PUSH31: case Instruction::PUSH32: + break; + case Instruction::NEG: + case Instruction::NOT: + case Instruction::CALLDATALOAD: + case Instruction::EXTCODESIZE: case Instruction::POP: + case Instruction::JUMP: + require(1); + break; + case Instruction::ADD: + case Instruction::MUL: + case Instruction::SUB: + case Instruction::DIV: + case Instruction::SDIV: + case Instruction::MOD: + case Instruction::SMOD: + case Instruction::EXP: + case Instruction::LT: + case Instruction::GT: + case Instruction::SLT: + case Instruction::SGT: + case Instruction::EQ: + case Instruction::AND: + case Instruction::OR: + case Instruction::XOR: + case Instruction::BYTE: + case Instruction::JUMPI: + require(2); + break; + case Instruction::ADDMOD: + case Instruction::MULMOD: + require(3); + break; case Instruction::DUP1: case Instruction::DUP2: case Instruction::DUP3: @@ -273,6 +284,8 @@ template dev::bytesConstRef dev::eth::VM::go(Ext& _ext, OnOpFunc con case Instruction::DUP14: case Instruction::DUP15: case Instruction::DUP16: + require(1 + (int)inst - (int)Instruction::DUP1); + break; case Instruction::SWAP1: case Instruction::SWAP2: case Instruction::SWAP3: @@ -289,12 +302,7 @@ template dev::bytesConstRef dev::eth::VM::go(Ext& _ext, OnOpFunc con case Instruction::SWAP14: case Instruction::SWAP15: case Instruction::SWAP16: - case Instruction::JUMP: - case Instruction::JUMPI: - case Instruction::PC: - case Instruction::MSIZE: - case Instruction::GAS: - case Instruction::JUMPDEST: + require((int)inst - (int)Instruction::SWAP1 + 2); break; default: BOOST_THROW_EXCEPTION(BadInstruction()); @@ -324,44 +332,36 @@ template dev::bytesConstRef dev::eth::VM::go(Ext& _ext, OnOpFunc con { case Instruction::ADD: //pops two items and pushes S[-1] + S[-2] mod 2^256. - require(2); m_stack[m_stack.size() - 2] += m_stack.back(); m_stack.pop_back(); break; case Instruction::MUL: //pops two items and pushes S[-1] * S[-2] mod 2^256. - require(2); m_stack[m_stack.size() - 2] *= m_stack.back(); m_stack.pop_back(); break; case Instruction::SUB: - require(2); m_stack[m_stack.size() - 2] = m_stack.back() - m_stack[m_stack.size() - 2]; m_stack.pop_back(); break; case Instruction::DIV: - require(2); m_stack[m_stack.size() - 2] = m_stack[m_stack.size() - 2] ? m_stack.back() / m_stack[m_stack.size() - 2] : 0; m_stack.pop_back(); break; case Instruction::SDIV: - require(2); m_stack[m_stack.size() - 2] = m_stack[m_stack.size() - 2] ? s2u(u2s(m_stack.back()) / u2s(m_stack[m_stack.size() - 2])) : 0; m_stack.pop_back(); break; case Instruction::MOD: - require(2); m_stack[m_stack.size() - 2] = m_stack[m_stack.size() - 2] ? m_stack.back() % m_stack[m_stack.size() - 2] : 0; m_stack.pop_back(); break; case Instruction::SMOD: - require(2); m_stack[m_stack.size() - 2] = m_stack[m_stack.size() - 2] ? s2u(u2s(m_stack.back()) % u2s(m_stack[m_stack.size() - 2])) : 0; m_stack.pop_back(); break; case Instruction::EXP: { - require(2); auto base = m_stack.back(); auto expon = m_stack[m_stack.size() - 2]; m_stack.pop_back(); @@ -369,73 +369,59 @@ template dev::bytesConstRef dev::eth::VM::go(Ext& _ext, OnOpFunc con break; } case Instruction::NEG: - require(1); m_stack.back() = ~(m_stack.back() - 1); break; case Instruction::LT: - require(2); m_stack[m_stack.size() - 2] = m_stack.back() < m_stack[m_stack.size() - 2] ? 1 : 0; m_stack.pop_back(); break; case Instruction::GT: - require(2); m_stack[m_stack.size() - 2] = m_stack.back() > m_stack[m_stack.size() - 2] ? 1 : 0; m_stack.pop_back(); break; case Instruction::SLT: - require(2); m_stack[m_stack.size() - 2] = u2s(m_stack.back()) < u2s(m_stack[m_stack.size() - 2]) ? 1 : 0; m_stack.pop_back(); break; case Instruction::SGT: - require(2); m_stack[m_stack.size() - 2] = u2s(m_stack.back()) > u2s(m_stack[m_stack.size() - 2]) ? 1 : 0; m_stack.pop_back(); break; case Instruction::EQ: - require(2); m_stack[m_stack.size() - 2] = m_stack.back() == m_stack[m_stack.size() - 2] ? 1 : 0; m_stack.pop_back(); break; case Instruction::NOT: - require(1); m_stack.back() = m_stack.back() ? 0 : 1; break; case Instruction::AND: - require(2); m_stack[m_stack.size() - 2] = m_stack.back() & m_stack[m_stack.size() - 2]; m_stack.pop_back(); break; case Instruction::OR: - require(2); m_stack[m_stack.size() - 2] = m_stack.back() | m_stack[m_stack.size() - 2]; m_stack.pop_back(); break; case Instruction::XOR: - require(2); m_stack[m_stack.size() - 2] = m_stack.back() ^ m_stack[m_stack.size() - 2]; m_stack.pop_back(); break; case Instruction::BYTE: - require(2); m_stack[m_stack.size() - 2] = m_stack.back() < 32 ? (m_stack[m_stack.size() - 2] >> (unsigned)(8 * (31 - m_stack.back()))) & 0xff : 0; m_stack.pop_back(); break; case Instruction::ADDMOD: - require(3); m_stack[m_stack.size() - 3] = u256((bigint(m_stack.back()) + bigint(m_stack[m_stack.size() - 2])) % m_stack[m_stack.size() - 3]); m_stack.pop_back(); m_stack.pop_back(); break; case Instruction::MULMOD: - require(3); m_stack[m_stack.size() - 3] = u256((bigint(m_stack.back()) * bigint(m_stack[m_stack.size() - 2])) % m_stack[m_stack.size() - 3]); m_stack.pop_back(); m_stack.pop_back(); break; case Instruction::SHA3: { - require(2); unsigned inOff = (unsigned)m_stack.back(); m_stack.pop_back(); unsigned inSize = (unsigned)m_stack.back(); @@ -451,7 +437,6 @@ template dev::bytesConstRef dev::eth::VM::go(Ext& _ext, OnOpFunc con break; case Instruction::BALANCE: { - require(1); m_stack.back() = _ext.balance(asAddress(m_stack.back())); break; } @@ -463,7 +448,6 @@ template dev::bytesConstRef dev::eth::VM::go(Ext& _ext, OnOpFunc con break; case Instruction::CALLDATALOAD: { - require(1); if ((unsigned)m_stack.back() + 31 < _ext.data.size()) m_stack.back() = (u256)*(h256 const*)(_ext.data.data() + (unsigned)m_stack.back()); else @@ -480,7 +464,6 @@ template dev::bytesConstRef dev::eth::VM::go(Ext& _ext, OnOpFunc con break; case Instruction::CALLDATACOPY: { - require(3); unsigned mf = (unsigned)m_stack.back(); m_stack.pop_back(); unsigned cf = (unsigned)m_stack.back(); @@ -497,7 +480,6 @@ template dev::bytesConstRef dev::eth::VM::go(Ext& _ext, OnOpFunc con break; case Instruction::CODECOPY: { - require(3); unsigned mf = (unsigned)m_stack.back(); m_stack.pop_back(); unsigned cf = (unsigned)m_stack.back(); @@ -510,12 +492,10 @@ template dev::bytesConstRef dev::eth::VM::go(Ext& _ext, OnOpFunc con break; } case Instruction::EXTCODESIZE: - require(1); m_stack.back() = _ext.codeAt(asAddress(m_stack.back())).size(); break; case Instruction::EXTCODECOPY: { - require(4); Address a = asAddress(m_stack.back()); m_stack.pop_back(); unsigned mf = (unsigned)m_stack.back(); @@ -591,7 +571,6 @@ template dev::bytesConstRef dev::eth::VM::go(Ext& _ext, OnOpFunc con break; } case Instruction::POP: - require(1); m_stack.pop_back(); break; case Instruction::DUP1: @@ -612,7 +591,6 @@ template dev::bytesConstRef dev::eth::VM::go(Ext& _ext, OnOpFunc con case Instruction::DUP16: { auto n = 1 + (int)inst - (int)Instruction::DUP1; - require(n); m_stack.push_back(m_stack[m_stack.size() - n]); break; } @@ -634,7 +612,6 @@ template dev::bytesConstRef dev::eth::VM::go(Ext& _ext, OnOpFunc con case Instruction::SWAP16: { unsigned n = (int)inst - (int)Instruction::SWAP1 + 2; - require(n); auto d = m_stack.back(); m_stack.back() = m_stack[m_stack.size() - n]; m_stack[m_stack.size() - n] = d; @@ -642,13 +619,11 @@ template dev::bytesConstRef dev::eth::VM::go(Ext& _ext, OnOpFunc con } case Instruction::MLOAD: { - require(1); m_stack.back() = (u256)*(h256 const*)(m_temp.data() + (unsigned)m_stack.back()); break; } case Instruction::MSTORE: { - require(2); *(h256*)&m_temp[(unsigned)m_stack.back()] = (h256)m_stack[m_stack.size() - 2]; m_stack.pop_back(); m_stack.pop_back(); @@ -656,31 +631,26 @@ template dev::bytesConstRef dev::eth::VM::go(Ext& _ext, OnOpFunc con } case Instruction::MSTORE8: { - require(2); m_temp[(unsigned)m_stack.back()] = (byte)(m_stack[m_stack.size() - 2] & 0xff); m_stack.pop_back(); m_stack.pop_back(); break; } case Instruction::SLOAD: - require(1); m_stack.back() = _ext.store(m_stack.back()); break; case Instruction::SSTORE: - require(2); _ext.setStore(m_stack.back(), m_stack[m_stack.size() - 2]); m_stack.pop_back(); m_stack.pop_back(); break; case Instruction::JUMP: - require(1); nextPC = m_stack.back(); if (nextPC && (Instruction)_ext.getCode(nextPC - 1) != Instruction::JUMPDEST) BOOST_THROW_EXCEPTION(BadJumpDestination()); m_stack.pop_back(); break; case Instruction::JUMPI: - require(2); if (m_stack[m_stack.size() - 2]) { nextPC = m_stack.back(); @@ -703,8 +673,6 @@ template dev::bytesConstRef dev::eth::VM::go(Ext& _ext, OnOpFunc con break; case Instruction::CREATE: { - require(3); - u256 endowment = m_stack.back(); m_stack.pop_back(); unsigned initOff = (unsigned)m_stack.back(); @@ -726,8 +694,6 @@ template dev::bytesConstRef dev::eth::VM::go(Ext& _ext, OnOpFunc con case Instruction::CALL: case Instruction::CALLCODE: { - require(7); - u256 gas = m_stack.back(); m_stack.pop_back(); Address receiveAddress = asAddress(m_stack.back()); @@ -759,8 +725,6 @@ template dev::bytesConstRef dev::eth::VM::go(Ext& _ext, OnOpFunc con } case Instruction::RETURN: { - require(2); - unsigned b = (unsigned)m_stack.back(); m_stack.pop_back(); unsigned s = (unsigned)m_stack.back(); @@ -770,7 +734,6 @@ template dev::bytesConstRef dev::eth::VM::go(Ext& _ext, OnOpFunc con } case Instruction::SUICIDE: { - require(1); Address dest = asAddress(m_stack.back()); _ext.suicide(dest); // ...follow through to... diff --git a/libevmface/Instruction.cpp b/libevmface/Instruction.cpp index 5538805a2..7b253f388 100644 --- a/libevmface/Instruction.cpp +++ b/libevmface/Instruction.cpp @@ -321,5 +321,5 @@ InstructionInfo dev::eth::instructionInfo(Instruction _inst) bool dev::eth::isValidInstruction(Instruction _inst) { - return c_instructionInfo.count(_inst); + return !!c_instructionInfo.count(_inst); } diff --git a/test/vm.cpp b/test/vm.cpp index 36837eea4..2e4571be5 100644 --- a/test/vm.cpp +++ b/test/vm.cpp @@ -24,7 +24,7 @@ #include #include -#define FILL_TESTS +//#define FILL_TESTS using namespace std; using namespace json_spirit; @@ -751,4 +751,3 @@ BOOST_AUTO_TEST_CASE(vmSystemOperationsTest) { dev::test::executeTests("vmSystemOperationsTest"); } -