Browse Source

DB prototyped.

cl-refactor
Gav Wood 10 years ago
parent
commit
dfea821aaf
  1. 86
      alethzero/MainWin.cpp
  2. 10
      alethzero/MainWin.h
  3. 2
      libp2p/Host.cpp
  4. 89
      libqethereum/QEthereum.cpp
  5. 67
      libqethereum/QEthereum.h
  6. 9
      third/MainWin.cpp
  7. 4
      third/MainWin.h

86
alethzero/MainWin.cpp

@ -131,6 +131,7 @@ Main::Main(QWidget *parent) :
connect(ui->ourAccounts->model(), SIGNAL(rowsMoved(const QModelIndex &, int, int, const QModelIndex &, int)), SLOT(ourAccountsRowsMoved()));
m_webThree.reset(new WebThreeDirect(string("AlethZero/v") + dev::Version + "/" DEV_QUOTED(ETH_BUILD_TYPE) "/" DEV_QUOTED(ETH_BUILD_PLATFORM), getDataDir() + "/AlethZero", false, {"eth", "shh"}));
m_ldb = new QLDB(this);
connect(ui->webView, &QWebView::loadStarted, [this]()
{
@ -138,8 +139,8 @@ Main::Main(QWidget *parent) :
m_whisper = nullptr;
// 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());
m_ethereum = new QEthereum(this, ethereum(), m_myKeys);
m_whisper = new QWhisper(this, whisper(), owned());
QWebSettings::globalSettings()->setAttribute(QWebSettings::DeveloperExtrasEnabled, true);
QWebFrame* f = ui->webView->page()->mainFrame();
@ -147,8 +148,9 @@ Main::Main(QWidget *parent) :
auto qdev = m_dev;
auto qeth = m_ethereum;
auto qshh = m_whisper;
connect(f, &QWebFrame::javaScriptWindowObjectCleared, QETH_INSTALL_JS_NAMESPACE(f, this, qdev, qeth, qshh));
connect(m_whisper, SIGNAL(idsChanged()), this, SLOT(refreshWhisper()));
auto qldb = m_ldb;
connect(f, &QWebFrame::javaScriptWindowObjectCleared, QETH_INSTALL_JS_NAMESPACE(f, this, qdev, qeth, qshh, qldb));
connect(m_whisper, SIGNAL(newIdToAdd(QString)), this, SLOT(addNewId(QString)));
});
connect(ui->webView, &QWebView::loadFinished, [=]()
@ -183,11 +185,20 @@ Main::~Main()
// Must do this here since otherwise m_ethereum'll be deleted (and therefore clearWatches() called by the destructor)
// *after* the client is dead.
m_ethereum->clientDieing();
m_whisper->faceDieing();
g_logPost = simpleDebugOut;
writeSettings();
}
void Main::addNewId(QString _ids)
{
Secret _id = toSecret(_ids);
KeyPair kp(_id);
m_myIdentities.push_back(kp);
m_whisper->setIdentities(owned());
}
dev::p2p::NetworkPreferences Main::netPrefs() const
{
return NetworkPreferences(ui->port->value(), ui->forceAddress->text().toStdString(), ui->upnp->isChecked(), ui->localNetworking->isChecked());
@ -494,15 +505,28 @@ void Main::on_paranoia_triggered()
void Main::writeSettings()
{
QSettings s("ethereum", "alethzero");
QByteArray b;
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);
QByteArray b;
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);
}
{
QByteArray b;
b.resize(sizeof(Secret) * m_myIdentities.size());
auto p = b.data();
for (auto i: m_myIdentities)
{
memcpy(p, &(i.secret()), sizeof(Secret));
p += sizeof(Secret);
}
s.setValue("identities", b);
}
s.setValue("address", b);
s.setValue("upnp", ui->upnp->isChecked());
s.setValue("forceAddress", ui->forceAddress->text());
@ -538,21 +562,39 @@ void Main::readSettings(bool _skipGeometry)
restoreGeometry(s.value("geometry").toByteArray());
restoreState(s.value("windowState").toByteArray());
m_myKeys.clear();
QByteArray b = s.value("address").toByteArray();
if (b.isEmpty())
m_myKeys.append(KeyPair::create());
else
{
h256 k;
for (unsigned i = 0; i < b.size() / sizeof(Secret); ++i)
m_myKeys.clear();
QByteArray b = s.value("address").toByteArray();
if (b.isEmpty())
m_myKeys.append(KeyPair::create());
else
{
memcpy(&k, b.data() + i * sizeof(Secret), sizeof(Secret));
if (!count(m_myKeys.begin(), m_myKeys.end(), KeyPair(k)))
m_myKeys.append(KeyPair(k));
h256 k;
for (unsigned i = 0; i < b.size() / sizeof(Secret); ++i)
{
memcpy(&k, b.data() + i * sizeof(Secret), sizeof(Secret));
if (!count(m_myKeys.begin(), m_myKeys.end(), KeyPair(k)))
m_myKeys.append(KeyPair(k));
}
}
ethereum()->setAddress(m_myKeys.back().address());
}
ethereum()->setAddress(m_myKeys.back().address());
{
m_myIdentities.clear();
QByteArray b = s.value("identities").toByteArray();
if (!b.isEmpty())
{
h256 k;
for (unsigned i = 0; i < b.size() / sizeof(Secret); ++i)
{
memcpy(&k, b.data() + i * sizeof(Secret), sizeof(Secret));
if (!count(m_myIdentities.begin(), m_myIdentities.end(), KeyPair(k)))
m_myIdentities.append(KeyPair(k));
}
}
}
m_peers = s.value("peers").toByteArray();
ui->upnp->setChecked(s.value("upnp", true).toBool());
ui->forceAddress->setText(s.value("forceAddress", "").toString());

