Browse Source

Merge branch 'develop-evmcc' into pr-jit

cl-refactor
Paweł Bylica 10 years ago
parent
commit
4ac6ebb790
  1. 3
      alethzero/CMakeLists.txt
  2. 7
      alethzero/MainWin.cpp
  3. 12
      eth/main.cpp
  4. 2
      libdevcore/Common.cpp
  5. 18
      libethcore/BlockInfo.cpp
  6. 4
      libethcore/BlockInfo.h
  7. 4
      libethcore/CommonEth.cpp
  8. 21
      libethereum/BlockChain.cpp
  9. 12
      libethereum/BlockChain.h
  10. 22
      libethereum/BlockDetails.h
  11. 3
      libethereum/CMakeLists.txt
  12. 18
      libethereum/Executive.cpp
  13. 2
      libethereum/Interface.h
  14. 7
      libethereum/State.cpp
  15. 8
      libethereum/State.h
  16. 28
      libethereum/VMFactory.cpp
  17. 28
      libethereum/VMFactory.h
  18. 6
      libevm/FeeStructure.cpp
  19. 6
      libevm/FeeStructure.h
  20. 17
      libevm/VM.h
  21. 12
      libevm/VMFace.cpp
  22. 6
      libevm/VMFace.h
  23. 3
      libevmjit/Compiler.cpp
  24. 8
      libevmjit/Ext.cpp
  25. 18
      libevmjit/GasMeter.cpp
  26. 3
      libevmjit/GasMeter.h
  27. 1
      libevmjit/VM.cpp
  28. 8
      libevmjit/VM.h
  29. 2
      libsolidity/ExpressionCompiler.cpp
  30. 2
      libsolidity/GlobalContext.cpp
  31. 2
      libsolidity/Types.cpp
  32. 1
      libweb3jsonrpc/WebThreeStubServer.cpp
  33. 6
      libwhisper/WhisperHost.cpp
  34. 9
      libwhisper/WhisperHost.h
  35. 14
      libwhisper/WhisperPeer.cpp
  36. 2
      libwhisper/WhisperPeer.h
  37. 18
      neth/main.cpp
  38. 3
      test/createRandomTest.cpp
  39. 10
      test/vm.cpp

3
alethzero/CMakeLists.txt

@ -54,6 +54,9 @@ endif ()
qt5_use_modules(${EXECUTEABLE} Core)# Gui Widgets Network WebKit WebKitWidgets) qt5_use_modules(${EXECUTEABLE} Core)# Gui Widgets Network WebKit WebKitWidgets)
target_link_libraries(${EXECUTEABLE} webthree qethereum ethereum evm ethcore devcrypto secp256k1 gmp ${CRYPTOPP_LS} serpent lll solidity evmcore devcore web3jsonrpc jsqrc) target_link_libraries(${EXECUTEABLE} webthree qethereum ethereum evm ethcore devcrypto secp256k1 gmp ${CRYPTOPP_LS} serpent lll solidity evmcore devcore web3jsonrpc jsqrc)
if (EVMJIT)
target_link_libraries(${EXECUTEABLE} evmjit)
endif()
if (APPLE) if (APPLE)
# First have qt5 install plugins and frameworks # First have qt5 install plugins and frameworks

7
alethzero/MainWin.cpp

@ -1259,7 +1259,6 @@ void Main::on_blocks_currentItemChanged()
s << "<br/>D/TD: <b>2^" << log2((double)info.difficulty) << "</b>/<b>2^" << log2((double)details.totalDifficulty) << "</b>"; s << "<br/>D/TD: <b>2^" << log2((double)info.difficulty) << "</b>/<b>2^" << log2((double)details.totalDifficulty) << "</b>";
s << "&nbsp;&emsp;&nbsp;Children: <b>" << details.children.size() << "</b></h5>"; s << "&nbsp;&emsp;&nbsp;Children: <b>" << details.children.size() << "</b></h5>";
s << "<br/>Gas used/limit: <b>" << info.gasUsed << "</b>/<b>" << info.gasLimit << "</b>"; s << "<br/>Gas used/limit: <b>" << info.gasUsed << "</b>/<b>" << info.gasLimit << "</b>";
s << "&nbsp;&emsp;&nbsp;Minimum gas price: <b>" << formatBalance(info.minGasPrice) << "</b>";
s << "<br/>Coinbase: <b>" << pretty(info.coinbaseAddress).toHtmlEscaped().toStdString() << "</b> " << info.coinbaseAddress; s << "<br/>Coinbase: <b>" << pretty(info.coinbaseAddress).toHtmlEscaped().toStdString() << "</b> " << info.coinbaseAddress;
s << "<br/>Nonce: <b>" << info.nonce << "</b>"; s << "<br/>Nonce: <b>" << info.nonce << "</b>";
s << "<br/>Parent: <b>" << info.parentHash << "</b>"; s << "<br/>Parent: <b>" << info.parentHash << "</b>";
@ -1665,7 +1664,7 @@ void Main::on_data_textChanged()
errs.append("<div style=\"border-left: 6px solid #c00; margin-top: 2px\">" + QString::fromStdString(i).toHtmlEscaped() + "</div>"); errs.append("<div style=\"border-left: 6px solid #c00; margin-top: 2px\">" + QString::fromStdString(i).toHtmlEscaped() + "</div>");
} }
ui->code->setHtml(errs + lll + solidity + "<h4>Code</h4>" + QString::fromStdString(disassemble(m_data)).toHtmlEscaped()); ui->code->setHtml(errs + lll + solidity + "<h4>Code</h4>" + QString::fromStdString(disassemble(m_data)).toHtmlEscaped());
ui->gas->setMinimum((qint64)Client::txGas(m_data.size(), 0)); ui->gas->setMinimum((qint64)Client::txGas(m_data, 0));
if (!ui->gas->isEnabled()) if (!ui->gas->isEnabled())
ui->gas->setValue(m_backupGas); ui->gas->setValue(m_backupGas);
ui->gas->setEnabled(true); ui->gas->setEnabled(true);
@ -1676,7 +1675,7 @@ void Main::on_data_textChanged()
ui->code->setHtml(QString::fromStdString(dev::memDump(m_data, 8, true))); ui->code->setHtml(QString::fromStdString(dev::memDump(m_data, 8, true)));
if (ethereum()->codeAt(fromString(ui->destination->currentText()), 0).size()) if (ethereum()->codeAt(fromString(ui->destination->currentText()), 0).size())
{ {
ui->gas->setMinimum((qint64)Client::txGas(m_data.size(), 1)); ui->gas->setMinimum((qint64)Client::txGas(m_data, 1));
if (!ui->gas->isEnabled()) if (!ui->gas->isEnabled())
ui->gas->setValue(m_backupGas); ui->gas->setValue(m_backupGas);
ui->gas->setEnabled(true); ui->gas->setEnabled(true);
@ -1685,7 +1684,7 @@ void Main::on_data_textChanged()
{ {
if (ui->gas->isEnabled()) if (ui->gas->isEnabled())
m_backupGas = ui->gas->value(); m_backupGas = ui->gas->value();
ui->gas->setValue((qint64)Client::txGas(m_data.size())); ui->gas->setValue((qint64)Client::txGas(m_data));
ui->gas->setEnabled(false); ui->gas->setEnabled(false);
} }
} }

12
eth/main.cpp

