Browse Source

Move misc to dev.* JS API.

Potential crash fix.
UPnP in thread.
cl-refactor
Gav Wood 10 years ago
parent
commit
6706c26471
  1. 4
      alethzero/MainWin.cpp
  2. 1
      alethzero/MainWin.h
  3. 1
      libdevcore/Worker.cpp
  4. 1
      libdevcore/Worker.h
  5. 51
      libp2p/Host.cpp
  6. 5
      libp2p/Host.h
  7. 2
      libp2p/UPnP.h
  8. 8
      libqethereum/QEthereum.cpp
  9. 69
      libqethereum/QEthereum.h
  10. 4
      third/MainWin.cpp
  11. 1
      third/MainWin.h

4
alethzero/MainWin.cpp

@ -135,15 +135,17 @@ Main::Main(QWidget *parent) :
connect(ui->webView, &QWebView::loadStarted, [this]()
{
// NOTE: no need to delete as QETH_INSTALL_JS_NAMESPACE adopts it.
m_dev = new QDev(this);
m_ethereum = new QEthereum(this, ethereum(), owned());
m_whisper = new QWhisper(this, whisper());
QWebSettings::globalSettings()->setAttribute(QWebSettings::DeveloperExtrasEnabled, true);
QWebFrame* f = ui->webView->page()->mainFrame();
f->disconnect(SIGNAL(javaScriptWindowObjectCleared()));
auto qdev = m_dev;
auto qeth = m_ethereum;
auto qshh = m_whisper;
connect(f, &QWebFrame::javaScriptWindowObjectCleared, QETH_INSTALL_JS_NAMESPACE(f, qeth, qshh, this));
connect(f, &QWebFrame::javaScriptWindowObjectCleared, QETH_INSTALL_JS_NAMESPACE(f, this, qdev, qeth, qshh));
});
connect(ui->webView, &QWebView::loadFinished, [=]()

1
alethzero/MainWin.h

@ -247,6 +247,7 @@ private:
QString m_logHistory;
bool m_logChanged = true;
QDev* m_dev = nullptr;
QEthereum* m_ethereum = nullptr;
QWhisper* m_whisper = nullptr;
};

1
libdevcore/Worker.cpp