10
alethzero/MainWin.h

@ -77,7 +77,7 @@ public:
dev::eth::Client* ethereum() const { return m_webThree->ethereum(); }
std::shared_ptr<dev::shh::WhisperHost> whisper() const { return m_webThree->whisper(); }
QList<dev::KeyPair> const& owned() const { return m_myKeys; }
QList<dev::KeyPair> owned() const { return m_myIdentities + m_myKeys; }
public slots:
void load(QString _file);
@ -153,9 +153,11 @@ private slots:
void on_newIdentity_triggered();
void refreshWhisper();
void addNewId(QString);
signals:
void poll();
void idsChanged();
private:
dev::p2p::NetworkPreferences netPrefs() const;
@ -179,6 +181,8 @@ private:
void readSettings(bool _skipGeometry = false);
void writeSettings();
void keysChanged();
bool isCreation() const;
dev::u256 fee() const;
dev::u256 total() const;
@ -189,8 +193,6 @@ private:
unsigned installWatch(dev::h256 _tf, std::function<void()> const& _f);
void uninstallWatch(unsigned _w);
void keysChanged();
void onNewPending();
void onNewBlock();
void onNameRegChange();
@ -228,6 +230,7 @@ private:
QByteArray m_peers;
QStringList m_servers;
QList<dev::KeyPair> m_myKeys;
QList<dev::KeyPair> m_myIdentities;
QString m_privateChain;
dev::bytes m_data;
dev::Address m_nameReg;
@ -255,4 +258,5 @@ private:
QDev* m_dev = nullptr;
QEthereum* m_ethereum = nullptr;
QWhisper* m_whisper = nullptr;
QLDB* m_ldb = nullptr;
};

2
libp2p/Host.cpp