@ -492,14 +492,12 @@ int main(int argc, char** argv)
cnote << ssbd.str(); cnote << ssbd.str();
int ssize = sechex.length(); int ssize = sechex.length();
int size = hexAddr.length(); int size = hexAddr.length();
u256 minGas = (u256)Client::txGas(data.size(), 0); u256 minGas = (u256)Client::txGas(data, 0);
if (size < 40) if (size < 40)
{ {
if (size > 0) if (size > 0)
cwarn << "Invalid address length:" << size; cwarn << "Invalid address length:" << size;
} }
else if (gasPrice < info.minGasPrice)
cwarn << "Minimum gas price is" << info.minGasPrice;
else if (gas < minGas) else if (gas < minGas)
cwarn << "Minimum gas amount is" << minGas; cwarn << "Minimum gas amount is" << minGas;
else if (ssize < 40) else if (ssize < 40)
@ -559,9 +557,9 @@ int main(int argc, char** argv)
auto h = bc.currentHash(); auto h = bc.currentHash();
auto blockData = bc.block(h); auto blockData = bc.block(h);
BlockInfo info(blockData); BlockInfo info(blockData);
u256 minGas = (u256)Client::txGas(0, 0); u256 minGas = (u256)Client::txGas(bytes(), 0);
Address dest = h160(fromHex(hexAddr)); Address dest = h160(fromHex(hexAddr));
c->transact(us.secret(), amount, dest, bytes(), minGas, info.minGasPrice); c->transact(us.secret(), amount, dest, bytes(), minGas);
} }
} }
else else
@ -598,11 +596,9 @@ int main(int argc, char** argv)
cnote << "Init:"; cnote << "Init:";
cnote << ssc.str(); cnote << ssc.str();
} }
u256 minGas = (u256)Client::txGas(init.size(), 0); u256 minGas = (u256)Client::txGas(init, 0);
if (endowment < 0) if (endowment < 0)
cwarn << "Invalid endowment"; cwarn << "Invalid endowment";
else if (gasPrice < info.minGasPrice)
cwarn << "Minimum gas price is" << info.minGasPrice;
else if (gas < minGas) else if (gas < minGas)
cwarn << "Minimum gas amount is" << minGas; cwarn << "Minimum gas amount is" << minGas;
else else

2
libdevcore/Common.cpp

@ -27,7 +27,7 @@ using namespace dev;
namespace dev namespace dev
{ {
char const* Version = "0.7.10"; char const* Version = "0.7.11";
} }

18
libethcore/BlockInfo.cpp

@ -58,9 +58,9 @@ h256 BlockInfo::headerHashWithoutNonce() const
void BlockInfo::streamRLP(RLPStream& _s, bool _nonce) const void BlockInfo::streamRLP(RLPStream& _s, bool _nonce) const
{ {
_s.appendList(_nonce ? 15 : 14) _s.appendList(_nonce ? 14 : 13)
<< parentHash << sha3Uncles << coinbaseAddress << stateRoot << transactionsRoot << receiptsRoot << logBloom << parentHash << sha3Uncles << coinbaseAddress << stateRoot << transactionsRoot << receiptsRoot << logBloom
<< difficulty << number << minGasPrice << gasLimit << gasUsed << timestamp << extraData; << difficulty << number << gasLimit << gasUsed << timestamp << extraData;
if (_nonce) if (_nonce)
_s << nonce; _s << nonce;
} }
@ -86,12 +86,11 @@ void BlockInfo::populateFromHeader(RLP const& _header, bool _checkNonce)
logBloom = _header[field = 6].toHash<h512>(); logBloom = _header[field = 6].toHash<h512>();
difficulty = _header[field = 7].toInt<u256>(); difficulty = _header[field = 7].toInt<u256>();
number = _header[field = 8].toInt<u256>(); number = _header[field = 8].toInt<u256>();
minGasPrice = _header[field = 9].toInt<u256>(); gasLimit = _header[field = 9].toInt<u256>();
gasLimit = _header[field = 10].toInt<u256>(); gasUsed = _header[field = 10].toInt<u256>();
gasUsed = _header[field = 11].toInt<u256>(); timestamp = _header[field = 11].toInt<u256>();
timestamp = _header[field = 12].toInt<u256>(); extraData = _header[field = 12].toBytes();
extraData = _header[field = 13].toBytes(); nonce = _header[field = 13].toHash<h256>();
nonce = _header[field = 14].toHash<h256>();
} }
catch (Exception const& _e) catch (Exception const& _e)
@ -147,9 +146,6 @@ void BlockInfo::verifyInternals(bytesConstRef _block) const
if (transactionsRoot != t.root()) if (transactionsRoot != t.root())
BOOST_THROW_EXCEPTION(InvalidTransactionsHash(t.root(), transactionsRoot)); BOOST_THROW_EXCEPTION(InvalidTransactionsHash(t.root(), transactionsRoot));
if (minGasPrice > mgp)
BOOST_THROW_EXCEPTION(InvalidMinGasPrice(minGasPrice, mgp));
if (sha3Uncles != sha3(root[2].data())) if (sha3Uncles != sha3(root[2].data()))
BOOST_THROW_EXCEPTION(InvalidUnclesHash()); BOOST_THROW_EXCEPTION(InvalidUnclesHash());
} }

4
libethcore/BlockInfo.h

@ -66,7 +66,6 @@ public:
h512 logBloom; // TODO LogBloom - get include h512 logBloom; // TODO LogBloom - get include
u256 difficulty; u256 difficulty;
u256 number; u256 number;
u256 minGasPrice;
u256 gasLimit; u256 gasLimit;
u256 gasUsed; u256 gasUsed;
u256 timestamp; u256 timestamp;
@ -95,7 +94,6 @@ public:
logBloom == _cmp.logBloom && logBloom == _cmp.logBloom &&
difficulty == _cmp.difficulty && difficulty == _cmp.difficulty &&
number == _cmp.number && number == _cmp.number &&
minGasPrice == _cmp.minGasPrice &&
gasLimit == _cmp.gasLimit && gasLimit == _cmp.gasLimit &&
gasUsed == _cmp.gasUsed && gasUsed == _cmp.gasUsed &&
timestamp == _cmp.timestamp && timestamp == _cmp.timestamp &&
@ -122,7 +120,7 @@ public:
inline std::ostream& operator<<(std::ostream& _out, BlockInfo const& _bi) inline std::ostream& operator<<(std::ostream& _out, BlockInfo const& _bi)
{ {
_out << _bi.hash << " " << _bi.parentHash << " " << _bi.sha3Uncles << " " << _bi.coinbaseAddress << " " << _bi.stateRoot << " " << _bi.transactionsRoot << " " << _out << _bi.hash << " " << _bi.parentHash << " " << _bi.sha3Uncles << " " << _bi.coinbaseAddress << " " << _bi.stateRoot << " " << _bi.transactionsRoot << " " <<
_bi.receiptsRoot << " " << _bi.logBloom << " " << _bi.difficulty << " " << _bi.number << " " << _bi.minGasPrice << " " << _bi.gasLimit << " " << _bi.receiptsRoot << " " << _bi.logBloom << " " << _bi.difficulty << " " << _bi.number << " " << _bi.gasLimit << " " <<
_bi.gasUsed << " " << _bi.timestamp << " " << _bi.nonce; _bi.gasUsed << " " << _bi.timestamp << " " << _bi.nonce;
return _out; return _out;
} }

4
libethcore/CommonEth.cpp

