diff --git a/alethzero/MainWin.cpp b/alethzero/MainWin.cpp index f23015399..b431c2afb 100644 --- a/alethzero/MainWin.cpp +++ b/alethzero/MainWin.cpp @@ -257,7 +257,7 @@ void Main::installWatches() void Main::installNameRegWatch() { m_client->uninstallWatch(m_nameRegFilter); - m_nameRegFilter = installWatch(eth::TransactionFilter().altered((u160)state().storage(c_config, 0)), [=](){ onNameRegChange(); }); + m_nameRegFilter = installWatch(eth::TransactionFilter().altered((u160)m_client->stateAt(c_config, 0)), [=](){ onNameRegChange(); }); } void Main::installCurrenciesWatch() @@ -446,11 +446,11 @@ Address Main::fromString(QString const& _a) const memset(n.data() + sn.size(), 0, 32 - sn.size()); if (_a.size()) { - if (h160 nameReg = (u160)state().storage(c_config, 0)) - if (h256 a = state().storage(nameReg, n)) + if (h160 nameReg = (u160)m_client->stateAt(c_config, 0)) + if (h256 a = m_client->stateAt(nameReg, n)) return right160(a); - if (h256 a = state().storage(m_nameReg, n)) + if (h256 a = m_client->stateAt(m_nameReg, n)) return right160(a); } if (_a.size() == 40) @@ -493,12 +493,9 @@ void Main::writeSettings() s.setValue("port", ui->port->value()); s.setValue("url", ui->urlEdit->text()); - if (m_client->peerServer()) - { - bytes d = m_client->peerServer()->savePeers(); + bytes d = m_client->savePeers(); + if (d.size()) m_peers = QByteArray((char*)d.data(), (int)d.size()); - - } s.setValue("peers", m_peers); s.setValue("nameReg", ui->nameReg->text()); @@ -597,7 +594,6 @@ void Main::on_preview_triggered() void Main::refreshMining() { - eth::ClientGuard g(m_client.get()); eth::MineProgress p = m_client->miningProgress(); ui->mineStatus->setText(m_client->isMining() ? QString("%1s @ %2kH/s").arg(p.ms / 1000).arg(p.ms ? p.hashes / p.ms : 0) : "Not mining"); if (!ui->miningView->isVisible()) @@ -652,11 +648,6 @@ void Main::refreshNetwork() 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())); } -eth::State const& Main::state() const -{ - return ui->preview->isChecked() ? m_client->postState() : m_client->state(); -} - void Main::refreshAll() { refreshDestination(); @@ -760,8 +751,6 @@ static bool transactionMatch(string const& _f, Transaction const& _t) void Main::refreshBlockChain() { cwatch << "refreshBlockChain()"; - eth::ClientGuard g(m_client.get()); - auto const& st = state(); QByteArray oldSelected = ui->blocks->count() ? ui->blocks->currentItem()->data(Qt::UserRole).toByteArray() : QByteArray(); ui->blocks->clear(); @@ -794,7 +783,7 @@ void Main::refreshBlockChain() .arg(render(t.safeSender())) .arg(render(t.receiveAddress)) .arg((unsigned)t.nonce) - .arg(st.addressHasCode(t.receiveAddress) ? '*' : '-') : + .arg(m_client->codeAt(t.receiveAddress).size() ? '*' : '-') : QString(" %2 +> %3: %1 [%4]") .arg(formatBalance(t.value).c_str()) .arg(render(t.safeSender())) @@ -933,13 +922,12 @@ string Main::renderDiff(eth::StateDiff const& _d) const void Main::on_transactionQueue_currentItemChanged() { ui->pendingInfo->clear(); - eth::ClientGuard g(m_client.get()); stringstream s; int i = ui->transactionQueue->currentRow(); - if (i >= 0 && i < (int)m_client->postState().pending().size()) + if (i >= 0 && i < (int)m_client->pending().size()) { - Transaction tx(m_client->postState().pending()[i]); + Transaction tx(m_client->pending()[i]); auto ss = tx.safeSender(); h256 th = sha3(rlpList(ss, tx.nonce)); s << "

" << th << "

"; @@ -967,7 +955,7 @@ void Main::on_transactionQueue_currentItemChanged() // s << "Pre: " << fs.rootHash() << "
"; // s << "Post: " << ts.rootHash() << ""; - s << renderDiff(m_client->postState().pendingDiff(i)); + s << renderDiff(m_client->diff(i, 0)); } ui->pendingInfo->setHtml(QString::fromStdString(s.str())); @@ -1002,7 +990,6 @@ void Main::on_blocks_currentItemChanged() ui->debugCurrent->setEnabled(false); ui->debugDumpState->setEnabled(false); ui->debugDumpStatePre->setEnabled(false); - eth::ClientGuard g(m_client.get()); if (auto item = ui->blocks->currentItem()) { auto hba = item->data(Qt::UserRole).toByteArray(); @@ -1069,10 +1056,7 @@ void Main::on_blocks_currentItemChanged() if (tx.data.size()) s << eth::memDump(tx.data, 16, true); } - auto st = eth::State(m_client->state().db(), m_client->blockChain(), h); - eth::State before = st.fromPending(txi); - eth::State after = st.fromPending(txi + 1); - s << renderDiff(before.diff(after)); + s << renderDiff(m_client->diff(txi, h)); ui->debugCurrent->setEnabled(true); ui->debugDumpState->setEnabled(true); ui->debugDumpStatePre->setEnabled(true); @@ -1084,7 +1068,6 @@ void Main::on_blocks_currentItemChanged() void Main::on_debugCurrent_triggered() { - eth::ClientGuard g(m_client.get()); if (auto item = ui->blocks->currentItem()) { auto hba = item->data(Qt::UserRole).toByteArray(); @@ -1093,11 +1076,10 @@ void Main::on_debugCurrent_triggered() if (!item->data(Qt::UserRole + 1).isNull()) { - eth::State st(m_client->state().db(), m_client->blockChain(), h); unsigned txi = item->data(Qt::UserRole + 1).toInt(); - m_executiveState = st.fromPending(txi); + m_executiveState = m_client->state(txi, h); m_currentExecution = unique_ptr(new Executive(m_executiveState)); - Transaction t = st.pending()[txi]; + Transaction t = m_client->pending()[txi]; auto r = t.rlp(); populateDebugger(&r); m_currentExecution.reset(); @@ -1107,7 +1089,6 @@ void Main::on_debugCurrent_triggered() void Main::on_debugDumpState_triggered(int _add) { - eth::ClientGuard g(m_client.get()); if (auto item = ui->blocks->currentItem()) { auto hba = item->data(Qt::UserRole).toByteArray(); @@ -1120,9 +1101,8 @@ void Main::on_debugDumpState_triggered(int _add) ofstream f(fn.toStdString()); if (f.is_open()) { - eth::State st(m_client->state().db(), m_client->blockChain(), h); unsigned txi = item->data(Qt::UserRole + 1).toInt(); - f << st.fromPending(txi + _add) << endl; + f << m_client->state(txi + _add, h) << endl; } } } @@ -1178,20 +1158,19 @@ void Main::populateDebugger(eth::bytesConstRef _r) void Main::on_contracts_currentItemChanged() { ui->contractInfo->clear(); - eth::ClientGuard l(&*m_client); if (auto item = ui->contracts->currentItem()) { auto hba = item->data(Qt::UserRole).toByteArray(); assert(hba.size() == 20); - auto h = h160((byte const*)hba.data(), h160::ConstructFromPointer); + auto address = h160((byte const*)hba.data(), h160::ConstructFromPointer); stringstream s; try { - auto storage = state().storage(h); + auto storage = m_client->storageAt(address); for (auto const& i: storage) s << "@" << showbase << hex << prettyU256(i.first).toStdString() << "    " << showbase << hex << prettyU256(i.second).toStdString() << "
"; - s << "

Body Code

" << disassemble(state().code(h)); + s << "

Body Code

" << disassemble(m_client->codeAt(address)); ui->contractInfo->appendHtml(QString::fromStdString(s.str())); } catch (eth::InvalidTrie) @@ -1203,8 +1182,7 @@ void Main::on_contracts_currentItemChanged() void Main::on_idealPeers_valueChanged() { - if (m_client->peerServer()) - m_client->peerServer()->setIdealPeerCount(ui->idealPeers->value()); + m_client->setIdealPeerCount(ui->idealPeers->value()); } void Main::on_ourAccounts_doubleClicked() @@ -1288,7 +1266,7 @@ void Main::on_data_textChanged() errs.append("
" + QString::fromStdString(i).toHtmlEscaped() + "
"); } ui->code->setHtml(errs + lll + "

Code

" + QString::fromStdString(disassemble(m_data)).toHtmlEscaped()); - ui->gas->setMinimum((qint64)state().createGas(m_data.size(), 0)); + ui->gas->setMinimum((qint64)Client::txGas(m_data.size(), 0)); if (!ui->gas->isEnabled()) ui->gas->setValue(m_backupGas); ui->gas->setEnabled(true); @@ -1344,9 +1322,9 @@ void Main::on_data_textChanged() s = s.mid(1); } ui->code->setHtml(QString::fromStdString(eth::memDump(m_data, 8, true))); - if (m_client->postState().addressHasCode(fromString(ui->destination->currentText()))) + if (m_client->codeAt(fromString(ui->destination->currentText()), 0).size()) { - ui->gas->setMinimum((qint64)state().callGas(m_data.size(), 1)); + ui->gas->setMinimum((qint64)Client::txGas(m_data.size(), 1)); if (!ui->gas->isEnabled()) ui->gas->setValue(m_backupGas); ui->gas->setEnabled(true); @@ -1355,7 +1333,7 @@ void Main::on_data_textChanged() { if (ui->gas->isEnabled()) m_backupGas = ui->gas->value(); - ui->gas->setValue((qint64)state().callGas(m_data.size())); + ui->gas->setValue((qint64)Client::txGas(m_data.size())); ui->gas->setEnabled(false); } } @@ -1412,7 +1390,7 @@ void Main::updateFee() bool ok = false; for (auto i: m_myKeys) - if (state().balance(i.address()) >= totalReq) + if (m_client->balanceAt(i.address()) >= totalReq) { ok = true; break; @@ -1436,7 +1414,7 @@ void Main::on_net_triggered() { m_client->startNetwork(ui->port->value(), string(), 0, NodeMode::Full, ui->idealPeers->value(), ui->forceAddress->text().toStdString(), ui->upnp->isChecked()); if (m_peers.size() && ui->usePast->isChecked()) - m_client->peerServer()->restorePeers(bytesConstRef((byte*)m_peers.data(), m_peers.size())); + m_client->restorePeers(bytesConstRef((byte*)m_peers.data(), m_peers.size())); } else m_client->stopNetwork(); @@ -1479,9 +1457,8 @@ void Main::on_mine_triggered() void Main::on_send_clicked() { u256 totalReq = value() + fee(); - eth::ClientGuard l(&*m_client); for (auto i: m_myKeys) - if (m_client->postState().balance(i.address()) >= totalReq) + if (m_client->balanceAt(i.address(), 0) >= totalReq) { debugFinished(); Secret s = i.secret(); @@ -1500,12 +1477,11 @@ void Main::on_debug_clicked() try { u256 totalReq = value() + fee(); - eth::ClientGuard l(&*m_client); for (auto i: m_myKeys) - if (m_client->state().balance(i.address()) >= totalReq) + if (m_client->balanceAt(i.address()) >= totalReq) { Secret s = i.secret(); - m_executiveState = state(); + m_executiveState = m_client->postState(); m_currentExecution = unique_ptr(new Executive(m_executiveState)); Transaction t; t.nonce = m_executiveState.transactionsFrom(toAddress(s)); diff --git a/alethzero/MainWin.h b/alethzero/MainWin.h index 35f8cb137..24e9c5ae1 100644 --- a/alethzero/MainWin.h +++ b/alethzero/MainWin.h @@ -156,8 +156,6 @@ private: void alterDebugStateGroup(bool _enable) const; - eth::State const& state() const; - void updateFee(); void readSettings(); void writeSettings(); diff --git a/eth/EthStubServer.cpp b/eth/EthStubServer.cpp index fc281a706..666a658f1 100644 --- a/eth/EthStubServer.cpp +++ b/eth/EthStubServer.cpp @@ -60,14 +60,12 @@ Json::Value EthStubServer::procedures() std::string EthStubServer::coinbase() { - ClientGuard g(&m_client); return toJS(m_client.address()); } std::string EthStubServer::balanceAt(std::string const& _a) { - ClientGuard g(&m_client); - return toJS(m_client.postState().balance(jsToAddress(_a))); + return toJS(m_client.balanceAt(jsToAddress(_a), 0)); } Json::Value EthStubServer::check(Json::Value const& _as) @@ -85,7 +83,6 @@ Json::Value EthStubServer::check(Json::Value const& _as) std::string EthStubServer::create(const std::string& _bCode, const std::string& _sec, const std::string& _xEndowment, const std::string& _xGas, const std::string& _xGasPrice) { - ClientGuard g(&m_client); Address ret = m_client.transact(jsToSecret(_sec), jsToU256(_xEndowment), jsToBytes(_bCode), jsToU256(_xGas), jsToU256(_xGasPrice)); return toJS(ret); } @@ -102,8 +99,7 @@ std::string EthStubServer::gasPrice() bool EthStubServer::isContractAt(const std::string& _a) { - ClientGuard g(&m_client); - return m_client.postState().addressHasCode(jsToAddress(_a)); + return m_client.codeAt(jsToAddress(_a), 0).size(); } bool EthStubServer::isListening() @@ -133,27 +129,23 @@ Json::Value EthStubServer::keys() int EthStubServer::peerCount() { - ClientGuard g(&m_client); return m_client.peerCount(); } std::string EthStubServer::storageAt(const std::string& _a, const std::string& x) { - ClientGuard g(&m_client); - return toJS(m_client.postState().storage(jsToAddress(_a), jsToU256(x))); + return toJS(m_client.stateAt(jsToAddress(_a), jsToU256(x), 0)); } Json::Value EthStubServer::transact(const std::string& _aDest, const std::string& _bData, const std::string& _sec, const std::string& _xGas, const std::string& _xGasPrice, const std::string& _xValue) { - ClientGuard g(&m_client); m_client.transact(jsToSecret(_sec), jsToU256(_xValue), jsToAddress(_aDest), jsToBytes(_bData), jsToU256(_xGas), jsToU256(_xGasPrice)); return Json::Value(); } std::string EthStubServer::txCountAt(const std::string& _a) { - ClientGuard g(&m_client); - return toJS(m_client.postState().transactionsFrom(jsToAddress(_a))); + return toJS(m_client.countAt(jsToAddress(_a), 0)); } std::string EthStubServer::secretToAddress(const std::string& _a) diff --git a/eth/main.cpp b/eth/main.cpp index dbb0234ce..d400b5c93 100644 --- a/eth/main.cpp +++ b/eth/main.cpp @@ -341,7 +341,6 @@ int main(int argc, char** argv) { eth::uint port; iss >> port; - ClientGuard g(&c); c.startNetwork((short)port); } else if (cmd == "connect") @@ -349,12 +348,10 @@ int main(int argc, char** argv) string addr; eth::uint port; iss >> addr >> port; - ClientGuard g(&c); c.connect(addr, (short)port); } else if (cmd == "netstop") { - ClientGuard g(&c); c.stopNetwork(); } else if (cmd == "minestart") @@ -405,12 +402,10 @@ int main(int argc, char** argv) } else if (cmd == "block") { - ClientGuard g(&c); cout << "Current block: " << c.blockChain().details().number; } else if (cmd == "peers") { - ClientGuard g(&c); for (auto it: c.peers()) cout << it.host << ":" << it.port << ", " << it.clientVersion << ", " << std::chrono::duration_cast(it.lastPing).count() << "ms" @@ -418,12 +413,10 @@ int main(int argc, char** argv) } else if (cmd == "balance") { - ClientGuard g(&c); - cout << "Current balance: " << formatBalance(c.postState().balance(us.address())) << " = " << c.postState().balance(us.address()) << " wei" << endl; + cout << "Current balance: " << formatBalance(c.balanceAt(us.address(), 0)) << " = " << c.balanceAt(us.address(), 0) << " wei" << endl; } else if (cmd == "transact") { - ClientGuard g(&c); auto const& bc = c.blockChain(); auto h = bc.currentHash(); auto blockData = bc.block(h); @@ -450,7 +443,7 @@ int main(int argc, char** argv) cnote << ssbd.str(); int ssize = sechex.length(); int size = hexAddr.length(); - u256 minGas = (u256)c.state().callGas(data.size(), 0); + u256 minGas = (u256)Client::txGas(data.size(), 0); if (size < 40) { if (size > 0) @@ -477,40 +470,28 @@ int main(int argc, char** argv) } else if (cmd == "listContracts") { - ClientGuard g(&c); - auto const& st = c.state(); - auto acs = st.addresses(); + auto acs = c.addresses(); string ss; for (auto const& i: acs) - { - auto r = i.first; - if (st.addressHasCode(r)) + if (c.codeAt(i, 0).size()) { - ss = toString(r) + " : " + toString(formatBalance(i.second)) + " [" + toString((unsigned)st.transactionsFrom(i.first)) + "]"; + ss = toString(i) + " : " + toString(c.balanceAt(i, 0)) + " [" + toString((unsigned)c.countAt(i)) + "]"; cout << ss << endl; } - } } else if (cmd == "listAccounts") { - ClientGuard g(&c); - auto const& st = c.state(); - auto acs = st.addresses(); + auto acs = c.addresses(); string ss; for (auto const& i: acs) - { - auto r = i.first; - if (!st.addressHasCode(r)) + if (c.codeAt(i, 0).empty()) { - ss = toString(r) + pretty(r, st) + " : " + toString(formatBalance(i.second)) + " [" + toString((unsigned)st.transactionsFrom(i.first)) + "]"; + ss = toString(i) + " : " + toString(c.balanceAt(i, 0)) + " [" + toString((unsigned)c.countAt(i)) + "]"; cout << ss << endl; } - - } } else if (cmd == "send") { - ClientGuard g(&c); if (iss.peek() != -1) { string hexAddr; @@ -529,23 +510,22 @@ int main(int argc, char** argv) auto h = bc.currentHash(); auto blockData = bc.block(h); BlockInfo info(blockData); - u256 minGas = (u256)c.state().callGas(0, 0); + u256 minGas = (u256)Client::txGas(0, 0); Address dest = h160(fromHex(hexAddr)); c.transact(us.secret(), amount, dest, bytes(), minGas, info.minGasPrice); } - } else cwarn << "Require parameters: send ADDRESS AMOUNT"; } else if (cmd == "contract") { - ClientGuard g(&c); auto const& bc = c.blockChain(); auto h = bc.currentHash(); auto blockData = bc.block(h); BlockInfo info(blockData); - if(iss.peek() != -1) { + if (iss.peek() != -1) + { u256 endowment; u256 gas; u256 gasPrice; @@ -569,7 +549,7 @@ int main(int argc, char** argv) cnote << "Init:"; cnote << ssc.str(); } - u256 minGas = (u256)c.state().createGas(init.size(), 0); + u256 minGas = (u256)Client::txGas(init.size(), 0); if (endowment < 0) cwarn << "Invalid endowment"; else if (gasPrice < info.minGasPrice) @@ -591,16 +571,15 @@ int main(int argc, char** argv) cwarn << "Invalid address length"; else { - ClientGuard g(&c); auto h = h160(fromHex(rechex)); stringstream s; try { - auto storage = c.state().storage(h); + auto storage = c.storageAt(h, 0); for (auto const& i: storage) s << "@" << showbase << hex << i.first << " " << showbase << hex << i.second << endl; - s << endl << disassemble(c.state().code(h)) << endl; + s << endl << disassemble(c.codeAt(h, 0)) << endl; string outFile = getDataDir() + "/" + rechex + ".evm"; ofstream ofs; diff --git a/libethereum/Client.cpp b/libethereum/Client.cpp index 2c9b4453b..904ed2040 100644 --- a/libethereum/Client.cpp +++ b/libethereum/Client.cpp @@ -92,6 +92,7 @@ void Client::ensureWorking() // Synchronise the state according to the head of the block chain. // TODO: currently it contains keys for *all* blocks. Make it remove old ones. + WriteGuard l(x_stateDB); m_preMine.sync(m_bc); m_postMine = m_preMine; })); @@ -99,14 +100,7 @@ void Client::ensureWorking() Client::~Client() { - if (m_work) - { - if (m_workState.load(std::memory_order_acquire) == Active) - m_workState.store(Deleting, std::memory_order_release); - while (m_workState.load(std::memory_order_acquire) != Deleted) - this_thread::sleep_for(chrono::milliseconds(10)); - m_work->join(); - } + stopNetwork(); } void Client::flushTransactions() @@ -116,7 +110,7 @@ void Client::flushTransactions() void Client::clearPending() { - ClientGuard l(this); + WriteGuard l(x_stateDB); if (!m_postMine.pending().size()) return; h256Set changeds; @@ -168,8 +162,10 @@ void Client::uninstallWatch(unsigned _i) void Client::appendFromNewPending(h256 _bloom, h256Set& o_changed) const { lock_guard l(m_filterLock); + ReadGuard sl(x_stateDB); + for (pair const& i: m_filters) - if ((unsigned)i.second.filter.latest() >= m_postMine.info().number && i.second.filter.matches(_bloom)) + if ((unsigned)i.second.filter.latest() > m_bc.number() && i.second.filter.matches(_bloom)) o_changed.insert(i.first); } @@ -196,56 +192,107 @@ void Client::noteChanged(h256Set const& _filters) void Client::startNetwork(unsigned short _listenPort, std::string const& _seedHost, unsigned short _port, NodeMode _mode, unsigned _peers, string const& _publicIP, bool _upnp) { - ensureWorking(); + static const char* c_threadName = "net"; { - Guard l(x_net); + UpgradableGuard l(x_net); if (m_net.get()) return; - try - { - m_net.reset(new PeerServer(m_clientVersion, m_bc, 0, _listenPort, _mode, _publicIP, _upnp)); - } - catch (std::exception const&) { - // Probably already have the port open. - cwarn << "Could not initialize with specified/default port. Trying system-assigned port"; - m_net.reset(new PeerServer(m_clientVersion, m_bc, 0, _mode, _publicIP, _upnp)); - } + UpgradeGuard ul(l); + if (!m_workNet) + m_workNet.reset(new thread([&]() + { + setThreadName(c_threadName); + m_workNetState.store(Active, std::memory_order_release); + while (m_workNetState.load(std::memory_order_acquire) != Deleting) + workNet(); + m_workNetState.store(Deleted, std::memory_order_release); + })); + + try + { + m_net.reset(new PeerServer(m_clientVersion, m_bc, 0, _listenPort, _mode, _publicIP, _upnp)); + } + catch (std::exception const&) + { + // Probably already have the port open. + cwarn << "Could not initialize with specified/default port. Trying system-assigned port"; + m_net.reset(new PeerServer(m_clientVersion, m_bc, 0, _mode, _publicIP, _upnp)); + } + } m_net->setIdealPeerCount(_peers); } if (_seedHost.size()) connect(_seedHost, _port); + + ensureWorking(); +} + +void Client::stopNetwork() +{ + UpgradableGuard l(x_net); + + if (m_workNet) + { + if (m_workNetState.load(std::memory_order_acquire) == Active) + m_workNetState.store(Deleting, std::memory_order_release); + while (m_workNetState.load(std::memory_order_acquire) != Deleted) + this_thread::sleep_for(chrono::milliseconds(10)); + m_workNet->join(); + } + if (m_net) + { + UpgradeGuard ul(l); + m_net.reset(nullptr); + m_workNet.reset(nullptr); + } } std::vector Client::peers() { - Guard l(x_net); + ReadGuard l(x_net); return m_net ? m_net->peers() : std::vector(); } size_t Client::peerCount() const { - Guard l(x_net); + ReadGuard l(x_net); return m_net ? m_net->peerCount() : 0; } +void Client::setIdealPeerCount(size_t _n) const +{ + ReadGuard l(x_net); + if (m_net) + return m_net->setIdealPeerCount(_n); +} + +bytes Client::savePeers() +{ + ReadGuard l(x_net); + if (m_net) + return m_net->savePeers(); + return bytes(); +} + +void Client::restorePeers(bytesConstRef _saved) +{ + ReadGuard l(x_net); + if (m_net) + return m_net->restorePeers(_saved); +} + void Client::connect(std::string const& _seedHost, unsigned short _port) { - Guard l(x_net); + ReadGuard l(x_net); if (!m_net.get()) return; m_net->connect(_seedHost, _port); } -void Client::stopNetwork() -{ - Guard l(x_net); - m_net.reset(nullptr); -} - void Client::startMining() { ensureWorking(); @@ -263,10 +310,12 @@ void Client::transact(Secret _secret, u256 _value, Address _dest, bytes const& _ { ensureWorking(); - ClientGuard l(this); Transaction t; // cdebug << "Nonce at " << toAddress(_secret) << " pre:" << m_preMine.transactionsFrom(toAddress(_secret)) << " post:" << m_postMine.transactionsFrom(toAddress(_secret)); - t.nonce = m_postMine.transactionsFrom(toAddress(_secret)); + { + ReadGuard l(x_stateDB); + t.nonce = m_postMine.transactionsFrom(toAddress(_secret)); + } t.value = _value; t.gasPrice = _gasPrice; t.gas = _gas; @@ -281,9 +330,11 @@ Address Client::transact(Secret _secret, u256 _endowment, bytes const& _init, u2 { ensureWorking(); - ClientGuard l(this); Transaction t; - t.nonce = m_postMine.transactionsFrom(toAddress(_secret)); + { + ReadGuard l(x_stateDB); + t.nonce = m_postMine.transactionsFrom(toAddress(_secret)); + } t.value = _endowment; t.gasPrice = _gasPrice; t.gas = _gas; @@ -299,21 +350,17 @@ void Client::inject(bytesConstRef _rlp) { ensureWorking(); - ClientGuard l(this); m_tq.attemptImport(_rlp); } -void Client::work(bool _justQueue) +void Client::workNet() { - cworkin << "WORK"; - h256Set changeds; - // Process network events. // Synchronise block chain with network. // Will broadcast any of our (new) transactions and blocks, and collect & add any of their (new) transactions and blocks. { - Guard l(x_net); - if (m_net && !_justQueue) + ReadGuard l(x_net); + if (m_net) { cwork << "NETWORK"; m_net->process(); // must be in guard for now since it uses the blockchain. @@ -325,6 +372,13 @@ void Client::work(bool _justQueue) cwork << "TQ:" << m_tq.items() << "; BQ:" << m_bq.items(); } } + this_thread::sleep_for(chrono::milliseconds(1)); +} + +void Client::work(bool _justQueue) +{ + cworkin << "WORK"; + h256Set changeds; // Do some mining. if (!_justQueue) @@ -338,7 +392,7 @@ void Client::work(bool _justQueue) m_mineProgress.best = (double)-1; m_mineProgress.hashes = 0; m_mineProgress.ms = 0; - ClientGuard l(this); + WriteGuard l(x_stateDB); if (m_paranoia) { if (m_postMine.amIJustParanoid(m_bc)) @@ -370,7 +424,7 @@ void Client::work(bool _justQueue) m_mineProgress.requirement = mineInfo.requirement; m_mineProgress.ms += 100; m_mineProgress.hashes += mineInfo.hashes; - ClientGuard l(this); + WriteGuard l(x_stateDB); m_mineHistory.push_back(mineInfo); if (mineInfo.completed) { @@ -403,11 +457,11 @@ void Client::work(bool _justQueue) // all blocks. // Resynchronise state with block chain & trans { - ClientGuard l(this); + WriteGuard l(x_stateDB); cwork << "BQ ==> CHAIN ==> STATE"; OverlayDB db = m_stateDB; - m_lock.unlock(); + x_stateDB.unlock(); h256s newBlocks = m_bc.sync(m_bq, db, 100); // TODO: remove transactions from m_tq nicely rather than relying on out of date nonce later on. if (newBlocks.size()) { @@ -415,7 +469,7 @@ void Client::work(bool _justQueue) appendFromNewBlock(i, changeds); changeds.insert(NewBlockFilter); } - m_lock.lock(); + x_stateDB.lock(); if (newBlocks.size()) m_stateDB = db; @@ -449,16 +503,6 @@ void Client::work(bool _justQueue) cworkout << "WORK"; } -void Client::lock() const -{ - m_lock.lock(); -} - -void Client::unlock() const -{ - m_lock.unlock(); -} - unsigned Client::numberOf(int _n) const { if (_n > 0) @@ -471,6 +515,7 @@ unsigned Client::numberOf(int _n) const State Client::asOf(int _h) const { + ReadGuard l(x_stateDB); if (_h == 0) return m_postMine; else if (_h == -1) @@ -479,9 +524,38 @@ State Client::asOf(int _h) const return State(m_stateDB, m_bc, m_bc.numberHash(numberOf(_h))); } +State Client::state(unsigned _txi, h256 _block) const +{ + ReadGuard l(x_stateDB); + return State(m_stateDB, m_bc, _block).fromPending(_txi); +} + +eth::State Client::state(h256 _block) const +{ + ReadGuard l(x_stateDB); + return State(m_stateDB, m_bc, _block); +} + +eth::State Client::state(unsigned _txi) const +{ + ReadGuard l(x_stateDB); + return m_postMine.fromPending(_txi); +} + +StateDiff Client::diff(unsigned _txi, int _block) const +{ + State st = state(_block); + return st.fromPending(_txi).diff(st.fromPending(_txi + 1)); +} + +StateDiff Client::diff(unsigned _txi, h256 _block) const +{ + State st = state(_block); + return st.fromPending(_txi).diff(st.fromPending(_txi + 1)); +} + std::vector
Client::addresses(int _block) const { - ClientGuard l(this); vector
ret; for (auto const& i: asOf(_block).addresses()) ret.push_back(i.first); @@ -490,25 +564,26 @@ std::vector
Client::addresses(int _block) const u256 Client::balanceAt(Address _a, int _block) const { - ClientGuard l(this); return asOf(_block).balance(_a); } +std::map Client::storageAt(Address _a, int _block) const +{ + return asOf(_block).storage(_a); +} + u256 Client::countAt(Address _a, int _block) const { - ClientGuard l(this); return asOf(_block).transactionsFrom(_a); } u256 Client::stateAt(Address _a, u256 _l, int _block) const { - ClientGuard l(this); return asOf(_block).storage(_a, _l); } bytes Client::codeAt(Address _a, int _block) const { - ClientGuard l(this); return asOf(_block).code(_a); } @@ -625,8 +700,6 @@ bool TransactionFilter::matches(Manifest const& _m, vector _p, Address PastMessages Client::transactions(TransactionFilter const& _f) const { - ClientGuard l(this); - PastMessages ret; unsigned begin = min(m_bc.number(), (unsigned)_f.latest()); unsigned end = min(begin, (unsigned)_f.earliest()); @@ -636,6 +709,7 @@ PastMessages Client::transactions(TransactionFilter const& _f) const // Handle pending transactions differently as they're not on the block chain. if (begin == m_bc.number()) { + ReadGuard l(x_stateDB); for (unsigned i = 0; i < m_postMine.pending().size(); ++i) { // Might have a transaction that contains a matching message. diff --git a/libethereum/Client.h b/libethereum/Client.h index 17d1bc149..420fe7ad3 100644 --- a/libethereum/Client.h +++ b/libethereum/Client.h @@ -27,7 +27,9 @@ #include #include #include +#include #include +#include "Guards.h" #include "BlockChain.h" #include "TransactionQueue.h" #include "State.h" @@ -47,16 +49,6 @@ struct MineProgress class Client; -class ClientGuard -{ -public: - inline ClientGuard(Client const* _c); - inline ~ClientGuard(); - -private: - Client const* m_client; -}; - enum ClientWorkState { Active = 0, @@ -198,19 +190,6 @@ public: // Informational stuff - // [OLD API]: - - /// Locks/unlocks the state/blockChain/transactionQueue for access. - void lock() const; - void unlock() const; - - /// Get the object representing the current state of Ethereum. - State const& state() const { return m_preMine; } - /// Get the object representing the current state of Ethereum. - State const& postState() const { return m_postMine; } - /// Get the object representing the current canonical blockchain. - BlockChain const& blockChain() const { return m_bc; } - // [NEW API] void setDefault(int _block) { m_default = _block; } @@ -219,29 +198,52 @@ 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); } + std::map storageAt(Address _a) const { return storageAt(_a, m_default); } u256 balanceAt(Address _a, int _block) const; u256 countAt(Address _a, int _block) const; u256 stateAt(Address _a, u256 _l, int _block) const; bytes codeAt(Address _a, int _block) const; - PastMessages transactions(TransactionFilter const& _filter) const; - PastMessages transactions(unsigned _watchId) const { try { std::lock_guard l(m_filterLock); return transactions(m_filters.at(m_watches.at(_watchId).id).filter); } catch (...) { return PastMessages(); } } + std::map storageAt(Address _a, int _block) const; + unsigned installWatch(TransactionFilter const& _filter); unsigned installWatch(h256 _filterId); void uninstallWatch(unsigned _watchId); bool peekWatch(unsigned _watchId) const { std::lock_guard l(m_filterLock); try { return m_watches.at(_watchId).changes != 0; } catch (...) { return false; } } bool checkWatch(unsigned _watchId) { std::lock_guard l(m_filterLock); bool ret = false; try { ret = m_watches.at(_watchId).changes != 0; m_watches.at(_watchId).changes = 0; } catch (...) {} return ret; } + PastMessages transactions(unsigned _watchId) const { try { std::lock_guard l(m_filterLock); return transactions(m_filters.at(m_watches.at(_watchId).id).filter); } catch (...) { return PastMessages(); } } + PastMessages transactions(TransactionFilter const& _filter) const; + // [EXTRA API]: /// Get a map containing each of the pending transactions. /// @TODO: Remove in favour of transactions(). Transactions pending() const { return m_postMine.pending(); } + /// Differences between transactions. + StateDiff diff(unsigned _txi) const { return diff(_txi, m_default); } + StateDiff diff(unsigned _txi, h256 _block) const; + StateDiff diff(unsigned _txi, int _block) const; + /// Get a list of all active addresses. std::vector
addresses() const { return addresses(m_default); } std::vector
addresses(int _block) const; + /// Get the fee associated for a transaction with the given data. + static u256 txGas(uint _dataCount, u256 _gas = 0) { return c_txDataGas * _dataCount + c_txGas + _gas; } + + // [PRIVATE API - only relevant for base clients, not available in general] + + eth::State state(unsigned _txi, h256 _block) const; + eth::State state(h256 _block) const; + eth::State state(unsigned _txi) const; + + /// Get the object representing the current state of Ethereum. + eth::State postState() const { ReadGuard l(x_stateDB); return m_postMine; } + /// Get the object representing the current canonical blockchain. + BlockChain const& blockChain() const { return m_bc; } + // Misc stuff: void setClientVersion(std::string const& _name) { m_clientVersion = _name; } @@ -252,6 +254,8 @@ public: std::vector peers(); /// Same as peers().size(), but more efficient. size_t peerCount() const; + /// Same as peers().size(), but more efficient. + void setIdealPeerCount(size_t _n) const; /// Start the network subsystem. void startNetwork(unsigned short _listenPort = 30303, std::string const& _remoteHost = std::string(), unsigned short _remotePort = 30303, NodeMode _mode = NodeMode::Full, unsigned _peers = 5, std::string const& _publicIP = std::string(), bool _upnp = true); @@ -260,9 +264,11 @@ public: /// Stop the network subsystem. void stopNetwork(); /// Is the network subsystem up? - bool haveNetwork() { Guard l(x_net); return !!m_net; } - /// Get access to the peer server object. This will be null if the network isn't online. DANGEROUS! DO NOT USE! - PeerServer* peerServer() const { Guard l(x_net); return m_net.get(); } + bool haveNetwork() { ReadGuard l(x_net); return !!m_net; } + /// Save peers + bytes savePeers(); + /// Restore peers + void restorePeers(bytesConstRef _saved); // Mining stuff: @@ -291,13 +297,16 @@ public: void clearPending(); private: - /// Ensure the worker thread is running. Needed for networking & mining. + /// Ensure the worker thread is running. Needed for blockchain maintenance & mining. void ensureWorking(); - /// Do some work. Handles networking and mining. + /// Do some work. Handles blockchain maintenance and mining. /// @param _justQueue If true will only processing the transaction queues. void work(bool _justQueue = false); + /// Do some work on the network. + void workNet(); + /// Collate the changed filters for the bloom filter of the given pending transaction. /// Insert any filters that are activated into @a o_changed. void appendFromNewPending(h256 _pendingTransactionBloom, h256Set& o_changed) const; @@ -316,24 +325,26 @@ private: State asOf(int _h) const; State asOf(unsigned _h) const; - std::string m_clientVersion; ///< Our end-application client's name/version. - VersionChecker m_vc; ///< Dummy object to check & update the protocol version. - BlockChain m_bc; ///< Maintains block database. - TransactionQueue m_tq; ///< Maintains a list of incoming transactions not yet in a block on the blockchain. - BlockQueue m_bq; ///< Maintains a list of incoming blocks not yet on the blockchain (to be imported). - OverlayDB m_stateDB; ///< Acts as the central point for the state database, so multiple States can share it. - State m_preMine; ///< The present state of the client. - State m_postMine; ///< The state of the client which we're mining (i.e. it'll have all the rewards added). - - mutable std::mutex x_net; ///< Lock for the network. - std::unique_ptr m_net; ///< Should run in background and send us events when blocks found and allow us to send blocks as required. - - std::unique_ptr m_work;///< The work thread. - - mutable std::recursive_mutex m_lock; + std::string m_clientVersion; ///< Our end-application client's name/version. + VersionChecker m_vc; ///< Dummy object to check & update the protocol version. + BlockChain m_bc; ///< Maintains block database. + TransactionQueue m_tq; ///< Maintains a list of incoming transactions not yet in a block on the blockchain. + BlockQueue m_bq; ///< Maintains a list of incoming blocks not yet on the blockchain (to be imported). + mutable boost::shared_mutex x_stateDB; // TODO: remove in favour of copying m_stateDB as required and thread-safing/copying State. Have a good think about what state objects there should be. Probably want 4 (pre, post, mining, user-visible). + OverlayDB m_stateDB; ///< Acts as the central point for the state database, so multiple States can share it. + State m_preMine; ///< The present state of the client. + State m_postMine; ///< The state of the client which we're mining (i.e. it'll have all the rewards added). + + std::unique_ptr m_workNet; ///< The network thread. + std::atomic m_workNetState; + mutable boost::shared_mutex x_net; ///< Lock for the network existance. + std::unique_ptr m_net; ///< Should run in background and send us events when blocks found and allow us to send blocks as required. + + std::unique_ptr m_work; ///< The work thread. std::atomic m_workState; + bool m_paranoia = false; - bool m_doMine = false; ///< Are we supposed to be mining? + bool m_doMine = false; ///< Are we supposed to be mining? MineProgress m_mineProgress; std::list m_mineHistory; mutable bool m_restartMining = false; @@ -345,14 +356,4 @@ private: int m_default = -1; }; -inline ClientGuard::ClientGuard(Client const* _c): m_client(_c) -{ - m_client->lock(); -} - -inline ClientGuard::~ClientGuard() -{ - m_client->unlock(); -} - } diff --git a/libethereum/State.h b/libethereum/State.h index ccf6bfdd0..9f014f0ab 100644 --- a/libethereum/State.h +++ b/libethereum/State.h @@ -264,15 +264,6 @@ public: /// @return the difference between this state (origin) and @a _c (destination). StateDiff diff(State const& _c) const; - /// Get the fee associated for a transaction with the given data. - u256 txGas(uint _dataCount, u256 _gas = 0) const { return c_txDataGas * _dataCount + c_txGas + _gas; } - - /// Get the fee associated for a contract created with the given data. - u256 createGas(uint _dataCount, u256 _gas = 0) const { return txGas(_dataCount, _gas); } - - /// Get the fee associated for a normal transaction. - u256 callGas(uint _dataCount, u256 _gas = 0) const { return txGas(_dataCount, _gas); } - /// Sync our state with the block chain. /// This basically involves wiping ourselves if we've been superceded and rebuilding from the transaction queue. bool sync(BlockChain const& _bc); diff --git a/libqethereum/QEthereum.cpp b/libqethereum/QEthereum.cpp index bc27c7f8a..7300b558a 100644 --- a/libqethereum/QEthereum.cpp +++ b/libqethereum/QEthereum.cpp @@ -187,50 +187,32 @@ QString QEthereum::balanceAt(QString _a) const QString QEthereum::storageAt(QString _a, QString _p) const { - if (!m_client) - return ""; - eth::ClientGuard l(const_cast(m_client)); - return toQJS(client()->postState().storage(toAddress(_a), toU256(_p))); + return m_client ? toQJS(client()->stateAt(toAddress(_a), toU256(_p))) : ""; } double QEthereum::txCountAt(QString _a) const { - if (!m_client) - return 0.0; - eth::ClientGuard l(const_cast(m_client)); - return (double)client()->postState().transactionsFrom(toAddress(_a)); + return m_client ? (double)client()->countAt(toAddress(_a)) : 0.0; } bool QEthereum::isContractAt(QString _a) const { - if (!m_client) - return false; - eth::ClientGuard l(const_cast(m_client)); - return client()->postState().addressHasCode(toAddress(_a)); + return m_client ? client()->codeAt(toAddress(_a)).size() : false; } u256 QEthereum::balanceAt(Address _a) const { - if (!m_client) - return 0; - eth::ClientGuard l(const_cast(m_client)); - return client()->postState().balance(_a); + return m_client ? client()->balanceAt(_a) : 0; } double QEthereum::txCountAt(Address _a) const { - if (!m_client) - return 0.0; - eth::ClientGuard l(const_cast(m_client)); - return (double)client()->postState().transactionsFrom(_a); + return m_client ? (double)client()->countAt(_a) : 0.0; } bool QEthereum::isContractAt(Address _a) const { - if (!m_client) - return false; - eth::ClientGuard l(const_cast(m_client)); - return client()->postState().addressHasCode(_a); + return m_client ? client()->codeAt(_a).size() : false; } QString QEthereum::balanceAt(QString _a, int _block) const diff --git a/neth/main.cpp b/neth/main.cpp index c085736b2..3eaeec7a9 100644 --- a/neth/main.cpp +++ b/neth/main.cpp @@ -481,10 +481,7 @@ int main(int argc, char** argv) if (!remoteHost.empty()) c.startNetwork(listenPort, remoteHost, remotePort, mode, peers, publicIP, upnp); if (mining) - { - ClientGuard g(&c); c.startMining(); - } #if ETH_JSONRPC auto_ptr jsonrpcServer; @@ -531,7 +528,6 @@ int main(int argc, char** argv) { eth::uint port; iss >> port; - ClientGuard g(&c); c.startNetwork((short)port); } else if (cmd == "connect") @@ -539,22 +535,18 @@ int main(int argc, char** argv) string addr; eth::uint port; iss >> addr >> port; - ClientGuard g(&c); c.connect(addr, (short)port); } else if (cmd == "netstop") { - ClientGuard g(&c); c.stopNetwork(); } else if (cmd == "minestart") { - ClientGuard g(&c); c.startMining(); } else if (cmd == "minestop") { - ClientGuard g(&c); c.stopMining(); } #if ETH_JSONRPC @@ -604,13 +596,12 @@ int main(int argc, char** argv) } else if (cmd == "balance") { - u256 balance = c.state().balance(us.address()); + u256 balance = c.balanceAt(us.address(), 0); ccout << "Current balance:" << endl; ccout << toString(balance) << endl; } else if (cmd == "transact") { - ClientGuard g(&c); auto const& bc = c.blockChain(); auto h = bc.currentHash(); auto blockData = bc.block(h); @@ -663,7 +654,7 @@ int main(int argc, char** argv) ssbd << bbd; cnote << ssbd.str(); int ssize = fields[4].length(); - u256 minGas = (u256)c.state().callGas(data.size(), 0); + u256 minGas = (u256)Client::txGas(data.size(), 0); if (size < 40) { if (size > 0) @@ -688,7 +679,6 @@ int main(int argc, char** argv) } else if (cmd == "send") { - ClientGuard g(&c); vector s; s.push_back("Address"); vector l; @@ -720,7 +710,7 @@ int main(int argc, char** argv) auto h = bc.currentHash(); auto blockData = bc.block(h); BlockInfo info(blockData); - u256 minGas = (u256)c.state().callGas(0, 0); + u256 minGas = (u256)Client::txGas(0, 0); Address dest = h160(fromHex(fields[0])); c.transact(us.secret(), amount, dest, bytes(), minGas, info.minGasPrice); } @@ -728,7 +718,6 @@ int main(int argc, char** argv) } else if (cmd == "contract") { - ClientGuard g(&c); auto const& bc = c.blockChain(); auto h = bc.currentHash(); auto blockData = bc.block(h); @@ -782,7 +771,7 @@ int main(int argc, char** argv) cnote << "Init:"; cnote << ssc.str(); } - u256 minGas = (u256)c.state().createGas(init.size(), 0); + u256 minGas = (u256)Client::txGas(init.size(), 0); if (endowment < 0) cwarn << "Invalid endowment"; else if (gasPrice < info.minGasPrice) @@ -804,16 +793,15 @@ int main(int argc, char** argv) cwarn << "Invalid address length"; else { - ClientGuard g(&c); - auto h = h160(fromHex(rechex)); + auto address = h160(fromHex(rechex)); stringstream s; try { - auto storage = c.state().storage(h); + auto storage = c.storageAt(address); for (auto const& i: storage) s << "@" << showbase << hex << i.first << " " << showbase << hex << i.second << endl; - s << endl << disassemble(c.state().code(h)) << endl; + s << endl << disassemble(c.codeAt(address)) << endl; string outFile = getDataDir() + "/" + rechex + ".evm"; ofstream ofs; @@ -848,9 +836,6 @@ int main(int argc, char** argv) // Lock to prevent corrupt block-chain errors - ClientGuard g(&c); - - auto const& st = c.state(); auto const& bc = c.blockChain(); ccout << "Genesis hash: " << bc.genesisHash() << endl; @@ -869,7 +854,7 @@ int main(int argc, char** argv) auto s = t.receiveAddress ? boost::format(" %1% %2%> %3%: %4% [%5%]") % toString(t.safeSender()) % - (st.addressHasCode(t.receiveAddress) ? '*' : '-') % + (c.codeAt(t.receiveAddress, 0).size() ? '*' : '-') % toString(t.receiveAddress) % toString(formatBalance(t.value)) % toString((unsigned)t.nonce) : @@ -894,7 +879,7 @@ int main(int argc, char** argv) auto s = t.receiveAddress ? boost::format("%1% %2%> %3%: %4% [%5%]") % toString(t.safeSender()) % - (st.addressHasCode(t.receiveAddress) ? '*' : '-') % + (c.codeAt(t.receiveAddress, 0).size() ? '*' : '-') % toString(t.receiveAddress) % toString(formatBalance(t.value)) % toString((unsigned)t.nonce) : @@ -912,38 +897,29 @@ int main(int argc, char** argv) // Contracts and addresses y = 1; int cc = 1; - auto acs = st.addresses(); + auto acs = c.addresses(); for (auto const& i: acs) - { - auto r = i.first; - - if (st.addressHasCode(r)) + if (c.codeAt(i, 0).size()) { auto s = boost::format("%1%%2% : %3% [%4%]") % - toString(r) % - pretty(r, st) % - toString(formatBalance(i.second)) % - toString((unsigned)st.transactionsFrom(i.first)); + toString(i) % + toString(formatBalance(c.balanceAt(i, 0))) % + toString((unsigned)c.countAt(i, 0)); mvwaddnstr(contractswin, cc++, x, s.str().c_str(), qwidth); if (cc > qheight - 2) break; } - } for (auto const& i: acs) - { - auto r = i.first; - if (!st.addressHasCode(r)) { + if (c.codeAt(i, 0).empty()) + { auto s = boost::format("%1%%2% : %3% [%4%]") % - toString(r) % - pretty(r, st) % - toString(formatBalance(i.second)) % - toString((unsigned)st.transactionsFrom(i.first)); + toString(i) % + toString(formatBalance(c.balanceAt(i, 0))) % + toString((unsigned)c.countAt(i, 0)); mvwaddnstr(addswin, y++, x, s.str().c_str(), width / 2 - 4); if (y > height * 3 / 5 - 4) break; } - } - // Peers y = 1; for (PeerInfo const& i: c.peers()) @@ -968,9 +944,9 @@ int main(int argc, char** argv) // Balance stringstream ssb; - u256 balance = c.state().balance(us.address()); + u256 balance = c.balanceAt(us.address(), 0); Address gavCoin("0115554959f43bf1d04cd7e3749d00fb0623ce1f"); - u256 totalGavCoinBalance = st.storage(gavCoin, (u160)us.address()); + u256 totalGavCoinBalance = c.stateAt(gavCoin, (u160)us.address()); ssb << "Balance: " << formatBalance(balance) << " | " << totalGavCoinBalance << " GAV"; mvwprintw(consolewin, 0, x, ssb.str().c_str()); diff --git a/walleth/MainWin.cpp b/walleth/MainWin.cpp index e7a5dca5b..d8f8a28c3 100644 --- a/walleth/MainWin.cpp +++ b/walleth/MainWin.cpp @@ -158,12 +158,9 @@ void Main::writeSettings() s.setValue("idealPeers", m_idealPeers); s.setValue("port", m_port); - if (client()->peerServer()) - { - bytes d = client()->peerServer()->savePeers(); + bytes d = client()->savePeers(); + if (d.size()) m_peers = QByteArray((char*)d.data(), (int)d.size()); - - } s.setValue("peers", m_peers); s.setValue("geometry", saveGeometry()); @@ -203,16 +200,8 @@ void Main::refreshNetwork() ui->peerCount->setText(QString::fromStdString(toString(ps.size())) + " peer(s)"); } -eth::State const& Main::state() const -{ - return ui->preview->isChecked() ? client()->postState() : client()->state(); -} - void Main::refresh() { - eth::ClientGuard l(client()); - auto const& st = state(); - auto d = client()->blockChain().details(); auto diff = BlockInfo(client()->blockChain().block()).difficulty; ui->blockCount->setText(QString("#%1 @%3 T%2").arg(d.number).arg(toLog2(d.totalDifficulty)).arg(toLog2(diff))); @@ -221,7 +210,7 @@ void Main::refresh() u256 totalBalance = 0; for (auto i: m_myKeys) { - u256 b = st.balance(i.address()); + u256 b = m_client->balanceAt(i.address()); totalBalance += b; } ui->balance->setText(QString::fromStdString(formatBalance(totalBalance))); @@ -244,7 +233,7 @@ void Main::on_net_triggered(bool _auto) else client()->startNetwork(m_port, string(), 0, NodeMode::Full, m_idealPeers, "", ui->upnp->isChecked()); if (m_peers.size()) - client()->peerServer()->restorePeers(bytesConstRef((byte*)m_peers.data(), m_peers.size())); + client()->restorePeers(bytesConstRef((byte*)m_peers.data(), m_peers.size())); } else client()->stopNetwork();