diff --git a/CMakeLists.txt b/CMakeLists.txt index dc3c1ec32..3a7ac1401 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -312,6 +312,7 @@ endif() add_subdirectory(libdevcore) add_subdirectory(libevmcore) +add_subdirectory(libevmasm) add_subdirectory(liblll) if (SERPENT) diff --git a/alethzero/CMakeLists.txt b/alethzero/CMakeLists.txt index 9abb3f1a4..41d9ea10f 100644 --- a/alethzero/CMakeLists.txt +++ b/alethzero/CMakeLists.txt @@ -55,8 +55,7 @@ target_link_libraries(${EXECUTABLE} lll) if (SOLIDITY) target_link_libraries(${EXECUTABLE} solidity) endif () -target_link_libraries(${EXECUTABLE} evmcore) -target_link_libraries(${EXECUTABLE} devcore) +target_link_libraries(${EXECUTABLE} evmasm) target_link_libraries(${EXECUTABLE} web3jsonrpc) target_link_libraries(${EXECUTABLE} jsqrc) target_link_libraries(${EXECUTABLE} natspec) diff --git a/alethzero/Context.h b/alethzero/Context.h index 76231d6fd..20c9696f9 100644 --- a/alethzero/Context.h +++ b/alethzero/Context.h @@ -59,10 +59,10 @@ class Context public: virtual ~Context(); - virtual QString pretty(dev::Address _a) const = 0; - virtual QString prettyU256(dev::u256 _n) const = 0; - virtual QString render(dev::Address _a) const = 0; - virtual std::pair fromString(QString const& _a) const = 0; + virtual std::string pretty(dev::Address const& _a) const = 0; + virtual std::string prettyU256(dev::u256 const& _n) const = 0; + virtual std::pair fromString(std::string const& _a) const = 0; virtual std::string renderDiff(dev::eth::StateDiff const& _d) const = 0; + virtual std::string render(dev::Address const& _a) const = 0; }; diff --git a/alethzero/DappLoader.cpp b/alethzero/DappLoader.cpp index 7c754f8f5..a91beb2f7 100644 --- a/alethzero/DappLoader.cpp +++ b/alethzero/DappLoader.cpp @@ -69,7 +69,11 @@ DappLocation DappLoader::resolveAppUri(QString const& _uri) string32 name = ZeroString32; QByteArray utf8 = parts[partIndex].toUtf8(); std::copy(utf8.data(), utf8.data() + utf8.size(), name.data()); - address = abiOut
(web3()->ethereum()->call(address, abiIn("subRegistrar(bytes32)", name)).output); + if (address != m_nameReg) + address = abiOut
(web3()->ethereum()->call(address, abiIn("subRegistrar(bytes32)", name)).output); + else + address = abiOut
(web3()->ethereum()->call(address, abiIn("register(bytes32)", name)).output); + domainParts.append(parts[partIndex]); if (!address) { diff --git a/alethzero/Debugger.cpp b/alethzero/Debugger.cpp index 371630456..a1d246a21 100644 --- a/alethzero/Debugger.cpp +++ b/alethzero/Debugger.cpp @@ -226,7 +226,7 @@ void Debugger::update() QString stack; for (auto i: ws.stack) - stack.prepend("
" + m_context->prettyU256(i) + "
"); + stack.prepend("
" + QString::fromStdString(m_context->prettyU256(i)) + "
"); ui->debugStack->setHtml(stack); ui->debugMemory->setHtml(QString::fromStdString(dev::memDump(ws.memory, 16, true))); assert(m_session.codes.count(ws.code)); @@ -246,7 +246,7 @@ void Debugger::update() ui->debugStateInfo->setText(QString::fromStdString(ss.str())); stringstream s; for (auto const& i: ws.storage) - s << "@" << m_context->prettyU256(i.first).toStdString() << "    " << m_context->prettyU256(i.second).toStdString() << "
"; + s << "@" << m_context->prettyU256(i.first) << "    " << m_context->prettyU256(i.second) << "
"; ui->debugStorage->setHtml(QString::fromStdString(s.str())); } } diff --git a/alethzero/DownloadView.cpp b/alethzero/DownloadView.cpp index 88a595566..009e2dc83 100644 --- a/alethzero/DownloadView.cpp +++ b/alethzero/DownloadView.cpp @@ -39,13 +39,13 @@ void DownloadView::paintEvent(QPaintEvent*) QPainter p(this); p.fillRect(rect(), Qt::white); - if (!m_man || m_man->chain().empty() || !m_man->subCount()) + if (!m_man || m_man->chainEmpty() || !m_man->subCount()) return; double ratio = (double)rect().width() / rect().height(); if (ratio < 1) ratio = 1 / ratio; - double n = min(16.0, min(rect().width(), rect().height()) / ceil(sqrt(m_man->chain().size() / ratio))); + double n = min(16.0, min(rect().width(), rect().height()) / ceil(sqrt(m_man->chainSize() / ratio))); // QSizeF area(rect().width() / floor(rect().width() / n), rect().height() / floor(rect().height() / n)); QSizeF area(n, n); diff --git a/alethzero/ExportState.cpp b/alethzero/ExportState.cpp index e39b74b76..a8e47ad6a 100644 --- a/alethzero/ExportState.cpp +++ b/alethzero/ExportState.cpp @@ -129,8 +129,8 @@ void ExportStateDialog::fillContracts() ui->contracts->setEnabled(true); for (auto i: ethereum()->addresses(m_block)) { - QString r = m_main->render(i); - (new QListWidgetItem(QString("%2: %1 [%3]").arg(formatBalance(ethereum()->balanceAt(i)).c_str()).arg(r).arg((unsigned)ethereum()->countAt(i)), ethereum()->codeAt(i).empty() ? ui->accounts : ui->contracts)) + string r = m_main->render(i); + (new QListWidgetItem(QString("%2: %1 [%3]").arg(formatBalance(ethereum()->balanceAt(i)).c_str()).arg(QString::fromStdString(r)).arg((unsigned)ethereum()->countAt(i)), ethereum()->codeAt(i).empty() ? ui->accounts : ui->contracts)) ->setData(Qt::UserRole, QByteArray((char const*)i.data(), Address::size)); } } diff --git a/alethzero/Main.ui b/alethzero/Main.ui index ee46017f5..736af8684 100644 --- a/alethzero/Main.ui +++ b/alethzero/Main.ui @@ -53,23 +53,23 @@ - + - 0 wei + 1 block - + - 0 peers + 0 wei - + - 1 block + 0 peers @@ -160,8 +160,8 @@ - - + + @@ -190,7 +190,6 @@ &View - @@ -218,43 +217,6 @@ - - - QDockWidget::DockWidgetFeatureMask - - - Accounts - - - 2 - - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - Qt::NoFocus - - - QFrame::NoFrame - - - - - - QDockWidget::DockWidgetFeatureMask @@ -294,6 +256,19 @@ + + + + + + + + + + Automatic + + + @@ -304,16 +279,6 @@ - - - - 1 - - - 5 - - - @@ -327,20 +292,21 @@ - - - - - + + - + Public IP + + + + Automatic - + Ideal &Peers @@ -350,21 +316,7 @@ - - - - Automatic - - - - - - - Public IP - - - - + &Client Name @@ -374,13 +326,30 @@ - + + + + 1 + + + 5 + + + + Anonymous + + + + true + + + @@ -590,18 +559,21 @@ - + QDockWidget::DockWidgetFeatureMask - Contracts + Accounts 2 + + 0 + 0 @@ -614,12 +586,66 @@ 0 + + + + + + Filter... + + + + + + + Basic + + + true + + + + + + + Contracts + + + true + + + true + + + + + + + Only Named + + + true + + + false + + + + + + + Refresh + + + + + Qt::Horizontal - + 0 @@ -633,7 +659,7 @@ QFrame::NoFrame - + 2 @@ -1482,7 +1508,7 @@ font-size: 14pt - &Export State... + &Export State... @@ -1732,7 +1758,6 @@ font-size: 14pt verbosity tabWidget urlEdit - idealPeers listenIP port transactionQueue diff --git a/alethzero/MainWin.cpp b/alethzero/MainWin.cpp index ff505d5f2..62515f171 100644 --- a/alethzero/MainWin.cpp +++ b/alethzero/MainWin.cpp @@ -80,29 +80,29 @@ using namespace dev::p2p; using namespace dev::eth; namespace js = json_spirit; -QString Main::fromRaw(h256 _n, unsigned* _inc) +string Main::fromRaw(h256 _n, unsigned* _inc) { if (_n) { string s((char const*)_n.data(), 32); auto l = s.find_first_of('\0'); if (!l) - return QString(); + return string(); if (l != string::npos) { auto p = s.find_first_not_of('\0', l); if (!(p == string::npos || (_inc && p == 31))) - return QString(); + return string(); if (_inc) *_inc = (byte)s[31]; s.resize(l); } for (auto i: s) if (i < 32) - return QString(); - return QString::fromStdString(s); + return string(); + return s; } - return QString(); + return string(); } QString contentsOfQResource(string const& res) @@ -143,11 +143,6 @@ Main::Main(QWidget *parent) : // ui->log->addItem(QString::fromStdString(s)); }; -#if !ETH_FATDB - delete ui->dockWidget_accounts; - delete ui->dockWidget_contracts; -#endif - #if ETH_DEBUG m_servers.append("127.0.0.1:30300"); #endif @@ -204,6 +199,9 @@ Main::Main(QWidget *parent) : // QWebEngineInspector* inspector = new QWebEngineInspector(); // inspector->setPage(page); readSettings(); +#if !ETH_FATDB + removeDockWidget(ui->dockWidget_accounts); +#endif installWatches(); startTimer(100); @@ -398,7 +396,7 @@ void Main::onNewBlock() // update blockchain dependent views. refreshBlockCount(); refreshBlockChain(); - refreshAccounts(); + ui->refreshAccounts->setEnabled(true); // We must update balances since we can't filter updates to basic accounts. refreshBalances(); @@ -410,7 +408,7 @@ void Main::onNewPending() // update any pending-transaction dependent views. refreshPending(); - refreshAccounts(); + ui->refreshAccounts->setEnabled(true); } void Main::on_forceMining_triggered() @@ -510,33 +508,33 @@ static Public stringToPublic(QString const& _a) return Public(); } -QString Main::pretty(dev::Address _a) const +std::string Main::pretty(dev::Address const& _a) const { auto g_newNameReg = getNameReg(); if (g_newNameReg) { - QString s = QString::fromStdString(toString(abiOut(ethereum()->call(g_newNameReg, abiIn("getName(address)", _a)).output))); - if (s.size()) - return s; + string n = toString(abiOut(ethereum()->call(g_newNameReg, abiIn("name(address)", _a)).output)); + if (!n.empty()) + return n; } - return QString(); + return string(); } -QString Main::render(dev::Address _a) const +std::string Main::render(dev::Address const& _a) const { - QString p = pretty(_a); - QString n; - try { - n = QString::fromStdString(ICAP(_a).encoded()); - } - catch (...) { - n = QString::fromStdString(_a.abridged()); - } - return p.isEmpty() ? n : (p + " " + n); + string p = pretty(_a); + string n; + if (p.size() == 9 && p.find_first_not_of("QWERYUOPASDFGHJKLZXCVBNM1234567890") == string::npos) + p = ICAP(p, "XREG").encoded(); + else + DEV_IGNORE_EXCEPTIONS(n = ICAP(_a).encoded()); + if (n.empty()) + n = _a.abridged(); + return p.empty() ? n : (p + " " + n); } -pair Main::fromString(QString const& _n) const +pair Main::fromString(std::string const& _n) const { if (_n == "(Create Contract)") return make_pair(Address(), bytes()); @@ -544,7 +542,7 @@ pair Main::fromString(QString const& _n) const auto g_newNameReg = getNameReg(); if (g_newNameReg) { - Address a = abiOut
(ethereum()->call(g_newNameReg, abiIn("addr(bytes32)", ::toString32(_n.toStdString()))).output); + Address a = abiOut
(ethereum()->call(g_newNameReg, abiIn("addr(bytes32)", ::toString32(_n))).output); if (a) return make_pair(a, bytes()); } @@ -552,7 +550,7 @@ pair Main::fromString(QString const& _n) const { try { - return make_pair(Address(fromHex(_n.toStdString(), WhenError::Throw)), bytes()); + return make_pair(Address(fromHex(_n, WhenError::Throw)), bytes()); } catch (BadHexCharacter& _e) { @@ -568,7 +566,7 @@ pair Main::fromString(QString const& _n) const } else try { - return ICAP::decoded(_n.toStdString()).address([&](Address const& a, bytes const& b) -> bytes + return ICAP::decoded(_n).address([&](Address const& a, bytes const& b) -> bytes { return ethereum()->call(a, b).output; }, g_newNameReg); @@ -600,7 +598,7 @@ QString Main::lookup(QString const& _a) const return QString("%1.%2.%3.%4").arg((int)ret[28]).arg((int)ret[29]).arg((int)ret[30]).arg((int)ret[31]); // TODO: support IPv6. else if (ret) - return fromRaw(ret); + return QString::fromStdString(fromRaw(ret)); else return _a; } @@ -817,7 +815,7 @@ void Main::on_exportKey_triggered() if (ui->ourAccounts->currentRow() >= 0 && ui->ourAccounts->currentRow() < m_myKeys.size()) { auto k = m_myKeys[ui->ourAccounts->currentRow()]; - QMessageBox::information(this, "Export Account Key", "Secret key to account " + render(k.address()) + " is:\n" + QString::fromStdString(toHex(k.sec().ref()))); + QMessageBox::information(this, "Export Account Key", "Secret key to account " + QString::fromStdString(render(k.address()) + " is:\n" + toHex(k.sec().ref()))); } } @@ -936,7 +934,7 @@ void Main::refreshBalances() for (auto i: m_myKeys) { u256 b = ethereum()->balanceAt(i.address()); - (new QListWidgetItem(QString("%2: %1 [%3]").arg(formatBalance(b).c_str()).arg(render(i.address())).arg((unsigned)ethereum()->countAt(i.address())), ui->ourAccounts)) + (new QListWidgetItem(QString("%2: %1 [%3]").arg(formatBalance(b).c_str()).arg(QString::fromStdString(render(i.address()))).arg((unsigned)ethereum()->countAt(i.address())), ui->ourAccounts)) ->setData(Qt::UserRole, QByteArray((char const*)i.address().data(), Address::size)); totalBalance += b; @@ -968,24 +966,24 @@ void Main::refreshNetwork() map sessions; for (PeerSessionInfo const& i: ps) ui->peers->addItem(QString("[%8 %7] %3 ms - %1:%2 - %4 %5 %6") - .arg(QString::fromStdString(i.host)) - .arg(i.port) - .arg(chrono::duration_cast(i.lastPing).count()) - .arg(sessions[i.id] = QString::fromStdString(i.clientVersion)) - .arg(QString::fromStdString(toString(i.caps))) - .arg(QString::fromStdString(toString(i.notes))) - .arg(i.socketId) - .arg(QString::fromStdString(i.id.abridged()))); + .arg(QString::fromStdString(i.host)) + .arg(i.port) + .arg(chrono::duration_cast(i.lastPing).count()) + .arg(sessions[i.id] = QString::fromStdString(i.clientVersion)) + .arg(QString::fromStdString(toString(i.caps))) + .arg(QString::fromStdString(toString(i.notes))) + .arg(i.socketId) + .arg(QString::fromStdString(i.id.abridged()))); auto ns = web3()->nodes(); for (p2p::Peer const& i: ns) ui->nodes->insertItem(sessions.count(i.id) ? 0 : ui->nodes->count(), QString("[%1 %3] %2 - ( =%5s | /%4s%6 ) - *%7 $%8") - .arg(QString::fromStdString(i.id.abridged())) - .arg(QString::fromStdString(i.endpoint.address.to_string())) - .arg(i.id == web3()->id() ? "self" : sessions.count(i.id) ? sessions[i.id] : "disconnected") - .arg(i.isOffline() ? " | " + QString::fromStdString(reasonOf(i.lastDisconnect())) + " | " + QString::number(i.failedAttempts()) + "x" : "") - .arg(i.rating()) - ); + .arg(QString::fromStdString(i.id.abridged())) + .arg(QString::fromStdString(i.endpoint.address.to_string())) + .arg(i.id == web3()->id() ? "self" : sessions.count(i.id) ? sessions[i.id] : "disconnected") + .arg(i.isOffline() ? " | " + QString::fromStdString(reasonOf(i.lastDisconnect())) + " | " + QString::number(i.failedAttempts()) + "x" : "") + .arg(i.rating()) + ); } } @@ -994,7 +992,7 @@ void Main::refreshAll() refreshBlockChain(); refreshBlockCount(); refreshPending(); - refreshAccounts(); + ui->refreshAccounts->setEnabled(true); refreshBalances(); } @@ -1007,40 +1005,66 @@ void Main::refreshPending() QString s = t.receiveAddress() ? QString("%2 %5> %3: %1 [%4]") .arg(formatBalance(t.value()).c_str()) - .arg(render(t.safeSender())) - .arg(render(t.receiveAddress())) + .arg(QString::fromStdString(render(t.safeSender()))) + .arg(QString::fromStdString(render(t.receiveAddress()))) .arg((unsigned)t.nonce()) .arg(ethereum()->codeAt(t.receiveAddress()).size() ? '*' : '-') : QString("%2 +> %3: %1 [%4]") .arg(formatBalance(t.value()).c_str()) - .arg(render(t.safeSender())) - .arg(render(right160(sha3(rlpList(t.safeSender(), t.nonce()))))) + .arg(QString::fromStdString(render(t.safeSender()))) + .arg(QString::fromStdString(render(right160(sha3(rlpList(t.safeSender(), t.nonce())))))) .arg((unsigned)t.nonce()); ui->transactionQueue->addItem(s); } } +void Main::on_accountsFilter_textChanged() +{ + ui->refreshAccounts->setEnabled(true); +} + +void Main::on_showBasic_toggled() +{ + ui->refreshAccounts->setEnabled(true); +} + +void Main::on_showContracts_toggled() +{ + ui->refreshAccounts->setEnabled(true); +} + +void Main::on_onlyNamed_toggled() +{ + ui->refreshAccounts->setEnabled(true); +} + +void Main::on_refreshAccounts_clicked() +{ + refreshAccounts(); +} + void Main::refreshAccounts() { -#if ETH_FATDB + DEV_TIMED_FUNCTION; +#if ETH_FATDB || !ETH_TRUE cwatch << "refreshAccounts()"; ui->accounts->clear(); - ui->contracts->clear(); - for (auto n = 0; n < 2; ++n) - for (auto i: ethereum()->addresses()) - { - auto r = render(i); - if (r.contains('(') == !n) - { - if (n == 0 || ui->showAllAccounts->isChecked()) - (new QListWidgetItem(QString("%2: %1 [%3]").arg(formatBalance(ethereum()->balanceAt(i)).c_str()).arg(r).arg((unsigned)ethereum()->countAt(i)), ui->accounts)) - ->setData(Qt::UserRole, QByteArray((char const*)i.data(), Address::size)); - if (ethereum()->codeAt(i).size()) - (new QListWidgetItem(QString("%2: %1 [%3]").arg(formatBalance(ethereum()->balanceAt(i)).c_str()).arg(r).arg((unsigned)ethereum()->countAt(i)), ui->contracts)) - ->setData(Qt::UserRole, QByteArray((char const*)i.data(), Address::size)); - } - } + bool showContract = ui->showContracts->isChecked(); + bool showBasic = ui->showBasic->isChecked(); + bool onlyNamed = ui->onlyNamed->isChecked(); + for (auto const& i: ethereum()->addresses()) + { + bool isContract = (ethereum()->codeHashAt(i) != EmptySHA3); + if (!((showContract && isContract) || (showBasic && !isContract))) + continue; + string r = render(i); + if (onlyNamed && !(r.find('"') != string::npos || r.substr(0, 2) == "XE")) + continue; + (new QListWidgetItem(QString("%2: %1 [%3]").arg(formatBalance(ethereum()->balanceAt(i)).c_str()).arg(QString::fromStdString(r)).arg((unsigned)ethereum()->countAt(i)), ui->accounts)) + ->setData(Qt::UserRole, QByteArray((char const*)i.data(), Address::size)); + } #endif + ui->refreshAccounts->setEnabled(false); } void Main::refreshBlockCount() @@ -1057,6 +1081,7 @@ void Main::on_turboMining_triggered() void Main::refreshBlockChain() { + DEV_TIMED_FUNCTION; cwatch << "refreshBlockChain()"; // TODO: keep the same thing highlighted. @@ -1105,14 +1130,14 @@ void Main::refreshBlockChain() QString s = t.receiveAddress() ? QString(" %2 %5> %3: %1 [%4]") .arg(formatBalance(t.value()).c_str()) - .arg(render(t.safeSender())) - .arg(render(t.receiveAddress())) + .arg(QString::fromStdString(render(t.safeSender()))) + .arg(QString::fromStdString(render(t.receiveAddress()))) .arg((unsigned)t.nonce()) .arg(ethereum()->codeAt(t.receiveAddress()).size() ? '*' : '-') : QString(" %2 +> %3: %1 [%4]") .arg(formatBalance(t.value()).c_str()) - .arg(render(t.safeSender())) - .arg(render(right160(sha3(rlpList(t.safeSender(), t.nonce()))))) + .arg(QString::fromStdString(render(t.safeSender()))) + .arg(QString::fromStdString(render(right160(sha3(rlpList(t.safeSender(), t.nonce())))))) .arg((unsigned)t.nonce()); QListWidgetItem* txItem = new QListWidgetItem(s, ui->blocks); auto hba = QByteArray((char const*)h.data(), h.size); @@ -1256,7 +1281,7 @@ string Main::renderDiff(StateDiff const& _d) const s << "
"; AccountDiff ad = i.second; - s << "" << lead(ad.changeType()) << " " << " " << render(i.first).toStdString() << ""; + s << "" << lead(ad.changeType()) << " " << " " << render(i.first) << ""; if (!ad.exist.to()) continue; @@ -1289,7 +1314,7 @@ string Main::renderDiff(StateDiff const& _d) const s << " * "; s << " "; - s << prettyU256(i.first).toStdString(); + s << prettyU256(i.first); /* if (i.first > u256(1) << 246) s << (h256)i.first; else if (i.first > u160(1) << 150) @@ -1298,11 +1323,11 @@ string Main::renderDiff(StateDiff const& _d) const s << hex << i.first; */ if (!i.second.from()) - s << ": " << prettyU256(i.second.to()).toStdString(); + s << ": " << prettyU256(i.second.to()); else if (!i.second.to()) - s << " (" << prettyU256(i.second.from()).toStdString() << ")"; + s << " (" << prettyU256(i.second.from()) << ")"; else - s << ": " << prettyU256(i.second.to()).toStdString() << " (" << prettyU256(i.second.from()).toStdString() << ")"; + s << ": " << prettyU256(i.second.to()) << " (" << prettyU256(i.second.from()) << ")"; } } return s.str(); @@ -1321,11 +1346,11 @@ void Main::on_transactionQueue_currentItemChanged() auto ss = tx.safeSender(); h256 th = sha3(rlpList(ss, tx.nonce())); s << "

" << th << "

"; - s << "From: " << pretty(ss).toStdString() << " " << ss; + s << "From: " << pretty(ss) << " " << ss; if (tx.isCreation()) - s << "
Creates: " << pretty(right160(th)).toStdString() << " " << right160(th); + s << "
Creates: " << pretty(right160(th)) << " " << right160(th); else - s << "
To: " << pretty(tx.receiveAddress()).toStdString() << " " << tx.receiveAddress(); + s << "
To: " << pretty(tx.receiveAddress()) << " " << tx.receiveAddress(); s << "
Value: " << formatBalance(tx.value()) << ""; s << "   #" << tx.nonce() << ""; s << "
Gas price: " << formatBalance(tx.gasPrice()) << ""; @@ -1413,6 +1438,11 @@ void Main::on_injectBlock_triggered() } } +static string htmlEscaped(string const& _s) +{ + return QString::fromStdString(_s).toHtmlEscaped().toStdString(); +} + void Main::on_blocks_currentItemChanged() { ui->info->clear(); @@ -1442,7 +1472,7 @@ void Main::on_blocks_currentItemChanged() s << "
D/TD: " << info.difficulty << "/" << details.totalDifficulty << " = 2^" << log2((double)info.difficulty) << "/2^" << log2((double)details.totalDifficulty) << "
"; s << "   Children: " << details.children.size() << ""; s << "
Gas used/limit: " << info.gasUsed << "/" << info.gasLimit << "" << "
"; - s << "
Beneficiary: " << pretty(info.coinbaseAddress).toHtmlEscaped().toStdString() << " " << info.coinbaseAddress << "" << "
"; + s << "
Beneficiary: " << htmlEscaped(pretty(info.coinbaseAddress)) << " " << info.coinbaseAddress << "" << "
"; s << "
Seed hash: " << info.seedHash() << "" << "
"; s << "
Mix hash: " << info.mixHash << "" << "
"; s << "
Nonce: " << info.nonce << "" << "
"; @@ -1473,7 +1503,7 @@ void Main::on_blocks_currentItemChanged() s << line << "Hash: " << uncle.hash() << "" << ""; s << line << "Parent: " << uncle.parentHash << "" << ""; s << line << "Number: " << uncle.number << "" << ""; - s << line << "Coinbase: " << pretty(uncle.coinbaseAddress).toHtmlEscaped().toStdString() << " " << uncle.coinbaseAddress << "" << ""; + s << line << "Coinbase: " << htmlEscaped(pretty(uncle.coinbaseAddress)) << " " << uncle.coinbaseAddress << "" << ""; s << line << "Seed hash: " << uncle.seedHash() << "" << ""; s << line << "Mix hash: " << uncle.mixHash << "" << ""; s << line << "Nonce: " << uncle.nonce << "" << ""; @@ -1508,11 +1538,11 @@ void Main::on_blocks_currentItemChanged() TransactionReceipt receipt = ethereum()->blockChain().receipts(h).receipts[txi]; s << "

" << th << "

"; s << "

" << h << "[" << txi << "]

"; - s << "
From: " << pretty(ss).toHtmlEscaped().toStdString() << " " << ss << "" << "
"; + s << "
From: " << htmlEscaped(pretty(ss)) << " " << ss << "" << "
"; if (tx.isCreation()) - s << "
Creates: " << pretty(right160(th)).toHtmlEscaped().toStdString() << " " << right160(th) << "
"; + s << "
Creates: " << htmlEscaped(pretty(right160(th))) << " " << right160(th) << "
"; else - s << "
To: " << pretty(tx.receiveAddress()).toHtmlEscaped().toStdString() << " " << tx.receiveAddress() << "
"; + s << "
To: " << htmlEscaped(pretty(tx.receiveAddress())) << " " << tx.receiveAddress() << "
"; s << "
Value: " << formatBalance(tx.value()) << "" << "
"; s << "   #" << tx.nonce() << "" << ""; s << "
Gas price: " << formatBalance(tx.gasPrice()) << "" << "
"; @@ -1590,10 +1620,10 @@ void Main::debugDumpState(int _add) } } -void Main::on_contracts_currentItemChanged() +void Main::on_accounts_currentItemChanged() { - ui->contractInfo->clear(); - if (auto item = ui->contracts->currentItem()) + ui->accountInfo->clear(); + if (auto item = ui->accounts->currentItem()) { auto hba = item->data(Qt::UserRole).toByteArray(); assert(hba.size() == 20); @@ -1604,16 +1634,16 @@ void Main::on_contracts_currentItemChanged() { auto storage = ethereum()->storageAt(address); for (auto const& i: storage) - s << "@" << showbase << hex << prettyU256(i.first).toStdString() << "    " << showbase << hex << prettyU256(i.second).toStdString() << "
"; + s << "@" << showbase << hex << prettyU256(i.first) << "    " << showbase << hex << prettyU256(i.second) << "
"; s << "

Body Code (" << sha3(ethereum()->codeAt(address)).abridged() << ")

" << disassemble(ethereum()->codeAt(address)); s << Div(Mono) << toHex(ethereum()->codeAt(address)) << ""; - ui->contractInfo->appendHtml(QString::fromStdString(s.str())); + ui->accountInfo->appendHtml(QString::fromStdString(s.str())); } catch (dev::InvalidTrie) { - ui->contractInfo->appendHtml("Corrupted trie."); + ui->accountInfo->appendHtml("Corrupted trie."); } - ui->contractInfo->moveCursor(QTextCursor::Start); + ui->accountInfo->moveCursor(QTextCursor::Start); } } @@ -1645,16 +1675,6 @@ void Main::on_accounts_doubleClicked() } } -void Main::on_contracts_doubleClicked() -{ - if (ui->contracts->count()) - { - auto hba = ui->contracts->currentItem()->data(Qt::UserRole).toByteArray(); - auto h = Address((byte const*)hba.data(), Address::ConstructFromPointer); - qApp->clipboard()->setText(QString::fromStdString(toHex(h.asArray()))); - } -} - static shh::FullTopic topicFromText(QString _s) { shh::BuildTopic ret; @@ -1754,6 +1774,7 @@ void Main::on_net_triggered() ethereum()->setNetworkId(m_privateChain.size() ? sha3(m_privateChain.toStdString()) : h256()); web3()->startNetwork(); ui->downloadView->setDownloadMan(ethereum()->downloadMan()); + ui->enode->setText(QString::fromStdString(web3()->enode())); } else { @@ -1885,7 +1906,12 @@ void Main::on_killAccount_triggered() if (ui->ourAccounts->currentRow() >= 0 && ui->ourAccounts->currentRow() < m_myKeys.size()) { auto k = m_myKeys[ui->ourAccounts->currentRow()]; - if (ethereum()->balanceAt(k.address()) != 0 && QMessageBox::critical(this, "Kill Account?!", "Account " + render(k.address()) + " has " + QString::fromStdString(formatBalance(ethereum()->balanceAt(k.address()))) + " in it. It, and any contract that this account can access, will be lost forever if you continue. Do NOT continue unless you know what you are doing.\nAre you sure you want to continue?", QMessageBox::Yes, QMessageBox::No) == QMessageBox::No) + if ( + ethereum()->balanceAt(k.address()) != 0 && + QMessageBox::critical(this, "Kill Account?!", + QString::fromStdString("Account " + render(k.address()) + " has " + formatBalance(ethereum()->balanceAt(k.address())) + " in it. It, and any contract that this account can access, will be lost forever if you continue. Do NOT continue unless you know what you are doing.\n" + "Are you sure you want to continue?"), + QMessageBox::Yes, QMessageBox::No) == QMessageBox::No) return; m_myKeys.erase(m_myKeys.begin() + ui->ourAccounts->currentRow()); keysChanged(); @@ -1902,10 +1928,10 @@ void Main::on_go_triggered() web3()->addNode(p2p::NodeId(), Host::pocHost()); } -QString Main::prettyU256(dev::u256 _n) const +std::string Main::prettyU256(dev::u256 const& _n) const { unsigned inc = 0; - QString raw; + string raw; ostringstream s; if (_n > szabo && _n < 1000000 * ether) s << "" << formatBalance(_n) << " (0x" << hex << (uint64_t)_n << ")"; @@ -1916,17 +1942,17 @@ QString Main::prettyU256(dev::u256 _n) const else if ((_n >> 160) == 0) { Address a = right160(_n); - QString n = pretty(a); - if (n.isNull()) + string n = pretty(a); + if (n.empty()) s << "0x" << a << ""; else - s << "" << n.toHtmlEscaped().toStdString() << " (0x" << a.abridged() << ")"; + s << "" << htmlEscaped(n) << " (0x" << a.abridged() << ")"; } else if ((raw = fromRaw((h256)_n, &inc)).size()) - return "\"" + raw.toHtmlEscaped() + "\"" + (inc ? " + " + QString::number(inc) : "") + ""; + return "\"" + htmlEscaped(raw) + "\"" + (inc ? " + " + toString(inc) : "") + ""; else s << "0x" << (h256)_n << ""; - return QString::fromStdString(s.str()); + return s.str(); } void Main::on_post_clicked() diff --git a/alethzero/MainWin.h b/alethzero/MainWin.h index 2a0c1401d..127b174c6 100644 --- a/alethzero/MainWin.h +++ b/alethzero/MainWin.h @@ -80,10 +80,10 @@ public: bool confirm() const; NatSpecFace* natSpec() { return &m_natSpecDB; } - QString pretty(dev::Address _a) const override; - QString prettyU256(dev::u256 _n) const override; - QString render(dev::Address _a) const override; - std::pair fromString(QString const& _a) const override; + std::string pretty(dev::Address const& _a) const override; + std::string prettyU256(dev::u256 const& _n) const override; + std::string render(dev::Address const& _a) const override; + std::pair fromString(std::string const& _a) const override; std::string renderDiff(dev::eth::StateDiff const& _d) const override; QList owned() const { return m_myIdentities + m_myKeys; } @@ -131,6 +131,13 @@ private slots: void on_importKeyFile_triggered(); void on_exportKey_triggered(); + // Account pane + void on_accountsFilter_textChanged(); + void on_showBasic_toggled(); + void on_showContracts_toggled(); + void on_onlyNamed_toggled(); + void on_refreshAccounts_clicked(); + // Tools void on_newTransaction_triggered(); void on_loadJS_triggered(); @@ -140,8 +147,7 @@ private slots: void ourAccountsRowsMoved(); void on_ourAccounts_doubleClicked(); void on_accounts_doubleClicked(); - void on_contracts_doubleClicked(); - void on_contracts_currentItemChanged(); + void on_accounts_currentItemChanged(); void on_transactionQueue_currentItemChanged(); void on_blockChainFilter_textChanged(); void on_blocks_currentItemChanged(); @@ -254,7 +260,7 @@ private: std::unique_ptr m_httpConnector; std::unique_ptr m_server; - static QString fromRaw(dev::h256 _n, unsigned* _inc = nullptr); + static std::string fromRaw(dev::h256 _n, unsigned* _inc = nullptr); NatspecHandler m_natSpecDB; Transact m_transact; diff --git a/alethzero/OurWebThreeStubServer.cpp b/alethzero/OurWebThreeStubServer.cpp index da588ba3e..161bb4926 100644 --- a/alethzero/OurWebThreeStubServer.cpp +++ b/alethzero/OurWebThreeStubServer.cpp @@ -73,7 +73,7 @@ bool OurWebThreeStubServer::showCreationNotice(TransactionSkeleton const& _t, bo bool OurWebThreeStubServer::showSendNotice(TransactionSkeleton const& _t, bool _toProxy) { - return showAuthenticationPopup("Fund Transfer Transaction", "ÐApp is attempting to send " + formatBalance(_t.value) + " to a recipient " + m_main->pretty(_t.to).toStdString() + (_toProxy ? " (this transaction is not executed directly, but forwarded to another ÐApp)" : "") + + return showAuthenticationPopup("Fund Transfer Transaction", "ÐApp is attempting to send " + formatBalance(_t.value) + " to a recipient " + m_main->pretty(_t.to) + (_toProxy ? " (this transaction is not executed directly, but forwarded to another ÐApp)" : "") + ", with additional network fees of up to " + formatBalance(_t.gas * _t.gasPrice) + ".\n\nMaximum total cost is " + formatBalance(_t.value + _t.gas * _t.gasPrice) + "."); } @@ -81,7 +81,7 @@ bool OurWebThreeStubServer::showUnknownCallNotice(TransactionSkeleton const& _t, { return showAuthenticationPopup("DANGEROUS! Unknown Contract Transaction!", "ÐApp is attempting to call into an unknown contract at address " + - m_main->pretty(_t.to).toStdString() + ".\n\n" + + m_main->pretty(_t.to) + ".\n\n" + (_toProxy ? "This transaction is not executed directly, but forwarded to another ÐApp.\n\n" : "") + "Call involves sending " + formatBalance(_t.value) + " to the recipient, with additional network fees of up to " + @@ -137,7 +137,7 @@ bool OurWebThreeStubServer::validateTransaction(TransactionSkeleton const& _t, b // otherwise it's a transaction to a contract for which we have the natspec return showAuthenticationPopup("Contract Transaction", "ÐApp attempting to conduct contract interaction with " + - m_main->pretty(_t.to).toStdString() + + m_main->pretty(_t.to) + ": " + userNotice + ".\n\n" + (_toProxy ? "This transaction is not executed directly, but forwarded to another ÐApp.\n\n" : "") + (_t.value > 0 ? diff --git a/alethzero/Transact.cpp b/alethzero/Transact.cpp index 6f6e47d16..2041bf39d 100644 --- a/alethzero/Transact.cpp +++ b/alethzero/Transact.cpp @@ -110,12 +110,12 @@ void Transact::updateDestination() cwatch << "updateDestination()"; QString s; for (auto i: ethereum()->addresses()) - if ((s = m_context->pretty(i)).size()) + if ((s = QString::fromStdString(m_context->pretty(i))).size()) // A namereg address if (ui->destination->findText(s, Qt::MatchExactly | Qt::MatchCaseSensitive) == -1) ui->destination->addItem(s); for (int i = 0; i < ui->destination->count(); ++i) - if (ui->destination->itemText(i) != "(Create Contract)" && !m_context->fromString(ui->destination->itemText(i)).first) + if (ui->destination->itemText(i) != "(Create Contract)" && !m_context->fromString(ui->destination->itemText(i).toStdString()).first) ui->destination->removeItem(i--); } @@ -142,9 +142,9 @@ void Transact::on_destination_currentTextChanged(QString) { if (ui->destination->currentText().size() && ui->destination->currentText() != "(Create Contract)") { - auto p = m_context->fromString(ui->destination->currentText()); + auto p = m_context->fromString(ui->destination->currentText().toStdString()); if (p.first) - ui->calculatedName->setText(m_context->render(p.first)); + ui->calculatedName->setText(QString::fromStdString(m_context->render(p.first))); else ui->calculatedName->setText("Unknown Address"); if (!p.second.empty()) @@ -347,7 +347,7 @@ void Transact::rejigData() else { // TODO: cache like m_data. - to = m_context->fromString(ui->destination->currentText()).first; + to = m_context->fromString(ui->destination->currentText().toStdString()).first; er = ethereum()->call(s, value(), to, m_data, gasNeeded, gasPrice()); } gasNeeded = (qint64)(er.gasUsed + er.gasRefunded); @@ -434,7 +434,7 @@ void Transact::on_send_clicked() } else // TODO: cache like m_data. - ethereum()->submitTransaction(s, value(), m_context->fromString(ui->destination->currentText()).first, m_data, ui->gas->value(), gasPrice()); + ethereum()->submitTransaction(s, value(), m_context->fromString(ui->destination->currentText().toStdString()).first, m_data, ui->gas->value(), gasPrice()); close(); } @@ -453,7 +453,7 @@ void Transact::on_debug_clicked() State st(ethereum()->postState()); Transaction t = isCreation() ? Transaction(value(), gasPrice(), ui->gas->value(), m_data, st.transactionsFrom(dev::toAddress(s)), s) : - Transaction(value(), gasPrice(), ui->gas->value(), m_context->fromString(ui->destination->currentText()).first, m_data, st.transactionsFrom(dev::toAddress(s)), s); + Transaction(value(), gasPrice(), ui->gas->value(), m_context->fromString(ui->destination->currentText().toStdString()).first, m_data, st.transactionsFrom(dev::toAddress(s)), s); Debugger dw(m_context, this); Executive e(st, ethereum()->blockChain(), 0); dw.populate(e, t); diff --git a/cmake/EthCompilerSettings.cmake b/cmake/EthCompilerSettings.cmake index 416bb3095..9e9ae687e 100644 --- a/cmake/EthCompilerSettings.cmake +++ b/cmake/EthCompilerSettings.cmake @@ -9,14 +9,6 @@ if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU") set(CMAKE_CXX_FLAGS_RELEASE "-O3 -DNDEBUG -DETH_RELEASE") set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -g -DETH_RELEASE") - if (PROFILING) - set(CMAKE_CXX_FLAGS "-g ${CMAKE_CXX_FLAGS}") - add_definitions(-DETH_PROFILING_GPERF) - set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -lprofiler") -# set(CMAKE_STATIC_LINKER_FLAGS "${CMAKE_STATIC_LINKER_FLAGS} -lprofiler") - set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lprofiler") - endif () - execute_process( COMMAND ${CMAKE_CXX_COMPILER} -dumpversion OUTPUT_VARIABLE GCC_VERSION) if (NOT (GCC_VERSION VERSION_GREATER 4.7 OR GCC_VERSION VERSION_EQUAL 4.7)) @@ -61,6 +53,14 @@ else () message(WARNING "Your compiler is not tested, if you run into any issues, we'd welcome any patches.") endif () +if (PROFILING AND (("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU") OR ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang"))) + set(CMAKE_CXX_FLAGS "-g ${CMAKE_CXX_FLAGS}") + add_definitions(-DETH_PROFILING_GPERF) + set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -lprofiler") +# set(CMAKE_STATIC_LINKER_FLAGS "${CMAKE_STATIC_LINKER_FLAGS} -lprofiler") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lprofiler") +endif () + if (("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU") OR ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")) option(USE_LD_GOLD "Use GNU gold linker" ON) if (USE_LD_GOLD) diff --git a/eth/main.cpp b/eth/main.cpp index a5624b69b..4f23f32eb 100644 --- a/eth/main.cpp +++ b/eth/main.cpp @@ -420,6 +420,7 @@ void stopMiningAfterXBlocks(eth::Client* _c, unsigned _start, unsigned _mining) int main(int argc, char** argv) { +#if 0 cout << "\x1b[30mEthBlack\x1b[0m" << endl; cout << "\x1b[90mEthCoal\x1b[0m" << endl; cout << "\x1b[37mEthGray\x1b[0m" << endl; @@ -485,7 +486,7 @@ int main(int argc, char** argv) cout << "\x1b[4;35mEthPurpleU\x1b[0m" << endl; cout << "\x1b[4;36mEthCyanU\x1b[0m" << endl; cout << "\x1b[4;37mEthWhiteU\x1b[0m" << endl; - +#endif // Init defaults Defaults::get(); @@ -1071,6 +1072,7 @@ int main(int argc, char** argv) cout << "Transaction Signer: " << sigKey.address() << endl; cout << "Mining Benefactor: " << coinbase << endl; web3.startNetwork(); + cout << "Node ID: " << web3.enode() << endl; if (bootstrap) web3.addNode(p2p::NodeId(), Host::pocHost()); diff --git a/evmjit/libevmjit-cpp/Env.cpp b/evmjit/libevmjit-cpp/Env.cpp index b89aca726..2c37412fc 100644 --- a/evmjit/libevmjit-cpp/Env.cpp +++ b/evmjit/libevmjit-cpp/Env.cpp @@ -1,7 +1,7 @@ #pragma GCC diagnostic ignored "-Wconversion" #include -#include +#include #include #include "Utils.h" diff --git a/exp/main.cpp b/exp/main.cpp index 366c5b2ff..973679f3d 100644 --- a/exp/main.cpp +++ b/exp/main.cpp @@ -33,6 +33,7 @@ #endif #include #include +#include #include #include #include @@ -43,6 +44,7 @@ #include #include #include +#include #include #include #include @@ -58,8 +60,94 @@ using namespace dev::eth; using namespace dev::p2p; using namespace dev::shh; namespace js = json_spirit; +namespace fs = boost::filesystem; -#if 0 +#if 1 + +inline h128 fromUUID(std::string const& _uuid) { return h128(boost::replace_all_copy(_uuid, "-", "")); } + +class KeyManager: public Worker +{ +public: + KeyManager() { readKeys(); } + ~KeyManager() {} + + Secret secret(h128 const& _uuid, std::string const& _pass) + { + auto it = m_keys.find(_uuid); + if (it == m_keys.end()) + return Secret(); + return Secret(decrypt(it->second, _pass)); + } + +private: + void readKeys(std::string const& _keysPath = getDataDir("web3") + "/keys") + { + fs::path p(_keysPath); + js::mValue v; + for (fs::directory_iterator it(p); it != fs::directory_iterator(); ++it) + if (is_regular_file(it->path())) + { + cdebug << "Reading" << it->path(); + js::read_string(contentsString(it->path().string()), v); + js::mObject o = v.get_obj(); + int version = o.count("Version") ? stoi(o["Version"].get_str()) : o.count("version") ? o["version"].get_int() : 0; + if (version == 2) + m_keys[fromUUID(o["id"].get_str())] = o["crypto"]; + else + cwarn << "Cannot read key version" << version; + } + } + + static bytes decrypt(js::mValue const& _v, std::string const& _pass) + { + js::mObject o = _v.get_obj(); + bytes pKey; + if (o["kdf"].get_str() == "pbkdf2") + { + auto params = o["kdfparams"].get_obj(); + unsigned iterations = params["c"].get_int(); + bytes salt = fromHex(params["salt"].get_str()); + pKey = pbkdf2(_pass, salt, iterations).asBytes(); + } + else + { + cwarn << "Unknown KDF" << o["kdf"].get_str() << "not supported."; + return bytes(); + } + + // TODO check MAC + h256 mac(o["mac"].get_str()); + (void)mac; + + bytes cipherText = fromHex(o["ciphertext"].get_str()); + bytes ret; + if (o["cipher"].get_str() == "aes-128-cbc") + { + auto params = o["cipherparams"].get_obj(); + h128 key(sha3(h128(pKey, h128::AlignRight)), h128::AlignRight); + h128 iv(params["iv"].get_str()); + decryptSymNoAuth(key, iv, &cipherText, ret); + } + else + { + cwarn << "Unknown cipher" << o["cipher"].get_str() << "not supported."; + return bytes(); + } + + return ret; + } + + std::map m_keys; +}; + +int main() +{ + KeyManager keyman; + cdebug << "Secret key for 0498f19a-59db-4d54-ac95-33901b4f1870 is " << keyman.secret(fromUUID("0498f19a-59db-4d54-ac95-33901b4f1870"), "foo"); +} + +#elif 0 int main() { DownloadMan man; diff --git a/libdevcore/Common.cpp b/libdevcore/Common.cpp index 3defa57b2..72b5543a8 100644 --- a/libdevcore/Common.cpp +++ b/libdevcore/Common.cpp @@ -21,6 +21,7 @@ #include "Common.h" #include "Exceptions.h" +#include "Log.h" using namespace std; using namespace dev; @@ -35,5 +36,10 @@ void HasInvariants::checkInvariants() const BOOST_THROW_EXCEPTION(FailedInvariant()); } +TimerHelper::~TimerHelper() +{ + cdebug << "Timer" << id << t.elapsed() << "s"; +} + } diff --git a/libdevcore/Common.h b/libdevcore/Common.h index 03da4c8aa..e5d746372 100644 --- a/libdevcore/Common.h +++ b/libdevcore/Common.h @@ -37,6 +37,7 @@ #include #include #include +#include #pragma warning(push) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-parameter" @@ -168,6 +169,25 @@ private: #define DEV_INVARIANT_CHECK (void)0; #endif +class TimerHelper +{ +public: + TimerHelper(char const* _id): id(_id) {} + ~TimerHelper(); + +private: + boost::timer t; + char const* id; +}; + +#define DEV_TIMED(S) for (::std::pair<::dev::TimerHelper, bool> __eth_t(#S, true); __eth_t.second; __eth_t.second = false) +#define DEV_TIMED_SCOPE(S) ::dev::TimerHelper __eth_t(S) +#if WIN32 +#define DEV_TIMED_FUNCTION DEV_TIMED_SCOPE(__FUNCSIG__) +#else +#define DEV_TIMED_FUNCTION DEV_TIMED_SCOPE(__PRETTY_FUNCTION__) +#endif + enum class WithExisting: int { Trust = 0, diff --git a/libdevcore/FixedHash.h b/libdevcore/FixedHash.h index 456365299..2cf81cb77 100644 --- a/libdevcore/FixedHash.h +++ b/libdevcore/FixedHash.h @@ -64,6 +64,9 @@ public: /// Convert from the corresponding arithmetic type. FixedHash(Arith const& _arith) { toBigEndian(_arith, m_data); } + /// Convert from unsigned + explicit FixedHash(unsigned _u) { toBigEndian(_u, m_data); } + /// Explicitly construct, copying from a byte array. explicit FixedHash(bytes const& _b, ConstructFromHashType _t = FailIfDifferent) { if (_b.size() == N) memcpy(m_data.data(), _b.data(), std::min(_b.size(), N)); else { m_data.fill(0); if (_t != FailIfDifferent) { auto c = std::min(_b.size(), N); for (unsigned i = 0; i < c; ++i) m_data[_t == AlignRight ? N - 1 - i : i] = _b[_t == AlignRight ? _b.size() - 1 - i : i]; } } } @@ -80,7 +83,7 @@ public: operator Arith() const { return fromBigEndian(m_data); } /// @returns true iff this is the empty hash. - explicit operator bool() const { return ((Arith)*this) != 0; } + explicit operator bool() const { return std::any_of(m_data.begin(), m_data.end(), [](byte _b) { return _b != 0; }); } // The obvious comparison operators. bool operator==(FixedHash const& _c) const { return m_data == _c.m_data; } diff --git a/libdevcore/Guards.h b/libdevcore/Guards.h index 4229428ce..d060108ef 100644 --- a/libdevcore/Guards.h +++ b/libdevcore/Guards.h @@ -22,6 +22,7 @@ #pragma once #include +#include #include namespace dev @@ -61,6 +62,18 @@ struct GenericUnguardSharedBool MutexType& m; }; +/** @brief Simple lock that waits for release without making context switch */ +class SpinLock +{ +public: + SpinLock() { m_lock.clear(); } + void lock() { while (m_lock.test_and_set(std::memory_order_acquire)) {} } + void unlock() { m_lock.clear(std::memory_order_release); } +private: + std::atomic_flag m_lock; +}; +using SpinGuard = std::lock_guard; + /** @brief Simple block guard. * The expression/block following is guarded though the given mutex. * Usage: diff --git a/libdevcore/Log.cpp b/libdevcore/Log.cpp index e086278ec..3dd2b3879 100644 --- a/libdevcore/Log.cpp +++ b/libdevcore/Log.cpp @@ -158,8 +158,8 @@ void dev::setThreadName(string const& _n) void dev::simpleDebugOut(std::string const& _s, char const*) { - static Mutex s_lock; - Guard l(s_lock); + static SpinLock s_lock; + SpinGuard l(s_lock); cerr << _s << endl << flush; diff --git a/libdevcrypto/Common.cpp b/libdevcrypto/Common.cpp index ec6a9121b..48dd5c384 100644 --- a/libdevcrypto/Common.cpp +++ b/libdevcrypto/Common.cpp @@ -112,13 +112,13 @@ bool dev::decryptSym(Secret const& _k, bytesConstRef _cipher, bytes& o_plain) return decrypt(_k, _cipher, o_plain); } -h128 dev::encryptSymNoAuth(Secret const& _k, bytesConstRef _plain, bytes& o_cipher) +h128 dev::encryptSymNoAuth(h128 const& _k, bytesConstRef _plain, bytes& o_cipher) { h128 iv(Nonce::get()); return encryptSymNoAuth(_k, _plain, o_cipher, iv); } -h128 dev::encryptSymNoAuth(Secret const& _k, bytesConstRef _plain, bytes& o_cipher, h128 const& _iv) +h128 dev::encryptSymNoAuth(h128 const& _k, bytesConstRef _plain, bytes& o_cipher, h128 const& _iv) { o_cipher.resize(_plain.size()); @@ -139,7 +139,7 @@ h128 dev::encryptSymNoAuth(Secret const& _k, bytesConstRef _plain, bytes& o_ciph } } -bool dev::decryptSymNoAuth(Secret const& _k, h128 const& _iv, bytesConstRef _cipher, bytes& o_plaintext) +bool dev::decryptSymNoAuth(h128 const& _k, h128 const& _iv, bytesConstRef _cipher, bytes& o_plaintext) { o_plaintext.resize(_cipher.size()); @@ -175,6 +175,14 @@ bool dev::verify(Public const& _p, Signature const& _s, h256 const& _hash) return s_secp256k1.verify(_p, _s, _hash.ref(), true); } +h256 dev::pbkdf2(string const& _pass, bytes const& _salt, unsigned _iterations) +{ + h256 ret; + PKCS5_PBKDF2_HMAC pbkdf; + pbkdf.DeriveKey(ret.data(), ret.size, 0, (byte*)_pass.data(), _pass.size(), _salt.data(), _salt.size(), _iterations); + return ret; +} + KeyPair KeyPair::create() { static boost::thread_specific_ptr s_eng; diff --git a/libdevcrypto/Common.h b/libdevcrypto/Common.h index 3159f4e7e..50072c1bf 100644 --- a/libdevcrypto/Common.h +++ b/libdevcrypto/Common.h @@ -103,13 +103,13 @@ void encryptECIES(Public const& _k, bytesConstRef _plain, bytes& o_cipher); bool decryptECIES(Secret const& _k, bytesConstRef _cipher, bytes& o_plaintext); /// Encrypts payload with random IV/ctr using AES128-CTR. -h128 encryptSymNoAuth(Secret const& _k, bytesConstRef _plain, bytes& o_cipher); +h128 encryptSymNoAuth(h128 const& _k, bytesConstRef _plain, bytes& o_cipher); /// Encrypts payload with specified IV/ctr using AES128-CTR. -h128 encryptSymNoAuth(Secret const& _k, bytesConstRef _plain, bytes& o_cipher, h128 const& _iv); +h128 encryptSymNoAuth(h128 const& _k, bytesConstRef _plain, bytes& o_cipher, h128 const& _iv); -/// Decrypts payload with specified IV/ctr. -bool decryptSymNoAuth(Secret const& _k, h128 const& _iv, bytesConstRef _cipher, bytes& o_plaintext); +/// Decrypts payload with specified IV/ctr using AES128-CTR. +bool decryptSymNoAuth(h128 const& _k, h128 const& _iv, bytesConstRef _cipher, bytes& o_plaintext); /// Recovers Public key from signed message hash. Public recover(Signature const& _sig, h256 const& _hash); @@ -120,6 +120,9 @@ Signature sign(Secret const& _k, h256 const& _hash); /// Verify signature. bool verify(Public const& _k, Signature const& _s, h256 const& _hash); +/// Derive key via PBKDF2. +h256 pbkdf2(std::string const& _pass, bytes const& _salt, unsigned _iterations); + /// Simple class that represents a "key pair". /// All of the data of the class can be regenerated from the secret key (m_secret) alone. /// Actually stores a tuplet of secret, public and address (the right 160-bits of the public). @@ -164,7 +167,7 @@ struct InvalidState: public dev::Exception {}; /// Key derivation h256 kdf(Secret const& _priv, h256 const& _hash); - + /** * @brief Generator for nonce material */ diff --git a/libdevcrypto/CryptoPP.cpp b/libdevcrypto/CryptoPP.cpp index ff22b9b45..e89857502 100644 --- a/libdevcrypto/CryptoPP.cpp +++ b/libdevcrypto/CryptoPP.cpp @@ -79,7 +79,7 @@ void Secp256k1::encryptECIES(Public const& _k, bytes& io_cipher) ctx.Final(mKey.data()); bytes cipherText; - encryptSymNoAuth(*(Secret*)eKey.data(), bytesConstRef(&io_cipher), cipherText, h128()); + encryptSymNoAuth(h128(eKey), bytesConstRef(&io_cipher), cipherText, h128()); if (cipherText.empty()) return; @@ -139,7 +139,7 @@ bool Secp256k1::decryptECIES(Secret const& _k, bytes& io_text) if (mac[i] != msgMac[i]) return false; - decryptSymNoAuth(*(Secret*)eKey.data(), iv, cipherNoIV, plain); + decryptSymNoAuth(h128(eKey), iv, cipherNoIV, plain); io_text.resize(plain.size()); io_text.swap(plain); diff --git a/libethash-cl/ethash_cl_miner.cpp b/libethash-cl/ethash_cl_miner.cpp index 111f92529..42098e09d 100644 --- a/libethash-cl/ethash_cl_miner.cpp +++ b/libethash-cl/ethash_cl_miner.cpp @@ -88,6 +88,13 @@ std::string ethash_cl_miner::platform_info(unsigned _platformId, unsigned _devic return "{ \"platform\": \"" + platforms[platform_num].getInfo() + "\", \"device\": \"" + device.getInfo() + "\", \"version\": \"" + device_version + "\" }"; } +unsigned ethash_cl_miner::get_num_platforms() +{ + std::vector platforms; + cl::Platform::get(&platforms); + return platforms.size(); +} + unsigned ethash_cl_miner::get_num_devices(unsigned _platformId) { std::vector platforms; @@ -117,14 +124,11 @@ void ethash_cl_miner::finish() } } -bool ethash_cl_miner::init(ethash_params const& params, std::function _fillDAG, unsigned workgroup_size, unsigned _platformId, unsigned _deviceId) +bool ethash_cl_miner::init(uint8_t const* _dag, uint64_t _dagSize, unsigned workgroup_size, unsigned _platformId, unsigned _deviceId) { - // store params - m_params = params; - // get all platforms - std::vector platforms; - cl::Platform::get(&platforms); + std::vector platforms; + cl::Platform::get(&platforms); if (platforms.empty()) { cout << "No OpenCL platforms found." << endl; @@ -137,10 +141,10 @@ bool ethash_cl_miner::init(ethash_params const& params, std::function().c_str() << endl; - // get GPU device of the default platform - std::vector devices; + // get GPU device of the default platform + std::vector devices; platforms[_platformId].getDevices(CL_DEVICE_TYPE_ALL, &devices); - if (devices.empty()) + if (devices.empty()) { cout << "No OpenCL devices found." << endl; return false; @@ -171,7 +175,7 @@ bool ethash_cl_miner::init(ethash_params const& params, std::function _fillDAG, unsigned workgroup_size = 64, unsigned _platformId = 0, unsigned _deviceId = 0); - static std::string platform_info(unsigned _platformId = 0, unsigned _deviceId = 0); + static unsigned get_num_platforms(); static unsigned get_num_devices(unsigned _platformId = 0); + static std::string platform_info(unsigned _platformId = 0, unsigned _deviceId = 0); - + bool init(uint8_t const* _dag, uint64_t _dagSize, unsigned workgroup_size = 64, unsigned _platformId = 0, unsigned _deviceId = 0); void finish(); void hash(uint8_t* ret, uint8_t const* header, uint64_t nonce, unsigned count); void search(uint8_t const* header, uint64_t target, search_hook& hook); @@ -43,7 +43,6 @@ public: private: enum { c_max_search_results = 63, c_num_buffers = 2, c_hash_batch_size = 1024, c_search_batch_size = 1024*256 }; - ethash_params m_params; cl::Context m_context; cl::CommandQueue m_queue; cl::Kernel m_hash_kernel; diff --git a/libethcore/BlockInfo.cpp b/libethcore/BlockInfo.cpp index e9ce070dc..24fc1cb65 100644 --- a/libethcore/BlockInfo.cpp +++ b/libethcore/BlockInfo.cpp @@ -23,10 +23,10 @@ #include #include #include +#include #include "EthashAux.h" #include "ProofOfWork.h" #include "Exceptions.h" -#include "Params.h" #include "BlockInfo.h" using namespace std; using namespace dev; diff --git a/libethcore/CMakeLists.txt b/libethcore/CMakeLists.txt index 1adb8428e..4dd626642 100644 --- a/libethcore/CMakeLists.txt +++ b/libethcore/CMakeLists.txt @@ -28,7 +28,7 @@ add_library(${EXECUTABLE} ${SRC_LIST} ${HEADERS}) target_link_libraries(${EXECUTABLE} ethash) target_link_libraries(${EXECUTABLE} devcrypto) -target_link_libraries(${EXECUTABLE} devcore) +target_link_libraries(${EXECUTABLE} evmcore) if (ETHASHCL) target_link_libraries(${EXECUTABLE} ethash-cl) diff --git a/libethcore/Ethash.cpp b/libethcore/Ethash.cpp index e932fced4..011f0b9e0 100644 --- a/libethcore/Ethash.cpp +++ b/libethcore/Ethash.cpp @@ -309,10 +309,10 @@ void Ethash::GPUMiner::workLoop() delete m_miner; m_miner = new ethash_cl_miner; - auto p = EthashAux::params(m_minerSeed); - auto cb = [&](void* d) { EthashAux::full(m_minerSeed, bytesRef((byte*)d, p.full_size)); }; unsigned device = instances() > 1 ? index() : s_deviceId; - m_miner->init(p, cb, 32, s_platformId, device); + + EthashAux::FullType dag = EthashAux::full(m_minerSeed); + m_miner->init(dag->data.data(), dag->data.size(), 32, s_platformId, device); } uint64_t upper64OfBoundary = (uint64_t)(u64)((u256)w.boundary >> 192); diff --git a/libethcore/EthashAux.cpp b/libethcore/EthashAux.cpp index 9cb4d9fad..0b9af98ac 100644 --- a/libethcore/EthashAux.cpp +++ b/libethcore/EthashAux.cpp @@ -33,7 +33,6 @@ #include #include #include -#include #include "BlockInfo.h" using namespace std; using namespace chrono; @@ -87,13 +86,10 @@ ethash_params EthashAux::params(h256 const& _seedHash) { Guard l(get()->x_epochs); unsigned epoch = 0; - try + auto epochIter = get()->m_epochs.find(_seedHash); + if (epochIter == get()->m_epochs.end()) { - epoch = get()->m_epochs.at(_seedHash); - } - catch (...) - { -// cdebug << "Searching for seedHash " << _seedHash; + // cdebug << "Searching for seedHash " << _seedHash; for (h256 h; h != _seedHash && epoch < 2048; ++epoch, h = sha3(h), get()->m_epochs[h] = epoch) {} if (epoch == 2048) { @@ -102,6 +98,8 @@ ethash_params EthashAux::params(h256 const& _seedHash) throw std::invalid_argument(error.str()); } } + else + epoch = epochIter->second; return params(epoch * ETHASH_EPOCH_LENGTH); } @@ -135,7 +133,6 @@ EthashAux::LightAllocation::~LightAllocation() ethash_delete_light(light); } - EthashAux::FullType EthashAux::full(BlockInfo const& _header, bytesRef _dest, bool _createIfMissing) { return full(_header.seedHash(), _dest, _createIfMissing); diff --git a/libethcore/ICAP.h b/libethcore/ICAP.h index 07e863d8d..b4229e1f5 100644 --- a/libethcore/ICAP.h +++ b/libethcore/ICAP.h @@ -51,8 +51,6 @@ public: ICAP() = default; /// Construct a direct ICAP object for given target address. Must have a zero first byte. ICAP(Address const& _target): m_type(Direct), m_direct(_target) {} - /// Construct an indirect ICAP object for given target name. - ICAP(std::string const& _target): m_type(Indirect), m_client(boost::algorithm::to_upper_copy(_target)), m_asset("ETH") {} /// Construct an indirect ICAP object for given client and institution names. ICAP(std::string const& _client, std::string const& _inst): m_type(Indirect), m_client(boost::algorithm::to_upper_copy(_client)), m_institution(boost::algorithm::to_upper_copy(_inst)), m_asset("XET") {} /// Construct an indirect ICAP object for given client, institution and asset names. You generally don't want to use this. diff --git a/libethcore/Params.cpp b/libethcore/Params.cpp index 655c8a78b..a6107e62b 100644 --- a/libethcore/Params.cpp +++ b/libethcore/Params.cpp @@ -14,7 +14,7 @@ You should have received a copy of the GNU General Public License along with cpp-ethereum. If not, see . */ -/** @file FeeStructure.cpp +/** @file Params.cpp * @author Gav Wood * @date 2014 */ @@ -36,40 +36,6 @@ u256 const c_gasLimitBoundDivisor = 1024; u256 const c_minimumDifficulty = 131072; u256 const c_difficultyBoundDivisor = 2048; u256 const c_durationLimit = 8; -u256 const c_stackLimit = 1024; -u256 const c_tierStepGas[] = {0, 2, 3, 5, 8, 10, 20, 0}; -u256 const c_expGas = 10; -u256 const c_expByteGas = 10; -u256 const c_sha3Gas = 30; -u256 const c_sha3WordGas = 6; -u256 const c_sloadGas = 50; -u256 const c_sstoreSetGas = 20000; -u256 const c_sstoreResetGas = 5000; -u256 const c_sstoreRefundGas = 15000; -u256 const c_jumpdestGas = 1; -u256 const c_logGas = 375; -u256 const c_logDataGas = 8; -u256 const c_logTopicGas = 375; -u256 const c_createGas = 32000; -u256 const c_callGas = 40; -u256 const c_callStipend = 2300; -u256 const c_callValueTransferGas = 9000; -u256 const c_callNewAccountGas = 25000; -u256 const c_suicideRefundGas = 24000; -u256 const c_memoryGas = 3; -u256 const c_quadCoeffDiv = 512; -u256 const c_createDataGas = 200; -u256 const c_txGas = 21000; -u256 const c_txDataZeroGas = 4; -u256 const c_txDataNonZeroGas = 68; -u256 const c_copyGas = 3; -u256 const c_ecrecoverGas = 3000; -u256 const c_sha256Gas = 60; -u256 const c_sha256WordGas = 12; -u256 const c_ripemd160Gas = 600; -u256 const c_ripemd160WordGas = 120; -u256 const c_identityGas = 15; -u256 const c_identityWordGas = 3; //--- END: AUTOGENERATED FROM /feeStructure.json } diff --git a/libethcore/Params.h b/libethcore/Params.h index b957f9737..3520b2f1b 100644 --- a/libethcore/Params.h +++ b/libethcore/Params.h @@ -14,7 +14,7 @@ You should have received a copy of the GNU General Public License along with cpp-ethereum. If not, see . */ -/** @file FeeStructure.h +/** @file Params.h * @author Gav Wood * @date 2014 */ @@ -37,41 +37,6 @@ extern u256 const c_minimumDifficulty; extern u256 const c_difficultyBoundDivisor; extern u256 const c_durationLimit; extern u256 const c_maximumExtraDataSize; -extern u256 const c_stackLimit; - -extern u256 const c_tierStepGas[8]; ///< Once per operation, for a selection of them. -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_sha3Gas; ///< Once per SHA3 operation. -extern u256 const c_sha3WordGas; ///< Once per word of the SHA3 operation's data. -extern u256 const c_copyGas; ///< Multiplied by the number of 32-byte words that are copied (round up) for any *COPY operation and added. -extern u256 const c_sloadGas; ///< Once per SLOAD operation. -extern u256 const c_sstoreSetGas; ///< Once per SSTORE operation if the zeroness changes from zero. -extern u256 const c_sstoreResetGas; ///< Once per SSTORE operation if the zeroness does not change from zero. NOTE: when c_sstoreSetGas does not apply. -extern u256 const c_sstoreRefundGas; ///< Refunded gas, once per SSTORE operation if the zeroness changes to zero. -extern u256 const c_jumpdestGas; ///< Once per JUMPDEST 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_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_createGas; ///< Once per CREATE operation & contract-creation transaction. -extern u256 const c_createDataGas; -extern u256 const c_callGas; ///< Once per CALL operation & message call transaction. -extern u256 const c_callStipend; ///< Free gas given at beginning of call. -extern u256 const c_callNewAccountGas; ///< Paid for CALL when the destination address didn't exist prior. -extern u256 const c_callValueTransferGas; ///< Paid for CALL when the value transfor is non-zero. -extern u256 const c_suicideRefundGas; ///< Refunded following a suicide operation. -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_quadCoeffDiv; ///< Divisor for the quadratic particle of the memory cost equation. -extern u256 const c_txGas; ///< Per 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_ecrecoverGas; -extern u256 const c_sha256Gas; -extern u256 const c_sha256WordGas; -extern u256 const c_ripemd160Gas; -extern u256 const c_ripemd160WordGas; -extern u256 const c_identityGas; -extern u256 const c_identityWordGas; } } diff --git a/libethereum/BlockChain.cpp b/libethereum/BlockChain.cpp index 69078b400..c7c8a23ac 100644 --- a/libethereum/BlockChain.cpp +++ b/libethereum/BlockChain.cpp @@ -37,6 +37,7 @@ #include #include #include +#include #include #include "GenesisInfo.h" #include "State.h" @@ -47,7 +48,7 @@ using namespace dev::eth; namespace js = json_spirit; #define ETH_CATCH 1 -#define ETH_TIMED_IMPORTS 1 +#define ETH_TIMED_IMPORTS 0 #ifdef _WIN32 const char* BlockChainDebug::name() { return EthBlue "8" EthWhite " <>"; } @@ -473,7 +474,7 @@ ImportRoute BlockChain::import(bytes const& _block, OverlayDB const& _db, Import t.restart(); #endif -#if ETH_PARANOIA +#if ETH_PARANOIA || !ETH_TRUE checkConsistency(); #endif @@ -488,7 +489,7 @@ ImportRoute BlockChain::import(bytes const& _block, OverlayDB const& _db, Import ETH_WRITE_GUARDED(x_details) m_details[bi.parentHash].children.push_back(bi.hash()); -#if ETH_TIMED_IMPORTS +#if ETH_TIMED_IMPORTS || !ETH_TRUE collation = t.elapsed(); t.restart(); #endif @@ -496,18 +497,15 @@ ImportRoute BlockChain::import(bytes const& _block, OverlayDB const& _db, Import blocksBatch.Put(toSlice(bi.hash()), (ldb::Slice)ref(_block)); ETH_READ_GUARDED(x_details) extrasBatch.Put(toSlice(bi.parentHash, ExtraDetails), (ldb::Slice)dev::ref(m_details[bi.parentHash].rlp())); + extrasBatch.Put(toSlice(bi.hash(), ExtraDetails), (ldb::Slice)dev::ref(BlockDetails((unsigned)pd.number + 1, td, bi.parentHash, {}).rlp())); extrasBatch.Put(toSlice(bi.hash(), ExtraLogBlooms), (ldb::Slice)dev::ref(blb.rlp())); extrasBatch.Put(toSlice(bi.hash(), ExtraReceipts), (ldb::Slice)dev::ref(br.rlp())); -#if ETH_TIMED_IMPORTS +#if ETH_TIMED_IMPORTS || !ETH_TRUE writing = t.elapsed(); t.restart(); #endif - -#if ETH_PARANOIA - checkConsistency(); -#endif } #if ETH_CATCH catch (InvalidNonce const& _e) @@ -609,7 +607,6 @@ ImportRoute BlockChain::import(bytes const& _block, OverlayDB const& _db, Import } clog(BlockChainNote) << " Imported and best" << td << " (#" << bi.number << "). Has" << (details(bi.parentHash).children.size() - 1) << "siblings. Route:" << route; - noteCanonChanged(); StructuredLogger::chainNewHead( bi.headerHash(WithoutNonce).abridged(), @@ -632,6 +629,10 @@ ImportRoute BlockChain::import(bytes const& _block, OverlayDB const& _db, Import m_lastBlockNumber = newLastBlockNumber; } +#if ETH_PARANOIA || !ETH_TRUE + checkConsistency(); +#endif + #if ETH_TIMED_IMPORTS checkBest = t.elapsed(); cnote << "Import took:" << total.elapsed(); @@ -642,6 +643,9 @@ ImportRoute BlockChain::import(bytes const& _block, OverlayDB const& _db, Import cnote << "checkBest:" << checkBest; #endif + if (!route.empty()) + noteCanonChanged(); + if (isKnown(bi.hash()) && !details(bi.hash())) { clog(BlockChainDebug) << "Known block just inserted has no details."; @@ -767,7 +771,7 @@ void BlockChain::noteUsed(h256 const& _h, unsigned _extra) const m_inUse.insert(id); } -template static unsigned getHashSize(map const& _map) +template static unsigned getHashSize(unordered_map const& _map) { unsigned ret = 0; for (auto const& i: _map) @@ -855,7 +859,7 @@ void BlockChain::garbageCollect(bool _force) } } m_cacheUsage.pop_back(); - m_cacheUsage.push_front(std::set{}); + m_cacheUsage.push_front(std::unordered_set{}); } void BlockChain::checkConsistency() diff --git a/libethereum/BlockChain.h b/libethereum/BlockChain.h index d04bff298..12e1fc785 100644 --- a/libethereum/BlockChain.h +++ b/libethereum/BlockChain.h @@ -28,6 +28,8 @@ #include #include +#include +#include #include #include #include @@ -40,6 +42,14 @@ #include "BlockQueue.h" namespace ldb = leveldb; +namespace std +{ +template <> struct hash> +{ + size_t operator()(pair const& _x) const { return hash()(_x.first) ^ hash()(_x.second); } +}; +} + namespace dev { @@ -66,7 +76,7 @@ std::map const& genesisState(); ldb::Slice toSlice(h256 const& _h, unsigned _sub = 0); -using BlocksHash = std::map; +using BlocksHash = std::unordered_map; using TransactionHashes = h256s; using UncleHashes = h256s; using ImportRoute = std::pair; @@ -144,7 +154,7 @@ public: UncleHashes uncleHashes() const { return uncleHashes(currentHash()); } /// Get the hash for a given block's number. - h256 numberHash(unsigned _i) const { if (!_i) return genesisHash(); return queryExtras(h256(u256(_i)), m_blockHashes, x_blockHashes, NullBlockHash).value; } + h256 numberHash(unsigned _i) const { if (!_i) return genesisHash(); return queryExtras(h256(_i), m_blockHashes, x_blockHashes, NullBlockHash).value; } /// Get the last N hashes for a given block. (N is determined by the LastHashes type.) LastHashes lastHashes() const { return lastHashes(number()); } @@ -251,7 +261,7 @@ private: void open(std::string const& _path, WithExisting _we = WithExisting::Trust); void close(); - template T queryExtras(h256 const& _h, std::map& _m, boost::shared_mutex& _x, T const& _n, ldb::DB* _extrasDB = nullptr) const + template T queryExtras(h256 const& _h, std::unordered_map& _m, boost::shared_mutex& _x, T const& _n, ldb::DB* _extrasDB = nullptr) const { { ReadGuard l(_x); @@ -295,8 +305,8 @@ private: using CacheID = std::pair; mutable Mutex x_cacheUsage; - mutable std::deque> m_cacheUsage; - mutable std::set m_inUse; + mutable std::deque> m_cacheUsage; + mutable std::unordered_set m_inUse; void noteUsed(h256 const& _h, unsigned _extra = (unsigned)-1) const; std::chrono::system_clock::time_point m_lastCollection; diff --git a/libethereum/BlockDetails.h b/libethereum/BlockDetails.h index 0baacb4da..19e2c7c7a 100644 --- a/libethereum/BlockDetails.h +++ b/libethereum/BlockDetails.h @@ -21,6 +21,7 @@ #pragma once +#include #pragma warning(push) #pragma warning(disable: 4100 4267) #include @@ -114,12 +115,12 @@ struct TransactionAddress static const unsigned size = 67; }; -using BlockDetailsHash = std::map; -using BlockLogBloomsHash = std::map; -using BlockReceiptsHash = std::map; -using TransactionAddressHash = std::map; -using BlockHashHash = std::map; -using BlocksBloomsHash = std::map; +using BlockDetailsHash = std::unordered_map; +using BlockLogBloomsHash = std::unordered_map; +using BlockReceiptsHash = std::unordered_map; +using TransactionAddressHash = std::unordered_map; +using BlockHashHash = std::unordered_map; +using BlocksBloomsHash = std::unordered_map; static const BlockDetails NullBlockDetails; static const BlockLogBlooms NullBlockLogBlooms; diff --git a/libethereum/CanonBlockChain.cpp b/libethereum/CanonBlockChain.cpp index b5c47b653..2cc1d24dc 100644 --- a/libethereum/CanonBlockChain.cpp +++ b/libethereum/CanonBlockChain.cpp @@ -29,6 +29,7 @@ #include #include #include +#include #include #include "GenesisInfo.h" #include "State.h" diff --git a/libethereum/Client.cpp b/libethereum/Client.cpp index e8ab0ff2f..394b0007e 100644 --- a/libethereum/Client.cpp +++ b/libethereum/Client.cpp @@ -36,12 +36,6 @@ using namespace dev; using namespace dev::eth; using namespace p2p; -namespace dev -{ -struct TimerHelper { TimerHelper(char const* _id): id(_id) {} ~TimerHelper() { cdebug << "Timer" << id << t.elapsed() << "s"; } boost::timer t; char const* id; }; -#define DEV_TIMED(S) for (::std::pair<::dev::TimerHelper, bool> __eth_t(#S, true); __eth_t.second; __eth_t.second = false) -} - VersionChecker::VersionChecker(string const& _dbPath): m_path(_dbPath.size() ? _dbPath : Defaults::dbPath()) { @@ -586,7 +580,9 @@ void Client::onChainChanged(ImportRoute const& _ir) for (auto const& t: m_postMine.pending()) { clog(ClientNote) << "Resubmitting post-mine transaction " << t; - m_tq.import(t, TransactionQueue::ImportCallback(), IfDropped::Retry); + auto ir = m_tq.import(t, TransactionQueue::ImportCallback(), IfDropped::Retry); + if (ir != ImportResult::Success) + onTransactionQueueReady(); } ETH_READ_GUARDED(x_working) DEV_TIMED(post) ETH_WRITE_GUARDED(x_postMine) m_postMine = m_working; @@ -596,6 +592,10 @@ void Client::onChainChanged(ImportRoute const& _ir) onPostStateChanged(); } + // Quick hack for now - the TQ at this point already has the prior pending transactions in it; + // we should resync with it manually until we are stricter about what constitutes "knowing". + onTransactionQueueReady(); + noteChanged(changeds); } diff --git a/libethereum/ClientBase.cpp b/libethereum/ClientBase.cpp index eba8dbc67..136239cf3 100644 --- a/libethereum/ClientBase.cpp +++ b/libethereum/ClientBase.cpp @@ -142,6 +142,11 @@ bytes ClientBase::codeAt(Address _a, BlockNumber _block) const return asOf(_block).code(_a); } +h256 ClientBase::codeHashAt(Address _a, BlockNumber _block) const +{ + return asOf(_block).codeHash(_a); +} + map ClientBase::storageAt(Address _a, BlockNumber _block) const { return asOf(_block).storage(_a); diff --git a/libethereum/ClientBase.h b/libethereum/ClientBase.h index 64dc2b6c7..fc0b301ad 100644 --- a/libethereum/ClientBase.h +++ b/libethereum/ClientBase.h @@ -92,12 +92,14 @@ public: using Interface::countAt; using Interface::stateAt; using Interface::codeAt; + using Interface::codeHashAt; using Interface::storageAt; virtual u256 balanceAt(Address _a, BlockNumber _block) const override; virtual u256 countAt(Address _a, BlockNumber _block) const override; virtual u256 stateAt(Address _a, u256 _l, BlockNumber _block) const override; virtual bytes codeAt(Address _a, BlockNumber _block) const override; + virtual h256 codeHashAt(Address _a, BlockNumber _block) const override; virtual std::map storageAt(Address _a, BlockNumber _block) const override; virtual LocalisedLogEntries logs(unsigned _watchId) const override; diff --git a/libethereum/CommonNet.h b/libethereum/CommonNet.h index 2083e9919..0b1469f19 100644 --- a/libethereum/CommonNet.h +++ b/libethereum/CommonNet.h @@ -56,7 +56,7 @@ class EthereumPeer; enum { StatusPacket = 0, - GetTransactionsPacket, + NewBlockHashesPacket, TransactionsPacket, GetBlockHashesPacket, BlockHashesPacket, diff --git a/libethereum/DownloadMan.cpp b/libethereum/DownloadMan.cpp index be33f5187..1b73dca5b 100644 --- a/libethereum/DownloadMan.cpp +++ b/libethereum/DownloadMan.cpp @@ -50,7 +50,7 @@ h256Set DownloadSub::nextFetch(unsigned _n) m_indices.clear(); m_remaining.clear(); - if (!m_man || m_man->chain().empty()) + if (!m_man || m_man->chainEmpty()) return h256Set(); m_asked = (~(m_man->taken() + m_attempted)).lowest(_n); diff --git a/libethereum/DownloadMan.h b/libethereum/DownloadMan.h index d32d0465c..82e0f09e2 100644 --- a/libethereum/DownloadMan.h +++ b/libethereum/DownloadMan.h @@ -143,7 +143,8 @@ public: return ret; } - h256s chain() const { ReadGuard l(m_lock); return m_chain; } + size_t chainSize() const { ReadGuard l(m_lock); return m_chain.size(); } + size_t chainEmpty() const { ReadGuard l(m_lock); return m_chain.empty(); } void foreachSub(std::function const& _f) const { ReadGuard l(x_subs); for(auto i: m_subs) _f(*i); } unsigned subCount() const { ReadGuard l(x_subs); return m_subs.size(); } RangeMask blocksGot() const { ReadGuard l(m_lock); return m_blocksGot; } diff --git a/libethereum/EthereumHost.cpp b/libethereum/EthereumHost.cpp index c98dd7642..34d5eb504 100644 --- a/libethereum/EthereumHost.cpp +++ b/libethereum/EthereumHost.cpp @@ -122,7 +122,7 @@ void EthereumHost::noteDoneBlocks(EthereumPeer* _who, bool _clemency) // Done our chain-get. clog(NetNote) << "Chain download complete."; // 1/100th for each useful block hash. - _who->addRating(m_man.chain().size() / 100); + _who->addRating(m_man.chainSize() / 100); m_man.reset(); } else if (_who->isSyncing()) @@ -189,7 +189,7 @@ void EthereumHost::maintainTransactions() for (auto const& i: ts) { bool unsent = !m_transactionsSent.count(i.first); - for (auto const& p: randomSelection(100, [&](EthereumPeer* p) { return p->m_requireTransactions || (unsent && !p->m_knownTransactions.count(i.first)); })) + for (auto const& p: randomSelection(0, [&](EthereumPeer* p) { return p->m_requireTransactions || (unsent && !p->m_knownTransactions.count(i.first)); }).second) peerTransactions[p].push_back(i.first); } for (auto const& t: ts) @@ -218,28 +218,28 @@ void EthereumHost::maintainTransactions() } } -std::vector> EthereumHost::randomSelection(unsigned _percent, std::function const& _allow) +pair>, vector>> EthereumHost::randomSelection(unsigned _percent, std::function const& _allow) { - std::vector> candidates; - candidates.reserve(peerSessions().size()); + pair>, vector>> ret; + ret.second.reserve(peerSessions().size()); for (auto const& j: peerSessions()) { auto pp = j.first->cap(); if (_allow(pp.get())) - candidates.push_back(pp); + ret.second.push_back(pp); } - std::vector> ret; - for (unsigned i = (peerSessions().size() * _percent + 99) / 100; i-- && candidates.size();) + ret.second.reserve((peerSessions().size() * _percent + 99) / 100); + for (unsigned i = (peerSessions().size() * _percent + 99) / 100; i-- && ret.second.size();) { - unsigned n = rand() % candidates.size(); - ret.push_back(std::move(candidates[n])); - candidates.erase(candidates.begin() + n); + unsigned n = rand() % ret.second.size(); + ret.first.push_back(std::move(ret.second[n])); + ret.second.erase(ret.second.begin() + n); } return ret; } -void EthereumHost::maintainBlocks(h256 _currentHash) +void EthereumHost::maintainBlocks(h256 const& _currentHash) { // Send any new blocks. auto detailsFrom = m_chain.details(m_latestBlockSent); @@ -253,17 +253,28 @@ void EthereumHost::maintainBlocks(h256 _currentHash) h256s blocks = get<0>(m_chain.treeRoute(m_latestBlockSent, _currentHash, false, false, true)); - for (auto const& p: randomSelection(100, [&](EthereumPeer* p){return !p->m_knownBlocks.count(_currentHash); })) + auto s = randomSelection(25, [&](EthereumPeer* p){ ETH_GUARDED(p->x_knownBlocks) return !p->m_knownBlocks.count(_currentHash); return false; }); + for (shared_ptr const& p: s.first) for (auto const& b: blocks) - if (!p->m_knownBlocks.count(b)) - { - RLPStream ts; - p->prep(ts, NewBlockPacket, 2).appendRaw(m_chain.block(b), 1).append(m_chain.details(b).totalDifficulty); + { + RLPStream ts; + p->prep(ts, NewBlockPacket, 2).appendRaw(m_chain.block(b), 1).append(m_chain.details(b).totalDifficulty); - Guard l(p->x_knownBlocks); - p->sealAndSend(ts); - p->m_knownBlocks.clear(); - } + Guard l(p->x_knownBlocks); + p->sealAndSend(ts); + p->m_knownBlocks.clear(); + } + for (shared_ptr const& p: s.second) + { + RLPStream ts; + p->prep(ts, NewBlockHashesPacket, blocks.size()); + for (auto const& b: blocks) + ts.append(b); + + Guard l(p->x_knownBlocks); + p->sealAndSend(ts); + p->m_knownBlocks.clear(); + } } m_latestBlockSent = _currentHash; } diff --git a/libethereum/EthereumHost.h b/libethereum/EthereumHost.h index c2fffcd82..baa850b5c 100644 --- a/libethereum/EthereumHost.h +++ b/libethereum/EthereumHost.h @@ -80,7 +80,7 @@ public: void noteNewBlocks() { m_newBlocks = true; } private: - std::vector> randomSelection(unsigned _percent = 25, std::function const& _allow = [](EthereumPeer const*){ return true; }); + std::pair>, std::vector>> randomSelection(unsigned _percent = 25, std::function const& _allow = [](EthereumPeer const*){ return true; }); /// Session is tell us that we may need (re-)syncing with the peer. void noteNeedsSyncing(EthereumPeer* _who); @@ -92,7 +92,7 @@ private: void doWork(); void maintainTransactions(); - void maintainBlocks(h256 _currentBlock); + void maintainBlocks(h256 const& _currentBlock); /// Get a bunch of needed blocks. /// Removes them from our list of needed blocks. diff --git a/libethereum/EthereumPeer.cpp b/libethereum/EthereumPeer.cpp index f3edaf8ea..c550bd4f7 100644 --- a/libethereum/EthereumPeer.cpp +++ b/libethereum/EthereumPeer.cpp @@ -326,12 +326,12 @@ bool EthereumPeer::interpret(unsigned _id, RLP const& _r) transition(Asking::Nothing); break; } - case GetTransactionsPacket: break; // DEPRECATED. case TransactionsPacket: { - clog(NetAllDetail) << "Transactions (" << dec << _r.itemCount() << "entries)"; + unsigned itemCount = _r.itemCount(); + clog(NetAllDetail) << "Transactions (" << dec << itemCount << "entries)"; Guard l(x_knownTransactions); - for (unsigned i = 0; i < _r.itemCount(); ++i) + for (unsigned i = 0; i < itemCount; ++i) { auto h = sha3(_r[i].data()); m_knownTransactions.insert(h); @@ -373,21 +373,22 @@ bool EthereumPeer::interpret(unsigned _id, RLP const& _r) } case BlockHashesPacket: { - clog(NetMessageSummary) << "BlockHashes (" << dec << _r.itemCount() << "entries)" << (_r.itemCount() ? "" : ": NoMoreHashes"); + unsigned itemCount = _r.itemCount(); + clog(NetMessageSummary) << "BlockHashes (" << dec << itemCount << "entries)" << (itemCount ? "" : ": NoMoreHashes"); if (m_asking != Asking::Hashes) { cwarn << "Peer giving us hashes when we didn't ask for them."; break; } - if (_r.itemCount() == 0) + if (itemCount == 0) { transition(Asking::Blocks); return true; } unsigned knowns = 0; unsigned unknowns = 0; - for (unsigned i = 0; i < _r.itemCount(); ++i) + for (unsigned i = 0; i < itemCount; ++i) { addRating(1); auto h = _r[i].toHash(); @@ -454,12 +455,13 @@ bool EthereumPeer::interpret(unsigned _id, RLP const& _r) } case BlocksPacket: { - clog(NetMessageSummary) << "Blocks (" << dec << _r.itemCount() << "entries)" << (_r.itemCount() ? "" : ": NoMoreBlocks"); + unsigned itemCount = _r.itemCount(); + clog(NetMessageSummary) << "Blocks (" << dec << itemCount << "entries)" << (itemCount ? "" : ": NoMoreBlocks"); if (m_asking != Asking::Blocks) clog(NetWarn) << "Unexpected Blocks received!"; - if (_r.itemCount() == 0) + if (itemCount == 0) { // Got to this peer's latest block - just give up. transition(Asking::Nothing); @@ -472,7 +474,7 @@ bool EthereumPeer::interpret(unsigned _id, RLP const& _r) unsigned got = 0; unsigned repeated = 0; - for (unsigned i = 0; i < _r.itemCount(); ++i) + for (unsigned i = 0; i < itemCount; ++i) { auto h = BlockInfo::headerHash(_r[i].data()); if (m_sub.noteBlock(h)) @@ -557,8 +559,51 @@ bool EthereumPeer::interpret(unsigned _id, RLP const& _r) default:; } - Guard l(x_knownBlocks); - m_knownBlocks.insert(h); + ETH_GUARDED(x_knownBlocks) + m_knownBlocks.insert(h); + } + break; + } + case NewBlockHashesPacket: + { + clog(NetMessageSummary) << "NewBlockHashes"; + if (host()->isSyncing()) + clog(NetMessageSummary) << "Ignoring since we're already downloading."; + else + { + unsigned knowns = 0; + unsigned unknowns = 0; + unsigned itemCount = _r.itemCount(); + for (unsigned i = 0; i < itemCount; ++i) + { + addRating(1); + auto h = _r[i].toHash(); + ETH_GUARDED(x_knownBlocks) + m_knownBlocks.insert(h); + auto status = host()->m_bq.blockStatus(h); + if (status == QueueStatus::Importing || status == QueueStatus::Ready || host()->m_chain.isKnown(h)) + knowns++; + else if (status == QueueStatus::Bad) + { + cwarn << "block hash bad!" << h << ". Bailing..."; + return true; + } + else if (status == QueueStatus::Unknown) + { + unknowns++; + m_syncingNeededBlocks.push_back(h); + } + else + knowns++; + } + clog(NetMessageSummary) << knowns << "knowns," << unknowns << "unknowns"; + if (unknowns > 0) + { + host()->m_man.resetToChain(m_syncingNeededBlocks); + host()->changeSyncer(this); + transition(Asking::Blocks); + } + return true; } break; } diff --git a/libethereum/EthereumPeer.h b/libethereum/EthereumPeer.h index a80d5dadd..75ebab02f 100644 --- a/libethereum/EthereumPeer.h +++ b/libethereum/EthereumPeer.h @@ -129,7 +129,7 @@ private: /// This is built as we ask for hashes. Once no more hashes are given, we present this to the /// host who initialises the DownloadMan and m_sub becomes active for us to begin asking for blocks. h256s m_syncingNeededBlocks; ///< The blocks that we should download from this peer. - h256 m_syncingLastReceivedHash; ///< Hash more recently received from peer. + h256 m_syncingLastReceivedHash; ///< Hash most recently received from peer. h256 m_syncingLatestHash; ///< Peer's latest block's hash, as of the current sync. u256 m_syncingTotalDifficulty; ///< Peer's latest block's total difficulty, as of the current sync. diff --git a/libethereum/Interface.h b/libethereum/Interface.h index 6edd97b4c..ba68e976e 100644 --- a/libethereum/Interface.h +++ b/libethereum/Interface.h @@ -25,7 +25,6 @@ #include #include #include -#include #include #include "LogFilter.h" #include "Transaction.h" @@ -100,12 +99,14 @@ public: u256 countAt(Address _a) const { return countAt(_a, m_default); } u256 stateAt(Address _a, u256 _l) const { return stateAt(_a, _l, m_default); } bytes codeAt(Address _a) const { return codeAt(_a, m_default); } + h256 codeHashAt(Address _a) const { return codeHashAt(_a, m_default); } std::map storageAt(Address _a) const { return storageAt(_a, m_default); } virtual u256 balanceAt(Address _a, BlockNumber _block) const = 0; virtual u256 countAt(Address _a, BlockNumber _block) const = 0; virtual u256 stateAt(Address _a, u256 _l, BlockNumber _block) const = 0; virtual bytes codeAt(Address _a, BlockNumber _block) const = 0; + virtual h256 codeHashAt(Address _a, BlockNumber _block) const = 0; virtual std::map storageAt(Address _a, BlockNumber _block) const = 0; // [LOGS API] diff --git a/libethereum/Precompiled.cpp b/libethereum/Precompiled.cpp index 62d159418..0fd5cb45b 100644 --- a/libethereum/Precompiled.cpp +++ b/libethereum/Precompiled.cpp @@ -24,7 +24,7 @@ #include #include #include -#include +#include using namespace std; using namespace dev; using namespace dev::eth; diff --git a/libethereum/State.h b/libethereum/State.h index d02521c7a..e3468c24c 100644 --- a/libethereum/State.h +++ b/libethereum/State.h @@ -31,7 +31,6 @@ #include #include #include -#include #include #include "TransactionQueue.h" #include "Account.h" diff --git a/libethereum/Transaction.h b/libethereum/Transaction.h index 4271a5f27..2b11c52d6 100644 --- a/libethereum/Transaction.h +++ b/libethereum/Transaction.h @@ -24,7 +24,7 @@ #include #include #include -#include +#include namespace dev { namespace eth diff --git a/libethereum/TransactionQueue.cpp b/libethereum/TransactionQueue.cpp index 1bfdf535a..5aca67a29 100644 --- a/libethereum/TransactionQueue.cpp +++ b/libethereum/TransactionQueue.cpp @@ -36,7 +36,6 @@ ImportResult TransactionQueue::import(bytesConstRef _transactionRLP, ImportCallb h256 h = sha3(_transactionRLP); UpgradableGuard l(m_lock); - // TODO: keep old transactions around and check in State for nonce validity auto ir = check_WITH_LOCK(h, _ik); if (ir != ImportResult::Success) diff --git a/libevm/VM.h b/libevm/VM.h index 1cf06b78b..30007e0b3 100644 --- a/libevm/VM.h +++ b/libevm/VM.h @@ -27,7 +27,7 @@ #include #include #include -#include +#include #include "VMFace.h" namespace dev diff --git a/libevmcore/Assembly.cpp b/libevmasm/Assembly.cpp similarity index 99% rename from libevmcore/Assembly.cpp rename to libevmasm/Assembly.cpp index eac946230..6cc09a4bc 100644 --- a/libevmcore/Assembly.cpp +++ b/libevmasm/Assembly.cpp @@ -22,8 +22,8 @@ #include "Assembly.h" #include #include -#include -#include +#include +#include #include using namespace std; using namespace dev; diff --git a/libevmcore/Assembly.h b/libevmasm/Assembly.h similarity index 98% rename from libevmcore/Assembly.h rename to libevmasm/Assembly.h index 4ac873682..b4850f7d0 100644 --- a/libevmcore/Assembly.h +++ b/libevmasm/Assembly.h @@ -25,9 +25,9 @@ #include #include #include -#include #include -#include +#include +#include #include "Exceptions.h" #include diff --git a/libevmcore/AssemblyItem.cpp b/libevmasm/AssemblyItem.cpp similarity index 100% rename from libevmcore/AssemblyItem.cpp rename to libevmasm/AssemblyItem.cpp diff --git a/libevmcore/AssemblyItem.h b/libevmasm/AssemblyItem.h similarity index 98% rename from libevmcore/AssemblyItem.h rename to libevmasm/AssemblyItem.h index 7400954d3..6f2a65de9 100644 --- a/libevmcore/AssemblyItem.h +++ b/libevmasm/AssemblyItem.h @@ -25,8 +25,8 @@ #include #include #include -#include #include +#include #include "Exceptions.h" namespace dev diff --git a/libevmasm/CMakeLists.txt b/libevmasm/CMakeLists.txt new file mode 100644 index 000000000..f8150806f --- /dev/null +++ b/libevmasm/CMakeLists.txt @@ -0,0 +1,33 @@ +cmake_policy(SET CMP0015 NEW) +# this policy was introduced in cmake 3.0 +# remove if, once 3.0 will be used on unix +if (${CMAKE_MAJOR_VERSION} GREATER 2) + # old policy do not use MACOSX_RPATH + cmake_policy(SET CMP0042 OLD) +endif() +set(CMAKE_AUTOMOC OFF) + +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSTATICLIB") + +aux_source_directory(. SRC_LIST) + +include_directories(BEFORE ${JSONCPP_INCLUDE_DIRS}) +include_directories(BEFORE ..) +include_directories(${Boost_INCLUDE_DIRS}) + +set(EXECUTABLE evmasm) + +file(GLOB HEADERS "*.h") + +if (ETH_STATIC) + add_library(${EXECUTABLE} STATIC ${SRC_LIST} ${HEADERS}) +else() + add_library(${EXECUTABLE} SHARED ${SRC_LIST} ${HEADERS}) +endif() + +target_link_libraries(${EXECUTABLE} evmcore) +target_link_libraries(${EXECUTABLE} devcrypto) + +install( TARGETS ${EXECUTABLE} RUNTIME DESTINATION bin ARCHIVE DESTINATION lib LIBRARY DESTINATION lib ) +install( FILES ${HEADERS} DESTINATION include/${EXECUTABLE} ) + diff --git a/libevmcore/CommonSubexpressionEliminator.cpp b/libevmasm/CommonSubexpressionEliminator.cpp similarity index 99% rename from libevmcore/CommonSubexpressionEliminator.cpp rename to libevmasm/CommonSubexpressionEliminator.cpp index 65305b42a..63524d6f3 100644 --- a/libevmcore/CommonSubexpressionEliminator.cpp +++ b/libevmasm/CommonSubexpressionEliminator.cpp @@ -24,8 +24,8 @@ #include #include #include -#include -#include +#include +#include using namespace std; using namespace dev; diff --git a/libevmcore/CommonSubexpressionEliminator.h b/libevmasm/CommonSubexpressionEliminator.h similarity index 99% rename from libevmcore/CommonSubexpressionEliminator.h rename to libevmasm/CommonSubexpressionEliminator.h index 6001f1780..6156bc81a 100644 --- a/libevmcore/CommonSubexpressionEliminator.h +++ b/libevmasm/CommonSubexpressionEliminator.h @@ -30,8 +30,8 @@ #include #include #include -#include -#include +#include +#include namespace dev { diff --git a/libevmcore/ControlFlowGraph.cpp b/libevmasm/ControlFlowGraph.cpp similarity index 97% rename from libevmcore/ControlFlowGraph.cpp rename to libevmasm/ControlFlowGraph.cpp index ca20a8fb0..cc4367e64 100644 --- a/libevmcore/ControlFlowGraph.cpp +++ b/libevmasm/ControlFlowGraph.cpp @@ -21,11 +21,11 @@ * Control flow analysis for the optimizer. */ -#include +#include #include -#include -#include -#include +#include +#include +#include using namespace std; using namespace dev; diff --git a/libevmcore/ControlFlowGraph.h b/libevmasm/ControlFlowGraph.h similarity index 100% rename from libevmcore/ControlFlowGraph.h rename to libevmasm/ControlFlowGraph.h diff --git a/libevmasm/Exceptions.h b/libevmasm/Exceptions.h new file mode 100644 index 000000000..7cc190e41 --- /dev/null +++ b/libevmasm/Exceptions.h @@ -0,0 +1,36 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file Exceptions.h + * @author Christian + * @date 2014 + */ + +#pragma once + +#include + +namespace dev +{ +namespace eth +{ + +struct AssemblyException: virtual Exception {}; +struct OptimizerException: virtual AssemblyException {}; +struct StackTooDeepException: virtual OptimizerException {}; + +} +} diff --git a/libevmcore/ExpressionClasses.cpp b/libevmasm/ExpressionClasses.cpp similarity index 99% rename from libevmcore/ExpressionClasses.cpp rename to libevmasm/ExpressionClasses.cpp index 7c5d9ad72..1e60a7fe8 100644 --- a/libevmcore/ExpressionClasses.cpp +++ b/libevmasm/ExpressionClasses.cpp @@ -21,14 +21,14 @@ * Container for equivalence classes of expressions for use in common subexpression elimination. */ -#include +#include #include #include #include #include #include -#include -#include +#include +#include using namespace std; using namespace dev; diff --git a/libevmcore/ExpressionClasses.h b/libevmasm/ExpressionClasses.h similarity index 99% rename from libevmcore/ExpressionClasses.h rename to libevmasm/ExpressionClasses.h index d5bf8e547..2f720f606 100644 --- a/libevmcore/ExpressionClasses.h +++ b/libevmasm/ExpressionClasses.h @@ -27,7 +27,7 @@ #include #include #include -#include +#include namespace dev { diff --git a/libevmcore/SemanticInformation.cpp b/libevmasm/SemanticInformation.cpp similarity index 97% rename from libevmcore/SemanticInformation.cpp rename to libevmasm/SemanticInformation.cpp index 3abb26dd9..83d59efc7 100644 --- a/libevmcore/SemanticInformation.cpp +++ b/libevmasm/SemanticInformation.cpp @@ -21,8 +21,8 @@ * Helper to provide semantic information about assembly items. */ -#include -#include +#include +#include using namespace std; using namespace dev; diff --git a/libevmcore/SemanticInformation.h b/libevmasm/SemanticInformation.h similarity index 100% rename from libevmcore/SemanticInformation.h rename to libevmasm/SemanticInformation.h diff --git a/libevmcore/SourceLocation.h b/libevmasm/SourceLocation.h similarity index 100% rename from libevmcore/SourceLocation.h rename to libevmasm/SourceLocation.h diff --git a/libevmcore/CMakeLists.txt b/libevmcore/CMakeLists.txt index 2da76882e..83042e65e 100644 --- a/libevmcore/CMakeLists.txt +++ b/libevmcore/CMakeLists.txt @@ -7,11 +7,8 @@ if (${CMAKE_MAJOR_VERSION} GREATER 2) endif() set(CMAKE_AUTOMOC OFF) -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSTATICLIB") - aux_source_directory(. SRC_LIST) -include_directories(BEFORE ${JSONCPP_INCLUDE_DIRS}) include_directories(BEFORE ..) include_directories(${Boost_INCLUDE_DIRS}) @@ -22,7 +19,6 @@ file(GLOB HEADERS "*.h") add_library(${EXECUTABLE} ${SRC_LIST} ${HEADERS}) target_link_libraries(${EXECUTABLE} devcore) -target_link_libraries(${EXECUTABLE} devcrypto) install( TARGETS ${EXECUTABLE} RUNTIME DESTINATION bin ARCHIVE DESTINATION lib LIBRARY DESTINATION lib ) install( FILES ${HEADERS} DESTINATION include/${EXECUTABLE} ) diff --git a/libevmcore/Exceptions.h b/libevmcore/Exceptions.h index fa3c19f13..72af277df 100644 --- a/libevmcore/Exceptions.h +++ b/libevmcore/Exceptions.h @@ -28,11 +28,8 @@ namespace dev namespace eth { -struct AssemblyException: virtual Exception {}; -struct InvalidDeposit: virtual AssemblyException {}; -struct InvalidOpcode: virtual AssemblyException {}; -struct OptimizerException: virtual AssemblyException {}; -struct StackTooDeepException: virtual OptimizerException {}; +struct InvalidDeposit: virtual Exception {}; +struct InvalidOpcode: virtual Exception {}; } } diff --git a/libevmcore/Params.cpp b/libevmcore/Params.cpp new file mode 100644 index 000000000..91b50d0f6 --- /dev/null +++ b/libevmcore/Params.cpp @@ -0,0 +1,69 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file Params.cpp + * @author Gav Wood + * @date 2014 + */ + +#include "Params.h" + +using namespace std; +namespace dev +{ +namespace eth +{ + +//--- BEGIN: AUTOGENERATED FROM github.com/ethereum/common/params.json +u256 const c_stackLimit = 1024; +u256 const c_tierStepGas[] = {0, 2, 3, 5, 8, 10, 20, 0}; +u256 const c_expGas = 10; +u256 const c_expByteGas = 10; +u256 const c_sha3Gas = 30; +u256 const c_sha3WordGas = 6; +u256 const c_sloadGas = 50; +u256 const c_sstoreSetGas = 20000; +u256 const c_sstoreResetGas = 5000; +u256 const c_sstoreRefundGas = 15000; +u256 const c_jumpdestGas = 1; +u256 const c_logGas = 375; +u256 const c_logDataGas = 8; +u256 const c_logTopicGas = 375; +u256 const c_createGas = 32000; +u256 const c_callGas = 40; +u256 const c_callStipend = 2300; +u256 const c_callValueTransferGas = 9000; +u256 const c_callNewAccountGas = 25000; +u256 const c_suicideRefundGas = 24000; +u256 const c_memoryGas = 3; +u256 const c_quadCoeffDiv = 512; +u256 const c_createDataGas = 200; +u256 const c_txGas = 21000; +u256 const c_txDataZeroGas = 4; +u256 const c_txDataNonZeroGas = 68; +u256 const c_copyGas = 3; +u256 const c_ecrecoverGas = 3000; +u256 const c_sha256Gas = 60; +u256 const c_sha256WordGas = 12; +u256 const c_ripemd160Gas = 600; +u256 const c_ripemd160WordGas = 120; +u256 const c_identityGas = 15; +u256 const c_identityWordGas = 3; +//--- END: AUTOGENERATED FROM /feeStructure.json + +} +} + diff --git a/libevmcore/Params.h b/libevmcore/Params.h new file mode 100644 index 000000000..213ff5a2d --- /dev/null +++ b/libevmcore/Params.h @@ -0,0 +1,69 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file Params.h + * @author Gav Wood + * @date 2014 + */ + +#pragma once + +#include + +namespace dev +{ +namespace eth +{ + +//--- BEGIN: AUTOGENERATED FROM /feeStructure.json +extern u256 const c_stackLimit; + +extern u256 const c_tierStepGas[8]; ///< Once per operation, for a selection of them. +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_sha3Gas; ///< Once per SHA3 operation. +extern u256 const c_sha3WordGas; ///< Once per word of the SHA3 operation's data. +extern u256 const c_copyGas; ///< Multiplied by the number of 32-byte words that are copied (round up) for any *COPY operation and added. +extern u256 const c_sloadGas; ///< Once per SLOAD operation. +extern u256 const c_sstoreSetGas; ///< Once per SSTORE operation if the zeroness changes from zero. +extern u256 const c_sstoreResetGas; ///< Once per SSTORE operation if the zeroness does not change from zero. NOTE: when c_sstoreSetGas does not apply. +extern u256 const c_sstoreRefundGas; ///< Refunded gas, once per SSTORE operation if the zeroness changes to zero. +extern u256 const c_jumpdestGas; ///< Once per JUMPDEST 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_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_createGas; ///< Once per CREATE operation & contract-creation transaction. +extern u256 const c_createDataGas; +extern u256 const c_callGas; ///< Once per CALL operation & message call transaction. +extern u256 const c_callStipend; ///< Free gas given at beginning of call. +extern u256 const c_callNewAccountGas; ///< Paid for CALL when the destination address didn't exist prior. +extern u256 const c_callValueTransferGas; ///< Paid for CALL when the value transfor is non-zero. +extern u256 const c_suicideRefundGas; ///< Refunded following a suicide operation. +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_quadCoeffDiv; ///< Divisor for the quadratic particle of the memory cost equation. +extern u256 const c_txGas; ///< Per 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_ecrecoverGas; +extern u256 const c_sha256Gas; +extern u256 const c_sha256WordGas; +extern u256 const c_ripemd160Gas; +extern u256 const c_ripemd160WordGas; +extern u256 const c_identityGas; +extern u256 const c_identityWordGas; + +} +} diff --git a/libjsqrc/setup.js b/libjsqrc/setup.js index 78ca2ffad..1423a5cd3 100644 --- a/libjsqrc/setup.js +++ b/libjsqrc/setup.js @@ -21,5 +21,5 @@ */ var web3 = require('web3'); -web3.setProvider(new web3.providers.HttpProvider("http://localhost:8080")); +web3.setProvider(new web3.providers.HttpProvider("http://localhost:8545")); diff --git a/liblll/CMakeLists.txt b/liblll/CMakeLists.txt index d3f465f37..66f32e4d8 100644 --- a/liblll/CMakeLists.txt +++ b/liblll/CMakeLists.txt @@ -21,8 +21,7 @@ file(GLOB HEADERS "*.h") add_library(${EXECUTABLE} ${SRC_LIST} ${HEADERS}) -target_link_libraries(${EXECUTABLE} evmcore) -target_link_libraries(${EXECUTABLE} devcore) +target_link_libraries(${EXECUTABLE} evmasm) install( TARGETS ${EXECUTABLE} RUNTIME DESTINATION bin ARCHIVE DESTINATION lib LIBRARY DESTINATION lib ) install( FILES ${HEADERS} DESTINATION include/${EXECUTABLE} ) diff --git a/liblll/CodeFragment.h b/liblll/CodeFragment.h index 554f90b46..03f812b60 100644 --- a/liblll/CodeFragment.h +++ b/liblll/CodeFragment.h @@ -23,7 +23,7 @@ #include #include -#include +#include #include "Exceptions.h" namespace boost { namespace spirit { class utree; } } diff --git a/libp2p/Host.cpp b/libp2p/Host.cpp index 030c406c0..d47f1764e 100644 --- a/libp2p/Host.cpp +++ b/libp2p/Host.cpp @@ -413,7 +413,6 @@ void Host::requirePeer(NodeId const& _n, NodeIPEndpoint const& _endpoint) // create or update m_peers entry shared_ptr p; ETH_RECURSIVE_GUARDED(x_sessions) - { if (m_peers.count(_n)) { p = m_peers[_n]; @@ -425,7 +424,6 @@ void Host::requirePeer(NodeId const& _n, NodeIPEndpoint const& _endpoint) p.reset(new Peer(node)); m_peers[_n] = p; } - } connect(p); } else if (m_nodeTable) @@ -438,6 +436,7 @@ void Host::requirePeer(NodeId const& _n, NodeIPEndpoint const& _endpoint) t->async_wait([this, _n](boost::system::error_code const& _ec) { if (!_ec && m_nodeTable) + // FIXME RACE CONDITION (use weak_ptr or mutex). if (auto n = m_nodeTable->node(_n)) requirePeer(n.id, n.endpoint); }); @@ -464,7 +463,7 @@ void Host::connect(std::shared_ptr const& _p) return; } - if (!m_nodeTable->haveNode(_p->id)) + if (!!m_nodeTable && !m_nodeTable->haveNode(_p->id)) { clog(NetWarn) << "Aborted connect. Node not in node table."; m_nodeTable->addNode(*_p.get()); diff --git a/libp2p/Host.h b/libp2p/Host.h index 375481c38..ea47b58b4 100644 --- a/libp2p/Host.h +++ b/libp2p/Host.h @@ -135,6 +135,8 @@ public: // TODO: P2P this should be combined with peers into a HostStat object of some kind; coalesce data, as it's only used for status information. Peers getPeers() const { RecursiveGuard l(x_sessions); Peers ret; for (auto const& i: m_peers) ret.push_back(*i.second); return ret; } + NetworkPreferences const& networkPreferences() const { return m_netPrefs; } + void setNetworkPreferences(NetworkPreferences const& _p, bool _dropPeers = false) { m_dropPeers = _dropPeers; auto had = isStarted(); if (had) stop(); m_netPrefs = _p; if (had) start(); } /// Start network. @threadsafe diff --git a/libp2p/Network.cpp b/libp2p/Network.cpp index de054a178..847e6a42d 100644 --- a/libp2p/Network.cpp +++ b/libp2p/Network.cpp @@ -226,7 +226,7 @@ bi::tcp::endpoint Network::resolveHost(string const& _addr) boost::system::error_code ec; // resolve returns an iterator (host can resolve to multiple addresses) bi::tcp::resolver r(s_resolverIoService); - auto it = r.resolve({split[0], toString(port)}, ec); + auto it = r.resolve({bi::tcp::v4(), split[0], toString(port)}, ec); if (ec) clog(NetWarn) << "Error resolving host address..." << LogTag::Url << _addr << ":" << LogTag::Error << ec.message(); else diff --git a/libsolidity/AST.h b/libsolidity/AST.h index c9ad6447e..fde0b71b0 100644 --- a/libsolidity/AST.h +++ b/libsolidity/AST.h @@ -27,7 +27,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/libsolidity/ASTUtils.h b/libsolidity/ASTUtils.h index f2b90ea53..b24a34048 100644 --- a/libsolidity/ASTUtils.h +++ b/libsolidity/ASTUtils.h @@ -22,7 +22,7 @@ #pragma once -#include +#include #include namespace dev diff --git a/libsolidity/CMakeLists.txt b/libsolidity/CMakeLists.txt index 3d31331a4..10c7bc2d2 100644 --- a/libsolidity/CMakeLists.txt +++ b/libsolidity/CMakeLists.txt @@ -22,7 +22,7 @@ file(GLOB HEADERS "*.h") add_library(${EXECUTABLE} ${SRC_LIST} ${HEADERS}) target_link_libraries(${EXECUTABLE} ${JSONCPP_LIBRARIES}) -target_link_libraries(${EXECUTABLE} evmcore) +target_link_libraries(${EXECUTABLE} evmasm) target_link_libraries(${EXECUTABLE} devcrypto) install( TARGETS ${EXECUTABLE} RUNTIME DESTINATION bin ARCHIVE DESTINATION lib LIBRARY DESTINATION lib ) diff --git a/libsolidity/Compiler.cpp b/libsolidity/Compiler.cpp index d57f30c12..fb2ab3156 100644 --- a/libsolidity/Compiler.cpp +++ b/libsolidity/Compiler.cpp @@ -24,7 +24,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/libsolidity/Compiler.h b/libsolidity/Compiler.h index c3c3b9dcc..106038d1c 100644 --- a/libsolidity/Compiler.h +++ b/libsolidity/Compiler.h @@ -26,7 +26,7 @@ #include #include #include -#include +#include namespace dev { namespace solidity { diff --git a/libsolidity/CompilerContext.h b/libsolidity/CompilerContext.h index 0ca6369dd..933912455 100644 --- a/libsolidity/CompilerContext.h +++ b/libsolidity/CompilerContext.h @@ -26,7 +26,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/libsolidity/Exceptions.h b/libsolidity/Exceptions.h index a0031ba7e..4bb6644b1 100644 --- a/libsolidity/Exceptions.h +++ b/libsolidity/Exceptions.h @@ -25,7 +25,7 @@ #include #include #include -#include +#include namespace dev { diff --git a/libsolidity/ExpressionCompiler.h b/libsolidity/ExpressionCompiler.h index 35526662a..45a2311ef 100644 --- a/libsolidity/ExpressionCompiler.h +++ b/libsolidity/ExpressionCompiler.h @@ -25,7 +25,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/libsolidity/LValue.h b/libsolidity/LValue.h index ad6225162..1617e8167 100644 --- a/libsolidity/LValue.h +++ b/libsolidity/LValue.h @@ -23,7 +23,7 @@ #pragma once #include -#include +#include #include namespace dev diff --git a/libsolidity/Parser.cpp b/libsolidity/Parser.cpp index 43571314a..37c358d3b 100644 --- a/libsolidity/Parser.cpp +++ b/libsolidity/Parser.cpp @@ -22,7 +22,7 @@ #include #include -#include +#include #include #include #include diff --git a/libsolidity/Scanner.h b/libsolidity/Scanner.h index b57b8a189..43fcd133c 100644 --- a/libsolidity/Scanner.h +++ b/libsolidity/Scanner.h @@ -55,7 +55,7 @@ #include #include #include -#include +#include #include namespace dev diff --git a/libsolidity/SourceReferenceFormatter.h b/libsolidity/SourceReferenceFormatter.h index ed2564f31..dd258c276 100644 --- a/libsolidity/SourceReferenceFormatter.h +++ b/libsolidity/SourceReferenceFormatter.h @@ -23,7 +23,7 @@ #pragma once #include -#include +#include namespace dev { diff --git a/libwebthree/WebThree.cpp b/libwebthree/WebThree.cpp index a520190ee..606126e43 100644 --- a/libwebthree/WebThree.cpp +++ b/libwebthree/WebThree.cpp @@ -72,6 +72,11 @@ WebThreeDirect::~WebThreeDirect() m_ethereum.reset(); } +p2p::NetworkPreferences const& WebThreeDirect::networkPreferences() const +{ + return m_net.networkPreferences(); +} + void WebThreeDirect::setNetworkPreferences(p2p::NetworkPreferences const& _n, bool _dropPeers) { auto had = isNetworkStarted(); diff --git a/libwebthree/WebThree.h b/libwebthree/WebThree.h index 90a4aa3c2..ece83abb8 100644 --- a/libwebthree/WebThree.h +++ b/libwebthree/WebThree.h @@ -73,6 +73,7 @@ public: virtual bool haveNetwork() const = 0; + virtual p2p::NetworkPreferences const& networkPreferences() const = 0; virtual void setNetworkPreferences(p2p::NetworkPreferences const& _n, bool _dropPeers) = 0; virtual p2p::NodeId id() const = 0; @@ -88,6 +89,8 @@ public: /// Is network working? there may not be any peers yet. virtual bool isNetworkStarted() const = 0; + + std::string enode() const { return "enode://" + toHex(id().ref()) + "@" + (networkPreferences().publicIPAddress.empty() ? "127.0.0.1" : networkPreferences().publicIPAddress) + ":" + toString(networkPreferences().listenPort); } }; @@ -164,6 +167,8 @@ public: bool haveNetwork() const override { return m_net.haveNetwork(); } + p2p::NetworkPreferences const& networkPreferences() const override; + void setNetworkPreferences(p2p::NetworkPreferences const& _n, bool _dropPeers = false) override; p2p::NodeId id() const override { return m_net.id(); } diff --git a/mix/ClientModel.cpp b/mix/ClientModel.cpp index 717757c70..fa5ec1c27 100644 --- a/mix/ClientModel.cpp +++ b/mix/ClientModel.cpp @@ -137,24 +137,29 @@ void ClientModel::mine() QString ClientModel::newSecret() { KeyPair a = KeyPair::create(); - return QString::fromStdString(toHex(a.secret().ref())); + return QString::fromStdString(dev::toHex(a.secret().ref())); } QString ClientModel::address(QString const& _secret) { - return QString::fromStdString(toHex(KeyPair(Secret(_secret.toStdString())).address().ref())); + return QString::fromStdString(dev::toHex(KeyPair(Secret(_secret.toStdString())).address().ref())); +} + +QString ClientModel::toHex(QString const& _int) +{ + return QString::fromStdString(dev::toHex(dev::u256(_int.toStdString()))); } QString ClientModel::encodeAbiString(QString _string) { ContractCallDataEncoder encoder; - return QString::fromStdString(toHex(encoder.encodeBytes(_string))); + return QString::fromStdString(dev::toHex(encoder.encodeBytes(_string))); } QString ClientModel::encodeStringParam(QString const& _param) { ContractCallDataEncoder encoder; - return QString::fromStdString(toHex(encoder.encodeStringParam(_param, 32))); + return QString::fromStdString(dev::toHex(encoder.encodeStringParam(_param, 32))); } QStringList ClientModel::encodeParams(QVariant const& _param, QString const& _contract, QString const& _function) @@ -179,7 +184,7 @@ QStringList ClientModel::encodeParams(QVariant const& _param, QString const& _co QSolidityType const* type = var->type(); QVariant value = _param.toMap().value(var->name()); encoder.encode(value, type->type()); - ret.push_back(QString::fromStdString(toHex(encoder.encodedData()))); + ret.push_back(QString::fromStdString(dev::toHex(encoder.encodedData()))); } return ret; } @@ -192,11 +197,11 @@ QVariantMap ClientModel::contractAddresses() const return res; } -QVariantMap ClientModel::gasCosts() const +QVariantList ClientModel::gasCosts() const { - QVariantMap res; + QVariantList res; for (auto const& c: m_gasCosts) - res.insert(c.first, QVariant::fromValue(static_cast(c.second))); + res.append(QVariant::fromValue(static_cast(c))); return res; } @@ -299,6 +304,7 @@ void ClientModel::executeSequence(vector const& _sequence, { vector
deployedContracts; onStateReset(); + m_gasCosts.clear(); for (TransactionSettings const& transaction: _sequence) { ContractCallDataEncoder encoder; @@ -345,7 +351,7 @@ void ClientModel::executeSequence(vector const& _sequence, if (type->type().type == SolidityType::Type::Address && value.toString().startsWith("<") && value.toString().endsWith(">")) { QStringList nb = value.toString().remove("<").remove(">").split(" - "); - value = QVariant(QString::fromStdString("0x" + toHex(deployedContracts.at(nb.back().toInt()).ref()))); + value = QVariant(QString::fromStdString("0x" + dev::toHex(deployedContracts.at(nb.back().toInt()).ref()))); } encoder.encode(value, type->type()); } @@ -364,7 +370,6 @@ void ClientModel::executeSequence(vector const& _sequence, contractAddressesChanged(); } gasCostsChanged(); - m_gasCosts[transaction.contractId] = m_client->lastExecution().gasUsed; } else { @@ -378,6 +383,7 @@ void ClientModel::executeSequence(vector const& _sequence, } callContract(contractAddressIter->second, encoder.encodedData(), transaction); } + m_gasCosts.append(m_client->lastExecution().gasUsed); } onNewTransaction(); } @@ -615,7 +621,7 @@ RecordLogEntry* ClientModel::lastBlock() const strGas << blockInfo.gasUsed; stringstream strNumber; strNumber << blockInfo.number; - RecordLogEntry* record = new RecordLogEntry(0, QString::fromStdString(strNumber.str()), tr(" - Block - "), tr("Hash: ") + QString(QString::fromStdString(toHex(blockInfo.hash().ref()))), QString(), QString(), QString(), false, RecordLogEntry::RecordType::Block, QString::fromStdString(strGas.str())); + RecordLogEntry* record = new RecordLogEntry(0, QString::fromStdString(strNumber.str()), tr(" - Block - "), tr("Hash: ") + QString(QString::fromStdString(dev::toHex(blockInfo.hash().ref()))), QString(), QString(), QString(), false, RecordLogEntry::RecordType::Block, QString::fromStdString(strGas.str())); QQmlEngine::setObjectOwnership(record, QQmlEngine::JavaScriptOwnership); return record; } diff --git a/mix/ClientModel.h b/mix/ClientModel.h index 9b0529ae6..91b66c76c 100644 --- a/mix/ClientModel.h +++ b/mix/ClientModel.h @@ -147,7 +147,7 @@ public: /// @returns deployed contracts addresses Q_PROPERTY(QVariantMap contractAddresses READ contractAddresses NOTIFY contractAddressesChanged) /// @returns deployed contracts gas costs - Q_PROPERTY(QVariantMap gasCosts READ gasCosts NOTIFY gasCostsChanged) + Q_PROPERTY(QVariantList gasCosts READ gasCosts NOTIFY gasCostsChanged) // @returns the last block Q_PROPERTY(RecordLogEntry* lastBlock READ lastBlock CONSTANT) /// ethereum.js RPC request entry point @@ -162,6 +162,8 @@ public: Q_INVOKABLE QStringList encodeParams(QVariant const& _param, QString const& _contract, QString const& _function); /// Encode parameter Q_INVOKABLE QString encodeStringParam(QString const& _param); + /// To Hex number + Q_INVOKABLE QString toHex(QString const& _int); public slots: /// Setup state, run transaction sequence, show debugger for the last transaction @@ -217,7 +219,7 @@ signals: private: RecordLogEntry* lastBlock() const; QVariantMap contractAddresses() const; - QVariantMap gasCosts() const; + QVariantList gasCosts() const; void executeSequence(std::vector const& _sequence, std::map const& _accounts, Secret const& _miner); dev::Address deployContract(bytes const& _code, TransactionSettings const& _tr = TransactionSettings()); void callContract(Address const& _contract, bytes const& _data, TransactionSettings const& _tr); @@ -233,7 +235,7 @@ private: std::unique_ptr m_client; std::unique_ptr m_rpcConnector; std::unique_ptr m_web3Server; - std::map m_gasCosts; + QList m_gasCosts; std::map m_contractAddresses; std::map m_contractNames; std::map m_stdContractAddresses; diff --git a/mix/CodeModel.cpp b/mix/CodeModel.cpp index 515123de5..636a665e6 100644 --- a/mix/CodeModel.cpp +++ b/mix/CodeModel.cpp @@ -26,7 +26,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/mix/CodeModel.h b/mix/CodeModel.h index 3c6c3abdf..3f713a17b 100644 --- a/mix/CodeModel.h +++ b/mix/CodeModel.h @@ -30,7 +30,7 @@ #include #include #include -#include +#include #include "SolidityType.h" class QTextDocument; diff --git a/mix/MixClient.cpp b/mix/MixClient.cpp index 3fb325bd4..b1d8f889e 100644 --- a/mix/MixClient.cpp +++ b/mix/MixClient.cpp @@ -28,6 +28,7 @@ #include #include #include +#include #include #include "Exceptions.h" using namespace std; diff --git a/mix/QBasicNodeDefinition.h b/mix/QBasicNodeDefinition.h index 9179905eb..6a327b734 100644 --- a/mix/QBasicNodeDefinition.h +++ b/mix/QBasicNodeDefinition.h @@ -23,7 +23,7 @@ #include #include -#include +#include namespace dev { diff --git a/mix/QBigInt.h b/mix/QBigInt.h index 0712ff984..b549a16db 100644 --- a/mix/QBigInt.h +++ b/mix/QBigInt.h @@ -79,7 +79,7 @@ public: ~QBigInt() {} /// @returns the current used big integer. - BigIntVariant internalValue() { return m_internalValue; } + BigIntVariant internalValue() const { return m_internalValue; } /// @returns a string representation of the big integer used. Invokable from QML. Q_INVOKABLE QString value() const; /// Set the value of the BigInteger used. Will use u256 type. Invokable from QML. diff --git a/mix/Web3Server.cpp b/mix/Web3Server.cpp index 4acb262df..7edc73060 100644 --- a/mix/Web3Server.cpp +++ b/mix/Web3Server.cpp @@ -70,6 +70,12 @@ class EmptyNetwork : public dev::WebThreeNetworkFace return false; } + p2p::NetworkPreferences const& networkPreferences() const override + { + static const p2p::NetworkPreferences c_ret; + return c_ret; + } + void setNetworkPreferences(p2p::NetworkPreferences const& _n, bool _dropPeers) override { (void)_n; diff --git a/mix/qml/DeploymentDialog.qml b/mix/qml/DeploymentDialog.qml index f8eeb7a88..1fbde3ac9 100644 --- a/mix/qml/DeploymentDialog.qml +++ b/mix/qml/DeploymentDialog.qml @@ -17,6 +17,10 @@ Dialog { width: 735 height: 400 visible: false + property int ownedRegistrarDeployGas: 1179075 // TODO: Use sol library to calculate gas requirement for each tr. + property int ownedRegistrarSetSubRegistrarGas: 50000 + property int ownedRegistrarSetContentHashGas: 50000 + property int urlHintSuggestUrlGas: 70000 property alias applicationUrlEth: applicationUrlEth.text property alias applicationUrlHttp: applicationUrlHttp.text property alias localPackageUrl: localPackageUrl.text @@ -24,7 +28,7 @@ Dialog { property string packageBase64 property string eth: registrarAddr.text property string currentAccount - property string gasToUse: "0x188132" //gasToUseInput.text + property string gasPrice property variant paramsModel: [] function close() @@ -43,7 +47,6 @@ Dialog { id: 0 }]; - console.log(packageHash); TransactionHelper.rpcCall(requests, function(arg1, arg2) { modelAccounts.clear(); @@ -70,16 +73,26 @@ Dialog { { var ether = QEtherHelper.createEther(balanceRet[k].result, QEther.Wei); comboAccounts.balances.push(ether.format()); + comboAccounts.weiBalances.push(balanceRet[k].result); } balance.text = comboAccounts.balances[0]; }); }); - var gas = 0; - var gasCosts = clientModel.gasCosts; - for (var g in gasCosts) - gas += gasCosts[g]; - gasToUse = gas; + if (clientModel.gasCosts.length === 0) + { + errorDialog.text = qsTr("Please run the state one time before deploying in order to calculate gas requirement."); + errorDialog.open(); + } + else + { + NetworkDeploymentCode.gasPrice(function(price) { + gasPrice = price; + gasPriceInt.setValue(gasPrice); + ctrDeployCtrLabel.calculateContractDeployGas(); + ctrRegisterLabel.calculateRegisterGas(); + }); + } } function stopForInputError(inError) @@ -114,6 +127,11 @@ Dialog { poolLog.start(); } + BigIntValue + { + id: gasPriceInt + } + Timer { id: poolLog @@ -265,6 +283,10 @@ Dialog { id: statesList textRole: "title" model: projectModel.stateListModel + onCurrentIndexChanged : { + ctrDeployCtrLabel.calculateContractDeployGas(); + ctrRegisterLabel.calculateRegisterGas(); + } } } @@ -278,7 +300,7 @@ Dialog { { Layout.preferredWidth: 350 id: registrarAddr - text: "c6d9d2cd449a754c494264e1809c50e34d64562b" + text: "ab69f864e49fc4294d18355c4bafb0b91b5e629b" visible: false } @@ -295,11 +317,15 @@ Dialog { ComboBox { id: comboAccounts property var balances: [] + property var weiBalances: [] onCurrentIndexChanged : { if (modelAccounts.count > 0) { currentAccount = modelAccounts.get(currentIndex).id; balance.text = balances[currentIndex]; + balanceInt.setValue(weiBalances[currentIndex]); + ctrDeployCtrLabel.calculateContractDeployGas(); + ctrRegisterLabel.calculateRegisterGas(); } } model: ListModel { @@ -314,19 +340,58 @@ Dialog { anchors.leftMargin: 20 id: balance; } + + BigIntValue + { + id: balanceInt + } } } DefaultLabel { - text: qsTr("Amount of gas to use for each contract deployment: ") + text: qsTr("Amount of gas to use for contract deployment: ") + id: ctrDeployCtrLabel + function calculateContractDeployGas() + { + var ether = QEtherHelper.createBigInt(NetworkDeploymentCode.gasUsed()); + var gasTotal = ether.multiply(gasPriceInt); + gasToUseInput.value = QEtherHelper.createEther(gasTotal.value(), QEther.Wei, parent); + gasToUseDeployInput.update(); + } } - DefaultTextField + Ether { + id: gasToUseInput + displayUnitSelection: false + displayFormattedValue: true + Layout.preferredWidth: 350 + } + + DefaultLabel { - text: "1000000" + text: qsTr("Amount of gas to use for dapp registration: ") + id: ctrRegisterLabel + function calculateRegisterGas() + { + if (!modalDeploymentDialog.visible) + return; + appUrlFormatted.text = NetworkDeploymentCode.formatAppUrl(applicationUrlEth.text).join('/'); + NetworkDeploymentCode.checkPathCreationCost(function(pathCreationCost) + { + var ether = QEtherHelper.createBigInt(pathCreationCost); + var gasTotal = ether.multiply(gasPriceInt); + gasToUseDeployInput.value = QEtherHelper.createEther(gasTotal.value(), QEther.Wei, parent); + gasToUseDeployInput.update(); + }); + } + } + + Ether { + id: gasToUseDeployInput + displayUnitSelection: false + displayFormattedValue: true Layout.preferredWidth: 350 - id: gasToUseInput } DefaultLabel @@ -344,7 +409,7 @@ Dialog { width: 200 id: applicationUrlEth onTextChanged: { - appUrlFormatted.text = NetworkDeploymentCode.formatAppUrl(text).join('/'); + ctrRegisterLabel.calculateRegisterGas(); } } @@ -489,6 +554,15 @@ Dialog { iconSource: "qrc:/qml/img/note.png" } + BigIntValue + { + id: registerUrlHintGas + Component.onCompleted: + { + setValue(modalDeploymentDialog.urlHintSuggestUrlGas); + } + } + Action { id: registerAction enabled: rowRegister.isOkToRegister() diff --git a/mix/qml/Ether.qml b/mix/qml/Ether.qml index dd9022b81..7a059e04d 100644 --- a/mix/qml/Ether.qml +++ b/mix/qml/Ether.qml @@ -15,9 +15,11 @@ RowLayout { property bool displayFormattedValue; property bool edit; property variant value; + property bool displayUnitSelection onValueChanged: update() Component.onCompleted: update() + function update() { if (value) @@ -45,13 +47,13 @@ RowLayout { } } readOnly: !edit - visible: edit id: etherValueEdit; } ComboBox { id: units + visible: displayUnitSelection; onCurrentTextChanged: { if (value) diff --git a/mix/qml/js/NetworkDeployment.js b/mix/qml/js/NetworkDeployment.js index 9bbed2415..8a833e144 100644 --- a/mix/qml/js/NetworkDeployment.js +++ b/mix/qml/js/NetworkDeployment.js @@ -23,6 +23,7 @@ .import org.ethereum.qml.QSolidityType 1.0 as QSolidityType Qt.include("TransactionHelper.js") +Qt.include("QEtherHelper.js") var jsonRpcRequestId = 1; @@ -47,6 +48,7 @@ function startDeployProject(erasePrevious) var ctrAddresses = {}; var state = retrieveState(projectModel.deployedState); + console.log(JSON.stringify(state)); if (!state) { var txt = qsTr("Unable to find state " + projectModel.deployedState); @@ -59,6 +61,47 @@ function startDeployProject(erasePrevious) }); } +function checkPathCreationCost(callBack) +{ + var dappUrl = formatAppUrl(deploymentDialog.applicationUrlEth); + checkEthPath(dappUrl, true, function(success, cause) { + if (!success) + { + switch (cause) + { + case "rootownedregistrar_notexist": + deploymentError(qsTr("Owned registrar does not exist under the global registrar. Please create one using DApp registration.")); + break; + case "ownedregistrar_creationfailed": + deploymentError(qsTr("The creation of your new owned registrar fails. Please use DApp registration to create one.")); + break; + case "ownedregistrar_notowner": + deploymentError(qsTr("You are not the owner of this registrar. You cannot register your Dapp here.")); + break; + default: + break; + } + } + else + { + deploymentStepChanged(qsTr("Your Dapp can be registered here.")); + callBack((dappUrl.length - 1) * (deploymentDialog.ownedRegistrarDeployGas + deploymentDialog.ownedRegistrarSetSubRegistrarGas) + deploymentDialog.ownedRegistrarSetContentHashGas); + } + }); +} + +function gasUsed() +{ + var gas = 0; + var gasCosts = clientModel.gasCosts; + for (var g in gasCosts) + { + gas += gasCosts[g]; + console.log(" gasCost " + gasCosts[g]); + } + return gas; +} + function retrieveState(state) { for (var k = 0; k < projectModel.stateListModel.count; k++) @@ -113,7 +156,8 @@ function executeTr(trIndex, state, ctrAddresses, callBack) executeTrNextStep(trIndex, state, ctrAddresses, callBack); else { - var rpcParams = { "from": deploymentDialog.currentAccount, "gas": deploymentDialog.gasToUse }; + var gasCost = clientModel.toHex(clientModel.gasCosts[trIndex]); + var rpcParams = { "from": deploymentDialog.currentAccount, "gas": "0x" + gasCost }; var params = replaceParamToken(func.parameters, tr.parameters, ctrAddresses); var encodedParams = clientModel.encodeParams(params, tr.contractId, tr.functionId); @@ -157,6 +201,19 @@ function executeTrNextStep(trIndex, state, ctrAddresses, callBack) callBack(); } +function gasPrice(callBack) +{ + var requests = [{ + jsonrpc: "2.0", + method: "eth_gasPrice", + params: [], + id: jsonRpcRequestId + }]; + rpcCall(requests, function (httpCall, response){ + callBack(JSON.parse(response)[0].result); + }); +} + function finalizeDeployment(deploymentId, addresses) { deploymentStepChanged(qsTr("Packaging application ...")); var deploymentDir = projectPath + deploymentId + "/"; @@ -185,8 +242,8 @@ function finalizeDeployment(deploymentId, addresses) { } //write deployment js var deploymentJs = - "// Autogenerated by Mix\n" + - "contracts = {};\n"; + "// Autogenerated by Mix\n" + + "contracts = {};\n"; for (var c in codeModel.contracts) { var contractAccessor = "contracts[\"" + codeModel.contracts[c].contract.name + "\"]"; deploymentJs += contractAccessor + " = {\n" + @@ -209,19 +266,27 @@ function finalizeDeployment(deploymentId, addresses) { applicationUrlEth = formatAppUrl(applicationUrlEth); deploymentStepChanged(qsTr("Registering application on the Ethereum network ...")); - checkEthPath(applicationUrlEth, function () { + checkEthPath(applicationUrlEth, false, function (success) { + if (!success) + return; deploymentComplete(); deployResourcesDialog.text = qsTr("Register Web Application to finalize deployment."); deployResourcesDialog.open(); }); } -function checkEthPath(dappUrl, callBack) +function checkEthPath(dappUrl, checkOnly, callBack) { if (dappUrl.length === 1) - reserve(deploymentDialog.eth, function() { - registerContentHash(deploymentDialog.eth, callBack); // we directly create a dapp under the root registrar. - }); + { + // convenient for dev purpose, should not be possible in normal env. + if (!checkOnly) + reserve(deploymentDialog.eth, function() { + registerContentHash(deploymentDialog.eth, callBack); // we directly create a dapp under the root registrar. + }); + else + callBack(true); + } else { // the first owned registrar must have been created to follow the path. @@ -231,7 +296,7 @@ function checkEthPath(dappUrl, callBack) //subRegistrar() jsonrpc: "2.0", method: "eth_call", - params: [ { "gas": "0xffff", "from": deploymentDialog.currentAccount, "to": '0x' + deploymentDialog.eth, "data": "0x5a3a05bd" + str }, "pending" ], + params: [ { "gas": "0xffff", "from": deploymentDialog.currentAccount, "to": '0x' + deploymentDialog.eth, "data": "0xe1fa8e84" + str }, "pending" ], id: jsonRpcRequestId++ }); rpcCall(requests, function (httpRequest, response) { @@ -242,35 +307,66 @@ function checkEthPath(dappUrl, callBack) var errorTxt = qsTr("Path does not exists " + JSON.stringify(dappUrl) + ". Please register using Registration Dapp. Aborting."); deploymentError(errorTxt); console.log(errorTxt); + callBack(false, "rootownedregistrar_notexist"); } else { dappUrl.splice(0, 1); - checkRegistration(dappUrl, addr, callBack); + checkRegistration(dappUrl, addr, callBack, checkOnly); } }); } } -function checkRegistration(dappUrl, addr, callBack) +function isOwner(addr, callBack) +{ + var requests = []; + requests.push({ + //getOwner() + jsonrpc: "2.0", + method: "eth_call", + params: [ { "from": deploymentDialog.currentAccount, "to": '0x' + addr, "data": "0xb387ef92" }, "pending" ], + id: jsonRpcRequestId++ + }); + rpcCall(requests, function (httpRequest, response) { + var res = JSON.parse(response); + callBack(normalizeAddress(deploymentDialog.currentAccount) === normalizeAddress(res[0].result)); + }); +} + +function checkRegistration(dappUrl, addr, callBack, checkOnly) +{ + isOwner(addr, function(ret){ + if (!ret) + { + var errorTxt = qsTr("You are not the owner of " + dappUrl[0] + ". Aborting"); + deploymentError(errorTxt); + console.log(errorTxt); + callBack(false, "ownedregistrar_notowner"); + } + else + continueRegistration(dappUrl, addr, callBack, checkOnly); + }); +} + +function continueRegistration(dappUrl, addr, callBack, checkOnly) { if (dappUrl.length === 1) - registerContentHash(addr, callBack); // We do not create the register for the last part, just registering the content hash. + { + if (!checkOnly) + registerContentHash(addr, callBack); // We do not create the register for the last part, just registering the content hash. + else + callBack(true); + } else { - var txt = qsTr("Checking " + JSON.stringify(dappUrl) + " ... in registrar " + addr); + var txt = qsTr("Checking " + JSON.stringify(dappUrl)); deploymentStepChanged(txt); console.log(txt); var requests = []; var registrar = {} var str = clientModel.encodeStringParam(dappUrl[0]); - requests.push({ - //getOwner() - jsonrpc: "2.0", - method: "eth_call", - params: [ { "gas" : 2000, "from": deploymentDialog.currentAccount, "to": '0x' + addr, "data": "0x02571be3" }, "pending" ], - id: jsonRpcRequestId++ - }); + requests.push({ //register() @@ -282,37 +378,37 @@ function checkRegistration(dappUrl, addr, callBack) rpcCall(requests, function (httpRequest, response) { var res = JSON.parse(response); - var nextAddr = normalizeAddress(res[1].result); + var nextAddr = normalizeAddress(res[0].result); var errorTxt; - if (res[1].result === "0x") + if (res[0].result === "0x") { - errorTxt = qsTr("Error when creating new owned regsitrar. Please use the regsitration Dapp. Aborting"); - deploymentError(errorTxt); - console.log(errorTxt); - } - else if (normalizeAddress(deploymentDialog.currentAccount) !== normalizeAddress(res[0].result)) - { - errorTxt = qsTr("You are not the owner of " + dappUrl[0] + ". Aborting"); + errorTxt = qsTr("Error when creating new owned registrar. Please use the registration Dapp. Aborting"); deploymentError(errorTxt); console.log(errorTxt); + callBack(false, "ownedregistrar_creationfailed"); } else if (nextAddr.replace(/0+/g, "") !== "") { dappUrl.splice(0, 1); - checkRegistration(dappUrl, nextAddr, callBack); + checkRegistration(dappUrl, nextAddr, callBack, checkOnly); } else { + if (checkOnly) + { + callBack(true); + return; + } var txt = qsTr("Registering sub domain " + dappUrl[0] + " ..."); console.log(txt); deploymentStepChanged(txt); //current registrar is owned => ownedregistrar creation and continue. requests = []; - + var gasCost = clientModel.toHex(deploymentDialog.ownedRegistrarDeployGas); requests.push({ jsonrpc: "2.0", method: "eth_sendTransaction", - params: [ { "from": deploymentDialog.currentAccount, "gas": 20000, "code": "0x600080547fffffffffffffffffffffffff0000000000000000000000000000000000000000163317815561058990819061003990396000f3007c010000000000000000000000000000000000000000000000000000000060003504630198489281146100a757806302571be3146100d957806321f8a721146100e35780632dff6941146100ed5780633b3b57de1461010d5780635a3a05bd1461013d5780635fd4b08a1461017057806389a69c0e1461017c578063b5c645bd146101b0578063be99a9801461022c578063c3d014d614610264578063d93e75731461029857005b73ffffffffffffffffffffffffffffffffffffffff600435166000908152600160205260409020548060005260206000f35b6000808052602081f35b6000808052602081f35b600435600090815260026020819052604090912001548060005260206000f35b600435600090815260026020908152604082205473ffffffffffffffffffffffffffffffffffffffff1680835291f35b600435600090815260026020908152604082206001015473ffffffffffffffffffffffffffffffffffffffff1680835291f35b60008060005260206000f35b6000546102c89060043590602435903373ffffffffffffffffffffffffffffffffffffffff90811691161461052557610585565b600435600090815260026020819052604090912080546001820154919092015473ffffffffffffffffffffffffffffffffffffffff9283169291909116908273ffffffffffffffffffffffffffffffffffffffff166000528173ffffffffffffffffffffffffffffffffffffffff166020528060405260606000f35b6000546102ce906004359060243590604435903373ffffffffffffffffffffffffffffffffffffffff9081169116146102e0576103af565b6000546102d49060043590602435903373ffffffffffffffffffffffffffffffffffffffff9081169116146103b4576103f1565b6000546102da90600435903373ffffffffffffffffffffffffffffffffffffffff9081169116146103f557610522565b60006000f35b60006000f35b60006000f35b60006000f35b600083815260026020526040902080547fffffffffffffffffffffffff000000000000000000000000000000000000000016831790558061034757827fa6697e974e6a320f454390be03f74955e8978f1a6971ea6730542e37b66179bc60006040a26103ae565b73ffffffffffffffffffffffffffffffffffffffff8216837ff63780e752c6a54a94fc52715dbc5518a3b4c3c2833d301a204226548a2a854560006040a373ffffffffffffffffffffffffffffffffffffffff821660009081526001602052604090208390555b5b505050565b600082815260026020819052604080832090910183905583917fa6697e974e6a320f454390be03f74955e8978f1a6971ea6730542e37b66179bc91a25b5050565b60008181526002602090815260408083205473ffffffffffffffffffffffffffffffffffffffff16835260019091529020548114610432576104b2565b6000818152600260205260408082205473ffffffffffffffffffffffffffffffffffffffff169183917ff63780e752c6a54a94fc52715dbc5518a3b4c3c2833d301a204226548a2a85459190a360008181526002602090815260408083205473ffffffffffffffffffffffffffffffffffffffff16835260019091528120555b600081815260026020819052604080832080547fffffffffffffffffffffffff00000000000000000000000000000000000000009081168255600182018054909116905590910182905582917fa6697e974e6a320f454390be03f74955e8978f1a6971ea6730542e37b66179bc91a25b50565b60008281526002602052604080822060010180547fffffffffffffffffffffffff0000000000000000000000000000000000000000168417905583917fa6697e974e6a320f454390be03f74955e8978f1a6971ea6730542e37b66179bc91a25b505056" } ], + params: [ { "from": deploymentDialog.currentAccount, "gas": "0x" + gasCost, "code": "0x600080547fffffffffffffffffffffffff000000000000000000000000000000000000000016331781556105cd90819061003990396000f3007c010000000000000000000000000000000000000000000000000000000060003504630198489281146100b257806321f8a721146100e45780632dff6941146100ee5780633b3b57de1461010e5780635a3a05bd1461013e5780635fd4b08a146101715780637dd564111461017d57806389a69c0e14610187578063b387ef92146101bb578063b5c645bd146101f4578063be99a98014610270578063c3d014d6146102a8578063d93e7573146102dc57005b73ffffffffffffffffffffffffffffffffffffffff600435166000908152600160205260409020548060005260206000f35b6000808052602081f35b600435600090815260026020819052604090912001548060005260206000f35b600435600090815260026020908152604082205473ffffffffffffffffffffffffffffffffffffffff1680835291f35b600435600090815260026020908152604082206001015473ffffffffffffffffffffffffffffffffffffffff1680835291f35b60008060005260206000f35b6000808052602081f35b60005461030c9060043590602435903373ffffffffffffffffffffffffffffffffffffffff908116911614610569576105c9565b60005473ffffffffffffffffffffffffffffffffffffffff168073ffffffffffffffffffffffffffffffffffffffff1660005260206000f35b600435600090815260026020819052604090912080546001820154919092015473ffffffffffffffffffffffffffffffffffffffff9283169291909116908273ffffffffffffffffffffffffffffffffffffffff166000528173ffffffffffffffffffffffffffffffffffffffff166020528060405260606000f35b600054610312906004359060243590604435903373ffffffffffffffffffffffffffffffffffffffff90811691161461045457610523565b6000546103189060043590602435903373ffffffffffffffffffffffffffffffffffffffff90811691161461052857610565565b60005461031e90600435903373ffffffffffffffffffffffffffffffffffffffff90811691161461032457610451565b60006000f35b60006000f35b60006000f35b60006000f35b60008181526002602090815260408083205473ffffffffffffffffffffffffffffffffffffffff16835260019091529020548114610361576103e1565b6000818152600260205260408082205473ffffffffffffffffffffffffffffffffffffffff169183917ff63780e752c6a54a94fc52715dbc5518a3b4c3c2833d301a204226548a2a85459190a360008181526002602090815260408083205473ffffffffffffffffffffffffffffffffffffffff16835260019091528120555b600081815260026020819052604080832080547fffffffffffffffffffffffff00000000000000000000000000000000000000009081168255600182018054909116905590910182905582917fa6697e974e6a320f454390be03f74955e8978f1a6971ea6730542e37b66179bc91a25b50565b600083815260026020526040902080547fffffffffffffffffffffffff00000000000000000000000000000000000000001683179055806104bb57827fa6697e974e6a320f454390be03f74955e8978f1a6971ea6730542e37b66179bc60006040a2610522565b73ffffffffffffffffffffffffffffffffffffffff8216837ff63780e752c6a54a94fc52715dbc5518a3b4c3c2833d301a204226548a2a854560006040a373ffffffffffffffffffffffffffffffffffffffff821660009081526001602052604090208390555b5b505050565b600082815260026020819052604080832090910183905583917fa6697e974e6a320f454390be03f74955e8978f1a6971ea6730542e37b66179bc91a25b5050565b60008281526002602052604080822060010180547fffffffffffffffffffffffff0000000000000000000000000000000000000000168417905583917fa6697e974e6a320f454390be03f74955e8978f1a6971ea6730542e37b66179bc91a25b505056" } ], id: jsonRpcRequestId++ }); @@ -329,11 +425,12 @@ function checkRegistration(dappUrl, addr, callBack) return; } var crLevel = clientModel.encodeStringParam(dappUrl[0]); + var gasCost = clientModel.toHex(deploymentDialog.ownedRegistrarSetSubRegistrarGas); requests.push({ //setRegister() jsonrpc: "2.0", method: "eth_sendTransaction", - params: [ { "from": deploymentDialog.currentAccount, "gas": 30000, "to": '0x' + addr, "data": "0x89a69c0e" + crLevel + deploymentDialog.pad(newCtrAddress) } ], + params: [ { "from": deploymentDialog.currentAccount, "gas": "0x" + gasCost, "to": '0x' + addr, "data": "0x89a69c0e" + crLevel + deploymentDialog.pad(newCtrAddress) } ], id: jsonRpcRequestId++ }); @@ -382,16 +479,16 @@ function registerContentHash(registrar, callBack) console.log(txt); var requests = []; var paramTitle = clientModel.encodeStringParam(projectModel.projectTitle); - + var gasCost = clientModel.toHex(deploymentDialog.ownedRegistrarSetContentHashGas); requests.push({ //setContent() jsonrpc: "2.0", method: "eth_sendTransaction", - params: [ { "from": deploymentDialog.currentAccount, "gas": "0xfffff", "to": '0x' + registrar, "data": "0xc3d014d6" + paramTitle + deploymentDialog.packageHash } ], + params: [ { "from": deploymentDialog.currentAccount, "gas": "0x" + gasCost, "to": '0x' + registrar, "data": "0xc3d014d6" + paramTitle + deploymentDialog.packageHash } ], id: jsonRpcRequestId++ }); rpcCall(requests, function (httpRequest, response) { - callBack(); + callBack(true); }); } @@ -402,12 +499,12 @@ function registerToUrlHint() urlHintAddress(function(urlHint){ var requests = []; var paramUrlHttp = clientModel.encodeStringParam(deploymentDialog.applicationUrlHttp); - + var gasCost = clientModel.toHex(deploymentDialog.urlHintSuggestUrlGas); requests.push({ //urlHint => suggestUrl jsonrpc: "2.0", method: "eth_sendTransaction", - params: [ { "to": '0x' + urlHint, "from": deploymentDialog.currentAccount, "gas": "0xfffff", "data": "0x584e86ad" + deploymentDialog.packageHash + paramUrlHttp } ], + params: [ { "to": '0x' + urlHint, "from": deploymentDialog.currentAccount, "gas": "0x" + gasCost, "data": "0x584e86ad" + deploymentDialog.packageHash + paramUrlHttp } ], id: jsonRpcRequestId++ }); @@ -425,7 +522,7 @@ function urlHintAddress(callBack) //registrar: get UrlHint addr jsonrpc: "2.0", method: "eth_call", - params: [ { "to": '0x' + deploymentDialog.eth, "from": deploymentDialog.currentAccount, "gas": "0xfffff", "data": "0x3b3b57de" + urlHint }, "pending" ], + params: [ { "to": '0x' + deploymentDialog.eth, "from": deploymentDialog.currentAccount, "data": "0x3b3b57de" + urlHint }, "pending" ], id: jsonRpcRequestId++ }); @@ -446,6 +543,8 @@ function normalizeAddress(addr) function formatAppUrl(url) { + if (url.toLowerCase().lastIndexOf("/") === url.length - 1) + url = url.substring(0, url.length - 1); if (url.toLowerCase().indexOf("eth://") === 0) url = url.substring(6); if (url.toLowerCase().indexOf(projectModel.projectTitle + ".") === 0) diff --git a/mix/qml/js/TransactionHelper.js b/mix/qml/js/TransactionHelper.js index be057917c..b0a5caa9e 100644 --- a/mix/qml/js/TransactionHelper.js +++ b/mix/qml/js/TransactionHelper.js @@ -15,7 +15,7 @@ function defaultTransaction() function rpcCall(requests, callBack) { - var jsonRpcUrl = "http://localhost:8080"; + var jsonRpcUrl = "http://localhost:8545"; var rpcRequest = JSON.stringify(requests); console.log(rpcRequest); var httpRequest = new XMLHttpRequest(); diff --git a/solc/CommandLineInterface.cpp b/solc/CommandLineInterface.cpp index 0d5f47242..e6f03a2ef 100644 --- a/solc/CommandLineInterface.cpp +++ b/solc/CommandLineInterface.cpp @@ -175,6 +175,9 @@ void CommandLineInterface::handleBytecode(string const& _contract) void CommandLineInterface::handleSignatureHashes(string const& _contract) { + if (!m_args.count(g_argSignatureHashes)) + return; + string out; for (auto const& it: m_compiler->getContractDefinition(_contract).getInterfaceFunctions()) out += toHex(it.first.ref()) + ": " + it.second->externalSignature() + "\n"; diff --git a/test/TestHelper.cpp b/test/TestHelper.cpp index eecf6f80d..144a1a286 100644 --- a/test/TestHelper.cpp +++ b/test/TestHelper.cpp @@ -715,11 +715,10 @@ Options::Options() vmtrace = true; else if (arg == "--filltests") fillTests = true; - else if (arg.compare(0, 7, "--stats") == 0) + else if (arg == "--stats" && i + 1 < argc) { stats = true; - if (arg.size() > 7) - statsOutFile = arg.substr(8); // skip '=' char + statsOutFile = argv[i + 1]; } else if (arg == "--performance") performance = true; @@ -741,6 +740,11 @@ Options::Options() inputLimits = true; bigData = true; } + else if (arg == "--singletest" && i + 1 < argc) + { + singleTest = true; + singleTestName = argv[i + 1]; + } } } diff --git a/test/TestHelper.h b/test/TestHelper.h index 10e76aa96..02f509e4c 100644 --- a/test/TestHelper.h +++ b/test/TestHelper.h @@ -188,6 +188,8 @@ public: /// Test selection /// @{ + bool singleTest = false; + std::string singleTestName; bool performance = false; bool quadratic = false; bool memory = false; diff --git a/test/libdevcrypto/crypto.cpp b/test/libdevcrypto/crypto.cpp index dbbc2dfa0..96826bdf9 100644 --- a/test/libdevcrypto/crypto.cpp +++ b/test/libdevcrypto/crypto.cpp @@ -588,7 +588,7 @@ BOOST_AUTO_TEST_CASE(handshakeNew) BOOST_AUTO_TEST_CASE(ecies_aes128_ctr_unaligned) { - Secret encryptK(sha3("...")); + h128 encryptK(sha3("..."), h128::AlignLeft); h256 egressMac(sha3("+++")); // TESTING: send encrypt magic sequence bytes magic {0x22,0x40,0x08,0x91}; @@ -610,7 +610,7 @@ BOOST_AUTO_TEST_CASE(ecies_aes128_ctr_unaligned) BOOST_AUTO_TEST_CASE(ecies_aes128_ctr) { - Secret k(sha3("0xAAAA")); + h128 k(sha3("0xAAAA"), h128::AlignLeft); string m = "AAAAAAAAAAAAAAAA"; bytesConstRef msg((byte*)m.data(), m.size()); diff --git a/test/libethereum/StateTestsFiller/stSolidityTestFiller.json b/test/libethereum/StateTestsFiller/stSolidityTestFiller.json index c74ced9de..a4243c8dd 100644 --- a/test/libethereum/StateTestsFiller/stSolidityTestFiller.json +++ b/test/libethereum/StateTestsFiller/stSolidityTestFiller.json @@ -1,4 +1,156 @@ { + "ContractInheritance" : { + "env" : { + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", + "currentDifficulty" : "45678256", + "currentGasLimit" : "1000000000000000000000", + "currentNumber" : "120", + "currentTimestamp" : 1, + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6" + }, + "expect" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "storage" : { + "0x" : "0x01" + } + } + }, + "pre" : + { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "100000", + "//" : "contract base ", + "//" : "{ ", + "//" : " function methodA() returns (uint32) ", + "//" : " { ", + "//" : " return 1; ", + "//" : " } ", + "//" : "} ", + "//" : " ", + "//" : "contract frombase is base ", + "//" : "{ ", + "//" : " function methodA() returns (uint32) ", + "//" : " { ", + "//" : " return 2; ", + "//" : " } ", + "//" : "} ", + "//" : " ", + "//" : "contract main ", + "//" : "{ ", + "//" : " bool returnValue; ", + "//" : " function run() returns (bool) ", + "//" : " { ", + "//" : " returnValue = testInheretance(); ", + "//" : " return returnValue; ", + "//" : " } ", + "//" : " ", + "//" : " function testInheretance() returns (bool res) ", + "//" : " { ", + "//" : " res = true; ", + "//" : " base contract1; ", + "//" : " if (contract1.methodA() != 1) ", + "//" : " return false; ", + "//" : " ", + "//" : " frombase contract2; ", + "//" : " if (contract2.methodA() != 2) ", + "//" : " return false; ", + "//" : " } ", + "//" : "} ", + "code" : "0x6000357c0100000000000000000000000000000000000000000000000000000000900480633e0bca3b1461003a578063c04062261461004c57005b610042610099565b8060005260206000f35b61005461005e565b8060005260206000f35b6000610068610099565b600060006101000a81548160ff02191690830217905550600060009054906101000a900460ff169050610096565b90565b60006000600060019250825060018273ffffffffffffffffffffffffffffffffffffffff166381bda09b60206000827c010000000000000000000000000000000000000000000000000000000002600052600460006000866161da5a03f16100fd57005b505060005163ffffffff1614156101135761011c565b60009250610194565b60028173ffffffffffffffffffffffffffffffffffffffff166381bda09b60206000827c010000000000000000000000000000000000000000000000000000000002600052600460006000866161da5a03f161017457005b505060005163ffffffff16141561018a57610193565b60009250610194565b5b50509056", + "nonce" : "0", + "storage" : { + } + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "50000000", + "nonce" : "0", + "code" : "", + "storage": {} + } + }, + "transaction" : + { + "data" : "run()", + "data" : "0xc0406226", + "gasLimit" : "35000000", + "gasPrice" : "1", + "nonce" : "0", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "0" + } + }, + + "TestOverflow" : { + "env" : { + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", + "currentDifficulty" : "45678256", + "currentGasLimit" : "1000000000000000000000", + "currentNumber" : "120", + "currentTimestamp" : 1, + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6" + }, + "expect" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "storage" : { + "0x" : "0x01" + } + } + }, + "pre" : + { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "100000", + "//" : "contract main ", + "//" : "{ ", + "//" : " bool returnValue; ", + "//" : " function run() returns (bool) ", + "//" : " { ", + "//" : " returnValue = testOverflow(); ", + "//" : " return returnValue; ", + "//" : " } ", + "//" : " ", + "//" : " function testOverflow() returns (bool res) ", + "//" : " { ", + "//" : " res = true; ", + "//" : " uint256 a = 115792089237316195423570985008687907853269984665640564039457584007913129639935; ", + "//" : " if (a + 1 != 0) ", + "//" : " return false; ", + "//" : " ", + "//" : " uint32 b = 4294967295; ", + "//" : " if (b + 1 != 0) ", + "//" : " return false; ", + "//" : " ", + "//" : " uint64 c = 18446744073709551615; ", + "//" : " if (c + 1 != 0) ", + "//" : " return false; ", + "//" : " } ", + "//" : "} ", + "code" : "0x6000357c0100000000000000000000000000000000000000000000000000000000900480638040cac41461003a578063c04062261461004c57005b610042610099565b8060005260206000f35b61005461005e565b8060005260206000f35b6000610068610099565b600060006101000a81548160ff02191690830217905550600060009054906101000a900460ff169050610096565b90565b60006000600060006001935083507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff925060006001840114156100db576100e4565b6000935061013b565b63ffffffff915060006001830163ffffffff1614156101025761010b565b6000935061013b565b67ffffffffffffffff905060006001820167ffffffffffffffff1614156101315761013a565b6000935061013b565b5b5050509056", + "nonce" : "0", + "storage" : { + } + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "50000000", + "nonce" : "0", + "code" : "", + "storage": {} + } + }, + "transaction" : + { + "data" : "run()", + "data" : "0xc0406226", + "gasLimit" : "35000000", + "gasPrice" : "1", + "nonce" : "0", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "0" + } + }, + "TestStoreGasPrices" : { "env" : { "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", @@ -125,10 +277,14 @@ "//" : " if (ripemd160('teststring') != 0xcd566972b5e50104011a92b59fa8e0b1234851ae) ", "//" : " return false; ", "//" : " ", - "//" : " //ecrecover ", + "//" : " if (ecrecover(0x18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c, ", + "//" : " 28, 0x73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f, ", + "//" : " 0xeeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549) ", + "//" : " != 0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b) ", + "//" : " return false; ", "//" : " } ", "//" : "} ", - "code" : "0x7c01000000000000000000000000000000000000000000000000000000006000350463c04062268114610039578063e0a9fd281461004b57005b61004161005d565b8060005260206000f35b61005361009d565b8060005260206000f35b600061006761009d565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016919091179081905560ff16905090565b7f74657374737472696e67000000000000000000000000000000000000000000006000908152600190600a90207f43c4b4524adb81e4e9a5c4648a98e9d320e3908ac5b6c889144b642cd08ae16d14156100f6576100fe565b5060006101eb565b60026020600060007f74657374737472696e67000000000000000000000000000000000000000000008152600a01600060008560325a03f161013c57005b506000517f3c8727e019a42b444667a587b6001251becadabbb36bfed8087a92c18882d111141561016c57610174565b5060006101eb565b60036020600060007f74657374737472696e67000000000000000000000000000000000000000000008152600a01600060008560325a03f16101b257005b506000517fcd566972b5e50104011a92b59fa8e0b1234851ae00000000000000000000000014156101e2576101ea565b5060006101eb565b5b9056", + "code" : "0x6000357c010000000000000000000000000000000000000000000000000000000090048063c04062261461003a578063e0a9fd281461004c57005b61004261005e565b8060005260206000f35b610054610099565b8060005260206000f35b6000610068610099565b600060006101000a81548160ff02191690830217905550600060009054906101000a900460ff169050610096565b90565b60006001905080507f43c4b4524adb81e4e9a5c4648a98e9d320e3908ac5b6c889144b642cd08ae16d60010260407f74657374737472696e67000000000000000000000000000000000000000000008152600a016040900360402014156100ff57610108565b600090506102ec565b7f3c8727e019a42b444667a587b6001251becadabbb36bfed8087a92c18882d11160010260026020600060007f74657374737472696e67000000000000000000000000000000000000000000008152600a0160006000856161da5a03f161016b57005b50600051141561017a57610183565b600090506102ec565b73cd566972b5e50104011a92b59fa8e0b1234851ae6c010000000000000000000000000260036020600060007f74657374737472696e67000000000000000000000000000000000000000000008152600a0160006000856161da5a03f16101e657005b506000516c010000000000000000000000000214156102045761020d565b600090506102ec565b73a94f5374fce5edbc8e2a8697c15331677e6ebf0b60016020600060007f18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c6001028152602001601c81526020017f73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f60010281526020017feeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549600102815260200160006000856161da5a03f16102bd57005b5060005173ffffffffffffffffffffffffffffffffffffffff1614156102e2576102eb565b600090506102ec565b5b9056", "nonce" : "0", "storage" : { } diff --git a/test/libethereum/state.cpp b/test/libethereum/state.cpp index 900f3060f..9f676d437 100644 --- a/test/libethereum/state.cpp +++ b/test/libethereum/state.cpp @@ -43,9 +43,14 @@ void doStateTests(json_spirit::mValue& v, bool _fillin) { for (auto& i: v.get_obj()) { - std::cout << " " << i.first << "\n"; mObject& o = i.second.get_obj(); + if (test::Options::get().singleTest && test::Options::get().singleTestName != i.first) + { + o.clear(); + continue; + } + std::cout << " " << i.first << std::endl; BOOST_REQUIRE(o.count("env") > 0); BOOST_REQUIRE(o.count("pre") > 0); BOOST_REQUIRE(o.count("transaction") > 0); @@ -62,7 +67,7 @@ void doStateTests(json_spirit::mValue& v, bool _fillin) } catch (Exception const& _e) { - cnote << "Exception:\n" << diagnostic_information(_e); + cnote << "Exception: " << diagnostic_information(_e); theState.commit(); } catch (std::exception const& _e) diff --git a/test/libp2p/peer.cpp b/test/libp2p/peer.cpp index 727430fc8..2e3320006 100644 --- a/test/libp2p/peer.cpp +++ b/test/libp2p/peer.cpp @@ -118,6 +118,61 @@ BOOST_AUTO_TEST_CASE(save_nodes) BOOST_AUTO_TEST_SUITE_END() +BOOST_FIXTURE_TEST_SUITE(p2pPeer, P2PFixture) + +BOOST_AUTO_TEST_CASE(requirePeer) +{ + auto oldLogVerbosity = g_logVerbosity; + g_logVerbosity = 10; + + const char* const localhost = "127.0.0.1"; + NetworkPreferences prefs1(localhost, 30301, false); + NetworkPreferences prefs2(localhost, 30302, false); + Host host1("Test", prefs1); + host1.start(); + + Host host2("Test", prefs2); + host2.start(); + + auto node2 = host2.id(); + host1.requirePeer(node2, NodeIPEndpoint(bi::address::from_string(localhost), prefs2.listenPort, prefs2.listenPort)); + + this_thread::sleep_for(chrono::seconds(3)); + + auto host1peerCount = host1.peerCount(); + auto host2peerCount = host2.peerCount(); + BOOST_REQUIRE_EQUAL(host1peerCount, 1); + BOOST_REQUIRE_EQUAL(host2peerCount, 1); + + PeerSessionInfos sis1 = host1.peerSessionInfo(); + PeerSessionInfos sis2 = host2.peerSessionInfo(); + + BOOST_REQUIRE_EQUAL(sis1.size(), 1); + BOOST_REQUIRE_EQUAL(sis2.size(), 1); + + Peers peers1 = host1.getPeers(); + Peers peers2 = host2.getPeers(); + BOOST_REQUIRE_EQUAL(peers1.size(), 1); + BOOST_REQUIRE_EQUAL(peers2.size(), 1); + + DisconnectReason disconnect1 = peers1[0].lastDisconnect(); + DisconnectReason disconnect2 = peers2[0].lastDisconnect(); + BOOST_REQUIRE_EQUAL(disconnect1, disconnect2); + + host1.relinquishPeer(node2); + + this_thread::sleep_for(chrono::seconds(1)); + + host1peerCount = host1.peerCount(); + host2peerCount = host2.peerCount(); + BOOST_REQUIRE_EQUAL(host1peerCount, 1); + BOOST_REQUIRE_EQUAL(host2peerCount, 1); + + g_logVerbosity = oldLogVerbosity; +} + +BOOST_AUTO_TEST_SUITE_END() + BOOST_AUTO_TEST_SUITE(peerTypes) BOOST_AUTO_TEST_CASE(emptySharedPeer) diff --git a/test/libsolidity/Assembly.cpp b/test/libsolidity/Assembly.cpp index 8dcee7fb5..ccc4bf811 100644 --- a/test/libsolidity/Assembly.cpp +++ b/test/libsolidity/Assembly.cpp @@ -17,20 +17,20 @@ /** * @author Lefteris Karapetsas * @date 2015 - * Unit tests for Assembly Items from evmcore/Assembly.h + * Unit tests for Assembly Items from evmasm/Assembly.h */ #include #include #include #include -#include +#include +#include #include #include #include #include #include -#include using namespace std; using namespace dev::eth; diff --git a/test/libsolidity/SolidityOptimizer.cpp b/test/libsolidity/SolidityOptimizer.cpp index ceb9c68d9..9cdaa5886 100644 --- a/test/libsolidity/SolidityOptimizer.cpp +++ b/test/libsolidity/SolidityOptimizer.cpp @@ -26,9 +26,9 @@ #include #include #include -#include -#include -#include +#include +#include +#include using namespace std; using namespace dev::eth;