@ -33,8 +33,8 @@ namespace dev
namespace eth namespace eth
{ {
const unsigned c_protocolVersion = 44; const unsigned c_protocolVersion = 45;
const unsigned c_databaseVersion = 4; const unsigned c_databaseVersion = 5;
static const vector<pair<u256, string>> g_units = static const vector<pair<u256, string>> g_units =
{ {

21
libethereum/BlockChain.cpp

@ -101,9 +101,8 @@ bytes BlockChain::createGenesisBlock()
stateRoot = state.root(); stateRoot = state.root();
} }
block.appendList(15) block.appendList(14)
// TODO: maybe make logbloom correct? << h256() << EmptyListSHA3 << h160() << stateRoot << EmptyTrie << EmptyTrie << LogBloom() << c_genesisDifficulty << 0 << 1000000 << 0 << (unsigned)0 << string() << sha3(bytes(1, 42));
<< h256() << EmptyListSHA3 << h160() << stateRoot << EmptyTrie << EmptyTrie << LogBloom() << c_genesisDifficulty << 0 << 0 << 1000000 << 0 << (unsigned)0 << string() << sha3(bytes(1, 42));
block.appendRaw(RLPEmptyList); block.appendRaw(RLPEmptyList);
block.appendRaw(RLPEmptyList); block.appendRaw(RLPEmptyList);
return block.out(); return block.out();
@ -169,8 +168,6 @@ void BlockChain::close()
delete m_db; delete m_db;
m_lastBlockHash = m_genesisHash; m_lastBlockHash = m_genesisHash;
m_details.clear(); m_details.clear();
m_blooms.clear();
m_traces.clear();
m_cache.clear(); m_cache.clear();
} }
@ -307,14 +304,10 @@ h256s BlockChain::import(bytes const& _block, OverlayDB const& _db)
State s(bi.coinbaseAddress, _db); State s(bi.coinbaseAddress, _db);
auto tdIncrease = s.enactOn(&_block, bi, *this); auto tdIncrease = s.enactOn(&_block, bi, *this);
auto b = s.oldBloom(); auto b = s.oldBloom();
BlockBlooms bb;
BlockTraces bt;
BlockLogBlooms blb; BlockLogBlooms blb;
BlockReceipts br; BlockReceipts br;
for (unsigned i = 0; i < s.pending().size(); ++i) for (unsigned i = 0; i < s.pending().size(); ++i)
{ {
bb.blooms.push_back(s.changesFromPending(i).bloom());
bt.traces.push_back(s.changesFromPending(i));
blb.blooms.push_back(s.receipt(i).bloom()); blb.blooms.push_back(s.receipt(i).bloom());
br.receipts.push_back(s.receipt(i)); br.receipts.push_back(s.receipt(i));
} }
@ -330,14 +323,6 @@ h256s BlockChain::import(bytes const& _block, OverlayDB const& _db)
m_details[newHash] = BlockDetails((unsigned)pd.number + 1, td, bi.parentHash, {}, b); m_details[newHash] = BlockDetails((unsigned)pd.number + 1, td, bi.parentHash, {}, b);
m_details[bi.parentHash].children.push_back(newHash); m_details[bi.parentHash].children.push_back(newHash);
} }
{
WriteGuard l(x_blooms);
m_blooms[newHash] = bb;
}
{
WriteGuard l(x_traces);
m_traces[newHash] = bt;
}
{ {
WriteGuard l(x_logBlooms); WriteGuard l(x_logBlooms);
m_logBlooms[newHash] = blb; m_logBlooms[newHash] = blb;
@ -349,8 +334,6 @@ h256s BlockChain::import(bytes const& _block, OverlayDB const& _db)
m_extrasDB->Put(m_writeOptions, toSlice(newHash), (ldb::Slice)dev::ref(m_details[newHash].rlp())); m_extrasDB->Put(m_writeOptions, toSlice(newHash), (ldb::Slice)dev::ref(m_details[newHash].rlp()));
m_extrasDB->Put(m_writeOptions, toSlice(bi.parentHash), (ldb::Slice)dev::ref(m_details[bi.parentHash].rlp())); m_extrasDB->Put(m_writeOptions, toSlice(bi.parentHash), (ldb::Slice)dev::ref(m_details[bi.parentHash].rlp()));
m_extrasDB->Put(m_writeOptions, toSlice(newHash, 1), (ldb::Slice)dev::ref(m_blooms[newHash].rlp()));
m_extrasDB->Put(m_writeOptions, toSlice(newHash, 2), (ldb::Slice)dev::ref(m_traces[newHash].rlp()));
m_extrasDB->Put(m_writeOptions, toSlice(newHash, 3), (ldb::Slice)dev::ref(m_logBlooms[newHash].rlp())); m_extrasDB->Put(m_writeOptions, toSlice(newHash, 3), (ldb::Slice)dev::ref(m_logBlooms[newHash].rlp()));
m_extrasDB->Put(m_writeOptions, toSlice(newHash, 4), (ldb::Slice)dev::ref(m_receipts[newHash].rlp())); m_extrasDB->Put(m_writeOptions, toSlice(newHash, 4), (ldb::Slice)dev::ref(m_receipts[newHash].rlp()));
m_db->Put(m_writeOptions, toSlice(newHash), (ldb::Slice)ref(_block)); m_db->Put(m_writeOptions, toSlice(newHash), (ldb::Slice)ref(_block));

12
libethereum/BlockChain.h

@ -101,14 +101,6 @@ public:
BlockDetails details(h256 _hash) const { return queryExtras<BlockDetails, 0>(_hash, m_details, x_details, NullBlockDetails); } BlockDetails details(h256 _hash) const { return queryExtras<BlockDetails, 0>(_hash, m_details, x_details, NullBlockDetails); }
BlockDetails details() const { return details(currentHash()); } BlockDetails details() const { return details(currentHash()); }
/// Get the transactions' bloom filters of a block (or the most recent mined if none given). Thread-safe.
BlockBlooms blooms(h256 _hash) const { return queryExtras<BlockBlooms, 1>(_hash, m_blooms, x_blooms, NullBlockBlooms); }
BlockBlooms blooms() const { return blooms(currentHash()); }
/// Get the transactions' trace manifests of a block (or the most recent mined if none given). Thread-safe.
BlockTraces traces(h256 _hash) const { return queryExtras<BlockTraces, 2>(_hash, m_traces, x_traces, NullBlockTraces); }
BlockTraces traces() const { return traces(currentHash()); }
/// Get the transactions' log blooms of a block (or the most recent mined if none given). Thread-safe. /// Get the transactions' log blooms of a block (or the most recent mined if none given). Thread-safe.
BlockLogBlooms logBlooms(h256 _hash) const { return queryExtras<BlockLogBlooms, 3>(_hash, m_logBlooms, x_logBlooms, NullBlockLogBlooms); } BlockLogBlooms logBlooms(h256 _hash) const { return queryExtras<BlockLogBlooms, 3>(_hash, m_logBlooms, x_logBlooms, NullBlockLogBlooms); }
BlockLogBlooms logBlooms() const { return logBlooms(currentHash()); } BlockLogBlooms logBlooms() const { return logBlooms(currentHash()); }
@ -193,10 +185,6 @@ private:
/// The caches of the disk DB and their locks. /// The caches of the disk DB and their locks.
mutable boost::shared_mutex x_details; mutable boost::shared_mutex x_details;
mutable BlockDetailsHash m_details; mutable BlockDetailsHash m_details;
mutable boost::shared_mutex x_blooms;
mutable BlockBloomsHash m_blooms;
mutable boost::shared_mutex x_traces;
mutable BlockTracesHash m_traces;
mutable boost::shared_mutex x_logBlooms; mutable boost::shared_mutex x_logBlooms;
mutable BlockLogBloomsHash m_logBlooms; mutable BlockLogBloomsHash m_logBlooms;
mutable boost::shared_mutex x_receipts; mutable boost::shared_mutex x_receipts;

22
libethereum/BlockDetails.h

@ -54,24 +54,6 @@ struct BlockDetails
h256 bloom; h256 bloom;
}; };
struct BlockBlooms
{
BlockBlooms() {}
BlockBlooms(RLP const& _r) { blooms = _r.toVector<h256>(); }
bytes rlp() const { RLPStream s; s << blooms; return s.out(); }
h256s blooms;
};
struct BlockTraces
{
BlockTraces() {}
BlockTraces(RLP const& _r) { for (auto const& i: _r) traces.emplace_back(i.data()); }
bytes rlp() const { RLPStream s(traces.size()); for (auto const& i: traces) i.streamRLP(s); return s.out(); }
Manifests traces;
};
struct BlockLogBlooms struct BlockLogBlooms
{ {
BlockLogBlooms() {} BlockLogBlooms() {}
@ -91,14 +73,10 @@ struct BlockReceipts
}; };
typedef std::map<h256, BlockDetails> BlockDetailsHash; typedef std::map<h256, BlockDetails> BlockDetailsHash;
typedef std::map<h256, BlockBlooms> BlockBloomsHash;
typedef std::map<h256, BlockTraces> BlockTracesHash;
typedef std::map<h256, BlockLogBlooms> BlockLogBloomsHash; typedef std::map<h256, BlockLogBlooms> BlockLogBloomsHash;
typedef std::map<h256, BlockReceipts> BlockReceiptsHash; typedef std::map<h256, BlockReceipts> BlockReceiptsHash;
static const BlockDetails NullBlockDetails; static const BlockDetails NullBlockDetails;
static const BlockBlooms NullBlockBlooms;
static const BlockTraces NullBlockTraces;
static const BlockLogBlooms NullBlockLogBlooms; static const BlockLogBlooms NullBlockLogBlooms;
static const BlockReceipts NullBlockReceipts; static const BlockReceipts NullBlockReceipts;

3
libethereum/CMakeLists.txt