@ -38,6 +38,7 @@ void Worker::startWorking()
m_work.reset(new thread([&]()
{
setThreadName(m_name.c_str());
startedWorking();
while (!m_stop)
{
this_thread::sleep_for(chrono::milliseconds(30));

1
libdevcore/Worker.h

@ -46,6 +46,7 @@ protected:
void startWorking();
void stopWorking();
bool isWorking() const { Guard l(x_work); return !!m_work; }
virtual void startedWorking() {}
virtual void doWork() = 0;
virtual void doneWorking() {}

51
libp2p/Host.cpp

@ -110,14 +110,6 @@ void Host::start()
}
}
determinePublic(m_netPrefs.publicIP, m_netPrefs.upnp);
ensureAccepting();
if (!m_public.address().is_unspecified() && (m_nodes.empty() || m_nodes[m_nodesList[0]]->id != id()))
noteNode(id(), m_public, Origin::Perfect, false);
clog(NetNote) << "Id:" << id().abridged();
for (auto const& h: m_capabilities)
h.second->onStarting();
@ -549,31 +541,31 @@ void Host::connect(bi::tcp::endpoint const& _ep)
});
}
void Node::connect(Host* _h)
void Host::connect(std::shared_ptr<Node> const& _n)
{
// if there's no ioService, it means we've had quit() called - bomb out - we're not allowed in here.
if (!_h->m_ioService)
if (!m_ioService)
return;
clog(NetConnect) << "Attempting connection to node" << id.abridged() << "@" << address << "from" << _h->id().abridged();
lastAttempted = std::chrono::system_clock::now();
failedAttempts++;
_h->m_ready -= index;
bi::tcp::socket* s = new bi::tcp::socket(*_h->m_ioService);
s->async_connect(address, [=](boost::system::error_code const& ec)
clog(NetConnect) << "Attempting connection to node" << _n->id.abridged() << "@" << _n->address << "from" << id().abridged();
_n->lastAttempted = std::chrono::system_clock::now();
_n->failedAttempts++;
m_ready -= _n->index;
bi::tcp::socket* s = new bi::tcp::socket(*m_ioService);
s->async_connect(_n->address, [=](boost::system::error_code const& ec)
{
if (ec)
{
clog(NetConnect) << "Connection refused to node" << id.abridged() << "@" << address << "(" << ec.message() << ")";
lastDisconnect = TCPError;
lastAttempted = std::chrono::system_clock::now();
_h->m_ready += index;
clog(NetConnect) << "Connection refused to node" << _n->id.abridged() << "@" << _n->address << "(" << ec.message() << ")";
_n->lastDisconnect = TCPError;
_n->lastAttempted = std::chrono::system_clock::now();
m_ready += _n->index;
}
else
{
clog(NetConnect) << "Connected to" << id.abridged() << "@" << address;
lastConnected = std::chrono::system_clock::now();
auto p = make_shared<Session>(_h, std::move(*s), _h->node(id), true); // true because we don't care about ids matched for now. Once we have permenant IDs this will matter a lot more and we can institute a safer mechanism.
clog(NetConnect) << "Connected to" << _n->id.abridged() << "@" << _n->address;
_n->lastConnected = std::chrono::system_clock::now();
auto p = make_shared<Session>(this, std::move(*s), node(_n->id), true); // true because we don't care about ids matched for now. Once we have permenant IDs this will matter a lot more and we can institute a safer mechanism.
p->start();
}
delete s;
@ -638,7 +630,7 @@ void Host::growPeers()
if (ns.size())
for (Node const& i: ns)
{
m_nodes[i.id]->connect(this);
connect(m_nodes[i.id]);
if (!--morePeers)
return;
}
@ -704,6 +696,17 @@ PeerInfos Host::peers(bool _updatePing) const
return ret;
}
void Host::startedWorking()
{
determinePublic(m_netPrefs.publicIP, m_netPrefs.upnp);
ensureAccepting();
if (!m_public.address().is_unspecified() && (m_nodes.empty() || m_nodes[m_nodesList[0]]->id != id()))
noteNode(id(), m_public, Origin::Perfect, false);
clog(NetNote) << "Id:" << id().abridged();
}
void Host::doWork()
{
// if there's no ioService, it means we've had quit() called - bomb out - we're not allowed in here.

5
libp2p/Host.h

@ -97,8 +97,6 @@ struct Node
else
return score < _n.score;
}
void connect(Host* _h);
};
using Nodes = std::vector<Node>;
@ -147,6 +145,7 @@ public:
static std::string pocHost();
void connect(std::string const& _addr, unsigned short _port = 30303) noexcept;
void connect(bi::tcp::endpoint const& _ep);
void connect(std::shared_ptr<Node> const& _n);
/// @returns true iff we have the a peer of the given id.
bool havePeer(NodeId _id) const;
@ -197,6 +196,8 @@ private:
void growPeers();
void prunePeers();
virtual void startedWorking();
/// Conduct I/O, polling, syncing, whatever.
/// Ideally all time-consuming I/O is done in a background thread or otherwise asynchronously, but you get this call every 100ms or so anyway.
/// This won't touch alter the blockchain.

2
libp2p/UPnP.h

@ -25,6 +25,7 @@
#include <set>
#include <string>
#include <memory>
#include <thread>
struct UPNPUrls;
struct IGDdatas;
@ -46,6 +47,7 @@ public:
bool isValid() const { return m_ok; }
private:
std::set<int> m_reg;
bool m_ok;
std::shared_ptr<struct UPNPUrls> m_urls;

8
libqethereum/QEthereum.cpp

@ -96,22 +96,22 @@ QString QEthereum::lll(QString _s) const
return toQJS(dev::eth::compileLLL(_s.toStdString()));
}
QString QEthereum::sha3(QString _s) const
QString QDev::sha3(QString _s) const
{
return toQJS(dev::sha3(toBytes(_s)));
}
QString QEthereum::sha3(QString _s1, QString _s2) const
QString QDev::sha3(QString _s1, QString _s2) const
{
return toQJS(dev::sha3(asBytes(padded(_s1, 32)) + asBytes(padded(_s2, 32))));
}
QString QEthereum::sha3(QString _s1, QString _s2, QString _s3) const
QString QDev::sha3(QString _s1, QString _s2, QString _s3) const
{
return toQJS(dev::sha3(asBytes(padded(_s1, 32)) + asBytes(padded(_s2, 32)) + asBytes(padded(_s3, 32))));
}
QString QEthereum::offset(QString _s, int _i) const
QString QDev::offset(QString _s, int _i) const
{
return toQJS(toU256(_s) + _i);
}

69
libqethereum/QEthereum.h

@ -98,6 +98,27 @@ inline QString fromBinary(QString const& _s, unsigned _padding = 32)
return fromBinary(asBytes(_s), _padding);
}
class QDev: public QObject
{
Q_OBJECT
public:
QDev(QObject* _p): QObject(_p) {}
virtual ~QDev() {}
Q_INVOKABLE QString sha3(QString _s) const;
Q_INVOKABLE QString sha3(QString _s1, QString _s2) const;
Q_INVOKABLE QString sha3(QString _s1, QString _s2, QString _s3) const;
Q_INVOKABLE QString offset(QString _s, int _offset) const;
Q_INVOKABLE QString toAscii(QString _s) const { return ::toBinary(_s); }
Q_INVOKABLE QString fromAscii(QString _s) const { return ::fromBinary(_s, 32); }
Q_INVOKABLE QString fromAscii(QString _s, unsigned _padding) const { return ::fromBinary(_s, _padding); }
Q_INVOKABLE QString toDecimal(QString _s) const { return ::toDecimal(_s); }
Q_INVOKABLE double fromFixed(QString _s) const { return ::fromFixed(_s); }
Q_INVOKABLE QString toFixed(double _d) const { return ::toFixed(_d); }
};
class QEthereum: public QObject
{
Q_OBJECT
@ -114,24 +135,11 @@ public:
void setAccounts(QList<dev::KeyPair> _l) { m_accounts = _l; keysChanged(); }
Q_INVOKABLE QString ethTest() const { return "Hello world!"; }
Q_INVOKABLE QEthereum* self() { return this; }
Q_INVOKABLE QString secretToAddress(QString _s) const;
Q_INVOKABLE QString lll(QString _s) const;
Q_INVOKABLE QString sha3(QString _s) const;
Q_INVOKABLE QString sha3(QString _s1, QString _s2) const;
Q_INVOKABLE QString sha3(QString _s1, QString _s2, QString _s3) const;
Q_INVOKABLE QString offset(QString _s, int _offset) const;
Q_INVOKABLE QString toAscii(QString _s) const { return ::toBinary(_s); }
Q_INVOKABLE QString fromAscii(QString _s) const { return ::fromBinary(_s, 32); }
Q_INVOKABLE QString fromAscii(QString _s, unsigned _padding) const { return ::fromBinary(_s, _padding); }
Q_INVOKABLE QString toDecimal(QString _s) const { return ::toDecimal(_s); }
Q_INVOKABLE double fromFixed(QString _s) const { return ::fromFixed(_s); }
Q_INVOKABLE QString toFixed(double _d) const { return ::toFixed(_d); }
// [NEW API] - Use this instead.
Q_INVOKABLE QString/*dev::u256*/ balanceAt(QString/*dev::Address*/ _a, int _block) const;
Q_INVOKABLE double countAt(QString/*dev::Address*/ _a, int _block) const;
@ -247,27 +255,28 @@ private:
};
// TODO: add p2p object
#define QETH_INSTALL_JS_NAMESPACE(frame, eth, shh, env) [frame, eth, shh, env]() \
#define QETH_INSTALL_JS_NAMESPACE(_frame, _env, _dev, _eth, _shh) [_frame, _env, _dev, _eth, _shh]() \
{ \
frame->disconnect(); \
frame->addToJavaScriptWindowObject("env", env, QWebFrame::QtOwnership); \
if (eth) \
_frame->disconnect(); \
_frame->addToJavaScriptWindowObject("env", _env, QWebFrame::QtOwnership); \
_frame->addToJavaScriptWindowObject("dev", _dev, QWebFrame::ScriptOwnership); \
if (_eth) \
{ \
frame->addToJavaScriptWindowObject("eth", eth, QWebFrame::ScriptOwnership); \
frame->evaluateJavaScript("eth.makeWatch = function(a) { var ww = eth.newWatch(a); var ret = { w: ww }; ret.uninstall = function() { eth.killWatch(w); }; ret.changed = function(f) { eth.watchChanged.connect(function(nw) { if (nw == ww) f() }); }; ret.messages = function() { return JSON.parse(eth.watchMessages(this.w)) }; return ret; }"); \
frame->evaluateJavaScript("eth.watch = function(a) { return eth.makeWatch(JSON.stringify(a)) }"); \
frame->evaluateJavaScript("eth.transact = function(a, f) { var r = eth.doTransact(JSON.stringify(a)); if (f) f(r); }"); \
frame->evaluateJavaScript("eth.call = function(a, f) { var ret = eth.doCallJson(JSON.stringify(a)); if (f) f(ret); return ret; }"); \
frame->evaluateJavaScript("eth.messages = function(a) { return JSON.parse(eth.getMessages(JSON.stringify(a))); }"); \
frame->evaluateJavaScript("eth.block = function(a) { return JSON.parse(eth.getBlock(a)); }"); \
frame->evaluateJavaScript("eth.transaction = function(a) { return JSON.parse(eth.getTransaction(a)); }"); \
frame->evaluateJavaScript("eth.uncle = function(a) { return JSON.parse(eth.getUncle(a)); }"); \
_frame->addToJavaScriptWindowObject("eth", _eth, QWebFrame::ScriptOwnership); \
_frame->evaluateJavaScript("eth.makeWatch = function(a) { var ww = eth.newWatch(a); var ret = { w: ww }; ret.uninstall = function() { eth.killWatch(w); }; ret.changed = function(f) { eth.watchChanged.connect(function(nw) { if (nw == ww) f() }); }; ret.messages = function() { return JSON.parse(eth.watchMessages(this.w)) }; return ret; }"); \
_frame->evaluateJavaScript("eth.watch = function(a) { return eth.makeWatch(JSON.stringify(a)) }"); \
_frame->evaluateJavaScript("eth.transact = function(a, f) { var r = eth.doTransact(JSON.stringify(a)); if (f) f(r); }"); \
_frame->evaluateJavaScript("eth.call = function(a, f) { var ret = eth.doCallJson(JSON.stringify(a)); if (f) f(ret); return ret; }"); \
_frame->evaluateJavaScript("eth.messages = function(a) { return JSON.parse(eth.getMessages(JSON.stringify(a))); }"); \
_frame->evaluateJavaScript("eth.block = function(a) { return JSON.parse(eth.getBlock(a)); }"); \
_frame->evaluateJavaScript("eth.transaction = function(a) { return JSON.parse(eth.getTransaction(a)); }"); \
_frame->evaluateJavaScript("eth.uncle = function(a) { return JSON.parse(eth.getUncle(a)); }"); \
} \
if (shh) \
if (_shh) \
{ \
frame->addToJavaScriptWindowObject("shh", shh, QWebFrame::ScriptOwnership); \
frame->evaluateJavaScript("shh.makeWatch = function(a) { var ww = shh.newWatch(a); var ret = { w: ww }; ret.uninstall = function() { shh.killWatch(w); }; ret.changed = function(f) { shh.watchChanged.connect(function(nw) { if (nw == ww) f() }); }; ret.messages = function() { return JSON.parse(shh.watchMessages(this.w)) }; return ret; }"); \
frame->evaluateJavaScript("shh.watch = function(a) { return shh.makeWatch(JSON.stringify(a)) }"); \
_frame->addToJavaScriptWindowObject("shh", _shh, QWebFrame::ScriptOwnership); \
_frame->evaluateJavaScript("shh.makeWatch = function(a) { var ww = shh.newWatch(a); var ret = { w: ww }; ret.uninstall = function() { shh.killWatch(w); }; ret.changed = function(f) { shh.watchChanged.connect(function(nw) { if (nw == ww) f() }); }; ret.messages = function() { return JSON.parse(shh.watchMessages(this.w)) }; return ret; }"); \
_frame->evaluateJavaScript("shh.watch = function(a) { return shh.makeWatch(JSON.stringify(a)) }"); \
} \
}