@ -369,7 +369,7 @@ void Host::populateAddresses()
shared_ptr<Node> Host::noteNode(NodeId _id, bi::tcp::endpoint _a, Origin _o, bool _ready, NodeId _oldId)
{
RecursiveGuard l(x_peers);
if (_a.port() < 30300 && _a.port() > 30303)
if (_a.port() < 30300 || _a.port() > 30303)
cwarn << "Wierd port being recorded!";
if (_a.port() >= /*49152*/32768)

89
libqethereum/QEthereum.cpp

@ -1,3 +1,25 @@
/*
This file is part of cpp-ethereum.
cpp-ethereum is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
cpp-ethereum is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file QEthereum.cpp
* @author Gav Wood <i@gavwood.com>
* @date 2014
*/
#include <boost/filesystem.hpp>
#include <QtCore/QtCore>
#include <QtWebKitWidgets/QWebFrame>
#include <libdevcrypto/FileSystem.h>
@ -536,8 +558,9 @@ void QEthereum::poll()
// TODO: repot and hook all these up.
QWhisper::QWhisper(QObject* _p, std::shared_ptr<dev::shh::Interface> const& _c): QObject(_p), m_face(_c)
QWhisper::QWhisper(QObject* _p, std::shared_ptr<dev::shh::Interface> const& _c, QList<dev::KeyPair> _ids): QObject(_p), m_face(_c)
{
setIdentities(_ids);
}
QWhisper::~QWhisper()
@ -613,6 +636,14 @@ void QWhisper::doPost(QString _json)
face()->inject(toSealed(_json, m, from));
}
void QWhisper::setIdentities(QList<dev::KeyPair> const& _l)
{
m_ids.clear();
for (auto i: _l)
m_ids[i.pub()] = i.secret();
emit idsChanged();
}
static pair<shh::TopicMask, Public> toWatch(QString _json)
{
shh::BuildTopicMask bt(shh::BuildTopicMask::Empty);
@ -714,11 +745,18 @@ QString QWhisper::newIdentity()
Public QWhisper::makeIdentity()
{
KeyPair kp = KeyPair::create();
m_ids[kp.pub()] = kp.sec();
emit idsChanged();
emit newIdToAdd(toQJS(kp.sec()));
return kp.pub();
}
QString QWhisper::createGroup(QString _json)
{
}
QString QWhisper::addToGroup(QString _group, QString _who)
{
}
void QWhisper::poll()
{
for (auto const& w: m_watches)
@ -740,6 +778,51 @@ void QWhisper::poll()
}
}
#include <libdevcrypto/FileSystem.h>
QLDB::QLDB(QObject* _p): QObject(_p)
{
auto path = getDataDir() + "/.web3";
boost::filesystem::create_directories(path);
ldb::Options o;
o.create_if_missing = true;
ldb::DB::Open(o, path, &m_db);
}
QLDB::~QLDB()
{
}
void QLDB::put(QString _p, QString _k, QString _v)
{
bytes k = sha3(_p.toStdString()).asBytes() + sha3(_k.toStdString()).asBytes();
bytes v = toBytes(_v);
m_db->Put(m_writeOptions, ldb::Slice((char const*)k.data(), k.size()), ldb::Slice((char const*)v.data(), v.size()));
}
QString QLDB::get(QString _p, QString _k)
{
bytes k = sha3(_p.toStdString()).asBytes() + sha3(_k.toStdString()).asBytes();
string ret;
m_db->Get(m_readOptions, ldb::Slice((char const*)k.data(), k.size()), &ret);
return toQJS(dev::asBytes(ret));
}
void QLDB::putString(QString _p, QString _k, QString _v)
{
bytes k = sha3(_p.toStdString()).asBytes() + sha3(_k.toStdString()).asBytes();
string v = _v.toStdString();
m_db->Put(m_writeOptions, ldb::Slice((char const*)k.data(), k.size()), ldb::Slice((char const*)v.data(), v.size()));
}
QString QLDB::getString(QString _p, QString _k)
{
bytes k = sha3(_p.toStdString()).asBytes() + sha3(_k.toStdString()).asBytes();
string ret;
m_db->Get(m_readOptions, ldb::Slice((char const*)k.data(), k.size()), &ret);
return QString::fromStdString(ret);
}
// extra bits needed to link on VS
#ifdef _MSC_VER

67
libqethereum/QEthereum.h