@ -28,6 +28,9 @@ endif()
target_link_libraries(${EXECUTABLE} ${LEVELDB_LS}) target_link_libraries(${EXECUTABLE} ${LEVELDB_LS})
target_link_libraries(${EXECUTABLE} ${CRYPTOPP_LS}) target_link_libraries(${EXECUTABLE} ${CRYPTOPP_LS})
target_link_libraries(${EXECUTABLE} gmp) target_link_libraries(${EXECUTABLE} gmp)
if (EVMJIT)
target_link_libraries(${EXECUTABLE} evmjit)
endif()
if("${TARGET_PLATFORM}" STREQUAL "w64") if("${TARGET_PLATFORM}" STREQUAL "w64")
target_link_libraries(${EXECUTABLE} boost_system-mt-s) target_link_libraries(${EXECUTABLE} boost_system-mt-s)

18
libethereum/Executive.cpp

@ -22,6 +22,7 @@
#include <boost/timer.hpp> #include <boost/timer.hpp>
#include <libdevcore/CommonIO.h> #include <libdevcore/CommonIO.h>
#include <libevm/VM.h> #include <libevm/VM.h>
#include "Interface.h"
#include "Executive.h" #include "Executive.h"
#include "State.h" #include "State.h"
#include "ExtVM.h" #include "ExtVM.h"
@ -58,15 +59,8 @@ bool Executive::setup(bytesConstRef _rlp)
BOOST_THROW_EXCEPTION(InvalidNonce(nonceReq, m_t.nonce())); BOOST_THROW_EXCEPTION(InvalidNonce(nonceReq, m_t.nonce()));
} }
// Don't like transactions whose gas price is too low. NOTE: this won't stay here forever - it's just until we get a proper gas price discovery protocol going.
if (m_t.gasPrice() < m_s.m_currentBlock.minGasPrice)
{
clog(StateDetail) << "Offered gas-price is too low: Require >" << m_s.m_currentBlock.minGasPrice << " Got" << m_t.gasPrice();
BOOST_THROW_EXCEPTION(GasPriceTooLow());
}
// Check gas cost is enough. // Check gas cost is enough.
u256 gasCost = m_t.data().size() * c_txDataGas + c_txGas; auto gasCost = Interface::txGas(m_t.data());
if (m_t.gas() < gasCost) if (m_t.gas() < gasCost)
{ {
@ -106,9 +100,9 @@ bool Executive::setup(bytesConstRef _rlp)
} }
if (m_t.isCreation()) if (m_t.isCreation())
return create(m_sender, m_t.value(), m_t.gasPrice(), m_t.gas() - gasCost, &m_t.data(), m_sender); return create(m_sender, m_t.value(), m_t.gasPrice(), m_t.gas() - (u256)gasCost, &m_t.data(), m_sender);
else else
return call(m_t.receiveAddress(), m_sender, m_t.value(), m_t.gasPrice(), bytesConstRef(&m_t.data()), m_t.gas() - gasCost, m_sender); return call(m_t.receiveAddress(), m_sender, m_t.value(), m_t.gasPrice(), bytesConstRef(&m_t.data()), m_t.gas() - (u256)gasCost, m_sender);
} }
bool Executive::call(Address _receiveAddress, Address _senderAddress, u256 _value, u256 _gasPrice, bytesConstRef _data, u256 _gas, Address _originAddress) bool Executive::call(Address _receiveAddress, Address _senderAddress, u256 _value, u256 _gasPrice, bytesConstRef _data, u256 _gas, Address _originAddress)
@ -118,7 +112,7 @@ bool Executive::call(Address _receiveAddress, Address _senderAddress, u256 _valu
if (m_s.addressHasCode(_receiveAddress)) if (m_s.addressHasCode(_receiveAddress))
{ {
m_vm = VMFace::create(VMFace::Interpreter, _gas).release(); m_vm = VMFactory::create(VMFactory::Interpreter, _gas).release();
bytes const& c = m_s.code(_receiveAddress); bytes const& c = m_s.code(_receiveAddress);
m_ext = new ExtVM(m_s, _receiveAddress, _senderAddress, _originAddress, _value, _gasPrice, _data, &c, m_ms); m_ext = new ExtVM(m_s, _receiveAddress, _senderAddress, _originAddress, _value, _gasPrice, _data, &c, m_ms);
} }
@ -137,7 +131,7 @@ bool Executive::create(Address _sender, u256 _endowment, u256 _gasPrice, u256 _g
m_s.m_cache[m_newAddress] = Account(m_s.balance(m_newAddress) + _endowment, Account::ContractConception); m_s.m_cache[m_newAddress] = Account(m_s.balance(m_newAddress) + _endowment, Account::ContractConception);
// Execute _init. // Execute _init.
m_vm = VMFace::create(VMFace::Interpreter, _gas).release(); m_vm = VMFactory::create(VMFactory::Interpreter, _gas).release();
m_ext = new ExtVM(m_s, m_newAddress, _sender, _origin, _endowment, _gasPrice, bytesConstRef(), _init, m_ms); m_ext = new ExtVM(m_s, m_newAddress, _sender, _origin, _endowment, _gasPrice, bytesConstRef(), _init, m_ms);
return _init.empty(); return _init.empty();
} }

2
libethereum/Interface.h

@ -128,7 +128,7 @@ public:
virtual Addresses addresses(int _block) const = 0; virtual Addresses addresses(int _block) const = 0;
/// Get the fee associated for a transaction with the given data. /// Get the fee associated for a transaction with the given data.
static u256 txGas(unsigned _dataCount, u256 _gas = 0) { return c_txDataGas * _dataCount + c_txGas + _gas; } template <class T> static bigint txGas(T const& _data, u256 _gas = 0) { bigint ret = c_txGas + _gas; for (auto i: _data) ret += i ? c_txDataNonZeroGas : c_txDataZeroGas; return ret; }
/// Get the remaining gas limit in this block. /// Get the remaining gas limit in this block.
virtual u256 gasLimitRemaining() const = 0; virtual u256 gasLimitRemaining() const = 0;

7
libethereum/State.cpp

