From 3e46b869ad9efb98e38106085f6baf8bb621b6cb Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Fri, 12 Jun 2015 12:59:52 +0900 Subject: [PATCH] Allow unlocking of wallets over RPC. --- alethzero/OurWebThreeStubServer.cpp | 2 +- eth/main.cpp | 4 ++-- libethereum/ClientBase.cpp | 17 ++--------------- libweb3jsonrpc/WebThreeStubServer.cpp | 16 +++++++++++----- libweb3jsonrpc/WebThreeStubServer.h | 9 ++++++++- libweb3jsonrpc/WebThreeStubServerBase.h | 1 + libweb3jsonrpc/abstractwebthreestubserver.h | 6 ++++++ libweb3jsonrpc/spec.json | 1 + test/libweb3jsonrpc/webthreestubclient.h | 10 ++++++++++ 9 files changed, 42 insertions(+), 24 deletions(-) diff --git a/alethzero/OurWebThreeStubServer.cpp b/alethzero/OurWebThreeStubServer.cpp index 7e9836818..85f930792 100644 --- a/alethzero/OurWebThreeStubServer.cpp +++ b/alethzero/OurWebThreeStubServer.cpp @@ -34,7 +34,7 @@ OurWebThreeStubServer::OurWebThreeStubServer( WebThreeDirect& _web3, Main* _main ): - WebThreeStubServer(_conn, _web3, make_shared(_web3, _main), _main->owned().toVector().toStdVector()), + WebThreeStubServer(_conn, _web3, make_shared(_web3, _main), _main->owned().toVector().toStdVector(), _main->keyManager()), m_main(_main) { } diff --git a/eth/main.cpp b/eth/main.cpp index 47dbae318..cfe000500 100644 --- a/eth/main.cpp +++ b/eth/main.cpp @@ -829,7 +829,7 @@ int main(int argc, char** argv) if (jsonrpc > -1) { jsonrpcConnector = unique_ptr(new jsonrpc::HttpServer(jsonrpc, "", "", SensibleHttpThreads)); - jsonrpcServer = shared_ptr(new WebThreeStubServer(*jsonrpcConnector.get(), web3, make_shared([&](){return web3.ethereum();}, getAccountPassword, keyManager), vector())); + jsonrpcServer = shared_ptr(new WebThreeStubServer(*jsonrpcConnector.get(), web3, make_shared([&](){return web3.ethereum();}, getAccountPassword, keyManager), vector(), keyManager)); jsonrpcServer->StartListening(); } #endif @@ -973,7 +973,7 @@ int main(int argc, char** argv) if (jsonrpc < 0) jsonrpc = SensibleHttpPort; jsonrpcConnector = unique_ptr(new jsonrpc::HttpServer(jsonrpc, "", "", SensibleHttpThreads)); - jsonrpcServer = shared_ptr(new WebThreeStubServer(*jsonrpcConnector.get(), web3, make_shared([&](){return web3.ethereum();}, getAccountPassword, keyManager), vector())); + jsonrpcServer = shared_ptr(new WebThreeStubServer(*jsonrpcConnector.get(), web3, make_shared([&](){ return web3.ethereum(); }, getAccountPassword, keyManager), vector(), keyManager)); jsonrpcServer->StartListening(); } else if (cmd == "jsonstop") diff --git a/libethereum/ClientBase.cpp b/libethereum/ClientBase.cpp index 38e92fcd7..d5bc0dbb9 100644 --- a/libethereum/ClientBase.cpp +++ b/libethereum/ClientBase.cpp @@ -49,30 +49,17 @@ void ClientBase::submitTransaction(Secret _secret, u256 _value, Address _dest, b { prepareForTransaction(); - auto a = toAddress(_secret); - u256 n = postMine().transactionsFrom(a); - cdebug << "submitTx: " << a << "postMine=" << n << "; tq=" << m_tq.maxNonce(a); - Transaction t(_value, _gasPrice, _gas, _dest, _data, _nonce, _secret); m_tq.import(t.rlp()); StructuredLogger::transactionReceived(t.sha3().abridged(), t.sender().abridged()); - cnote << "New transaction " << t << "(maxNonce for sender" << a << "is" << m_tq.maxNonce(a) << ")"; + cnote << "New transaction " << t; } void ClientBase::submitTransaction(Secret _secret, u256 _value, Address _dest, bytes const& _data, u256 _gas, u256 _gasPrice) { - prepareForTransaction(); - auto a = toAddress(_secret); - u256 n = postMine().transactionsFrom(a); - cdebug << "submitTx: " << a << "postMine=" << n << "; tq=" << m_tq.maxNonce(a); - n = max(n, m_tq.maxNonce(a)); - Transaction t(_value, _gasPrice, _gas, _dest, _data, n, _secret); - m_tq.import(t.rlp()); - - StructuredLogger::transactionReceived(t.sha3().abridged(), t.sender().abridged()); - cnote << "New transaction " << t << "(maxNonce for sender" << a << "is" << m_tq.maxNonce(a) << ")"; + submitTransaction(_secret, _value, _dest, _data, _gas, _gasPrice, max(postMine().transactionsFrom(a), m_tq.maxNonce(a))); } Address ClientBase::submitTransaction(Secret _secret, u256 _endowment, bytes const& _init, u256 _gas, u256 _gasPrice) diff --git a/libweb3jsonrpc/WebThreeStubServer.cpp b/libweb3jsonrpc/WebThreeStubServer.cpp index 44f7f521c..eae15cd7e 100644 --- a/libweb3jsonrpc/WebThreeStubServer.cpp +++ b/libweb3jsonrpc/WebThreeStubServer.cpp @@ -24,18 +24,18 @@ // Make sure boost/asio.hpp is included before windows.h. #include #include - -#include #include +#include +#include #include "WebThreeStubServer.h" - using namespace std; using namespace dev; using namespace dev::eth; -WebThreeStubServer::WebThreeStubServer(jsonrpc::AbstractServerConnector& _conn, WebThreeDirect& _web3, shared_ptr const& _ethAccounts, std::vector const& _shhAccounts): +WebThreeStubServer::WebThreeStubServer(jsonrpc::AbstractServerConnector& _conn, WebThreeDirect& _web3, shared_ptr const& _ethAccounts, std::vector const& _shhAccounts, KeyManager& _keyMan): WebThreeStubServerBase(_conn, _ethAccounts, _shhAccounts), - m_web3(_web3) + m_web3(_web3), + m_keyMan(_keyMan) { auto path = getDataDir() + "/.web3"; boost::filesystem::create_directories(path); @@ -44,6 +44,12 @@ WebThreeStubServer::WebThreeStubServer(jsonrpc::AbstractServerConnector& _conn, ldb::DB::Open(o, path, &m_db); } +bool WebThreeStubServer::eth_notePassword(string const& _password) +{ + m_keyMan.notePassword(_password); + return true; +} + std::string WebThreeStubServer::web3_clientVersion() { return m_web3.clientVersion(); diff --git a/libweb3jsonrpc/WebThreeStubServer.h b/libweb3jsonrpc/WebThreeStubServer.h index 1eddc22d4..68de1808b 100644 --- a/libweb3jsonrpc/WebThreeStubServer.h +++ b/libweb3jsonrpc/WebThreeStubServer.h @@ -33,6 +33,10 @@ namespace dev { class WebThreeDirect; +namespace eth +{ +class KeyManager; +} } /** @@ -41,7 +45,7 @@ class WebThreeDirect; class WebThreeStubServer: public dev::WebThreeStubServerBase, public dev::WebThreeStubDatabaseFace { public: - WebThreeStubServer(jsonrpc::AbstractServerConnector& _conn, dev::WebThreeDirect& _web3, std::shared_ptr const& _ethAccounts, std::vector const& _shhAccounts); + WebThreeStubServer(jsonrpc::AbstractServerConnector& _conn, dev::WebThreeDirect& _web3, std::shared_ptr const& _ethAccounts, std::vector const& _shhAccounts, dev::eth::KeyManager& _keyMan); virtual std::string web3_clientVersion() override; @@ -54,8 +58,11 @@ private: virtual std::string get(std::string const& _name, std::string const& _key) override; virtual void put(std::string const& _name, std::string const& _key, std::string const& _value) override; + virtual bool eth_notePassword(std::string const& _password); + private: dev::WebThreeDirect& m_web3; + dev::eth::KeyManager& m_keyMan; leveldb::ReadOptions m_readOptions; leveldb::WriteOptions m_writeOptions; leveldb::DB* m_db; diff --git a/libweb3jsonrpc/WebThreeStubServerBase.h b/libweb3jsonrpc/WebThreeStubServerBase.h index ec24cb08d..07d1d6827 100644 --- a/libweb3jsonrpc/WebThreeStubServerBase.h +++ b/libweb3jsonrpc/WebThreeStubServerBase.h @@ -122,6 +122,7 @@ public: virtual std::string eth_signTransaction(Json::Value const& _transaction); virtual Json::Value eth_inspectTransaction(std::string const& _rlp); virtual bool eth_injectTransaction(std::string const& _rlp); + virtual bool eth_notePassword(std::string const&) { return false; } virtual bool db_put(std::string const& _name, std::string const& _key, std::string const& _value); virtual std::string db_get(std::string const& _name, std::string const& _key); diff --git a/libweb3jsonrpc/abstractwebthreestubserver.h b/libweb3jsonrpc/abstractwebthreestubserver.h index 522d418c1..2f5764197 100644 --- a/libweb3jsonrpc/abstractwebthreestubserver.h +++ b/libweb3jsonrpc/abstractwebthreestubserver.h @@ -64,6 +64,7 @@ class AbstractWebThreeStubServer : public jsonrpc::AbstractServerbindAndAddMethod(jsonrpc::Procedure("eth_signTransaction", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_OBJECT, NULL), &AbstractWebThreeStubServer::eth_signTransactionI); this->bindAndAddMethod(jsonrpc::Procedure("eth_inspectTransaction", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_OBJECT, "param1",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_inspectTransactionI); this->bindAndAddMethod(jsonrpc::Procedure("eth_injectTransaction", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, "param1",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_injectTransactionI); + this->bindAndAddMethod(jsonrpc::Procedure("eth_notePassword", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, "param1",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_notePasswordI); this->bindAndAddMethod(jsonrpc::Procedure("db_put", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, "param1",jsonrpc::JSON_STRING,"param2",jsonrpc::JSON_STRING,"param3",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::db_putI); this->bindAndAddMethod(jsonrpc::Procedure("db_get", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_STRING,"param2",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::db_getI); this->bindAndAddMethod(jsonrpc::Procedure("shh_post", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, "param1",jsonrpc::JSON_OBJECT, NULL), &AbstractWebThreeStubServer::shh_postI); @@ -301,6 +302,10 @@ class AbstractWebThreeStubServer : public jsonrpc::AbstractServereth_injectTransaction(request[0u].asString()); } + inline virtual void eth_notePasswordI(const Json::Value &request, Json::Value &response) + { + response = this->eth_notePassword(request[0u].asString()); + } inline virtual void db_putI(const Json::Value &request, Json::Value &response) { response = this->db_put(request[0u].asString(), request[1u].asString(), request[2u].asString()); @@ -398,6 +403,7 @@ class AbstractWebThreeStubServer : public jsonrpc::AbstractServerCallMethod("eth_notePassword",p); + if (result.isBool()) + return result.asBool(); + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } bool db_put(const std::string& param1, const std::string& param2, const std::string& param3) throw (jsonrpc::JsonRpcException) { Json::Value p;