diff --git a/alethzero/MainWin.cpp b/alethzero/MainWin.cpp index c4058a5b2..5fe5bef54 100644 --- a/alethzero/MainWin.cpp +++ b/alethzero/MainWin.cpp @@ -149,7 +149,7 @@ Main::Main(QWidget *parent) : 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_qwebConnector = new QWebThreeConnector(); - m_server = unique_ptr(new WebThreeStubServer(m_qwebConnector, *web3(), keysAsVector(owned()))); + m_server = unique_ptr(new WebThreeStubServer(m_qwebConnector, *web3(), keysAsVector(m_myKeys))); m_server->StartListening(); @@ -1142,7 +1142,7 @@ void Main::ourAccountsRowsMoved() m_myKeys = myKeys; if (m_server.get()) - m_server->setAccounts(keysAsVector(owned())); + m_server->setAccounts(keysAsVector(m_myKeys)); } void Main::on_inject_triggered() diff --git a/alethzero/MainWin.h b/alethzero/MainWin.h index d22ebb9c9..f25b21beb 100644 --- a/alethzero/MainWin.h +++ b/alethzero/MainWin.h @@ -78,7 +78,7 @@ public: dev::eth::Client* ethereum() const { return m_webThree->ethereum(); } std::shared_ptr whisper() const { return m_webThree->whisper(); } - QList const& owned() const { return m_myKeys; } + QList const& owned() const { return m_myIdentities + m_myKeys; } public slots: void load(QString _file); @@ -229,6 +229,7 @@ private: QByteArray m_peers; QStringList m_servers; QList m_myKeys; + QList m_myIdentities; QString m_privateChain; dev::bytes m_data; dev::Address m_nameReg; diff --git a/libdevcore/CommonJS.h b/libdevcore/CommonJS.h index 51e362026..be98c2372 100644 --- a/libdevcore/CommonJS.h +++ b/libdevcore/CommonJS.h @@ -82,8 +82,9 @@ template boost::multiprecision::number>>(asBytes(jsPadded(_s, N))); } -inline Address jsToAddress(std::string const& _s) { return jsToFixed<20>(_s); } -inline Secret jsToSecret(std::string const& _s) { return jsToFixed<32>(_s); } +inline Address jsToAddress(std::string const& _s) { return jsToFixed(_s); } +inline Public jsToPublic(std::string const& _s) { return jsToFixed(_s); } +inline Secret jsToSecret(std::string const& _s) { return jsToFixed(_s); } inline u256 jsToU256(std::string const& _s) { return jsToInt<32>(_s); } inline std::string jsToBinary(std::string const& _s) diff --git a/libweb3jsonrpc/WebThreeStubServer.cpp b/libweb3jsonrpc/WebThreeStubServer.cpp index ba7867f4d..1f3634047 100644 --- a/libweb3jsonrpc/WebThreeStubServer.cpp +++ b/libweb3jsonrpc/WebThreeStubServer.cpp @@ -29,6 +29,8 @@ #include #include #include +#include +#include using namespace std; using namespace dev; @@ -145,6 +147,40 @@ static dev::eth::MessageFilter toMessageFilter(Json::Value const& _json) return filter; } +static shh::Message toMessage(Json::Value const& _json) +{ + shh::Message ret; + if (!_json["from"].empty()) + ret.setFrom(jsToPublic(_json["from"].asString())); + if (!_json["to"].empty()) + ret.setTo(jsToPublic(_json["to"].asString())); + if (!_json["payload"].empty()) + ret.setPayload(jsToBytes(_json["payload"].asString())); + return ret; +} + +static shh::Envelope toSealed(Json::Value const& _json, shh::Message const& _m, Secret _from) +{ + unsigned ttl = 50; + unsigned workToProve = 50; + + shh::BuildTopic bt; + + if (!_json["ttl"].empty()) + ttl = _json["ttl"].asInt(); + if (!_json["workToProve"].empty()) + workToProve = _json["workToProve"].asInt(); + if (!_json["topic"].empty()) + { + if (_json["topic"].isString()) + bt.shift(asBytes(jsPadded(_json["topic"].asString(), 32))); + else if (_json["topic"].isArray()) + for (auto i: _json["topic"]) + bt.shift(asBytes(jsPadded(i.asString(), 32))); + } + return _m.seal(_from, bt, ttl, workToProve); +} + WebThreeStubServer::WebThreeStubServer(jsonrpc::AbstractServerConnector* _conn, WebThreeDirect& _web3, std::vector const& _accounts): AbstractWebThreeStubServer(_conn), m_web3(_web3) @@ -165,11 +201,24 @@ void WebThreeStubServer::setAccounts(std::vector const& _accounts) m_accounts[i.address()] = i.secret(); } +void WebThreeStubServer::setIdentities(std::vector const& _ids) +{ + m_ids.clear(); + for (auto i: _ids) + m_ids[i.pub()] = i.secret(); + // emit ids changed? +} + dev::eth::Interface* WebThreeStubServer::client() const { return m_web3.ethereum(); } +std::shared_ptr WebThreeStubServer::face() const +{ + return m_web3.whisper(); +} + Json::Value WebThreeStubServer::accounts() { Json::Value ret; @@ -178,6 +227,13 @@ Json::Value WebThreeStubServer::accounts() return ret; } +std::string WebThreeStubServer::addToGroup(std::string const& _group, std::string const& _who) +{ + (void)_group; + (void)_who; + return ""; +} + std::string WebThreeStubServer::balanceAt(string const& _address) { int block = 0; @@ -319,6 +375,11 @@ std::string WebThreeStubServer::getString(std::string const& _name, std::string return ret; } +bool WebThreeStubServer::haveIdentity(std::string const& _id) +{ + return m_ids.count(jsToPublic(_id)) > 0; +} + bool WebThreeStubServer::listening() { return m_web3.isNetworkStarted(); @@ -350,6 +411,20 @@ int WebThreeStubServer::newFilterString(std::string const& _filter) return ret; } +std::string WebThreeStubServer::newGroup(std::string const& _id, std::string const& _who) +{ + (void)_id; + (void)_who; + return ""; +} + +std::string WebThreeStubServer::newIdentity() +{ + KeyPair kp = KeyPair::create(); + // emit newId + return toJS(kp.pub()); +} + std::string WebThreeStubServer::compile(string const& _s) { return toJS(dev::eth::compileLLL(_s)); @@ -365,6 +440,22 @@ int WebThreeStubServer::peerCount() return m_web3.peerCount(); } +bool WebThreeStubServer::post(Json::Value const& _json) +{ + shh::Message m = toMessage(_json); + Secret from; + + if (m.from() && m_ids.count(m.from())) + { + cwarn << "Silently signing message from identity" << m.from().abridged() << ": User validation hook goes here."; + // TODO: insert validification hook here. + from = m_ids[m.from()]; + } + + face()->inject(toSealed(_json, m, from)); + return true; +} + bool WebThreeStubServer::put(std::string const& _name, std::string const& _key, std::string const& _value) { bytes k = sha3(_name).asBytes() + sha3(_key).asBytes(); diff --git a/libweb3jsonrpc/WebThreeStubServer.h b/libweb3jsonrpc/WebThreeStubServer.h index 3dc568933..d7a771688 100644 --- a/libweb3jsonrpc/WebThreeStubServer.h +++ b/libweb3jsonrpc/WebThreeStubServer.h @@ -38,7 +38,19 @@ namespace ldb = leveldb; -namespace dev { class WebThreeDirect; namespace eth { class Interface; } class KeyPair; } +namespace dev +{ +class WebThreeDirect; +class KeyPair; +namespace eth +{ +class Interface; +} +namespace shh +{ +class Interface; +} +} class WebThreeStubServer: public AbstractWebThreeStubServer { @@ -46,6 +58,7 @@ public: WebThreeStubServer(jsonrpc::AbstractServerConnector* _conn, dev::WebThreeDirect& _web3, std::vector const& _accounts); virtual Json::Value accounts(); + virtual std::string addToGroup(std::string const& _group, std::string const& _who); virtual std::string balanceAt(std::string const& _address); virtual Json::Value blockByHash(std::string const& _hash); virtual Json::Value blockByNumber(int const& _number); @@ -60,12 +73,16 @@ public: virtual std::string get(std::string const& _name, std::string const& _key); virtual Json::Value getMessages(int const& _id); virtual std::string getString(std::string const& _name, std::string const& _key); + virtual bool haveIdentity(std::string const& _id); virtual bool listening(); virtual bool mining(); virtual int newFilter(Json::Value const& _json); virtual int newFilterString(std::string const& _filter); + virtual std::string newGroup(std::string const& _id, std::string const& _who); + virtual std::string newIdentity(); virtual int number(); virtual int peerCount(); + virtual bool post(Json::Value const& _json); virtual bool put(std::string const& _name, std::string const& _key, std::string const& _value); virtual bool putString(std::string const& _name, std::string const& _key, std::string const& _value); virtual bool setCoinbase(std::string const& _address); @@ -81,12 +98,16 @@ public: virtual bool uninstallFilter(int const& _id); void setAccounts(std::vector const& _accounts); + void setIdentities(std::vector const& _ids); private: dev::eth::Interface* client() const; + std::shared_ptr face() const; dev::WebThreeDirect& m_web3; std::map m_accounts; ldb::ReadOptions m_readOptions; ldb::WriteOptions m_writeOptions; ldb::DB* m_db; + + std::map m_ids; }; diff --git a/libweb3jsonrpc/abstractwebthreestubserver.h b/libweb3jsonrpc/abstractwebthreestubserver.h index 0b16057f8..5d305e47c 100644 --- a/libweb3jsonrpc/abstractwebthreestubserver.h +++ b/libweb3jsonrpc/abstractwebthreestubserver.h @@ -14,6 +14,7 @@ class AbstractWebThreeStubServer : public jsonrpc::AbstractServer(conn) { this->bindAndAddMethod(new jsonrpc::Procedure("accounts", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_ARRAY, NULL), &AbstractWebThreeStubServer::accountsI); + this->bindAndAddMethod(new jsonrpc::Procedure("addToGroup", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_STRING,"param2",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::addToGroupI); this->bindAndAddMethod(new jsonrpc::Procedure("balanceAt", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::balanceAtI); this->bindAndAddMethod(new jsonrpc::Procedure("blockByHash", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_OBJECT, "param1",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::blockByHashI); this->bindAndAddMethod(new jsonrpc::Procedure("blockByNumber", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_OBJECT, "param1",jsonrpc::JSON_INTEGER, NULL), &AbstractWebThreeStubServer::blockByNumberI); @@ -28,12 +29,16 @@ class AbstractWebThreeStubServer : public jsonrpc::AbstractServerbindAndAddMethod(new jsonrpc::Procedure("get", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_STRING,"param2",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::getI); this->bindAndAddMethod(new jsonrpc::Procedure("getMessages", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_ARRAY, "param1",jsonrpc::JSON_INTEGER, NULL), &AbstractWebThreeStubServer::getMessagesI); this->bindAndAddMethod(new jsonrpc::Procedure("getString", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_STRING,"param2",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::getStringI); + this->bindAndAddMethod(new jsonrpc::Procedure("haveIdentity", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, "param1",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::haveIdentityI); this->bindAndAddMethod(new jsonrpc::Procedure("listening", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, NULL), &AbstractWebThreeStubServer::listeningI); this->bindAndAddMethod(new jsonrpc::Procedure("mining", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, NULL), &AbstractWebThreeStubServer::miningI); this->bindAndAddMethod(new jsonrpc::Procedure("newFilter", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_INTEGER, "param1",jsonrpc::JSON_OBJECT, NULL), &AbstractWebThreeStubServer::newFilterI); this->bindAndAddMethod(new jsonrpc::Procedure("newFilterString", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_INTEGER, "param1",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::newFilterStringI); + this->bindAndAddMethod(new jsonrpc::Procedure("newGroup", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_STRING,"param2",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::newGroupI); + this->bindAndAddMethod(new jsonrpc::Procedure("newIdentity", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::newIdentityI); this->bindAndAddMethod(new jsonrpc::Procedure("number", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_INTEGER, NULL), &AbstractWebThreeStubServer::numberI); this->bindAndAddMethod(new jsonrpc::Procedure("peerCount", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_INTEGER, NULL), &AbstractWebThreeStubServer::peerCountI); + this->bindAndAddMethod(new jsonrpc::Procedure("post", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, "param1",jsonrpc::JSON_OBJECT, NULL), &AbstractWebThreeStubServer::postI); this->bindAndAddMethod(new jsonrpc::Procedure("put", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, "param1",jsonrpc::JSON_STRING,"param2",jsonrpc::JSON_STRING,"param3",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::putI); this->bindAndAddMethod(new jsonrpc::Procedure("putString", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, "param1",jsonrpc::JSON_STRING,"param2",jsonrpc::JSON_STRING,"param3",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::putStringI); this->bindAndAddMethod(new jsonrpc::Procedure("setCoinbase", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, "param1",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::setCoinbaseI); @@ -55,6 +60,11 @@ class AbstractWebThreeStubServer : public jsonrpc::AbstractServeraccounts(); } + inline virtual void addToGroupI(const Json::Value& request, Json::Value& response) + { + response = this->addToGroup(request[0u].asString(), request[1u].asString()); + } + inline virtual void balanceAtI(const Json::Value& request, Json::Value& response) { response = this->balanceAt(request[0u].asString()); @@ -125,6 +135,11 @@ class AbstractWebThreeStubServer : public jsonrpc::AbstractServergetString(request[0u].asString(), request[1u].asString()); } + inline virtual void haveIdentityI(const Json::Value& request, Json::Value& response) + { + response = this->haveIdentity(request[0u].asString()); + } + inline virtual void listeningI(const Json::Value& request, Json::Value& response) { response = this->listening(); @@ -145,6 +160,16 @@ class AbstractWebThreeStubServer : public jsonrpc::AbstractServernewFilterString(request[0u].asString()); } + inline virtual void newGroupI(const Json::Value& request, Json::Value& response) + { + response = this->newGroup(request[0u].asString(), request[1u].asString()); + } + + inline virtual void newIdentityI(const Json::Value& request, Json::Value& response) + { + response = this->newIdentity(); + } + inline virtual void numberI(const Json::Value& request, Json::Value& response) { response = this->number(); @@ -155,6 +180,11 @@ class AbstractWebThreeStubServer : public jsonrpc::AbstractServerpeerCount(); } + inline virtual void postI(const Json::Value& request, Json::Value& response) + { + response = this->post(request[0u]); + } + inline virtual void putI(const Json::Value& request, Json::Value& response) { response = this->put(request[0u].asString(), request[1u].asString(), request[2u].asString()); @@ -222,6 +252,7 @@ class AbstractWebThreeStubServer : public jsonrpc::AbstractServerclient->CallMethod("addToGroup",p); + if (result.isString()) + return result.asString(); + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + + } + std::string balanceAt(const std::string& param1) throw (jsonrpc::JsonRpcException) { Json::Value p; @@ -212,6 +226,19 @@ p.append(param2); } + bool haveIdentity(const std::string& param1) throw (jsonrpc::JsonRpcException) + { + Json::Value p; + p.append(param1); + + Json::Value result = this->client->CallMethod("haveIdentity",p); + if (result.isBool()) + return result.asBool(); + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + + } + bool listening() throw (jsonrpc::JsonRpcException) { Json::Value p; @@ -262,6 +289,32 @@ p.append(param2); } + std::string newGroup(const std::string& param1, const std::string& param2) throw (jsonrpc::JsonRpcException) + { + Json::Value p; + p.append(param1); +p.append(param2); + + Json::Value result = this->client->CallMethod("newGroup",p); + if (result.isString()) + return result.asString(); + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + + } + + std::string newIdentity() throw (jsonrpc::JsonRpcException) + { + Json::Value p; + p = Json::nullValue; + Json::Value result = this->client->CallMethod("newIdentity",p); + if (result.isString()) + return result.asString(); + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + + } + int number() throw (jsonrpc::JsonRpcException) { Json::Value p; @@ -286,6 +339,19 @@ p.append(param2); } + bool post(const Json::Value& param1) throw (jsonrpc::JsonRpcException) + { + Json::Value p; + p.append(param1); + + Json::Value result = this->client->CallMethod("post",p); + if (result.isBool()) + return result.asBool(); + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + + } + bool put(const std::string& param1, const std::string& param2, const std::string& param3) throw (jsonrpc::JsonRpcException) { Json::Value p;