@ -54,7 +54,7 @@ void ecrecoverCode(bytesConstRef _in, bytesRef _out)
memcpy(&in, _in.data(), min(_in.size(), sizeof(in))); memcpy(&in, _in.data(), min(_in.size(), sizeof(in)));
memset(_out.data(), 0, _out.size()); memset(_out.data(), 0, _out.size());
if (in.v > 28) if ((u256)in.v > 28)
return; return;
SignatureStruct sig{in.r, in.s, (byte)((int)(u256)in.v - 27)}; SignatureStruct sig{in.r, in.s, (byte)((int)(u256)in.v - 27)};
if (!sig.isValid()) if (!sig.isValid())
@ -503,7 +503,6 @@ void State::resetCurrent()
m_currentBlock.timestamp = time(0); m_currentBlock.timestamp = time(0);
m_currentBlock.transactionsRoot = h256(); m_currentBlock.transactionsRoot = h256();
m_currentBlock.sha3Uncles = h256(); m_currentBlock.sha3Uncles = h256();
m_currentBlock.minGasPrice = 10 * szabo;
m_currentBlock.populateFromParent(m_previousBlock); m_currentBlock.populateFromParent(m_previousBlock);
// Update timestamp according to clock. // Update timestamp according to clock.
@ -1216,7 +1215,7 @@ bool State::call(Address _receiveAddress, Address _codeAddress, Address _senderA
} }
else if (addressHasCode(_codeAddress)) else if (addressHasCode(_codeAddress))
{ {
auto vmObj = VMFace::create(getVMKind(), *_gas); auto vmObj = VMFactory::create(getVMKind(), *_gas);
auto& vm = *vmObj; auto& vm = *vmObj;
ExtVM evm(*this, _receiveAddress, _senderAddress, _originAddress, _value, _gasPrice, _data, &code(_codeAddress), o_ms, _level); ExtVM evm(*this, _receiveAddress, _senderAddress, _originAddress, _value, _gasPrice, _data, &code(_codeAddress), o_ms, _level);
bool revert = false; bool revert = false;
@ -1276,7 +1275,7 @@ h160 State::create(Address _sender, u256 _endowment, u256 _gasPrice, u256* _gas,
m_cache[newAddress] = Account(balance(newAddress) + _endowment, Account::ContractConception); m_cache[newAddress] = Account(balance(newAddress) + _endowment, Account::ContractConception);
// Execute init code. // Execute init code.
auto vmObj = VMFace::create(getVMKind(), *_gas); auto vmObj = VMFactory::create(getVMKind(), *_gas);
auto& vm = *vmObj; auto& vm = *vmObj;
ExtVM evm(*this, newAddress, _sender, _origin, _endowment, _gasPrice, bytesConstRef(), _code, o_ms, _level); ExtVM evm(*this, newAddress, _sender, _origin, _endowment, _gasPrice, bytesConstRef(), _code, o_ms, _level);
bool revert = false; bool revert = false;

8
libethereum/State.h

@ -30,6 +30,7 @@
#include <libethcore/Exceptions.h> #include <libethcore/Exceptions.h>
#include <libethcore/BlockInfo.h> #include <libethcore/BlockInfo.h>
#include <libethcore/ProofOfWork.h> #include <libethcore/ProofOfWork.h>
#include <libethereum/VMFactory.h>
#include <libevm/FeeStructure.h> #include <libevm/FeeStructure.h>
#include <libevm/ExtVMFace.h> #include <libevm/ExtVMFace.h>
#include <libevm/VMFace.h> #include <libevm/VMFace.h>
@ -39,6 +40,7 @@
#include "TransactionReceipt.h" #include "TransactionReceipt.h"
#include "Executive.h" #include "Executive.h"
#include "AccountDiff.h" #include "AccountDiff.h"
#include "VMFactory.h"
namespace dev namespace dev
{ {
@ -261,10 +263,10 @@ public:
void cleanup(bool _fullCommit); void cleanup(bool _fullCommit);
/// Sets VM kind to be used by the state /// Sets VM kind to be used by the state
void setVMKind(VMFace::Kind _kind) { m_vmKind = _kind; } void setVMKind(VMFactory::Kind _kind) { m_vmKind = _kind; }
/// Get the kind of VM used by the state /// Get the kind of VM used by the state
VMFace::Kind getVMKind() const { return m_vmKind; } VMFactory::Kind getVMKind() const { return m_vmKind; }
private: private:
/// Undo the changes to the state for committing to mine. /// Undo the changes to the state for committing to mine.
@ -333,7 +335,7 @@ private:
u256 m_blockReward; u256 m_blockReward;
VMFace::Kind m_vmKind = VMFace::Interpreter; ///< The kind of VM used by the state VMFactory::Kind m_vmKind = VMFactory::Interpreter; ///< The kind of VM used by the state
static std::string c_defaultPath; static std::string c_defaultPath;

28
libethereum/VMFactory.cpp

@ -0,0 +1,28 @@
#include <libevm/VM.h>
#if ETH_EVMJIT
#include<libevmjit/VM.h>
#endif
#include "VMFactory.h"
namespace dev
{
namespace eth
{
std::unique_ptr<VMFace> VMFactory::create(VMFactory::Kind _kind, u256 _gas)
{
#if ETH_EVMJIT
auto vm = _kind == Kind::JIT ? static_cast<VMFace*>(new jit::VM)
: static_cast<VMFace*>(new VM);
#else
VMFace* vm = new VM;
#endif
vm->reset(_gas);
return std::unique_ptr<VMFace>(vm);
}
}
}

28
libethereum/VMFactory.h

@ -0,0 +1,28 @@
#pragma once
#include <libevm/VMFace.h>
namespace dev
{
namespace eth
{
/**
*/
class VMFactory
{
public:
enum Kind: bool {
Interpreter,
#if ETH_EVMJIT
JIT
#endif
};
static std::unique_ptr<VMFace> create(Kind, u256 _gas = 0);
};
}
}

6
libevm/FeeStructure.cpp

@ -34,9 +34,13 @@ u256 const dev::eth::c_sstoreResetGas = 100;
u256 const dev::eth::c_sstoreRefundGas = 100; u256 const dev::eth::c_sstoreRefundGas = 100;
u256 const dev::eth::c_createGas = 100; u256 const dev::eth::c_createGas = 100;
u256 const dev::eth::c_callGas = 20; u256 const dev::eth::c_callGas = 20;
u256 const dev::eth::c_expGas = 1;
u256 const dev::eth::c_expByteGas = 1;
u256 const dev::eth::c_memoryGas = 1; u256 const dev::eth::c_memoryGas = 1;
u256 const dev::eth::c_txDataGas = 5; u256 const dev::eth::c_txDataZeroGas = 1;
u256 const dev::eth::c_txDataNonZeroGas = 5;
u256 const dev::eth::c_txGas = 500; u256 const dev::eth::c_txGas = 500;
u256 const dev::eth::c_logGas = 32; u256 const dev::eth::c_logGas = 32;
u256 const dev::eth::c_logDataGas = 1; u256 const dev::eth::c_logDataGas = 1;
u256 const dev::eth::c_logTopicGas = 32; u256 const dev::eth::c_logTopicGas = 32;
u256 const dev::eth::c_copyGas = 1;

6
libevm/FeeStructure.h

@ -37,12 +37,16 @@ extern u256 const c_sstoreResetGas; ///< Once per SSTORE operation if the zeron
extern u256 const c_sstoreRefundGas; ///< Refunded gas, once per SSTORE operation if the zeroness changes to zero. extern u256 const c_sstoreRefundGas; ///< Refunded gas, once per SSTORE operation if the zeroness changes to zero.
extern u256 const c_createGas; ///< Once per CREATE operation & contract-creation transaction. extern u256 const c_createGas; ///< Once per CREATE operation & contract-creation transaction.
extern u256 const c_callGas; ///< Once per CALL operation & message call transaction. extern u256 const c_callGas; ///< Once per CALL operation & message call transaction.
extern u256 const c_expGas; ///< Once per EXP instuction.
extern u256 const c_expByteGas; ///< Times ceil(log256(exponent)) for the EXP instruction.
extern u256 const c_memoryGas; ///< Times the address of the (highest referenced byte in memory + 1). NOTE: referencing happens on read, write and in instructions such as RETURN and CALL. extern u256 const c_memoryGas; ///< Times the address of the (highest referenced byte in memory + 1). NOTE: referencing happens on read, write and in instructions such as RETURN and CALL.
extern u256 const c_txDataGas; ///< Per byte of data attached to a transaction. NOTE: Not payable on data of calls between transactions. extern u256 const c_txDataZeroGas; ///< Per byte of data attached to a transaction that equals zero. NOTE: Not payable on data of calls between transactions.
extern u256 const c_txDataNonZeroGas; ///< Per byte of data attached to a transaction that is not equal to zero. NOTE: Not payable on data of calls between transactions.
extern u256 const c_txGas; ///< Per transaction. NOTE: Not payable on data of calls between transactions. extern u256 const c_txGas; ///< Per transaction. NOTE: Not payable on data of calls between transactions.
extern u256 const c_logGas; ///< Per LOG* operation. extern u256 const c_logGas; ///< Per LOG* operation.
extern u256 const c_logDataGas; ///< Per byte in a LOG* operation's data. extern u256 const c_logDataGas; ///< Per byte in a LOG* operation's data.
extern u256 const c_logTopicGas; ///< Multiplied by the * of the LOG*, per LOG transaction. e.g. LOG0 incurs 0 * c_txLogTopicGas, LOG4 incurs 4 * c_txLogTopicGas. extern u256 const c_logTopicGas; ///< Multiplied by the * of the LOG*, per LOG transaction. e.g. LOG0 incurs 0 * c_txLogTopicGas, LOG4 incurs 4 * c_txLogTopicGas.
extern u256 const c_copyGas; ///< Multiplied by the number of 32-byte words that are copied (round up) for any *COPY operation and added.
} }
} }

17
libevm/VM.h

@ -36,6 +36,8 @@ namespace dev
namespace eth namespace eth
{ {
class VMFactory;
/** /**
*/ */
class VM : public VMFace class VM : public VMFace
@ -53,7 +55,7 @@ public:
u256s const& stack() const { return m_stack; } u256s const& stack() const { return m_stack; }
private: private:
friend VMFace; friend VMFactory;
explicit VM(u256 _gas = 0): VMFace(_gas) {} explicit VM(u256 _gas = 0): VMFace(_gas) {}
template <class Ext> template <class Ext>
@ -108,6 +110,7 @@ template <class Ext> dev::bytesConstRef dev::eth::VM::go(Ext& _ext, OnOpFunc con
// FEES... // FEES...
bigint runGas = c_stepGas; bigint runGas = c_stepGas;
bigint newTempSize = m_temp.size(); bigint newTempSize = m_temp.size();
bigint copySize = 0;
auto onOperation = [&]() auto onOperation = [&]()
{ {
@ -170,14 +173,17 @@ template <class Ext> dev::bytesConstRef dev::eth::VM::go(Ext& _ext, OnOpFunc con
break; break;
case Instruction::CALLDATACOPY: case Instruction::CALLDATACOPY:
require(3); require(3);
copySize = m_stack[m_stack.size() - 3];
newTempSize = memNeed(m_stack.back(), m_stack[m_stack.size() - 3]); newTempSize = memNeed(m_stack.back(), m_stack[m_stack.size() - 3]);
break; break;
case Instruction::CODECOPY: case Instruction::CODECOPY:
require(3); require(3);
copySize = m_stack[m_stack.size() - 3];
newTempSize = memNeed(m_stack.back(), m_stack[m_stack.size() - 3]); newTempSize = memNeed(m_stack.back(), m_stack[m_stack.size() - 3]);
break; break;
case Instruction::EXTCODECOPY: case Instruction::EXTCODECOPY:
require(4); require(4);
copySize = m_stack[m_stack.size() - 4];
newTempSize = memNeed(m_stack[m_stack.size() - 2], m_stack[m_stack.size() - 4]); newTempSize = memNeed(m_stack[m_stack.size() - 2], m_stack[m_stack.size() - 4]);
break; break;
@ -215,6 +221,13 @@ template <class Ext> dev::bytesConstRef dev::eth::VM::go(Ext& _ext, OnOpFunc con
runGas = c_createGas; runGas = c_createGas;
break; break;
} }
case Instruction::EXP:
{
require(2);
auto expon = m_stack[m_stack.size() - 2];
runGas = c_expGas + c_expByteGas * (32 - (h256(expon).firstBitSet() / 8));
break;
}
case Instruction::PC: case Instruction::PC:
case Instruction::MSIZE: case Instruction::MSIZE:
@ -281,7 +294,6 @@ template <class Ext> dev::bytesConstRef dev::eth::VM::go(Ext& _ext, OnOpFunc con
case Instruction::SDIV: case Instruction::SDIV:
case Instruction::MOD: case Instruction::MOD:
case Instruction::SMOD: case Instruction::SMOD:
case Instruction::EXP:
case Instruction::LT: case Instruction::LT:
case Instruction::GT: case Instruction::GT:
case Instruction::SLT: case Instruction::SLT:
@ -342,6 +354,7 @@ template <class Ext> dev::bytesConstRef dev::eth::VM::go(Ext& _ext, OnOpFunc con
newTempSize = (newTempSize + 31) / 32 * 32; newTempSize = (newTempSize + 31) / 32 * 32;
if (newTempSize > m_temp.size()) if (newTempSize > m_temp.size())
runGas += c_memoryGas * (newTempSize - m_temp.size()) / 32; runGas += c_memoryGas * (newTempSize - m_temp.size()) / 32;
runGas += c_copyGas * (copySize + 31) / 32;
onOperation(); onOperation();
// if (_onOp) // if (_onOp)

12
libevm/VMFace.cpp

@ -22,15 +22,7 @@
using namespace dev; using namespace dev;
using namespace dev::eth; using namespace dev::eth;
std::unique_ptr<VMFace> VMFace::create(VMFace::Kind _kind, u256 _gas) void VMFace::reset(u256 _gas) noexcept
{ {
std::unique_ptr<VMFace> vm; m_gas = _gas;
#if ETH_EVMJIT
vm.reset(_kind == Kind::JIT ? static_cast<VMFace*>(new jit::VM) : new VM);
#else
(void) _kind; // suppress unused var warning
vm.reset(new VM);
#endif
vm->reset(_gas);
return vm;
} }

6
libevm/VMFace.h

@ -62,16 +62,12 @@ public:
VMFace(VMFace const&) = delete; VMFace(VMFace const&) = delete;
void operator=(VMFace const&) = delete; void operator=(VMFace const&) = delete;
virtual void reset(u256 _gas = 0) noexcept { m_gas = _gas; } virtual void reset(u256 _gas = 0) noexcept;
virtual bytesConstRef go(ExtVMFace& _ext, OnOpFunc const& _onOp = {}, uint64_t _steps = (uint64_t)-1) = 0; virtual bytesConstRef go(ExtVMFace& _ext, OnOpFunc const& _onOp = {}, uint64_t _steps = (uint64_t)-1) = 0;
u256 gas() const { return m_gas; } u256 gas() const { return m_gas; }
enum Kind: bool { Interpreter, JIT };
static std::unique_ptr<VMFace> create(Kind, u256 _gas = 0);
protected: protected:
u256 m_gas = 0; u256 m_gas = 0;
}; };

3
libevmjit/Compiler.cpp

@ -805,6 +805,9 @@ void Compiler::compileBasicBlock(BasicBlock& _basicBlock, bytes const& _bytecode
auto numBytes = stack.pop(); auto numBytes = stack.pop();
_memory.require(beginIdx, numBytes); _memory.require(beginIdx, numBytes);
// This will commit the current cost block
_gasMeter.countLogData(numBytes);
std::array<llvm::Value*,4> topics; std::array<llvm::Value*,4> topics;
auto numTopics = static_cast<size_t>(inst) - static_cast<size_t>(Instruction::LOG0); auto numTopics = static_cast<size_t>(inst) - static_cast<size_t>(Instruction::LOG0);
for (size_t i = 0; i < numTopics; ++i) for (size_t i = 0; i < numTopics; ++i)

8
libevmjit/Ext.cpp

@ -167,8 +167,8 @@ llvm::Value* Ext::codesizeAt(llvm::Value* _addr)
void Ext::log(llvm::Value* _memIdx, llvm::Value* _numBytes, size_t _numTopics, std::array<llvm::Value*,4> const& _topics) void Ext::log(llvm::Value* _memIdx, llvm::Value* _numBytes, size_t _numTopics, std::array<llvm::Value*,4> const& _topics)
{ {
static llvm::Value* args[] = {nullptr, m_args[0], m_args[1], m_arg2, m_arg3, m_arg4, m_arg5}; llvm::Value* args[] = {nullptr, m_args[0], m_args[1], m_arg2, m_arg3, m_arg4, m_arg5};
static llvm::Value* funcs[] = {m_log0, m_log1, m_log2, m_log3, m_log4}; llvm::Value* funcs[] = {m_log0, m_log1, m_log2, m_log3, m_log4};
args[0] = getRuntimeManager().getRuntimePtr(); args[0] = getRuntimeManager().getRuntimePtr();
m_builder.CreateStore(_memIdx, m_args[0]); m_builder.CreateStore(_memIdx, m_args[0]);
@ -320,8 +320,8 @@ extern "C"
{ {
auto&& ext = _rt->getExt(); auto&& ext = _rt->getExt();
auto memIdx = static_cast<size_t>(llvm2eth(*_memIdx)); auto memIdx = llvm2eth(*_memIdx).convert_to<size_t>();
auto numBytes = static_cast<size_t>(llvm2eth(*_numBytes)); auto numBytes = llvm2eth(*_numBytes).convert_to<size_t>();
auto dataRef = bytesConstRef(_rt->getMemory().data() + memIdx, numBytes); auto dataRef = bytesConstRef(_rt->getMemory().data() + memIdx, numBytes);
ext.log({}, dataRef); ext.log({}, dataRef);

18
libevmjit/GasMeter.cpp

@ -47,6 +47,16 @@ uint64_t getStepCost(Instruction inst) // TODO: Add this function to FeeSructure
case Instruction::CREATE: case Instruction::CREATE:
return static_cast<uint64_t>(c_createGas); return static_cast<uint64_t>(c_createGas);
case Instruction::LOG0:
case Instruction::LOG1:
case Instruction::LOG2:
case Instruction::LOG3:
case Instruction::LOG4:
{
auto numTopics = static_cast<uint64_t>(inst) - static_cast<uint64_t>(Instruction::LOG0);
return static_cast<uint64_t>(c_logGas) + numTopics * static_cast<uint64_t>(c_logTopicGas);
}
default: // Assumes instruction code is valid default: // Assumes instruction code is valid
return static_cast<uint64_t>(c_stepGas); return static_cast<uint64_t>(c_stepGas);
} }
@ -138,6 +148,14 @@ void GasMeter::countSStore(Ext& _ext, llvm::Value* _index, llvm::Value* _newValu
createCall(m_gasCheckFunc, cost); createCall(m_gasCheckFunc, cost);
} }
void GasMeter::countLogData(llvm::Value* _dataLength)
{
assert(m_checkCall);
assert(m_blockCost > 0); // LOGn instruction is already counted
auto cost = m_builder.CreateMul(_dataLength, Constant::get(c_logDataGas), "logdata_cost");
commitCostBlock(cost);
}
void GasMeter::giveBack(llvm::Value* _gas) void GasMeter::giveBack(llvm::Value* _gas)
{ {
m_runtimeManager.setGas(m_builder.CreateAdd(m_runtimeManager.getGas(), _gas)); m_runtimeManager.setGas(m_builder.CreateAdd(m_runtimeManager.getGas(), _gas));

3
libevmjit/GasMeter.h

@ -24,6 +24,9 @@ public:
/// Calculate & count gas cost for SSTORE instruction /// Calculate & count gas cost for SSTORE instruction
void countSStore(class Ext& _ext, llvm::Value* _index, llvm::Value* _newValue); void countSStore(class Ext& _ext, llvm::Value* _index, llvm::Value* _newValue);
/// Count gas cost of LOG data
void countLogData(llvm::Value* _dataLength);
/// Finalize cost-block by checking gas needed for the block before the block /// Finalize cost-block by checking gas needed for the block before the block
/// @param _additionalCost adds additional cost to cost-block before commit /// @param _additionalCost adds additional cost to cost-block before commit
void commitCostBlock(llvm::Value* _additionalCost = nullptr); void commitCostBlock(llvm::Value* _additionalCost = nullptr);

1
libevmjit/VM.cpp

@ -2,6 +2,7 @@
#include "VM.h" #include "VM.h"
#include <libevm/VMFace.h> #include <libevm/VMFace.h>
#include <libevm/VM.h>
#include "ExecutionEngine.h" #include "ExecutionEngine.h"
#include "Compiler.h" #include "Compiler.h"

8
libevmjit/VM.h

@ -9,6 +9,9 @@ namespace dev
{ {
namespace eth namespace eth
{ {
class VMFactory;
namespace jit namespace jit
{ {
@ -16,8 +19,11 @@ class VM: public VMFace
{ {
virtual bytesConstRef go(ExtVMFace& _ext, OnOpFunc const& _onOp = {}, uint64_t _steps = (uint64_t)-1) override final; virtual bytesConstRef go(ExtVMFace& _ext, OnOpFunc const& _onOp = {}, uint64_t _steps = (uint64_t)-1) override final;
enum Kind: bool { Interpreter, JIT };
static std::unique_ptr<VMFace> create(Kind, u256 _gas = 0);
private: private:
friend VMFace; friend VMFactory;
explicit VM(u256 _gas = 0): VMFace(_gas) {} explicit VM(u256 _gas = 0): VMFace(_gas) {}
bytes m_output; bytes m_output;

2
libsolidity/ExpressionCompiler.cpp

@ -363,7 +363,7 @@ void ExpressionCompiler::endVisit(Identifier& _identifier)
m_context << m_context.getFunctionEntryLabel(*functionDef).pushTag(); m_context << m_context.getFunctionEntryLabel(*functionDef).pushTag();
return; return;
} }
if (VariableDeclaration* varDef = dynamic_cast<VariableDeclaration*>(declaration)) if (/*VariableDeclaration* varDef = */dynamic_cast<VariableDeclaration*>(declaration))
{ {
m_currentLValue.fromIdentifier(_identifier, *_identifier.getReferencedDeclaration()); m_currentLValue.fromIdentifier(_identifier, *_identifier.getReferencedDeclaration());
m_currentLValue.retrieveValueIfLValueNotRequested(_identifier); m_currentLValue.retrieveValueIfLValueNotRequested(_identifier);

2
libsolidity/GlobalContext.cpp

@ -58,7 +58,7 @@ GlobalContext::GlobalContext():
FunctionType::Location::ECRECOVER)), FunctionType::Location::ECRECOVER)),
make_shared<MagicVariableDeclaration>("ripemd160", make_shared<MagicVariableDeclaration>("ripemd160",
make_shared<FunctionType>(TypePointers({std::make_shared<IntegerType>(256, IntegerType::Modifier::HASH)}), make_shared<FunctionType>(TypePointers({std::make_shared<IntegerType>(256, IntegerType::Modifier::HASH)}),
TypePointers({std::make_shared<IntegerType>(256, IntegerType::Modifier::HASH)}), TypePointers({std::make_shared<IntegerType>(160, IntegerType::Modifier::HASH)}),
FunctionType::Location::RIPEMD160))} FunctionType::Location::RIPEMD160))}
{ {
} }

2
libsolidity/Types.cpp

@ -397,11 +397,11 @@ MagicType::MagicType(MagicType::Kind _kind):
break; break;
case Kind::MSG: case Kind::MSG:
m_members = MemberList({{"sender", make_shared<IntegerType const>(0, IntegerType::Modifier::ADDRESS)}, m_members = MemberList({{"sender", make_shared<IntegerType const>(0, IntegerType::Modifier::ADDRESS)},
{"gas", make_shared<IntegerType const>(256)},
{"value", make_shared<IntegerType const>(256)}}); {"value", make_shared<IntegerType const>(256)}});
break; break;
case Kind::TX: case Kind::TX:
m_members = MemberList({{"origin", make_shared<IntegerType const>(0, IntegerType::Modifier::ADDRESS)}, m_members = MemberList({{"origin", make_shared<IntegerType const>(0, IntegerType::Modifier::ADDRESS)},
{"gas", make_shared<IntegerType const>(256)},
{"gasprice", make_shared<IntegerType const>(256)}}); {"gasprice", make_shared<IntegerType const>(256)}});
break; break;
default: default:

1
libweb3jsonrpc/WebThreeStubServer.cpp

@ -51,7 +51,6 @@ static Json::Value toJson(dev::eth::BlockInfo const& _bi)
res["transactionsRoot"] = toJS(_bi.transactionsRoot); res["transactionsRoot"] = toJS(_bi.transactionsRoot);
res["difficulty"] = toJS(_bi.difficulty); res["difficulty"] = toJS(_bi.difficulty);
res["number"] = (int)_bi.number; res["number"] = (int)_bi.number;
res["minGasPrice"] = toJS(_bi.minGasPrice);
res["gasLimit"] = (int)_bi.gasLimit; res["gasLimit"] = (int)_bi.gasLimit;
res["timestamp"] = (int)_bi.timestamp; res["timestamp"] = (int)_bi.timestamp;
res["extraData"] = jsFromBinary(_bi.extraData); res["extraData"] = jsFromBinary(_bi.extraData);

6
libwhisper/WhisperHost.cpp

@ -156,6 +156,12 @@ void WhisperHost::uninstallWatch(unsigned _i)
m_filters.erase(fit); m_filters.erase(fit);
} }
void WhisperHost::doWork()
{
for (auto& i: peers())
i->cap<WhisperPeer>()->sendMessages();
}
void WhisperHost::cleanup() void WhisperHost::cleanup()
{ {
// remove old messages. // remove old messages.

9
libwhisper/WhisperHost.h

@ -27,6 +27,7 @@
#include <memory> #include <memory>
#include <utility> #include <utility>
#include <libdevcore/RLP.h> #include <libdevcore/RLP.h>
#include <libdevcore/Worker.h>
#include <libdevcore/Guards.h> #include <libdevcore/Guards.h>
#include <libdevcrypto/SHA3.h> #include <libdevcrypto/SHA3.h>
#include "Common.h" #include "Common.h"
@ -38,7 +39,7 @@ namespace dev
namespace shh namespace shh
{ {
class WhisperHost: public HostCapability<WhisperPeer>, public Interface class WhisperHost: public HostCapability<WhisperPeer>, public Interface, public Worker
{ {
friend class WhisperPeer; friend class WhisperPeer;
@ -64,7 +65,13 @@ public:
void cleanup(); void cleanup();
protected:
void doWork();
private: private:
virtual void onStarting() { startWorking(); }
virtual void onStopping() { stopWorking(); }
void streamMessage(h256 _m, RLPStream& _s) const; void streamMessage(h256 _m, RLPStream& _s) const;
void noteChanged(h256 _messageHash, h256 _filter); void noteChanged(h256 _messageHash, h256 _filter);

14
libwhisper/WhisperPeer.cpp

@ -72,7 +72,6 @@ bool WhisperPeer::interpret(unsigned _id, RLP const& _r)
for (auto i: _r) for (auto i: _r)
if (n++) if (n++)
host()->inject(Envelope(i), this); host()->inject(Envelope(i), this);
sendMessages();
break; break;
} }
default: default:
@ -97,10 +96,15 @@ void WhisperPeer::sendMessages()
} }
} }
if (!n) // the message subsystem should really just keep pumping out messages while m_unseen.size() and there's bandwidth for them.
// pause for a bit if no messages to send - this is horrible and broken. auto diff = chrono::duration_cast<chrono::milliseconds>(chrono::system_clock::now() - m_timer);
// the message subsystem should really just keep pumping out messages while m_unseen.size() and there's bandwidth for them. if (n || diff.count() > 0)
this_thread::sleep_for(chrono::milliseconds(20)); {
RLPStream s;
prep(s, MessagesPacket, n).appendRaw(amalg.out(), n);
sealAndSend(s);
m_timer = chrono::system_clock::now();
}
{ {
RLPStream s; RLPStream s;

2
libwhisper/WhisperPeer.h

@ -68,6 +68,8 @@ private:
mutable dev::Mutex x_unseen; mutable dev::Mutex x_unseen;
std::map<unsigned, h256> m_unseen; ///< Rated according to what they want. std::map<unsigned, h256> m_unseen; ///< Rated according to what they want.
std::chrono::system_clock::time_point m_timer = std::chrono::system_clock::now();
}; };
} }

18
neth/main.cpp

@ -603,7 +603,7 @@ int main(int argc, char** argv)
vector<string> l; vector<string> l;
l.push_back("Amount"); l.push_back("Amount");
stringstream label; stringstream label;
label << "Gas price (" << info.minGasPrice << ")"; label << "Gas price";
l.push_back(label.str()); l.push_back(label.str());
l.push_back("Gas"); l.push_back("Gas");
vector<string> b; vector<string> b;
@ -646,14 +646,12 @@ int main(int argc, char** argv)
ssbd << bbd; ssbd << bbd;
cnote << ssbd.str(); cnote << ssbd.str();
int ssize = fields[4].length(); int ssize = fields[4].length();
u256 minGas = (u256)Client::txGas(data.size(), 0); u256 minGas = (u256)Client::txGas(data, 0);
if (size < 40) if (size < 40)
{ {
if (size > 0) if (size > 0)
cwarn << "Invalid address length:" << size; cwarn << "Invalid address length:" << size;
} }
else if (gasPrice < info.minGasPrice)
cwarn << "Minimum gas price is" << info.minGasPrice;
else if (gas < minGas) else if (gas < minGas)
cwarn << "Minimum gas amount is" << minGas; cwarn << "Minimum gas amount is" << minGas;
else if (ssize < 40) else if (ssize < 40)
@ -702,9 +700,9 @@ int main(int argc, char** argv)
auto h = bc.currentHash(); auto h = bc.currentHash();
auto blockData = bc.block(h); auto blockData = bc.block(h);
BlockInfo info(blockData); BlockInfo info(blockData);
u256 minGas = (u256)Client::txGas(0, 0); u256 minGas = (u256)Client::txGas(bytes(), 0);
Address dest = h160(fromHex(fields[0])); Address dest = h160(fromHex(fields[0]));
c.transact(us.secret(), amount, dest, bytes(), minGas, info.minGasPrice); c.transact(us.secret(), amount, dest, bytes(), minGas);
} }
} }
} }
@ -718,7 +716,7 @@ int main(int argc, char** argv)
vector<string> l; vector<string> l;
l.push_back("Endowment"); l.push_back("Endowment");
stringstream label; stringstream label;
label << "Gas price (" << info.minGasPrice << ")"; label << "Gas price";
l.push_back(label.str()); l.push_back(label.str());
l.push_back("Gas"); l.push_back("Gas");
vector<string> b; vector<string> b;
@ -763,16 +761,14 @@ int main(int argc, char** argv)
cnote << "Init:"; cnote << "Init:";
cnote << ssc.str(); cnote << ssc.str();
} }
u256 minGas = (u256)Client::txGas(init.size(), 0); u256 minGas = (u256)Client::txGas(init, 0);
if (endowment < 0) if (endowment < 0)
cwarn << "Invalid endowment"; cwarn << "Invalid endowment";
else if (gasPrice < info.minGasPrice)
cwarn << "Minimum gas price is" << info.minGasPrice;
else if (gas < minGas) else if (gas < minGas)
cwarn << "Minimum gas amount is" << minGas; cwarn << "Minimum gas amount is" << minGas;
else else
{ {
c.transact(us.secret(), endowment, init, gas, gasPrice); c.transact(us.secret(), endowment, init, gas);
} }
} }
} }