4
third/MainWin.cpp

@ -105,14 +105,16 @@ Main::Main(QWidget *parent) :
connect(ui->webView, &QWebView::loadStarted, [this]()
{
// NOTE: no need to delete as QETH_INSTALL_JS_NAMESPACE adopts it.
m_dev = new QDev(this);
m_ethereum = new QEthereum(this, ethereum(), owned());
m_whisper = new QWhisper(this, whisper());
QWebFrame* f = ui->webView->page()->mainFrame();
f->disconnect(SIGNAL(javaScriptWindowObjectCleared()));
auto qdev = m_dev;
auto qeth = m_ethereum;
auto qshh = m_whisper;
connect(f, &QWebFrame::javaScriptWindowObjectCleared, QETH_INSTALL_JS_NAMESPACE(f, qeth, qshh, this));
connect(f, &QWebFrame::javaScriptWindowObjectCleared, QETH_INSTALL_JS_NAMESPACE(f, this, qdev, qeth, qshh));
});
connect(ui->webView, &QWebView::loadFinished, [=]()

1
third/MainWin.h

@ -132,6 +132,7 @@ private:
QNetworkAccessManager m_webCtrl;
QDev* m_dev = nullptr;
QEthereum* m_ethereum = nullptr;
QWhisper* m_whisper = nullptr;
};

Loading…
Cancel
Save