From e191e7f4367997d9d92f445a5e95032a0c1f27cb Mon Sep 17 00:00:00 2001 From: Christoph Jentzsch Date: Thu, 23 Oct 2014 10:26:53 +0200 Subject: [PATCH 1/5] eliminiate warning --- libevmface/Instruction.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libevmface/Instruction.cpp b/libevmface/Instruction.cpp index 5538805a2..e5255a44d 100644 --- a/libevmface/Instruction.cpp +++ b/libevmface/Instruction.cpp @@ -321,5 +321,8 @@ InstructionInfo dev::eth::instructionInfo(Instruction _inst) bool dev::eth::isValidInstruction(Instruction _inst) { - return c_instructionInfo.count(_inst); + if (c_instructionInfo.count(_inst)) + return true; + else + return false; } From d07901d32c60a075085d74d11909ae38fd662c4e Mon Sep 17 00:00:00 2001 From: Christoph Jentzsch Date: Thu, 23 Oct 2014 11:25:34 +0200 Subject: [PATCH 2/5] Changing gas cost to zero at stackunderflow --- libevm/VM.h | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++++ test/vm.cpp | 3 +-- 2 files changed, 63 insertions(+), 2 deletions(-) diff --git a/libevm/VM.h b/libevm/VM.h index 2eb34ed04..f4603b63f 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,6 +165,7 @@ template dev::bytesConstRef dev::eth::VM::go(Ext& _ext, OnOpFunc con break; case Instruction::BALANCE: + require(1); runGas = c_balanceGas; break; @@ -189,34 +192,82 @@ template dev::bytesConstRef dev::eth::VM::go(Ext& _ext, OnOpFunc con } case Instruction::ADD: + require(2); + break; case Instruction::MUL: + require(2); + break; case Instruction::SUB: + require(2); + break; case Instruction::DIV: + require(2); + break; case Instruction::SDIV: + require(2); + break; case Instruction::MOD: + require(2); + break; case Instruction::SMOD: + require(2); + break; case Instruction::EXP: + require(2); + break; case Instruction::NEG: + require(1); + break; case Instruction::LT: + require(2); + break; case Instruction::GT: + require(2); + break; case Instruction::SLT: + require(2); + break; case Instruction::SGT: + require(2); + break; case Instruction::EQ: + require(2); + break; case Instruction::NOT: + require(1); + break; case Instruction::AND: + require(2); + break; case Instruction::OR: + require(2); + break; case Instruction::XOR: + require(2); + break; case Instruction::BYTE: + require(2); + break; case Instruction::ADDMOD: + require(3); + break; case Instruction::MULMOD: + require(3); + break; case Instruction::ADDRESS: case Instruction::ORIGIN: case Instruction::CALLER: case Instruction::CALLVALUE: + break; case Instruction::CALLDATALOAD: + require(1); + break; case Instruction::CALLDATASIZE: case Instruction::CODESIZE: + break; case Instruction::EXTCODESIZE: + require(1); + break; case Instruction::GASPRICE: case Instruction::PREVHASH: case Instruction::COINBASE: @@ -256,7 +307,10 @@ template dev::bytesConstRef dev::eth::VM::go(Ext& _ext, OnOpFunc con case Instruction::PUSH30: case Instruction::PUSH31: case Instruction::PUSH32: + break; case Instruction::POP: + require(1); + break; case Instruction::DUP1: case Instruction::DUP2: case Instruction::DUP3: @@ -273,6 +327,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,8 +345,14 @@ template dev::bytesConstRef dev::eth::VM::go(Ext& _ext, OnOpFunc con case Instruction::SWAP14: case Instruction::SWAP15: case Instruction::SWAP16: + require((int)inst - (int)Instruction::SWAP1 + 2); + break; case Instruction::JUMP: + require(1); + break; case Instruction::JUMPI: + require(2); + break; case Instruction::PC: case Instruction::MSIZE: case Instruction::GAS: 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"); } - From 0f353285df31372f40d7627d2fef1a4ea83be854 Mon Sep 17 00:00:00 2001 From: Christoph Jentzsch Date: Thu, 23 Oct 2014 12:21:27 +0200 Subject: [PATCH 3/5] group patterns in VM.h --- libevm/VM.h | 115 +++++++++++++++------------------------------------- 1 file changed, 33 insertions(+), 82 deletions(-) diff --git a/libevm/VM.h b/libevm/VM.h index f4603b63f..c67011f24 100644 --- a/libevm/VM.h +++ b/libevm/VM.h @@ -191,83 +191,16 @@ template dev::bytesConstRef dev::eth::VM::go(Ext& _ext, OnOpFunc con break; } - case Instruction::ADD: - require(2); - break; - case Instruction::MUL: - require(2); - break; - case Instruction::SUB: - require(2); - break; - case Instruction::DIV: - require(2); - break; - case Instruction::SDIV: - require(2); - break; - case Instruction::MOD: - require(2); - break; - case Instruction::SMOD: - require(2); - break; - case Instruction::EXP: - require(2); - break; - case Instruction::NEG: - require(1); - break; - case Instruction::LT: - require(2); - break; - case Instruction::GT: - require(2); - break; - case Instruction::SLT: - require(2); - break; - case Instruction::SGT: - require(2); - break; - case Instruction::EQ: - require(2); - break; - case Instruction::NOT: - require(1); - break; - case Instruction::AND: - require(2); - break; - case Instruction::OR: - require(2); - break; - case Instruction::XOR: - require(2); - break; - case Instruction::BYTE: - require(2); - break; - case Instruction::ADDMOD: - require(3); - break; - case Instruction::MULMOD: - require(3); - break; + case Instruction::PC: + case Instruction::MSIZE: + case Instruction::GAS: + case Instruction::JUMPDEST: case Instruction::ADDRESS: case Instruction::ORIGIN: case Instruction::CALLER: case Instruction::CALLVALUE: - break; - case Instruction::CALLDATALOAD: - require(1); - break; case Instruction::CALLDATASIZE: case Instruction::CODESIZE: - break; - case Instruction::EXTCODESIZE: - require(1); - break; case Instruction::GASPRICE: case Instruction::PREVHASH: case Instruction::COINBASE: @@ -308,9 +241,38 @@ template dev::bytesConstRef dev::eth::VM::go(Ext& _ext, OnOpFunc con 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: @@ -347,17 +309,6 @@ template dev::bytesConstRef dev::eth::VM::go(Ext& _ext, OnOpFunc con case Instruction::SWAP16: require((int)inst - (int)Instruction::SWAP1 + 2); break; - case Instruction::JUMP: - require(1); - break; - case Instruction::JUMPI: - require(2); - break; - case Instruction::PC: - case Instruction::MSIZE: - case Instruction::GAS: - case Instruction::JUMPDEST: - break; default: BOOST_THROW_EXCEPTION(BadInstruction()); } From c61131a0c3e35073aeeb3327195ca5e062df6579 Mon Sep 17 00:00:00 2001 From: Christoph Jentzsch Date: Thu, 23 Oct 2014 13:02:30 +0200 Subject: [PATCH 4/5] Avoid double calling of require() --- libevm/VM.h | 50 -------------------------------------------------- 1 file changed, 50 deletions(-) diff --git a/libevm/VM.h b/libevm/VM.h index c67011f24..ce8001bbf 100644 --- a/libevm/VM.h +++ b/libevm/VM.h @@ -170,11 +170,6 @@ template dev::bytesConstRef dev::eth::VM::go(Ext& _ext, OnOpFunc con 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]; @@ -337,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(); @@ -382,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(); @@ -464,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; } @@ -476,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 @@ -493,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(); @@ -510,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(); @@ -523,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(); @@ -604,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: @@ -625,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; } @@ -647,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; @@ -655,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(); @@ -669,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(); @@ -716,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(); @@ -739,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()); @@ -772,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(); @@ -783,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... From 027c386e052a77dac4c8d1ba38738929641f754f Mon Sep 17 00:00:00 2001 From: Christoph Jentzsch Date: Thu, 23 Oct 2014 16:14:24 +0200 Subject: [PATCH 5/5] Shortcut for boolean conversion --- libevmface/Instruction.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/libevmface/Instruction.cpp b/libevmface/Instruction.cpp index e5255a44d..7b253f388 100644 --- a/libevmface/Instruction.cpp +++ b/libevmface/Instruction.cpp @@ -321,8 +321,5 @@ InstructionInfo dev::eth::instructionInfo(Instruction _inst) bool dev::eth::isValidInstruction(Instruction _inst) { - if (c_instructionInfo.count(_inst)) - return true; - else - return false; + return !!c_instructionInfo.count(_inst); }