3
test/createRandomTest.cpp

@ -31,6 +31,7 @@
#include <json_spirit/json_spirit_writer_template.h> #include <json_spirit/json_spirit_writer_template.h>
#include <libdevcore/CommonIO.h> #include <libdevcore/CommonIO.h>
#include <libdevcore/CommonData.h> #include <libdevcore/CommonData.h>
#include <libethereum/VMFactory.h>
#include <libevmcore/Instruction.h> #include <libevmcore/Instruction.h>
#include <libevm/VM.h> #include <libevm/VM.h>
#include "vm.h" #include "vm.h"
@ -128,7 +129,7 @@ void doMyTests(json_spirit::mValue& v)
assert(o.count("exec") > 0); assert(o.count("exec") > 0);
auto vmObj = eth::VMFace::create(eth::VMFace::Interpreter); auto vmObj = eth::VMFactory::create(eth::VMFactory::Interpreter);
auto& vm = *vmObj; auto& vm = *vmObj;
test::FakeExtVM fev; test::FakeExtVM fev;
fev.importEnv(o["env"].get_obj()); fev.importEnv(o["env"].get_obj());

10
test/vm.cpp

@ -22,6 +22,7 @@
#include <chrono> #include <chrono>
#include <boost/filesystem.hpp> #include <boost/filesystem.hpp>
#include <libethereum/VMFactory.h>
#include "vm.h" #include "vm.h"
using namespace std; using namespace std;
using namespace json_spirit; using namespace json_spirit;
@ -322,8 +323,11 @@ void doVMTests(json_spirit::mValue& v, bool _fillin)
auto useJit = false; auto useJit = false;
for (auto i = 0; i < argc && !useJit; ++i) for (auto i = 0; i < argc && !useJit; ++i)
useJit |= std::string(argv[i]) == "--jit"; useJit |= std::string(argv[i]) == "--jit";
auto vmKind = useJit ? VMFace::JIT : VMFace::Interpreter; #if ETH_EVMJIT
auto vmKind = useJit ? VMFactory::JIT : VMFactory::Interpreter;
#else
auto vmKind == VMFactory::Interpreter;
#endif
dev::test::FakeExtVM fev; dev::test::FakeExtVM fev;
fev.importEnv(o["env"].get_obj()); fev.importEnv(o["env"].get_obj());
@ -339,7 +343,7 @@ void doVMTests(json_spirit::mValue& v, bool _fillin)
fev.code = fev.thisTxCode; fev.code = fev.thisTxCode;
} }
auto vm = VMFace::create(vmKind, fev.gas); auto vm = VMFactory::create(vmKind, fev.gas);
bytes output; bytes output;
auto startTime = std::chrono::high_resolution_clock::now(); auto startTime = std::chrono::high_resolution_clock::now();

Loading…
Cancel
Save