diff --git a/alethzero/Main.ui b/alethzero/Main.ui index d2f4e893e..f9e734c8b 100644 --- a/alethzero/Main.ui +++ b/alethzero/Main.ui @@ -1,198 +1,41 @@ Main - + 0 0 - 991 - 556 + 1112 + 766 AlethZero Ethereum Client - + + QMainWindow::AllowTabbedDocks|QMainWindow::VerticalTabs + + true - - - - - QFrame::NoFrame - - - QFrame::Raised - - - - 0 - - - - - - 0 - 0 - - - - UPnP - - - true - - - true - - - - - - - Net - - - true - - - - - - - 1024 - - - 32767 - - - 30303 - - - - - - - Connect - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - wei - - - 430000000 - - - 1000 - - - - - - - ) - - - (fee - - - 430000000 - - - 100 - - - - - - - - - - Send - - - - - - - Create - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - Mine - - - true - - - - - - - - - - - 0 - 0 - - - - Qt::Horizontal - - - + + + + 4 + + + 0 + + + QFrame::NoFrame - - - - - - - - - 0 - + + + @@ -201,9 +44,9 @@ - - - true + + + 0 peers @@ -214,17 +57,386 @@ - - - - 0 peers - - - - - - + + + + + + + 0 + 0 + 1112 + 28 + + + + + &File + + + + + + &Network + + + + + + + + &Tools + + + + + + + + + + + + QDockWidget::DockWidgetFeatureMask + + + All Accounts + + + 2 + + + + + 0 + + + + + QFrame::NoFrame + + + + + + + + + QDockWidget::DockWidgetFeatureMask + + + Network + + + 2 + + + + + 4 + + + 0 + + + + + QFrame::NoFrame + + + + + + + + + Listen on + + + + + + + 1024 + + + 32767 + + + 30303 + + + + + + + + + + + QDockWidget::DockWidgetFeatureMask + + + Log + + + 8 + + + + + 0 + + + + + QFrame::NoFrame + + + + + + + + + QDockWidget::DockWidgetFeatureMask + + + Pending + + + 2 + + + + + 0 + + + 0 + + + + + QFrame::NoFrame + + + + + + + + + toolBar + + + TopToolBarArea + + + false + + + + + + + + 0 + 0 + + + + + 349 + 225 + + + + QDockWidget::DockWidgetFeatureMask + + + Transact + + + 1 + + + + + 0 + + + 4 + + + + + + 1 + 0 + + + + + + + + Send + + + + + + + + + + Amount + + + + + + + + + + 430000000 + + + 1000 + + + + + + + + 0 + 0 + + + + To + + + + + + + + + + + + + + + + 430000000 + + + 100 + + + + + + + Fee + + + + + + + + + + Data + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + + + QDockWidget::DockWidgetFeatureMask + + + Owned Accounts + + + 1 + + + + + 0 + + + + + QFrame::NoFrame + + + QAbstractItemView::InternalMove + + + true + + + + + + + + + &Quit + + + + + true + + + true + + + Use &UPnP + + + + + &Connect + + + + + true + + + &Listen + + + + + true + + + &Mine + + + + + &New Address + + diff --git a/alethzero/MainWin.cpp b/alethzero/MainWin.cpp index 6e8bc64fc..3e9612b7b 100644 --- a/alethzero/MainWin.cpp +++ b/alethzero/MainWin.cpp @@ -7,13 +7,22 @@ using namespace std; using namespace eth; +static void initUnits(QComboBox* _b) +{ + for (int n = units().size() - 1; n >= 0; --n) + _b->addItem(QString::fromStdString(units()[n].second), n); + _b->setCurrentIndex(6); +} + Main::Main(QWidget *parent) : - QDialog(parent), + QMainWindow(parent), ui(new Ui::Main), - m_client("AlethZero/v0.1") + m_client("AlethZero/v0.1.1") { setWindowFlags(Qt::Window); ui->setupUi(this); + initUnits(ui->valueUnits); + initUnits(ui->feeUnits); readSettings(); refresh(); @@ -34,10 +43,13 @@ Main::Main(QWidget *parent) : m_webCtrl.get(r); srand(time(0)); #endif + + g_logPost = [=](std::string const& s, char const*) { ui->log->addItem(QString::fromStdString(s)); }; } Main::~Main() { + g_logPost = simpleDebugOut; writeSettings(); delete ui; } @@ -46,8 +58,13 @@ void Main::writeSettings() { QSettings s("ethereum", "alethzero"); QByteArray b; - b.resize(32); - memcpy(b.data(), &m_myKey, 32); + b.resize(sizeof(Secret) * m_myKeys.size()); + auto p = b.data(); + for (auto i: m_myKeys) + { + memcpy(p, &(i.secret()), sizeof(Secret)); + p += sizeof(Secret); + } s.setValue("address", b); // TODO: save peers - implement it in PeerNetwork though returning RLP bytes @@ -62,14 +79,17 @@ void Main::readSettings() QSettings s("ethereum", "alethzero"); QByteArray b = s.value("address").toByteArray(); if (b.isEmpty()) - m_myKey = KeyPair::create(); + m_myKeys.append(KeyPair::create()); else { h256 k; - memcpy(&k, b.data(), 32); - m_myKey = KeyPair(k); + for (unsigned i = 0; i < b.size() / sizeof(Secret); ++i) + { + memcpy(&k, b.data() + i * sizeof(Secret), sizeof(Secret)); + m_myKeys.append(KeyPair(k)); + } } - m_client.setAddress(m_myKey.address()); + m_client.setAddress(m_myKeys.back().address()); writeSettings(); @@ -83,68 +103,89 @@ void Main::readSettings() void Main::refresh() { m_client.lock(); - ui->balance->setText(QString::fromStdString(formatBalance(m_client.state().balance(m_myKey.address())))); - ui->peerCount->setText(QString::fromStdString(toString(m_client.peerCount())) + " peer(s)"); - ui->address->setText(QString::fromStdString(asHex(m_client.state().address().asArray()))); - ui->peers->clear(); - for (PeerInfo const& i: m_client.peers()) - ui->peers->addItem(QString("%3 ms - %1:%2 - %4").arg(i.host.c_str()).arg(i.port).arg(chrono::duration_cast(i.lastPing).count()).arg(i.clientVersion.c_str())); - - auto d = m_client.blockChain().details(); - auto diff = BlockInfo(m_client.blockChain().block()).difficulty; - ui->blockChain->setText(QString("#%1 @%3 T%2").arg(d.number).arg(toLog2(d.totalDifficulty)).arg(toLog2(diff))); - - auto acs = m_client.state().addresses(); - ui->accounts->clear(); - for (auto i: acs) - ui->accounts->addItem(QString("%1 @ %2").arg(formatBalance(i.second).c_str()).arg(asHex(i.first.asArray()).c_str())); - - ui->transactionQueue->clear(); - for (pair const& i: m_client.transactionQueue().transactions()) + if (m_client.changed()) { - Transaction t(i.second); - ui->transactionQueue->addItem(QString("%1 (%2 fee) @ %3 <- %4") - .arg(formatBalance(t.value).c_str()) - .arg(formatBalance(t.fee).c_str()) - .arg(asHex(t.receiveAddress.asArray()).c_str()) - .arg(asHex(t.sender().asArray()).c_str()) ); - } + ui->peerCount->setText(QString::fromStdString(toString(m_client.peerCount())) + " peer(s)"); + ui->peers->clear(); + for (PeerInfo const& i: m_client.peers()) + ui->peers->addItem(QString("%3 ms - %1:%2 - %4").arg(i.host.c_str()).arg(i.port).arg(chrono::duration_cast(i.lastPing).count()).arg(i.clientVersion.c_str())); + + auto d = m_client.blockChain().details(); + auto diff = BlockInfo(m_client.blockChain().block()).difficulty; + ui->blockChain->setText(QString("#%1 @%3 T%2").arg(d.number).arg(toLog2(d.totalDifficulty)).arg(toLog2(diff))); + + auto acs = m_client.state().addresses(); + ui->accounts->clear(); + for (auto i: acs) + ui->accounts->addItem(QString("%1 @ %2").arg(formatBalance(i.second).c_str()).arg(asHex(i.first.asArray()).c_str())); + + ui->transactionQueue->clear(); + for (pair const& i: m_client.transactionQueue().transactions()) + { + Transaction t(i.second); + ui->transactionQueue->addItem(QString("%1 (%2 fee) @ %3 <- %4") + .arg(formatBalance(t.value).c_str()) + .arg(formatBalance(t.fee).c_str()) + .arg(asHex(t.receiveAddress.asArray()).c_str()) + .arg(asHex(t.sender().asArray()).c_str()) ); + } - ui->transactions->clear(); - auto const& bc = m_client.blockChain(); - for (auto h = bc.currentHash(); h != bc.genesisHash(); h = bc.details(h).parent) - { - auto d = bc.details(h); - ui->transactions->addItem(QString("# %1 ==== %2").arg(d.number).arg(asHex(h.asArray()).c_str())); - for (auto const& i: RLP(bc.block(h))[1]) + ui->transactions->clear(); + auto const& bc = m_client.blockChain(); + for (auto h = bc.currentHash(); h != bc.genesisHash(); h = bc.details(h).parent) { - Transaction t(i.data()); - ui->transactions->addItem(QString("%1 wei (%2 fee) @ %3 <- %4") - .arg(toString(t.value).c_str()) - .arg(toString(t.fee).c_str()) - .arg(asHex(t.receiveAddress.asArray()).c_str()) - .arg(asHex(t.sender().asArray()).c_str()) ); + auto d = bc.details(h); + ui->transactions->addItem(QString("# %1 ==== %2").arg(d.number).arg(asHex(h.asArray()).c_str())); + for (auto const& i: RLP(bc.block(h))[1]) + { + Transaction t(i.data()); + ui->transactions->addItem(QString("%1 (%2) @ %3 <- %4") + .arg(formatBalance(t.value).c_str()) + .arg(formatBalance(t.fee).c_str()) + .arg(asHex(t.receiveAddress.asArray()).c_str()) + .arg(asHex(t.sender().asArray()).c_str()) ); + } } } + ui->ourAccounts->clear(); + u256 totalBalance = 0; + for (auto i: m_myKeys) + { + u256 b = m_client.state().balance(i.address()); + ui->ourAccounts->addItem(QString("%1 @ %2").arg(formatBalance(b).c_str()).arg(asHex(i.address().asArray()).c_str())); + totalBalance += b; + } + ui->balance->setText(QString::fromStdString(formatBalance(totalBalance))); m_client.unlock(); } -void Main::on_net_toggled() +void Main::on_ourAccounts_doubleClicked() { + qApp->clipboard()->setText(ui->ourAccounts->currentItem()->text().section(" @ ", 1)); +} + +void Main::on_accounts_doubleClicked() +{ + qApp->clipboard()->setText(ui->accounts->currentItem()->text().section(" @ ", 1)); +} + +void Main::on_net_triggered() +{ + ui->port->setEnabled(!ui->net->isChecked()); if (ui->net->isChecked()) - m_client.startNetwork(ui->port->value(), string(), 30303, 6, NodeMode::Full, 5, std::string(), ui->upnp->isChecked()); + m_client.startNetwork(ui->port->value(), string(), 0, NodeMode::Full, 5, std::string(), ui->upnp->isChecked()); else m_client.stopNetwork(); } -void Main::on_connect_clicked() +void Main::on_connect_triggered() { if (!ui->net->isChecked()) ui->net->setChecked(true); bool ok = false; QString s = QInputDialog::getItem(this, "Connect to a Network Peer", "Enter a peer to which a connection may be made:", m_servers, m_servers.count() ? rand() % m_servers.count() : 0, true, &ok); - if (ok) + if (ok && s.contains(":")) { string host = s.section(":", 0, 0).toStdString(); short port = s.section(":", 1).toInt(); @@ -152,25 +193,43 @@ void Main::on_connect_clicked() } } -void Main::on_mine_toggled() +void Main::on_mine_triggered() { if (ui->mine->isChecked()) + { + m_client.setAddress(m_myKeys.last().address()); m_client.startMining(); + } else m_client.stopMining(); } void Main::on_send_clicked() { - Secret s = m_myKey.secret(); - Address r = Address(fromUserHex(ui->destination->text().toStdString())); - m_client.transact(s, r, ui->value->value(), ui->fee->value()); - refresh(); + u256 value = ui->value->value() * units()[units().size() - 1 - ui->valueUnits->currentIndex()].first; + u256 fee = ui->fee->value() * units()[units().size() - 1 - ui->feeUnits->currentIndex()].first; + u256 totalReq = value + fee; + m_client.lock(); + for (auto i: m_myKeys) + if (m_client.state().balance(i.address()) >= totalReq) + { + m_client.unlock(); + Secret s = m_myKeys.front().secret(); + Address r = Address(fromUserHex(ui->destination->text().toStdString())); + auto ds = ui->data->toPlainText().split(QRegExp("[^0-9a-fA-Fx]+")); + u256s data; + data.reserve(ds.size()); + for (QString const& i: ds) + data.push_back(u256(i.toStdString())); + m_client.transact(s, r, value, fee, data); + refresh(); + return; + } + m_client.unlock(); + statusBar()->showMessage("Couldn't make transaction: no single account contains at least the required amount."); } -void Main::on_create_clicked() +void Main::on_create_triggered() { - KeyPair p = KeyPair::create(); - QString s = QString::fromStdString("The new secret key is:\n" + asHex(p.secret().asArray()) + "\n\nAddress:\n" + asHex(p.address().asArray())); - QMessageBox::information(this, "Create Key", s, QMessageBox::Ok); + m_myKeys.append(KeyPair::create()); } diff --git a/alethzero/MainWin.h b/alethzero/MainWin.h index 037763754..6df549e18 100644 --- a/alethzero/MainWin.h +++ b/alethzero/MainWin.h @@ -3,7 +3,7 @@ #include #include -#include +#include #include #include @@ -11,7 +11,7 @@ namespace Ui { class Main; } -class Main : public QDialog +class Main : public QMainWindow { Q_OBJECT @@ -20,11 +20,14 @@ public: ~Main(); private slots: - void on_connect_clicked(); - void on_mine_toggled(); + void on_connect_triggered(); + void on_mine_triggered(); void on_send_clicked(); - void on_create_clicked(); - void on_net_toggled(); + void on_create_triggered(); + void on_net_triggered(); + void on_ourAccounts_doubleClicked(); + void on_accounts_doubleClicked(); + void on_quit_triggered() { close(); } void refresh(); @@ -36,12 +39,10 @@ private: eth::Client m_client; - eth::KeyPair m_myKey; - std::vector m_peers; - QMutex m_guiLock; QTimer* m_refresh; QStringList m_servers; + QVector m_myKeys; QNetworkAccessManager m_webCtrl; }; diff --git a/eth/main.cpp b/eth/main.cpp index 2d6c96a73..04e4871b3 100644 --- a/eth/main.cpp +++ b/eth/main.cpp @@ -68,7 +68,6 @@ int main(int argc, char** argv) bool interactive = false; string dbPath; eth::uint mining = ~(eth::uint)0; - unsigned verbosity = 1; NodeMode mode = NodeMode::Full; unsigned peers = 5; string publicIP; @@ -144,7 +143,7 @@ int main(int argc, char** argv) } } else if ((arg == "-v" || arg == "--verbosity") && i + 1 < argc) - verbosity = atoi(argv[++i]); + g_logVerbosity = atoi(argv[++i]); else if ((arg == "-x" || arg == "--peers") && i + 1 < argc) peers = atoi(argv[++i]); else if ((arg == "-o" || arg == "--mode") && i + 1 < argc) @@ -229,7 +228,7 @@ int main(int argc, char** argv) } else { - c.startNetwork(listenPort, remoteHost, remotePort, verbosity, mode, peers, publicIP, upnp); + c.startNetwork(listenPort, remoteHost, remotePort, mode, peers, publicIP, upnp); eth::uint n = c.blockChain().details().number; while (true) { diff --git a/libethereum/Client.cpp b/libethereum/Client.cpp index 774ba308e..3be0a96d9 100644 --- a/libethereum/Client.cpp +++ b/libethereum/Client.cpp @@ -41,7 +41,7 @@ Client::Client(std::string const& _clientVersion, Address _us, std::string const m_s.sync(m_tq); m_changed = true; - m_work = new thread([&](){ while (m_workState != Deleting) work(); m_workState = Deleted; }); + m_work = new thread([&](){ setThreadName("eth"); while (m_workState != Deleting) work(); m_workState = Deleted; }); } Client::~Client() @@ -52,13 +52,12 @@ Client::~Client() usleep(10000); } -void Client::startNetwork(short _listenPort, std::string const& _seedHost, short _port, unsigned _verbosity, NodeMode _mode, unsigned _peers, string const& _publicIP, bool _upnp) +void Client::startNetwork(short _listenPort, std::string const& _seedHost, short _port, NodeMode _mode, unsigned _peers, string const& _publicIP, bool _upnp) { if (m_net) return; m_net = new PeerServer(m_clientVersion, m_bc, 0, _listenPort, _mode, _publicIP, _upnp); m_net->setIdealPeerCount(_peers); - m_net->setVerbosity(_verbosity); if (_seedHost.size()) m_net->connect(_seedHost, _port); } diff --git a/libethereum/Client.h b/libethereum/Client.h index 89053a203..5f193fea2 100644 --- a/libethereum/Client.h +++ b/libethereum/Client.h @@ -92,7 +92,7 @@ public: unsigned peerCount() const { return m_net ? m_net->peerCount() : 0; } /// Start the network subsystem. - void startNetwork(short _listenPort = 30303, std::string const& _seedHost = std::string(), short _port = 30303, unsigned _verbosity = 4, NodeMode _mode = NodeMode::Full, unsigned _peers = 5, std::string const& _publicIP = std::string(), bool _upnp = true); + void startNetwork(short _listenPort = 30303, std::string const& _seedHost = std::string(), short _port = 30303, NodeMode _mode = NodeMode::Full, unsigned _peers = 5, std::string const& _publicIP = std::string(), bool _upnp = true); /// Connect to a particular peer. void connect(std::string const& _seedHost, short _port = 30303); /// Stop the network subsystem. diff --git a/libethereum/Common.cpp b/libethereum/Common.cpp index 548883a2e..c05662ef8 100644 --- a/libethereum/Common.cpp +++ b/libethereum/Common.cpp @@ -18,6 +18,10 @@ * @author Gav Wood * @date 2014 */ + +#include "Common.h" + +#include #if WIN32 #pragma warning(push) #pragma warning(disable:4244) @@ -30,32 +34,22 @@ #pragma warning(pop) #else #endif -#include -#include "Common.h" #include "Exceptions.h" using namespace std; using namespace eth; // Logging -bool eth::g_debugEnabled[256] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, true, true, true, true, true, true}; -char const* g_debugName[256] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ">>>", "<<<", "LOG", "---", "***", "!!!"}; +int eth::g_logVerbosity = 6; +map eth::g_logOverride; +thread_local std::string eth::t_logThreadName = "???"; +static std::string g_mainThreadName = (eth::t_logThreadName = "main"); -void eth::simpleDebugOut(std::string const& _s, unsigned char _id) +void eth::simpleDebugOut(std::string const& _s, char const*) { - // TODO: Time & thread. - if (g_debugEnabled[_id]) - std::cout << (g_debugName[_id] ? g_debugName[_id] : " ") << " " << _s << std::endl << std::flush; + cout << _s << endl << flush; } -std::function eth::g_debugPost = simpleDebugOut; -std::function eth::g_syslogPost = - [](char _c, string const& _s) - { - if (_c == 'C') - simpleDebugOut(_s, LogChannel); - else - simpleDebugOut("", LogChannel); - }; +std::function eth::g_logPost = simpleDebugOut; std::string eth::escaped(std::string const& _s, bool _all) { @@ -202,38 +196,45 @@ KeyPair KeyPair::create() return ret; } +static const vector> g_units = +{ + {((((u256(1000000000) * 1000000000) * 1000000000) * 1000000000) * 1000000000) * 1000000000, "Uether"}, + {((((u256(1000000000) * 1000000000) * 1000000000) * 1000000000) * 1000000000) * 1000000, "Vether"}, + {((((u256(1000000000) * 1000000000) * 1000000000) * 1000000000) * 1000000000) * 1000, "Dether"}, + {(((u256(1000000000) * 1000000000) * 1000000000) * 1000000000) * 1000000000, "Nether"}, + {(((u256(1000000000) * 1000000000) * 1000000000) * 1000000000) * 1000000, "Yether"}, + {(((u256(1000000000) * 1000000000) * 1000000000) * 1000000000) * 1000, "Zether"}, + {((u256(1000000000) * 1000000000) * 1000000000) * 1000000000, "Eether"}, + {((u256(1000000000) * 1000000000) * 1000000000) * 1000000, "Pether"}, + {((u256(1000000000) * 1000000000) * 1000000000) * 1000, "Tether"}, + {(u256(1000000000) * 1000000000) * 1000000000, "Gether"}, + {(u256(1000000000) * 1000000000) * 1000000, "Mether"}, + {(u256(1000000000) * 1000000000) * 1000, "Kether"}, + {u256(1000000000) * 1000000000, "ether"}, + {u256(1000000000) * 1000000, "finney"}, + {u256(1000000000) * 1000, "szabo"}, + {u256(1000000000), "Gwei"}, + {u256(1000000), "Mwei"}, + {u256(1000), "Kwei"}, + {u256(1), "wei"} +}; + +vector> const& eth::units() +{ + return g_units; +} + std::string eth::formatBalance(u256 _b) { - static const vector> c_units = - { - {((((u256(1000000000) * 1000000000) * 1000000000) * 1000000000) * 1000000000) * 1000000000, "Uether"}, - {((((u256(1000000000) * 1000000000) * 1000000000) * 1000000000) * 1000000000) * 1000000, "Vether"}, - {((((u256(1000000000) * 1000000000) * 1000000000) * 1000000000) * 1000000000) * 1000, "Dether"}, - {(((u256(1000000000) * 1000000000) * 1000000000) * 1000000000) * 1000000000, "Nether"}, - {(((u256(1000000000) * 1000000000) * 1000000000) * 1000000000) * 1000000, "Yether"}, - {(((u256(1000000000) * 1000000000) * 1000000000) * 1000000000) * 1000, "Zether"}, - {((u256(1000000000) * 1000000000) * 1000000000) * 1000000000, "Eether"}, - {((u256(1000000000) * 1000000000) * 1000000000) * 1000000, "Pether"}, - {((u256(1000000000) * 1000000000) * 1000000000) * 1000, "Tether"}, - {(u256(1000000000) * 1000000000) * 1000000000, "Gether"}, - {(u256(1000000000) * 1000000000) * 1000000, "Mether"}, - {(u256(1000000000) * 1000000000) * 1000, "Kether"}, - {u256(1000000000) * 1000000000, "ether"}, - {u256(1000000000) * 1000000, "finney"}, - {u256(1000000000) * 1000, "szabo"}, - {u256(1000000000), "Gwei"}, - {u256(1000000), "Mwei"}, - {u256(1000), "Kwei"} - }; ostringstream ret; - if (_b > c_units[0].first * 10000) + if (_b > g_units[0].first * 10000) { - ret << (_b / c_units[0].first) << " " << c_units[0].second; + ret << (_b / g_units[0].first) << " " << g_units[0].second; return ret.str(); } ret << setprecision(5); - for (auto const& i: c_units) - if (_b >= i.first * 100) + for (auto const& i: g_units) + if (i.first != 1 && _b >= i.first * 100) { ret << (double(_b / (i.first / 1000)) / 1000.0) << " " << i.second; return ret.str(); diff --git a/libethereum/Common.h b/libethereum/Common.h index f4518651a..bd64fadc5 100644 --- a/libethereum/Common.h +++ b/libethereum/Common.h @@ -28,6 +28,9 @@ #pragma warning(disable:4244) #endif +#include +#include +#include #include #include #include @@ -148,68 +151,63 @@ public: template NullOutputStream& operator<<(T const&) { return *this; } }; -extern bool g_debugEnabled[256]; -static const uint8_t WarnChannel = 255; -static const uint8_t NoteChannel = 254; -static const uint8_t DebugChannel = 253; -static const uint8_t LogChannel = 252; -static const uint8_t LeftChannel = 251; -static const uint8_t RightChannel = 250; -// Unused for now. -/*template struct LogName { static const char constexpr* name = " "; }; -template <> struct LogName { static const char constexpr* name = "<<<"; }; -template <> struct LogName { static const char constexpr* name = ">>>"; }; -template <> struct LogName { static const char constexpr* name = "!!!"; }; -template <> struct LogName { static const char constexpr* name = "***"; }; -template <> struct LogName { static const char constexpr* name = "---"; }; -template <> struct LogName { static const char constexpr* name = "LOG"; };*/ - -extern std::function g_debugPost; -extern std::function g_syslogPost; - -void simpleDebugOut(std::string const&, unsigned char); - -template -class DebugOutputStream -{ -public: - DebugOutputStream(char const* _start = " ") { sstr << _start; } - ~DebugOutputStream() { g_debugPost(sstr.str(), _Id); } - template DebugOutputStream& operator<<(T const& _t) { if (_AutoSpacing && sstr.str().size() && sstr.str().back() != ' ') sstr << " "; sstr << _t; return *this; } - std::stringstream sstr; -}; +extern std::map g_logOverride; +extern thread_local std::string t_logThreadName; + +inline void setThreadName(std::string const& _n) { t_logThreadName = _n; } + +struct LogChannel { static const char constexpr* name = " "; static const int verbosity = 1; }; +struct LeftChannel: public LogChannel { static const char constexpr* name = "<<<"; }; +struct RightChannel: public LogChannel { static const char constexpr* name = ">>>"; }; +struct WarnChannel: public LogChannel { static const char constexpr* name = "!!!"; static const int verbosity = 0; }; +struct NoteChannel: public LogChannel { static const char constexpr* name = "***"; }; +struct DebugChannel: public LogChannel { static const char constexpr* name = "---"; static const int verbosity = 0; }; -template -class SysLogOutputStream +extern int g_logVerbosity; +extern std::function g_logPost; + +void simpleDebugOut(std::string const&, char const* ); + +template +class LogOutputStream { public: - SysLogOutputStream() {} - ~SysLogOutputStream() { if (sstr.str().size()) g_syslogPost('C', sstr.str()); } - template SysLogOutputStream& operator<<(T const& _t) { if (_AutoSpacing && sstr.str().size() && sstr.str().back() != ' ') sstr << " "; sstr << _t; return *this; } - static void write(char _type, std::string const& _s) { g_syslogPost(_type, _s); } - template static void writePod(char _type, _T const& _s) { char const* begin = (char const*)&_s; char const* end = (char const*)&_s + sizeof(_T); g_syslogPost(_type, std::string(begin, end)); } + LogOutputStream(bool _term = true) + { + std::type_info const* i = &typeid(Id); + auto it = g_logOverride.find(i); + if ((it != g_logOverride.end() && it->second == true) || (it == g_logOverride.end() && Id::verbosity <= g_logVerbosity)) + { + time_t rawTime = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()); + sstr << Id::name << " [ " << rawTime /*put_time("%T", std::localtime(&rawTime)) */<< " | " << t_logThreadName << (_term ? " ] " : ""); + } + } + ~LogOutputStream() { if (Id::verbosity <= g_logVerbosity) g_logPost(sstr.str(), Id::name); } + template LogOutputStream& operator<<(T const& _t) { if (Id::verbosity <= g_logVerbosity) { if (_AutoSpacing && sstr.str().size() && sstr.str().back() != ' ') sstr << " "; sstr << _t; } return *this; } std::stringstream sstr; }; // Dirties the global namespace, but oh so convenient... -#define cnote eth::DebugOutputStream() -#define cwarn eth::DebugOutputStream() +#define cnote eth::LogOutputStream() +#define cwarn eth::LogOutputStream() -#define nbug(X) if (true) {} else eth::NullOutputStream() -#define nsbug(X) if (true) {} else eth::NullOutputStream() #define ndebug if (true) {} else eth::NullOutputStream() +#define nlog(X) if (true) {} else eth::NullOutputStream() +#define nslog(X) if (true) {} else eth::NullOutputStream() #if NDEBUG -#define cbug(X) nbug(X) -#define csbug(X) nsbug(X) #define cdebug ndebug #else -#define cbug(X) eth::DebugOutputStream() -#define csbug(X) eth::DebugOutputStream() -#define cdebug eth::DebugOutputStream() +#define cdebug eth::LogOutputStream() #endif -#define clog eth::SysLogOutputStream() +#if NLOG +#define clog(X) nlog(X) +#define cslog(X) nslog(X) +#else +#define clog(X) eth::LogOutputStream() +#define cslog(X) eth::LogOutputStream() +#endif @@ -412,6 +410,9 @@ h256 sha3(bytesConstRef _input); inline h256 sha3(bytes const& _input) { return sha3(bytesConstRef((bytes*)&_input)); } inline h256 sha3(std::string const& _input) { return sha3(bytesConstRef(_input)); } +/// Get information concerning the currency denominations. +std::vector> const& units(); + /// Convert a private key into the public key equivalent. /// @returns 0 if it's not a valid private key. Address toAddress(h256 _private); @@ -424,8 +425,8 @@ public: static KeyPair create(); - Secret secret() const { return m_secret; } - Address address() const { return m_address; } + Secret const& secret() const { return m_secret; } + Address const& address() const { return m_address; } private: Secret m_secret; diff --git a/libethereum/PeerNetwork.cpp b/libethereum/PeerNetwork.cpp index 0730f23f9..6336235b5 100644 --- a/libethereum/PeerNetwork.cpp +++ b/libethereum/PeerNetwork.cpp @@ -40,6 +40,8 @@ using namespace std; using namespace eth; +#define clogS(X) eth::LogOutputStream(false) << " | " << std::setw(2) << m_socket.native_handle() << " ] " + static const eth::uint c_maxHashes = 256; ///< Maximum number of hashes GetChain will ever send. static const eth::uint c_maxBlocks = 128; ///< Maximum number of blocks Blocks will ever send. BUG: if this gets too big (e.g. 2048) stuff starts going wrong. static const eth::uint c_maxBlocksAsk = 2048; ///< Maximum number of blocks we ask to receive in Blocks (when using GetChain). @@ -84,8 +86,7 @@ bi::tcp::endpoint PeerSession::endpoint() const bool PeerSession::interpret(RLP const& _r) { - if (m_server->m_verbosity >= 8) - cout << ">>> " << _r << endl; + clogS(NetRight) << _r; switch (_r[0].toInt()) { case HelloPacket: @@ -96,10 +97,9 @@ bool PeerSession::interpret(RLP const& _r) m_caps = _r.itemCount() > 4 ? _r[4].toInt() : 0x07; m_listenPort = _r.itemCount() > 5 ? _r[5].toInt() : 0; - if (m_server->m_verbosity >= 2) - cout << std::setw(2) << m_socket.native_handle() << " | Hello: " << clientVersion << " " << showbase << hex << m_caps << dec << " " << m_listenPort << endl; + clogS(NetMessageSummary) << "Hello: " << clientVersion << " " << showbase << hex << m_caps << dec << " " << m_listenPort; - if (m_protocolVersion != 0 || m_networkId != m_reqNetworkId) + if (m_protocolVersion != 1 || m_networkId != m_reqNetworkId) { disconnect(); return false; @@ -131,53 +131,45 @@ bool PeerSession::interpret(RLP const& _r) break; } case DisconnectPacket: - if (m_server->m_verbosity >= 2) - cout << std::setw(2) << m_socket.native_handle() << " | Disconnect" << endl; - if (m_server->m_verbosity >= 1) - { - if (m_socket.is_open()) - cout << "Closing " << m_socket.remote_endpoint() << endl; - else - cout << "Remote closed on " << m_socket.native_handle() << endl; - } + clogS(NetMessageSummary) << "Disconnect"; + if (m_socket.is_open()) + clogS(NetNote) << "Closing " << m_socket.remote_endpoint(); + else + clogS(NetNote) << "Remote closed."; m_socket.close(); return false; case PingPacket: { -// cout << std::setw(2) << m_socket.native_handle() << " | Ping" << endl; +// clogS(NetMessageSummary) << "Ping"; RLPStream s; sealAndSend(prep(s).appendList(1) << PongPacket); break; } case PongPacket: m_info.lastPing = std::chrono::steady_clock::now() - m_ping; -// cout << "Latency: " << chrono::duration_cast(m_lastPing).count() << " ms" << endl; +// clogS(NetMessageSummary) << "Latency: " << chrono::duration_cast(m_lastPing).count() << " ms"; break; case GetPeersPacket: { - if (m_server->m_verbosity >= 2) - cout << std::setw(2) << m_socket.native_handle() << " | GetPeers" << endl; + clogS(NetMessageSummary) << "GetPeers"; std::vector peers = m_server->potentialPeers(); RLPStream s; prep(s).appendList(peers.size() + 1); s << PeersPacket; for (auto i: peers) { - if (m_server->m_verbosity >= 3) - cout << " Sending peer " << i << endl; + clogS(NetMessageDetail) << "Sending peer " << i; s.appendList(2) << i.address().to_v4().to_bytes() << i.port(); } sealAndSend(s); break; } case PeersPacket: - if (m_server->m_verbosity >= 2) - cout << std::setw(2) << m_socket.native_handle() << " | Peers (" << dec << (_r.itemCount() - 1) << " entries)" << endl; + clogS(NetMessageSummary) << "Peers (" << dec << (_r.itemCount() - 1) << " entries)"; for (unsigned i = 1; i < _r.itemCount(); ++i) { auto ep = bi::tcp::endpoint(bi::address_v4(_r[i][0].toArray()), _r[i][1].toInt()); - if (m_server->m_verbosity >= 6) - cout << "Checking: " << ep << endl; + clogS(NetAllDetail) << "Checking: " << ep; // check that we're not already connected to addr: if (!ep.port()) goto CONTINUE; @@ -187,8 +179,7 @@ bool PeerSession::interpret(RLP const& _r) for (auto i: m_server->m_peers) if (shared_ptr p = i.lock()) { - if (m_server->m_verbosity >= 6) - cout << " ...against " << p->endpoint() << endl; + clogS(NetAllDetail) << " ...against " << p->endpoint(); if (p->m_socket.is_open() && p->endpoint() == ep) goto CONTINUE; } @@ -196,16 +187,14 @@ bool PeerSession::interpret(RLP const& _r) if (i == ep) goto CONTINUE; m_server->m_incomingPeers.push_back(ep); - if (m_server->m_verbosity >= 3) - cout << "New peer: " << ep << endl; + clogS(NetMessageDetail) << "New peer: " << ep; CONTINUE:; } break; case TransactionsPacket: if (m_server->m_mode == NodeMode::PeerServer) break; - if (m_server->m_verbosity >= 2) - cout << std::setw(2) << m_socket.native_handle() << " | Transactions (" << dec << (_r.itemCount() - 1) << " entries)" << endl; + clogS(NetMessageSummary) << "Transactions (" << dec << (_r.itemCount() - 1) << " entries)"; m_rating += _r.itemCount() - 1; for (unsigned i = 1; i < _r.itemCount(); ++i) { @@ -216,23 +205,22 @@ bool PeerSession::interpret(RLP const& _r) case BlocksPacket: if (m_server->m_mode == NodeMode::PeerServer) break; - if (m_server->m_verbosity >= 2) - cout << std::setw(2) << m_socket.native_handle() << " | Blocks (" << dec << (_r.itemCount() - 1) << " entries)" << endl; + clogS(NetMessageSummary) << "Blocks (" << dec << (_r.itemCount() - 1) << " entries)"; m_rating += _r.itemCount() - 1; for (unsigned i = 1; i < _r.itemCount(); ++i) { m_server->m_incomingBlocks.push_back(_r[i].data().toBytes()); m_knownBlocks.insert(sha3(_r[i].data())); } - if (m_server->m_verbosity >= 3) + if (g_logVerbosity >= 3) for (unsigned i = 1; i < _r.itemCount(); ++i) { auto h = sha3(_r[i].data()); BlockInfo bi(_r[i].data()); if (!m_server->m_chain->details(bi.parentHash) && !m_knownBlocks.count(bi.parentHash)) - cerr << "*** Unknown parent " << bi.parentHash << " of block " << h << endl; + clogS(NetMessageDetail) << "Unknown parent " << bi.parentHash << " of block " << h; else - cerr << "--- Known parent " << bi.parentHash << " of block " << h << endl; + clogS(NetMessageDetail) << "Known parent " << bi.parentHash << " of block " << h; } if (_r.itemCount() > 1) // we received some - check if there's any more { @@ -254,14 +242,12 @@ bool PeerSession::interpret(RLP const& _r) parents.reserve(_r.itemCount() - 2); for (unsigned i = 1; i < _r.itemCount() - 1; ++i) parents.push_back(_r[i].toHash()); - if (m_server->m_verbosity >= 2) - cout << std::setw(2) << m_socket.native_handle() << " | GetChain (" << (_r.itemCount() - 2) << " hashes, " << (_r[_r.itemCount() - 1].toInt()) << ")" << endl; + clogS(NetMessageSummary) << "GetChain (" << (_r.itemCount() - 2) << " hashes, " << (_r[_r.itemCount() - 1].toInt()) << ")"; if (_r.itemCount() == 2) break; // return 2048 block max. uint baseCount = (uint)min(_r[_r.itemCount() - 1].toInt(), c_maxBlocks); - if (m_server->m_verbosity >= 2) - cout << std::setw(2) << m_socket.native_handle() << " | GetChain (" << baseCount << " max, from " << parents.front() << " to " << parents.back() << ")" << endl; + clogS(NetMessageSummary) << "GetChain (" << baseCount << " max, from " << parents.front() << " to " << parents.back() << ")"; for (auto parent: parents) { auto h = m_server->m_chain->currentHash(); @@ -275,27 +261,23 @@ bool PeerSession::interpret(RLP const& _r) latestNumber = m_server->m_chain->details(latest).number; parentNumber = m_server->m_chain->details(parent).number; uint count = min(latestNumber - parentNumber, baseCount); - if (m_server->m_verbosity >= 6) - cout << "Requires " << dec << (latestNumber - parentNumber) << " blocks from " << latestNumber << " to " << parentNumber << endl - << latest << " - " << parent << endl; + clogS(NetAllDetail) << "Requires " << dec << (latestNumber - parentNumber) << " blocks from " << latestNumber << " to " << parentNumber; + clogS(NetAllDetail) << latest << " - " << parent; prep(s); s.appendList(1 + count) << BlocksPacket; uint endNumber = m_server->m_chain->details(parent).number; uint startNumber = endNumber + count; - if (m_server->m_verbosity >= 6) - cout << "Sending " << dec << count << " blocks from " << startNumber << " to " << endNumber << endl; + clogS(NetAllDetail) << "Sending " << dec << count << " blocks from " << startNumber << " to " << endNumber; uint n = latestNumber; for (; n > startNumber; n--, h = m_server->m_chain->details(h).parent) {} for (uint i = 0; h != parent && n > endNumber && i < count; ++i, --n, h = m_server->m_chain->details(h).parent) { - if (m_server->m_verbosity >= 6) - cout << " " << dec << i << " " << h << endl; + clogS(NetAllDetail) << " " << dec << i << " " << h; s.appendRaw(m_server->m_chain->block(h)); } - if (m_server->m_verbosity >= 6) - cout << "Parent: " << h << endl; + clogS(NetAllDetail) << "Parent: " << h; } else if (parent != parents.back()) continue; @@ -306,8 +288,7 @@ bool PeerSession::interpret(RLP const& _r) if (parent == parents.back()) { // out of parents... - if (m_server->m_verbosity >= 6) - cout << std::setw(2) << m_socket.native_handle() << " | GetChain failed; not in chain" << endl; + clogS(NetAllDetail) << "GetChain failed; not in chain"; // No good - must have been on a different branch. s.clear(); prep(s).appendList(2) << NotInChainPacket << parents.back(); @@ -328,12 +309,10 @@ bool PeerSession::interpret(RLP const& _r) if (m_server->m_mode == NodeMode::PeerServer) break; h256 noGood = _r[1].toHash(); - if (m_server->m_verbosity >= 2) - cout << std::setw(2) << m_socket.native_handle() << " | NotInChain (" << noGood << ")" << endl; + clogS(NetMessageSummary) << "NotInChain (" << noGood << ")"; if (noGood == m_server->m_chain->genesisHash()) { - if (m_server->m_verbosity) - cout << std::setw(2) << m_socket.native_handle() << " | Discordance over genesis block! Disconnect." << endl; + clogS(NetWarn) << "Discordance over genesis block! Disconnect."; disconnect(); } else @@ -377,8 +356,7 @@ RLPStream& PeerSession::prep(RLPStream& _s) void PeerServer::seal(bytes& _b) { - if (m_verbosity >= 9) - cbug(LeftChannel) << RLP(bytesConstRef(&_b).cropped(8)); + clogS(NetLeft) << RLP(bytesConstRef(&_b).cropped(8)); _b[0] = 0x22; _b[1] = 0x40; _b[2] = 0x08; @@ -403,13 +381,11 @@ void PeerSession::sendDestroy(bytes& _msg) std::shared_ptr buffer = std::make_shared(); swap(*buffer, _msg); assert((*buffer)[0] == 0x22); -// cout << "Sending " << (buffer->size() - 8) << endl; -// cout << "Sending " << RLP(bytesConstRef(buffer.get()).cropped(8)) << endl; ba::async_write(m_socket, ba::buffer(*buffer), [=](boost::system::error_code ec, std::size_t length) { if (ec) dropped(); -// cout << length << " bytes written (EC: " << ec << ")" << endl; +// cbug << length << " bytes written (EC: " << ec << ")"; }); } @@ -417,24 +393,20 @@ void PeerSession::send(bytesConstRef _msg) { std::shared_ptr buffer = std::make_shared(_msg.toBytes()); assert((*buffer)[0] == 0x22); -// cout << "Sending " << (_msg.size() - 8) << endl;// RLP(bytesConstRef(buffer.get()).cropped(8)) << endl; ba::async_write(m_socket, ba::buffer(*buffer), [=](boost::system::error_code ec, std::size_t length) { if (ec) dropped(); -// cout << length << " bytes written (EC: " << ec << ")" << endl; +// cbug << length << " bytes written (EC: " << ec << ")"; }); } void PeerSession::dropped() { - if (m_server->m_verbosity >= 1) - { - if (m_socket.is_open()) - try { - cout << "Closing " << m_socket.remote_endpoint() << endl; - }catch (...){} - } + if (m_socket.is_open()) + try { + clogS(NetNote) << "Closing " << m_socket.remote_endpoint(); + }catch (...){} m_socket.close(); for (auto i = m_server->m_peers.begin(); i != m_server->m_peers.end(); ++i) if (i->lock().get() == this) @@ -458,15 +430,12 @@ void PeerSession::disconnect() } else { - if (m_server->m_verbosity >= 1) - { - if (m_socket.is_open()) - try { - cout << "Closing " << m_socket.remote_endpoint() << endl; - } catch (...){} - else - cout << "Remote closed on" << m_socket.native_handle() << endl; - } + if (m_socket.is_open()) + try { + clogS(NetNote) << "Closing " << m_socket.remote_endpoint(); + } catch (...){} + else + clogS(NetNote) << "Remote closed on" << m_socket.native_handle(); m_socket.close(); } } @@ -503,15 +472,14 @@ void PeerSession::doRead() { if (m_incoming[0] != 0x22 || m_incoming[1] != 0x40 || m_incoming[2] != 0x08 || m_incoming[3] != 0x91) { - if (m_server->m_verbosity) - cerr << std::setw(2) << m_socket.native_handle() << " | Out of alignment. Skipping: " << hex << showbase << (int)m_incoming[0] << dec << endl; + clogS(NetWarn) << "Out of alignment. Skipping: " << hex << showbase << (int)m_incoming[0] << dec; memmove(m_incoming.data(), m_incoming.data() + 1, m_incoming.size() - 1); m_incoming.resize(m_incoming.size() - 1); } else { uint32_t len = fromBigEndian(bytesConstRef(m_incoming.data() + 4, 4)); - // cout << "Received packet of " << len << " bytes" << endl; + // cdebug << "Received packet of " << len << " bytes"; if (m_incoming.size() - 8 < len) break; @@ -528,8 +496,7 @@ void PeerSession::doRead() } catch (std::exception const& _e) { - if (m_server->m_verbosity) - cerr << std::setw(2) << m_socket.native_handle() << " | ERROR: " << _e.what() << endl; + clogS(NetWarn) << "ERROR: " << _e.what(); dropped(); } } @@ -548,8 +515,7 @@ PeerServer::PeerServer(std::string const& _clientVersion, BlockChain const& _ch, populateAddresses(); determinePublic(_publicAddress, _upnp); ensureAccepting(); - if (m_verbosity) - cout << "Mode: " << (_m == NodeMode::PeerServer ? "PeerServer" : "Full") << endl; + clog(NetNote) << "Mode: " << (_m == NodeMode::PeerServer ? "PeerServer" : "Full"); } PeerServer::PeerServer(std::string const& _clientVersion, uint _networkId): @@ -561,8 +527,7 @@ PeerServer::PeerServer(std::string const& _clientVersion, uint _networkId): { // populate addresses. populateAddresses(); - if (m_verbosity) - cout << "Genesis: " << m_chain->genesisHash() << endl; + clog(NetNote) << "Genesis: " << m_chain->genesisHash(); } PeerServer::~PeerServer() @@ -585,14 +550,14 @@ void PeerServer::determinePublic(string const& _publicAddress, bool _upnp) bi::tcp::resolver r(m_ioService); if (m_upnp && m_upnp->isValid() && m_peerAddresses.size()) { - cnote << "External addr: " << m_upnp->externalIP(); + clog(NetNote) << "External addr: " << m_upnp->externalIP(); int p = m_upnp->addRedirect(m_peerAddresses[0].to_string().c_str(), m_listenPort); if (p) - cnote << "Punched through NAT and mapped local port" << m_listenPort << "onto external port" << p << "."; + clog(NetNote) << "Punched through NAT and mapped local port" << m_listenPort << "onto external port" << p << "."; else { // couldn't map - cwarn << "Couldn't punch through NAT (or no NAT in place). Assuming " << m_listenPort << " is local & external port."; + clog(NetWarn) << "Couldn't punch through NAT (or no NAT in place). Assuming " << m_listenPort << " is local & external port."; p = m_listenPort; } @@ -625,7 +590,7 @@ void PeerServer::populateAddresses() char ac[80]; if (gethostname(ac, sizeof(ac)) == SOCKET_ERROR) { - cerr << "Error " << WSAGetLastError() << " when getting local host name." << endl; + clog(NetWarn) << "Error " << WSAGetLastError() << " when getting local host name."; WSACleanup(); throw NoNetworking(); } @@ -633,7 +598,7 @@ void PeerServer::populateAddresses() struct hostent* phe = gethostbyname(ac); if (phe == 0) { - cerr << "Bad host lookup." << endl; + clog(NetWarn) << "Bad host lookup."; WSACleanup(); throw NoNetworking(); } @@ -648,8 +613,7 @@ void PeerServer::populateAddresses() bool isLocal = std::find(c_rejectAddresses.begin(), c_rejectAddresses.end(), ad) != c_rejectAddresses.end(); if (isLocal) m_peerAddresses.push_back(ad.to_v4()); - if (m_verbosity >= 1) - cout << "Address: " << ac << " = " << m_addresses.back() << (isLocal ? " [LOCAL]" : " [PEER]") << endl; + clog(NetNote) << "Address: " << ac << " = " << m_addresses.back() << (isLocal ? " [LOCAL]" : " [PEER]"); } WSACleanup(); @@ -676,8 +640,7 @@ void PeerServer::populateAddresses() bool isLocal = std::find(c_rejectAddresses.begin(), c_rejectAddresses.end(), ad) != c_rejectAddresses.end(); if (!isLocal) m_peerAddresses.push_back(ad.to_v4()); - if (m_verbosity >= 1) - cout << "Address: " << host << " = " << m_addresses.back() << (isLocal ? " [LOCAL]" : " [PEER]") << endl; + clog(NetNote) << "Address: " << host << " = " << m_addresses.back() << (isLocal ? " [LOCAL]" : " [PEER]"); } } @@ -704,26 +667,23 @@ void PeerServer::ensureAccepting() { if (m_accepting == false) { - if (m_verbosity >= 1) - cout << "Listening on local port " << m_listenPort << " (public: " << m_public << ")" << endl; + clog(NetNote) << "Listening on local port " << m_listenPort << " (public: " << m_public << ")"; m_accepting = true; m_acceptor.async_accept(m_socket, [=](boost::system::error_code ec) { if (!ec) try { - if (m_verbosity >= 1) - try { - cout << "Accepted connection from " << m_socket.remote_endpoint() << std::endl; - } catch (...){} + try { + clog(NetNote) << "Accepted connection from " << m_socket.remote_endpoint(); + } catch (...){} auto p = std::make_shared(this, std::move(m_socket), m_requiredNetworkId); m_peers.push_back(p); p->start(); } catch (std::exception const& _e) { - if (m_verbosity) - cerr << "*** ERROR: " << _e.what() << endl; + clog(NetWarn) << "ERROR: " << _e.what(); } m_accepting = false; @@ -735,22 +695,19 @@ void PeerServer::ensureAccepting() void PeerServer::connect(bi::tcp::endpoint const& _ep) { - if (m_verbosity >= 1) - cout << "Attempting connection to " << _ep << endl; + clog(NetNote) << "Attempting connection to " << _ep; bi::tcp::socket* s = new bi::tcp::socket(m_ioService); s->async_connect(_ep, [=](boost::system::error_code const& ec) { if (ec) { - if (m_verbosity >= 1) - cout << "Connection refused to " << _ep << " (" << ec.message() << ")" << endl; + clog(NetNote) << "Connection refused to " << _ep << " (" << ec.message() << ")"; } else { auto p = make_shared(this, std::move(*s), m_requiredNetworkId); m_peers.push_back(p); - if (m_verbosity >= 1) - cout << "Connected to " << p->endpoint() << endl; + clog(NetNote) << "Connected to " << p->endpoint(); p->start(); } delete s; @@ -791,8 +748,7 @@ bool PeerServer::process(BlockChain& _bc, TransactionQueue& _tq, Overlay& _o) { // First time - just initialise. m_latestBlockSent = _bc.currentHash(); - if (m_verbosity) - cout << "Initialising: latest=" << m_latestBlockSent << endl; + clog(NetNote) << "Initialising: latest=" << m_latestBlockSent; for (auto const& i: _tq.transactions()) m_transactionsSent.insert(i.first); diff --git a/libethereum/PeerNetwork.h b/libethereum/PeerNetwork.h index b4408699b..f2a5bc84a 100644 --- a/libethereum/PeerNetwork.h +++ b/libethereum/PeerNetwork.h @@ -37,6 +37,14 @@ namespace eth class BlockChain; class TransactionQueue; +struct NetWarn: public LogChannel { static const char constexpr* name = "!N!"; static const int verbosity = 0; }; +struct NetNote: public LogChannel { static const char constexpr* name = "*N*"; static const int verbosity = 1; }; +struct NetMessageSummary: public LogChannel { static const char constexpr* name = "-N-"; static const int verbosity = 2; }; +struct NetMessageDetail: public LogChannel { static const char constexpr* name = "=N="; static const int verbosity = 3; }; +struct NetAllDetail: public LogChannel { static const char constexpr* name = "=N="; static const int verbosity = 6; }; +struct NetRight: public LogChannel { static const char constexpr* name = ">N>"; static const int verbosity = 8; }; +struct NetLeft: public LogChannel { static const char constexpr* name = " peers() const; @@ -168,17 +175,6 @@ private: std::string m_clientVersion; NodeMode m_mode = NodeMode::Full; - /** - * 0: Quiet - just errors on stderr. - * 1: Accepting/connecting/connected & one-off info. - * 2: Messages summary. - * 3: Messages detail. - * 6: Debug details. - * 8: Received raw. - * 9: Sent raw. - */ - unsigned m_verbosity = 4; - short m_listenPort; BlockChain const* m_chain = nullptr; diff --git a/libethereum/State.cpp b/libethereum/State.cpp index ceef91b24..98a3c2f00 100644 --- a/libethereum/State.cpp +++ b/libethereum/State.cpp @@ -67,7 +67,7 @@ std::map const& eth::genesisState() if (s_ret.empty()) { // Initialise. - s_ret[Address(fromUserHex("812413ae7e515a3bcaf7b3444116527bce958c02"))] = AddressState(u256(1) << 200, 0); + s_ret[Address(fromUserHex("07598a40bfaa73256b60764c1bf40675a99083ef"))] = AddressState(u256(1) << 200, 0); s_ret[Address(fromUserHex("93658b04240e4bd4046fd2d6d417d20f146f4b43"))] = AddressState(u256(1) << 200, 0); s_ret[Address(fromUserHex("1e12515ce3e0f817a4ddef9ca55788a1d66bd2df"))] = AddressState(u256(1) << 200, 0); s_ret[Address(fromUserHex("80c01a26338f0d905e295fccb71fa9ea849ffa12"))] = AddressState(u256(1) << 200, 0);