@ -1,11 +1,39 @@
/*
This file is part of cpp-ethereum.
cpp-ethereum is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
cpp-ethereum is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file QEthereum.h
* @author Gav Wood <i@gavwood.com>
* @date 2014
*/
#pragma once
#pragma warning(push)
#pragma warning(disable: 4100 4267)
#include <leveldb/db.h>
#pragma warning(pop)
#include <QtCore/QObject>
#include <QtCore/QStringList>
#include <QtCore/QList>
#include <libdevcore/CommonIO.h>
#include <libethcore/CommonEth.h>
namespace ldb = leveldb;
namespace dev {
namespace eth {
class Interface;
@ -214,12 +242,14 @@ class QWhisper: public QObject
Q_OBJECT
public:
QWhisper(QObject* _p, std::shared_ptr<dev::shh::Interface> const& _c);
QWhisper(QObject* _p, std::shared_ptr<dev::shh::Interface> const& _c, QList<dev::KeyPair> _ids);
virtual ~QWhisper();
std::shared_ptr<dev::shh::Interface> face() const;
void setFace(std::shared_ptr<dev::shh::Interface> const& _c) { m_face = _c; }
void setIdentities(QList<dev::KeyPair> const& _l);
/// Call when the face() is going to be deleted to make this object useless but safe.
void faceDieing();
@ -230,6 +260,9 @@ public:
Q_INVOKABLE QString newIdentity();
Q_INVOKABLE QString newGroup(QString _id, QString _who);
Q_INVOKABLE QString addToGroup(QString _group, QString _who);
// Watches interface
Q_INVOKABLE unsigned newWatch(QString _json);
Q_INVOKABLE void killWatch(unsigned _w);
@ -247,6 +280,7 @@ public slots:
signals:
void watchChanged(unsigned _w, QString _envelopeJson);
void idsChanged();
void newIdToAdd(QString _id);
private:
std::weak_ptr<dev::shh::Interface> m_face;
@ -255,16 +289,41 @@ private:
std::map<dev::Public, dev::Secret> m_ids;
};
class QLDB: public QObject
{
Q_OBJECT
public:
QLDB(QObject* _p);
~QLDB();
Q_INVOKABLE void put(QString _name, QString _key, QString _value);
Q_INVOKABLE QString get(QString _name, QString _key);
Q_INVOKABLE void putString(QString _name, QString _key, QString _value);
Q_INVOKABLE QString getString(QString _name, QString _key);
private:
ldb::ReadOptions m_readOptions;
ldb::WriteOptions m_writeOptions;
ldb::DB* m_db;
};
// TODO: add p2p object
#define QETH_INSTALL_JS_NAMESPACE(_frame, _env, _web3, _eth, _shh) [_frame, _env, _web3, _eth, _shh]() \
#define QETH_INSTALL_JS_NAMESPACE(_frame, _env, _web3, _eth, _shh, _ldb) [_frame, _env, _web3, _eth, _shh, _ldb]() \
{ \
_frame->disconnect(); \
_frame->addToJavaScriptWindowObject("env", _env, QWebFrame::QtOwnership); \
_frame->addToJavaScriptWindowObject("web3", _web3, QWebFrame::ScriptOwnership); \
if (_ldb) \
{ \
_frame->addToJavaScriptWindowObject("_web3_dot_db", _ldb, QWebFrame::QtOwnership); \
_frame->evaluateJavaScript("web3.db = _web3_dot_db"); \
} \
if (_eth) \
{ \
_frame->addToJavaScriptWindowObject("_web3_dot_eth", _eth, QWebFrame::ScriptOwnership); \
_frame->evaluateJavaScript("_web3_dot_eth.makeWatch = function(a) { var ww = _web3_dot_eth.newWatch(a); var ret = { w: ww }; ret.uninstall = function() { _web3_dot_eth.killWatch(w); }; ret.changed = function(f) { _web3_dot_eth.watchChanged.connect(function(nw) { if (nw == ww) f() }); }; ret.messages = function() { return JSON.parse(_web3_dot_eth.watchMessages(this.w)) }; return ret; }"); \
_frame->evaluateJavaScript("_web3_dot_eth.makeWatch = function(a) { var ww = _web3_dot_eth.newWatch(a); var ret = { w: ww }; ret.uninstall = function() { _web3_dot_eth.killWatch(this.w); }; ret.changed = function(f) { _web3_dot_eth.watchChanged.connect(function(nw) { if (nw == ww) f() }); }; ret.messages = function() { return JSON.parse(_web3_dot_eth.watchMessages(this.w)) }; return ret; }"); \
_frame->evaluateJavaScript("_web3_dot_eth.watch = function(a) { return _web3_dot_eth.makeWatch(JSON.stringify(a)) }"); \
_frame->evaluateJavaScript("_web3_dot_eth.transact = function(a, f) { var r = _web3_dot_eth.doTransact(JSON.stringify(a)); if (f) f(r); }"); \
_frame->evaluateJavaScript("_web3_dot_eth.call = function(a, f) { var ret = _web3_dot_eth.doCallJson(JSON.stringify(a)); if (f) f(ret); return ret; }"); \
@ -277,7 +336,7 @@ private:
if (_shh) \
{ \
_frame->addToJavaScriptWindowObject("_web3_dot_shh", _shh, QWebFrame::ScriptOwnership); \
_frame->evaluateJavaScript("_web3_dot_shh.makeWatch = function(json) { var ww = _web3_dot_shh.newWatch(json); var ret = { w: ww }; ret.uninstall = function() { _web3_dot_shh.killWatch(w); }; ret.arrived = function(f) { _web3_dot_shh.watchChanged.connect(function(nw, envelope) { if (nw == ww) f(JSON.parse(envelope)) }); var existing = JSON.parse(_web3_dot_shh.watchMessages(ww)); for (var e in existing) f(existing[e]) }; return ret; }"); \
_frame->evaluateJavaScript("_web3_dot_shh.makeWatch = function(json) { var ww = _web3_dot_shh.newWatch(json); var ret = { w: ww }; ret.uninstall = function() { _web3_dot_shh.killWatch(this.w); }; ret.arrived = function(f) { _web3_dot_shh.watchChanged.connect(function(nw, envelope) { if (nw == ww) f(JSON.parse(envelope)) }); var existing = JSON.parse(_web3_dot_shh.watchMessages(this.w)); for (var e in existing) f(existing[e]) }; return ret; }"); \
_frame->evaluateJavaScript("_web3_dot_shh.watch = function(filter) { return _web3_dot_shh.makeWatch(JSON.stringify(filter)) }"); \
_frame->evaluateJavaScript("_web3_dot_shh.post = function(message) { return _web3_dot_shh.doPost(JSON.stringify(message)) }"); \
_frame->evaluateJavaScript("web3.shh = _web3_dot_shh"); \

9
third/MainWin.cpp

@ -102,19 +102,22 @@ Main::Main(QWidget *parent) :
m_web3.reset(new WebThreeDirect("Third", getDataDir() + "/Third", false, {"eth", "shh"}));
m_web3->connect(Host::pocHost());
m_ldb = new QLDB(this);
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());
m_ethereum = new QEthereum(this, ethereum(), m_myKeys);
m_whisper = new QWhisper(this, whisper(), owned());
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, this, qdev, qeth, qshh));
auto qldb = m_ldb;
connect(f, &QWebFrame::javaScriptWindowObjectCleared, QETH_INSTALL_JS_NAMESPACE(f, this, qdev, qeth, qshh, qldb));
});
connect(ui->webView, &QWebView::loadFinished, [=]()

4
third/MainWin.h

@ -61,7 +61,7 @@ public:
dev::eth::Client* ethereum() const;
std::shared_ptr<dev::shh::WhisperHost> whisper() const;
QList<dev::KeyPair> const& owned() const { return m_myKeys; }
QList<dev::KeyPair> owned() const { return m_myKeys + m_myIdentities; }
public slots:
void note(QString _entry);
@ -121,6 +121,7 @@ private:
std::unique_ptr<dev::WebThreeDirect> m_web3;
QList<dev::KeyPair> m_myKeys;
QList<dev::KeyPair> m_myIdentities;
std::map<unsigned, std::function<void()>> m_handlers;
unsigned m_nameRegFilter = (unsigned)-1;
@ -135,4 +136,5 @@ private:
QDev* m_dev = nullptr;
QEthereum* m_ethereum = nullptr;
QWhisper* m_whisper = nullptr;
QLDB* m_ldb = nullptr;
};

Loading…
Cancel
Save