diff --git a/alethzero/CMakeLists.txt b/alethzero/CMakeLists.txt
index 01dfb88dc..721ab79ba 100644
--- a/alethzero/CMakeLists.txt
+++ b/alethzero/CMakeLists.txt
@@ -54,6 +54,9 @@ endif ()
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)
+if (EVMJIT)
+ target_link_libraries(${EXECUTEABLE} evmjit)
+endif()
if (APPLE)
# First have qt5 install plugins and frameworks
diff --git a/alethzero/MainWin.cpp b/alethzero/MainWin.cpp
index e5506a660..fc27d6e30 100644
--- a/alethzero/MainWin.cpp
+++ b/alethzero/MainWin.cpp
@@ -1259,7 +1259,6 @@ void Main::on_blocks_currentItemChanged()
s << "
D/TD: 2^" << log2((double)info.difficulty) << "/2^" << log2((double)details.totalDifficulty) << "";
s << " Children: " << details.children.size() << "";
s << "
Gas used/limit: " << info.gasUsed << "/" << info.gasLimit << "";
- s << " Minimum gas price: " << formatBalance(info.minGasPrice) << "";
s << "
Coinbase: " << pretty(info.coinbaseAddress).toHtmlEscaped().toStdString() << " " << info.coinbaseAddress;
s << "
Nonce: " << info.nonce << "";
s << "
Parent: " << info.parentHash << "";
@@ -1665,7 +1664,7 @@ void Main::on_data_textChanged()
errs.append("
" + QString::fromStdString(i).toHtmlEscaped() + "
");
}
ui->code->setHtml(errs + lll + solidity + "Code
" + 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())
ui->gas->setValue(m_backupGas);
ui->gas->setEnabled(true);
@@ -1676,7 +1675,7 @@ void Main::on_data_textChanged()
ui->code->setHtml(QString::fromStdString(dev::memDump(m_data, 8, true)));
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())
ui->gas->setValue(m_backupGas);
ui->gas->setEnabled(true);
@@ -1685,7 +1684,7 @@ void Main::on_data_textChanged()
{
if (ui->gas->isEnabled())
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);
}
}
diff --git a/eth/main.cpp b/eth/main.cpp
index 408654018..9b63e0643 100644
--- a/eth/main.cpp
+++ b/eth/main.cpp
@@ -492,14 +492,12 @@ int main(int argc, char** argv)
cnote << ssbd.str();
int ssize = sechex.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 > 0)
cwarn << "Invalid address length:" << size;
}
- else if (gasPrice < info.minGasPrice)
- cwarn << "Minimum gas price is" << info.minGasPrice;
else if (gas < minGas)
cwarn << "Minimum gas amount is" << minGas;
else if (ssize < 40)
@@ -559,9 +557,9 @@ int main(int argc, char** argv)
auto h = bc.currentHash();
auto blockData = bc.block(h);
BlockInfo info(blockData);
- u256 minGas = (u256)Client::txGas(0, 0);
+ u256 minGas = (u256)Client::txGas(bytes(), 0);
Address dest = h160(fromHex(hexAddr));
- c->transact(us.secret(), amount, dest, bytes(), minGas, info.minGasPrice);
+ c->transact(us.secret(), amount, dest, bytes(), minGas);
}
}
else
@@ -598,11 +596,9 @@ int main(int argc, char** argv)
cnote << "Init:";
cnote << ssc.str();
}
- u256 minGas = (u256)Client::txGas(init.size(), 0);
+ u256 minGas = (u256)Client::txGas(init, 0);
if (endowment < 0)
cwarn << "Invalid endowment";
- else if (gasPrice < info.minGasPrice)
- cwarn << "Minimum gas price is" << info.minGasPrice;
else if (gas < minGas)
cwarn << "Minimum gas amount is" << minGas;
else
diff --git a/libdevcore/Common.cpp b/libdevcore/Common.cpp
index ae073b9b1..280268d8b 100644
--- a/libdevcore/Common.cpp
+++ b/libdevcore/Common.cpp
@@ -27,7 +27,7 @@ using namespace dev;
namespace dev
{
-char const* Version = "0.7.10";
+char const* Version = "0.7.11";
}
diff --git a/libethcore/BlockInfo.cpp b/libethcore/BlockInfo.cpp
index 44da9603c..015f8dad6 100644
--- a/libethcore/BlockInfo.cpp
+++ b/libethcore/BlockInfo.cpp
@@ -58,9 +58,9 @@ h256 BlockInfo::headerHashWithoutNonce() 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
- << difficulty << number << minGasPrice << gasLimit << gasUsed << timestamp << extraData;
+ << difficulty << number << gasLimit << gasUsed << timestamp << extraData;
if (_nonce)
_s << nonce;
}
@@ -86,12 +86,11 @@ void BlockInfo::populateFromHeader(RLP const& _header, bool _checkNonce)
logBloom = _header[field = 6].toHash();
difficulty = _header[field = 7].toInt();
number = _header[field = 8].toInt();
- minGasPrice = _header[field = 9].toInt();
- gasLimit = _header[field = 10].toInt();
- gasUsed = _header[field = 11].toInt();
- timestamp = _header[field = 12].toInt();
- extraData = _header[field = 13].toBytes();
- nonce = _header[field = 14].toHash();
+ gasLimit = _header[field = 9].toInt();
+ gasUsed = _header[field = 10].toInt();
+ timestamp = _header[field = 11].toInt();
+ extraData = _header[field = 12].toBytes();
+ nonce = _header[field = 13].toHash();
}
catch (Exception const& _e)
@@ -147,9 +146,6 @@ void BlockInfo::verifyInternals(bytesConstRef _block) const
if (transactionsRoot != t.root())
BOOST_THROW_EXCEPTION(InvalidTransactionsHash(t.root(), transactionsRoot));
- if (minGasPrice > mgp)
- BOOST_THROW_EXCEPTION(InvalidMinGasPrice(minGasPrice, mgp));
-
if (sha3Uncles != sha3(root[2].data()))
BOOST_THROW_EXCEPTION(InvalidUnclesHash());
}
diff --git a/libethcore/BlockInfo.h b/libethcore/BlockInfo.h
index d91ff244d..aa7456f72 100644
--- a/libethcore/BlockInfo.h
+++ b/libethcore/BlockInfo.h
@@ -66,7 +66,6 @@ public:
h512 logBloom; // TODO LogBloom - get include
u256 difficulty;
u256 number;
- u256 minGasPrice;
u256 gasLimit;
u256 gasUsed;
u256 timestamp;
@@ -95,7 +94,6 @@ public:
logBloom == _cmp.logBloom &&
difficulty == _cmp.difficulty &&
number == _cmp.number &&
- minGasPrice == _cmp.minGasPrice &&
gasLimit == _cmp.gasLimit &&
gasUsed == _cmp.gasUsed &&
timestamp == _cmp.timestamp &&
@@ -122,7 +120,7 @@ public:
inline std::ostream& operator<<(std::ostream& _out, BlockInfo const& _bi)
{
_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;
return _out;
}
diff --git a/libethcore/CommonEth.cpp b/libethcore/CommonEth.cpp
index c12c71774..010b7e408 100644
--- a/libethcore/CommonEth.cpp
+++ b/libethcore/CommonEth.cpp
@@ -33,8 +33,8 @@ namespace dev
namespace eth
{
-const unsigned c_protocolVersion = 44;
-const unsigned c_databaseVersion = 4;
+const unsigned c_protocolVersion = 45;
+const unsigned c_databaseVersion = 5;
static const vector> g_units =
{
diff --git a/libethereum/BlockChain.cpp b/libethereum/BlockChain.cpp
index 765b54627..531005fb2 100644
--- a/libethereum/BlockChain.cpp
+++ b/libethereum/BlockChain.cpp
@@ -101,9 +101,8 @@ bytes BlockChain::createGenesisBlock()
stateRoot = state.root();
}
- block.appendList(15)
- // TODO: maybe make logbloom correct?
- << h256() << EmptyListSHA3 << h160() << stateRoot << EmptyTrie << EmptyTrie << LogBloom() << c_genesisDifficulty << 0 << 0 << 1000000 << 0 << (unsigned)0 << string() << sha3(bytes(1, 42));
+ block.appendList(14)
+ << h256() << EmptyListSHA3 << h160() << stateRoot << EmptyTrie << EmptyTrie << LogBloom() << c_genesisDifficulty << 0 << 1000000 << 0 << (unsigned)0 << string() << sha3(bytes(1, 42));
block.appendRaw(RLPEmptyList);
block.appendRaw(RLPEmptyList);
return block.out();
@@ -169,8 +168,6 @@ void BlockChain::close()
delete m_db;
m_lastBlockHash = m_genesisHash;
m_details.clear();
- m_blooms.clear();
- m_traces.clear();
m_cache.clear();
}
@@ -307,14 +304,10 @@ h256s BlockChain::import(bytes const& _block, OverlayDB const& _db)
State s(bi.coinbaseAddress, _db);
auto tdIncrease = s.enactOn(&_block, bi, *this);
auto b = s.oldBloom();
- BlockBlooms bb;
- BlockTraces bt;
BlockLogBlooms blb;
BlockReceipts br;
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());
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[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);
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(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, 4), (ldb::Slice)dev::ref(m_receipts[newHash].rlp()));
m_db->Put(m_writeOptions, toSlice(newHash), (ldb::Slice)ref(_block));
diff --git a/libethereum/BlockChain.h b/libethereum/BlockChain.h
index 74d94e164..d03818bd3 100644
--- a/libethereum/BlockChain.h
+++ b/libethereum/BlockChain.h
@@ -101,14 +101,6 @@ public:
BlockDetails details(h256 _hash) const { return queryExtras(_hash, m_details, x_details, NullBlockDetails); }
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(_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(_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.
BlockLogBlooms logBlooms(h256 _hash) const { return queryExtras(_hash, m_logBlooms, x_logBlooms, NullBlockLogBlooms); }
BlockLogBlooms logBlooms() const { return logBlooms(currentHash()); }
@@ -193,10 +185,6 @@ private:
/// The caches of the disk DB and their locks.
mutable boost::shared_mutex x_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 BlockLogBloomsHash m_logBlooms;
mutable boost::shared_mutex x_receipts;
diff --git a/libethereum/BlockDetails.h b/libethereum/BlockDetails.h
index 973e93070..0c3af5b33 100644
--- a/libethereum/BlockDetails.h
+++ b/libethereum/BlockDetails.h
@@ -54,24 +54,6 @@ struct BlockDetails
h256 bloom;
};
-struct BlockBlooms
-{
- BlockBlooms() {}
- BlockBlooms(RLP const& _r) { blooms = _r.toVector(); }
- 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
{
BlockLogBlooms() {}
@@ -91,14 +73,10 @@ struct BlockReceipts
};
typedef std::map BlockDetailsHash;
-typedef std::map BlockBloomsHash;
-typedef std::map BlockTracesHash;
typedef std::map BlockLogBloomsHash;
typedef std::map BlockReceiptsHash;
static const BlockDetails NullBlockDetails;
-static const BlockBlooms NullBlockBlooms;
-static const BlockTraces NullBlockTraces;
static const BlockLogBlooms NullBlockLogBlooms;
static const BlockReceipts NullBlockReceipts;
diff --git a/libethereum/CMakeLists.txt b/libethereum/CMakeLists.txt
index cb2049886..6088525fb 100644
--- a/libethereum/CMakeLists.txt
+++ b/libethereum/CMakeLists.txt
@@ -28,6 +28,9 @@ endif()
target_link_libraries(${EXECUTABLE} ${LEVELDB_LS})
target_link_libraries(${EXECUTABLE} ${CRYPTOPP_LS})
target_link_libraries(${EXECUTABLE} gmp)
+if (EVMJIT)
+ target_link_libraries(${EXECUTABLE} evmjit)
+endif()
if("${TARGET_PLATFORM}" STREQUAL "w64")
target_link_libraries(${EXECUTABLE} boost_system-mt-s)
diff --git a/libethereum/Executive.cpp b/libethereum/Executive.cpp
index f609c9c14..42c063d3f 100644
--- a/libethereum/Executive.cpp
+++ b/libethereum/Executive.cpp
@@ -22,6 +22,7 @@
#include
#include
#include
+#include "Interface.h"
#include "Executive.h"
#include "State.h"
#include "ExtVM.h"
@@ -58,15 +59,8 @@ bool Executive::setup(bytesConstRef _rlp)
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.
- u256 gasCost = m_t.data().size() * c_txDataGas + c_txGas;
+ auto gasCost = Interface::txGas(m_t.data());
if (m_t.gas() < gasCost)
{
@@ -106,9 +100,9 @@ bool Executive::setup(bytesConstRef _rlp)
}
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
- 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)
@@ -118,7 +112,7 @@ bool Executive::call(Address _receiveAddress, Address _senderAddress, u256 _valu
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);
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);
// 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);
return _init.empty();
}
diff --git a/libethereum/Interface.h b/libethereum/Interface.h
index add9a1bda..d598e1f9b 100644
--- a/libethereum/Interface.h
+++ b/libethereum/Interface.h
@@ -128,7 +128,7 @@ public:
virtual Addresses addresses(int _block) const = 0;
/// 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 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.
virtual u256 gasLimitRemaining() const = 0;
diff --git a/libethereum/State.cpp b/libethereum/State.cpp
index 2bfa83ca8..66d24a27b 100644
--- a/libethereum/State.cpp
+++ b/libethereum/State.cpp
@@ -54,7 +54,7 @@ void ecrecoverCode(bytesConstRef _in, bytesRef _out)
memcpy(&in, _in.data(), min(_in.size(), sizeof(in)));
memset(_out.data(), 0, _out.size());
- if (in.v > 28)
+ if ((u256)in.v > 28)
return;
SignatureStruct sig{in.r, in.s, (byte)((int)(u256)in.v - 27)};
if (!sig.isValid())
@@ -503,7 +503,6 @@ void State::resetCurrent()
m_currentBlock.timestamp = time(0);
m_currentBlock.transactionsRoot = h256();
m_currentBlock.sha3Uncles = h256();
- m_currentBlock.minGasPrice = 10 * szabo;
m_currentBlock.populateFromParent(m_previousBlock);
// Update timestamp according to clock.
@@ -1216,7 +1215,7 @@ bool State::call(Address _receiveAddress, Address _codeAddress, Address _senderA
}
else if (addressHasCode(_codeAddress))
{
- auto vmObj = VMFace::create(getVMKind(), *_gas);
+ auto vmObj = VMFactory::create(getVMKind(), *_gas);
auto& vm = *vmObj;
ExtVM evm(*this, _receiveAddress, _senderAddress, _originAddress, _value, _gasPrice, _data, &code(_codeAddress), o_ms, _level);
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);
// Execute init code.
- auto vmObj = VMFace::create(getVMKind(), *_gas);
+ auto vmObj = VMFactory::create(getVMKind(), *_gas);
auto& vm = *vmObj;
ExtVM evm(*this, newAddress, _sender, _origin, _endowment, _gasPrice, bytesConstRef(), _code, o_ms, _level);
bool revert = false;
diff --git a/libethereum/State.h b/libethereum/State.h
index 96d53bc9e..f7bc0d119 100644
--- a/libethereum/State.h
+++ b/libethereum/State.h
@@ -30,6 +30,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -39,6 +40,7 @@
#include "TransactionReceipt.h"
#include "Executive.h"
#include "AccountDiff.h"
+#include "VMFactory.h"
namespace dev
{
@@ -261,10 +263,10 @@ public:
void cleanup(bool _fullCommit);
/// 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
- VMFace::Kind getVMKind() const { return m_vmKind; }
+ VMFactory::Kind getVMKind() const { return m_vmKind; }
private:
/// Undo the changes to the state for committing to mine.
@@ -333,7 +335,7 @@ private:
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;
diff --git a/libethereum/VMFactory.cpp b/libethereum/VMFactory.cpp
new file mode 100644
index 000000000..1c8de319b
--- /dev/null
+++ b/libethereum/VMFactory.cpp
@@ -0,0 +1,28 @@
+#include
+
+#if ETH_EVMJIT
+ #include
+#endif
+
+#include "VMFactory.h"
+
+namespace dev
+{
+namespace eth
+{
+
+std::unique_ptr VMFactory::create(VMFactory::Kind _kind, u256 _gas)
+{
+#if ETH_EVMJIT
+ auto vm = _kind == Kind::JIT ? static_cast(new jit::VM)
+ : static_cast(new VM);
+#else
+ VMFace* vm = new VM;
+#endif
+
+ vm->reset(_gas);
+ return std::unique_ptr(vm);
+}
+
+}
+}
diff --git a/libethereum/VMFactory.h b/libethereum/VMFactory.h
new file mode 100644
index 000000000..5d8edc391
--- /dev/null
+++ b/libethereum/VMFactory.h
@@ -0,0 +1,28 @@
+#pragma once
+
+#include
+
+namespace dev
+{
+namespace eth
+{
+
+/**
+ */
+
+class VMFactory
+{
+public:
+ enum Kind: bool {
+ Interpreter,
+#if ETH_EVMJIT
+ JIT
+#endif
+ };
+
+ static std::unique_ptr create(Kind, u256 _gas = 0);
+};
+
+
+}
+}
diff --git a/libevm/FeeStructure.cpp b/libevm/FeeStructure.cpp
index 6d868cac5..3e957118e 100644
--- a/libevm/FeeStructure.cpp
+++ b/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_createGas = 100;
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_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_logGas = 32;
u256 const dev::eth::c_logDataGas = 1;
u256 const dev::eth::c_logTopicGas = 32;
+u256 const dev::eth::c_copyGas = 1;
diff --git a/libevm/FeeStructure.h b/libevm/FeeStructure.h
index e57f7ccf8..3fb8175e6 100644
--- a/libevm/FeeStructure.h
+++ b/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_createGas; ///< Once per CREATE operation & contract-creation 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_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_logGas; ///< Per LOG* operation.
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_copyGas; ///< Multiplied by the number of 32-byte words that are copied (round up) for any *COPY operation and added.
}
}
diff --git a/libevm/VM.h b/libevm/VM.h
index 0a9b54106..993197924 100644
--- a/libevm/VM.h
+++ b/libevm/VM.h
@@ -36,6 +36,8 @@ namespace dev
namespace eth
{
+class VMFactory;
+
/**
*/
class VM : public VMFace
@@ -53,7 +55,7 @@ public:
u256s const& stack() const { return m_stack; }
private:
- friend VMFace;
+ friend VMFactory;
explicit VM(u256 _gas = 0): VMFace(_gas) {}
template
@@ -108,6 +110,7 @@ template dev::bytesConstRef dev::eth::VM::go(Ext& _ext, OnOpFunc con
// FEES...
bigint runGas = c_stepGas;
bigint newTempSize = m_temp.size();
+ bigint copySize = 0;
auto onOperation = [&]()
{
@@ -170,14 +173,17 @@ template dev::bytesConstRef dev::eth::VM::go(Ext& _ext, OnOpFunc con
break;
case Instruction::CALLDATACOPY:
require(3);
+ copySize = m_stack[m_stack.size() - 3];
newTempSize = memNeed(m_stack.back(), m_stack[m_stack.size() - 3]);
break;
case Instruction::CODECOPY:
require(3);
+ copySize = m_stack[m_stack.size() - 3];
newTempSize = memNeed(m_stack.back(), m_stack[m_stack.size() - 3]);
break;
case Instruction::EXTCODECOPY:
require(4);
+ copySize = m_stack[m_stack.size() - 4];
newTempSize = memNeed(m_stack[m_stack.size() - 2], m_stack[m_stack.size() - 4]);
break;
@@ -215,6 +221,13 @@ template dev::bytesConstRef dev::eth::VM::go(Ext& _ext, OnOpFunc con
runGas = c_createGas;
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::MSIZE:
@@ -281,7 +294,6 @@ template dev::bytesConstRef dev::eth::VM::go(Ext& _ext, OnOpFunc con
case Instruction::SDIV:
case Instruction::MOD:
case Instruction::SMOD:
- case Instruction::EXP:
case Instruction::LT:
case Instruction::GT:
case Instruction::SLT:
@@ -342,6 +354,7 @@ template dev::bytesConstRef dev::eth::VM::go(Ext& _ext, OnOpFunc con
newTempSize = (newTempSize + 31) / 32 * 32;
if (newTempSize > m_temp.size())
runGas += c_memoryGas * (newTempSize - m_temp.size()) / 32;
+ runGas += c_copyGas * (copySize + 31) / 32;
onOperation();
// if (_onOp)
diff --git a/libevm/VMFace.cpp b/libevm/VMFace.cpp
index 3313ee926..9f8c6549c 100644
--- a/libevm/VMFace.cpp
+++ b/libevm/VMFace.cpp
@@ -22,15 +22,7 @@
using namespace dev;
using namespace dev::eth;
-std::unique_ptr VMFace::create(VMFace::Kind _kind, u256 _gas)
+void VMFace::reset(u256 _gas) noexcept
{
- std::unique_ptr vm;
-#if ETH_EVMJIT
- vm.reset(_kind == Kind::JIT ? static_cast(new jit::VM) : new VM);
-#else
- (void) _kind; // suppress unused var warning
- vm.reset(new VM);
-#endif
- vm->reset(_gas);
- return vm;
+ m_gas = _gas;
}
diff --git a/libevm/VMFace.h b/libevm/VMFace.h
index 76dc8a219..6617db1da 100644
--- a/libevm/VMFace.h
+++ b/libevm/VMFace.h
@@ -62,16 +62,12 @@ public:
VMFace(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;
u256 gas() const { return m_gas; }
- enum Kind: bool { Interpreter, JIT };
-
- static std::unique_ptr create(Kind, u256 _gas = 0);
-
protected:
u256 m_gas = 0;
};
diff --git a/libevmjit/Compiler.cpp b/libevmjit/Compiler.cpp
index 94e1450cd..1cc86d8aa 100644
--- a/libevmjit/Compiler.cpp
+++ b/libevmjit/Compiler.cpp
@@ -805,6 +805,9 @@ void Compiler::compileBasicBlock(BasicBlock& _basicBlock, bytes const& _bytecode
auto numBytes = stack.pop();
_memory.require(beginIdx, numBytes);
+ // This will commit the current cost block
+ _gasMeter.countLogData(numBytes);
+
std::array topics;
auto numTopics = static_cast(inst) - static_cast(Instruction::LOG0);
for (size_t i = 0; i < numTopics; ++i)
diff --git a/libevmjit/Ext.cpp b/libevmjit/Ext.cpp
index 17cbf5dc4..6eb35acda 100644
--- a/libevmjit/Ext.cpp
+++ b/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 const& _topics)
{
- static 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* args[] = {nullptr, m_args[0], m_args[1], m_arg2, m_arg3, m_arg4, m_arg5};
+ llvm::Value* funcs[] = {m_log0, m_log1, m_log2, m_log3, m_log4};
args[0] = getRuntimeManager().getRuntimePtr();
m_builder.CreateStore(_memIdx, m_args[0]);
@@ -320,8 +320,8 @@ extern "C"
{
auto&& ext = _rt->getExt();
- auto memIdx = static_cast(llvm2eth(*_memIdx));
- auto numBytes = static_cast(llvm2eth(*_numBytes));
+ auto memIdx = llvm2eth(*_memIdx).convert_to();
+ auto numBytes = llvm2eth(*_numBytes).convert_to();
auto dataRef = bytesConstRef(_rt->getMemory().data() + memIdx, numBytes);
ext.log({}, dataRef);
diff --git a/libevmjit/GasMeter.cpp b/libevmjit/GasMeter.cpp
index 734931c32..48499259a 100644
--- a/libevmjit/GasMeter.cpp
+++ b/libevmjit/GasMeter.cpp
@@ -47,6 +47,16 @@ uint64_t getStepCost(Instruction inst) // TODO: Add this function to FeeSructure
case Instruction::CREATE:
return static_cast(c_createGas);
+ case Instruction::LOG0:
+ case Instruction::LOG1:
+ case Instruction::LOG2:
+ case Instruction::LOG3:
+ case Instruction::LOG4:
+ {
+ auto numTopics = static_cast(inst) - static_cast(Instruction::LOG0);
+ return static_cast(c_logGas) + numTopics * static_cast(c_logTopicGas);
+ }
+
default: // Assumes instruction code is valid
return static_cast(c_stepGas);
}
@@ -138,6 +148,14 @@ void GasMeter::countSStore(Ext& _ext, llvm::Value* _index, llvm::Value* _newValu
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)
{
m_runtimeManager.setGas(m_builder.CreateAdd(m_runtimeManager.getGas(), _gas));
diff --git a/libevmjit/GasMeter.h b/libevmjit/GasMeter.h
index 4be6c1a02..dfb4fb548 100644
--- a/libevmjit/GasMeter.h
+++ b/libevmjit/GasMeter.h
@@ -24,6 +24,9 @@ public:
/// Calculate & count gas cost for SSTORE instruction
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
/// @param _additionalCost adds additional cost to cost-block before commit
void commitCostBlock(llvm::Value* _additionalCost = nullptr);
diff --git a/libevmjit/VM.cpp b/libevmjit/VM.cpp
index 9b60fccf1..b968008aa 100644
--- a/libevmjit/VM.cpp
+++ b/libevmjit/VM.cpp
@@ -2,6 +2,7 @@
#include "VM.h"
#include
+#include
#include "ExecutionEngine.h"
#include "Compiler.h"
diff --git a/libevmjit/VM.h b/libevmjit/VM.h
index 93b359cd7..1c6c71181 100644
--- a/libevmjit/VM.h
+++ b/libevmjit/VM.h
@@ -9,6 +9,9 @@ namespace dev
{
namespace eth
{
+
+class VMFactory;
+
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;
+ enum Kind: bool { Interpreter, JIT };
+ static std::unique_ptr create(Kind, u256 _gas = 0);
+
private:
- friend VMFace;
+ friend VMFactory;
explicit VM(u256 _gas = 0): VMFace(_gas) {}
bytes m_output;
diff --git a/libsolidity/ExpressionCompiler.cpp b/libsolidity/ExpressionCompiler.cpp
index 4dc377791..c3c7116e4 100644
--- a/libsolidity/ExpressionCompiler.cpp
+++ b/libsolidity/ExpressionCompiler.cpp
@@ -363,7 +363,7 @@ void ExpressionCompiler::endVisit(Identifier& _identifier)
m_context << m_context.getFunctionEntryLabel(*functionDef).pushTag();
return;
}
- if (VariableDeclaration* varDef = dynamic_cast(declaration))
+ if (/*VariableDeclaration* varDef = */dynamic_cast(declaration))
{
m_currentLValue.fromIdentifier(_identifier, *_identifier.getReferencedDeclaration());
m_currentLValue.retrieveValueIfLValueNotRequested(_identifier);
diff --git a/libsolidity/GlobalContext.cpp b/libsolidity/GlobalContext.cpp
index e958352fd..d8b637076 100644
--- a/libsolidity/GlobalContext.cpp
+++ b/libsolidity/GlobalContext.cpp
@@ -58,7 +58,7 @@ GlobalContext::GlobalContext():
FunctionType::Location::ECRECOVER)),
make_shared("ripemd160",
make_shared(TypePointers({std::make_shared(256, IntegerType::Modifier::HASH)}),
- TypePointers({std::make_shared(256, IntegerType::Modifier::HASH)}),
+ TypePointers({std::make_shared(160, IntegerType::Modifier::HASH)}),
FunctionType::Location::RIPEMD160))}
{
}
diff --git a/libsolidity/Types.cpp b/libsolidity/Types.cpp
index 4ab53bf86..b81fbbe31 100644
--- a/libsolidity/Types.cpp
+++ b/libsolidity/Types.cpp
@@ -397,11 +397,11 @@ MagicType::MagicType(MagicType::Kind _kind):
break;
case Kind::MSG:
m_members = MemberList({{"sender", make_shared(0, IntegerType::Modifier::ADDRESS)},
+ {"gas", make_shared(256)},
{"value", make_shared(256)}});
break;
case Kind::TX:
m_members = MemberList({{"origin", make_shared(0, IntegerType::Modifier::ADDRESS)},
- {"gas", make_shared(256)},
{"gasprice", make_shared(256)}});
break;
default:
diff --git a/libweb3jsonrpc/WebThreeStubServer.cpp b/libweb3jsonrpc/WebThreeStubServer.cpp
index 8ee9ee722..7607b7a95 100644
--- a/libweb3jsonrpc/WebThreeStubServer.cpp
+++ b/libweb3jsonrpc/WebThreeStubServer.cpp
@@ -51,7 +51,6 @@ static Json::Value toJson(dev::eth::BlockInfo const& _bi)
res["transactionsRoot"] = toJS(_bi.transactionsRoot);
res["difficulty"] = toJS(_bi.difficulty);
res["number"] = (int)_bi.number;
- res["minGasPrice"] = toJS(_bi.minGasPrice);
res["gasLimit"] = (int)_bi.gasLimit;
res["timestamp"] = (int)_bi.timestamp;
res["extraData"] = jsFromBinary(_bi.extraData);
diff --git a/libwhisper/WhisperHost.cpp b/libwhisper/WhisperHost.cpp
index 0fb7a206c..9b26e3260 100644
--- a/libwhisper/WhisperHost.cpp
+++ b/libwhisper/WhisperHost.cpp
@@ -156,6 +156,12 @@ void WhisperHost::uninstallWatch(unsigned _i)
m_filters.erase(fit);
}
+void WhisperHost::doWork()
+{
+ for (auto& i: peers())
+ i->cap()->sendMessages();
+}
+
void WhisperHost::cleanup()
{
// remove old messages.
diff --git a/libwhisper/WhisperHost.h b/libwhisper/WhisperHost.h
index 91934dd98..b38964f8e 100644
--- a/libwhisper/WhisperHost.h
+++ b/libwhisper/WhisperHost.h
@@ -27,6 +27,7 @@
#include
#include
#include
+#include
#include
#include
#include "Common.h"
@@ -38,7 +39,7 @@ namespace dev
namespace shh
{
-class WhisperHost: public HostCapability, public Interface
+class WhisperHost: public HostCapability, public Interface, public Worker
{
friend class WhisperPeer;
@@ -64,7 +65,13 @@ public:
void cleanup();
+protected:
+ void doWork();
+
private:
+ virtual void onStarting() { startWorking(); }
+ virtual void onStopping() { stopWorking(); }
+
void streamMessage(h256 _m, RLPStream& _s) const;
void noteChanged(h256 _messageHash, h256 _filter);
diff --git a/libwhisper/WhisperPeer.cpp b/libwhisper/WhisperPeer.cpp
index 56f4e456e..c3a28e3c3 100644
--- a/libwhisper/WhisperPeer.cpp
+++ b/libwhisper/WhisperPeer.cpp
@@ -72,7 +72,6 @@ bool WhisperPeer::interpret(unsigned _id, RLP const& _r)
for (auto i: _r)
if (n++)
host()->inject(Envelope(i), this);
- sendMessages();
break;
}
default:
@@ -97,10 +96,15 @@ void WhisperPeer::sendMessages()
}
}
- if (!n)
- // pause for a bit if no messages to send - this is horrible and broken.
- // the message subsystem should really just keep pumping out messages while m_unseen.size() and there's bandwidth for them.
- this_thread::sleep_for(chrono::milliseconds(20));
+ // the message subsystem should really just keep pumping out messages while m_unseen.size() and there's bandwidth for them.
+ auto diff = chrono::duration_cast(chrono::system_clock::now() - m_timer);
+ if (n || diff.count() > 0)
+ {
+ RLPStream s;
+ prep(s, MessagesPacket, n).appendRaw(amalg.out(), n);
+ sealAndSend(s);
+ m_timer = chrono::system_clock::now();
+ }
{
RLPStream s;
diff --git a/libwhisper/WhisperPeer.h b/libwhisper/WhisperPeer.h
index f60de8f01..faac2d870 100644
--- a/libwhisper/WhisperPeer.h
+++ b/libwhisper/WhisperPeer.h
@@ -68,6 +68,8 @@ private:
mutable dev::Mutex x_unseen;
std::map m_unseen; ///< Rated according to what they want.
+
+ std::chrono::system_clock::time_point m_timer = std::chrono::system_clock::now();
};
}
diff --git a/neth/main.cpp b/neth/main.cpp
index 6be555fbb..cb6d35593 100644
--- a/neth/main.cpp
+++ b/neth/main.cpp
@@ -603,7 +603,7 @@ int main(int argc, char** argv)
vector l;
l.push_back("Amount");
stringstream label;
- label << "Gas price (" << info.minGasPrice << ")";
+ label << "Gas price";
l.push_back(label.str());
l.push_back("Gas");
vector b;
@@ -646,14 +646,12 @@ int main(int argc, char** argv)
ssbd << bbd;
cnote << ssbd.str();
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 > 0)
cwarn << "Invalid address length:" << size;
}
- else if (gasPrice < info.minGasPrice)
- cwarn << "Minimum gas price is" << info.minGasPrice;
else if (gas < minGas)
cwarn << "Minimum gas amount is" << minGas;
else if (ssize < 40)
@@ -702,9 +700,9 @@ int main(int argc, char** argv)
auto h = bc.currentHash();
auto blockData = bc.block(h);
BlockInfo info(blockData);
- u256 minGas = (u256)Client::txGas(0, 0);
+ u256 minGas = (u256)Client::txGas(bytes(), 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 l;
l.push_back("Endowment");
stringstream label;
- label << "Gas price (" << info.minGasPrice << ")";
+ label << "Gas price";
l.push_back(label.str());
l.push_back("Gas");
vector b;
@@ -763,16 +761,14 @@ int main(int argc, char** argv)
cnote << "Init:";
cnote << ssc.str();
}
- u256 minGas = (u256)Client::txGas(init.size(), 0);
+ u256 minGas = (u256)Client::txGas(init, 0);
if (endowment < 0)
cwarn << "Invalid endowment";
- else if (gasPrice < info.minGasPrice)
- cwarn << "Minimum gas price is" << info.minGasPrice;
else if (gas < minGas)
cwarn << "Minimum gas amount is" << minGas;
else
{
- c.transact(us.secret(), endowment, init, gas, gasPrice);
+ c.transact(us.secret(), endowment, init, gas);
}
}
}
diff --git a/test/createRandomTest.cpp b/test/createRandomTest.cpp
index f22e5c0aa..87bb13846 100644
--- a/test/createRandomTest.cpp
+++ b/test/createRandomTest.cpp
@@ -31,6 +31,7 @@
#include
#include
#include
+#include
#include
#include
#include "vm.h"
@@ -128,7 +129,7 @@ void doMyTests(json_spirit::mValue& v)
assert(o.count("exec") > 0);
- auto vmObj = eth::VMFace::create(eth::VMFace::Interpreter);
+ auto vmObj = eth::VMFactory::create(eth::VMFactory::Interpreter);
auto& vm = *vmObj;
test::FakeExtVM fev;
fev.importEnv(o["env"].get_obj());
diff --git a/test/vm.cpp b/test/vm.cpp
index b34dc1829..ce0fe0808 100644
--- a/test/vm.cpp
+++ b/test/vm.cpp
@@ -22,6 +22,7 @@
#include
#include
+#include
#include "vm.h"
using namespace std;
using namespace json_spirit;
@@ -322,8 +323,11 @@ void doVMTests(json_spirit::mValue& v, bool _fillin)
auto useJit = false;
for (auto i = 0; i < argc && !useJit; ++i)
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;
fev.importEnv(o["env"].get_obj());
@@ -339,7 +343,7 @@ void doVMTests(json_spirit::mValue& v, bool _fillin)
fev.code = fev.thisTxCode;
}
- auto vm = VMFace::create(vmKind, fev.gas);
+ auto vm = VMFactory::create(vmKind, fev.gas);
bytes output;
auto startTime = std::chrono::high_resolution_clock::now();