diff --git a/src/DBInit.cpp b/src/DBInit.cpp index ba9d954503..9f1f3a92a8 100644 --- a/src/DBInit.cpp +++ b/src/DBInit.cpp @@ -58,6 +58,12 @@ const char *WalletDBInit[] = { Dh1024 TEXT \ );", + // Local persistence of the RPC client + "CREATE TABLE RPCData ( \ + Key TEXT PRIMARY Key, \ + Value TEXT \ + );", + // Miscellaneous persistent information // Integer: 1 : Used to simplify SQL. // ScoreUpdated: when scores was last updated. diff --git a/src/RPCServer.cpp b/src/RPCServer.cpp index 624bb67198..8fb2d0e683 100644 --- a/src/RPCServer.cpp +++ b/src/RPCServer.cpp @@ -827,6 +827,76 @@ Json::Value RPCServer::doCreditSet(Json::Value& params) } } +// data_delete +Json::Value RPCServer::doDataDelete(Json::Value& params) +{ + if (params.size() != 1) + { + return JSONRPCError(400, "invalid params"); + } + + std::string strKey = params[0u].asString(); + + Json::Value ret = Json::Value(Json::objectValue); + + if (theApp->getWallet().dataDelete(strKey)) + { + ret["key"] = strKey; + } + else + { + ret = JSONRPCError(500, "internal error"); + } + + return ret; +} + +// data_fetch +Json::Value RPCServer::doDataFetch(Json::Value& params) +{ + if (params.size() != 1) + { + return JSONRPCError(400, "invalid params"); + } + + std::string strKey = params[0u].asString(); + std::string strValue; + + Json::Value ret = Json::Value(Json::objectValue); + + ret["key"] = strKey; + if (theApp->getWallet().dataFetch(strKey, strValue)) + ret["value"] = strValue; + + return ret; +} + +// data_store +Json::Value RPCServer::doDataStore(Json::Value& params) +{ + if (params.size() != 2) + { + return JSONRPCError(400, "invalid params"); + } + + std::string strKey = params[0u].asString(); + std::string strValue = params[1u].asString(); + + Json::Value ret = Json::Value(Json::objectValue); + + if (theApp->getWallet().dataStore(strKey, strValue)) + { + ret["key"] = strKey; + ret["value"] = strValue; + } + else + { + ret = JSONRPCError(500, "internal error"); + } + + return ret; +} + // nickname_info // Note: Nicknames are not automatically looked up by commands as they are advisory and can be changed. Json::Value RPCServer::doNicknameInfo(Json::Value& params) @@ -1336,7 +1406,7 @@ Json::Value RPCServer::doTx(Json::Value& params) return txn->getJson(true); } - return "not implemented"; + return JSONRPCError(501, "not implemented"); } // ledger @@ -1352,7 +1422,7 @@ Json::Value RPCServer::doLedger(Json::Value& params) return ret; } - return "not implemented"; + return JSONRPCError(501, "not implemented"); } // unl_add | [] @@ -2006,6 +2076,9 @@ Json::Value RPCServer::doCommand(const std::string& command, Json::Value& params if (command == "account_wallet_set") return doAccountWalletSet(params); if (command == "connect") return doConnect(params); if (command == "credit_set") return doCreditSet(params); + if (command == "data_delete") return doDataDelete(params); + if (command == "data_fetch") return doDataFetch(params); + if (command == "data_store") return doDataStore(params); if (command == "nickname_info") return doNicknameInfo(params); if (command == "nickname_set") return doNicknameSet(params); if (command == "password_fund") return doPasswordFund(params); diff --git a/src/RPCServer.h b/src/RPCServer.h index a972b05a6e..4af47f84d4 100644 --- a/src/RPCServer.h +++ b/src/RPCServer.h @@ -55,6 +55,9 @@ private: Json::Value doAccountWalletSet(Json::Value ¶ms); Json::Value doConnect(Json::Value& params); Json::Value doCreditSet(Json::Value& params); + Json::Value doDataDelete(Json::Value& params); + Json::Value doDataFetch(Json::Value& params); + Json::Value doDataStore(Json::Value& params); Json::Value doLedger(Json::Value& params); Json::Value doNicknameInfo(Json::Value& params); Json::Value doNicknameSet(Json::Value& params); diff --git a/src/Wallet.cpp b/src/Wallet.cpp index c636dd992e..f3c079fa71 100644 --- a/src/Wallet.cpp +++ b/src/Wallet.cpp @@ -43,7 +43,7 @@ bool Wallet::nodeIdentityLoad() ScopedLock sl(theApp->getWalletDB()->getDBLock()); bool bSuccess = false; - if(db->executeSQL("SELECT * FROM NodeIdentity;") && db->startIterRows()) + if (db->executeSQL("SELECT * FROM NodeIdentity;") && db->startIterRows()) { std::string strPublicKey, strPrivateKey; @@ -112,6 +112,55 @@ bool Wallet::nodeIdentityCreate() { return true; } +bool Wallet::dataDelete(const std::string& strKey) +{ + Database* db = theApp->getWalletDB()->getDB(); + + ScopedLock sl(theApp->getWalletDB()->getDBLock()); + + return db->executeSQL(str(boost::format("DELETE FROM RPCData WHERE Key=%s;") + % db->escape(strKey))); +} + +bool Wallet::dataFetch(const std::string& strKey, std::string& strValue) +{ + Database* db = theApp->getWalletDB()->getDB(); + + ScopedLock sl(theApp->getWalletDB()->getDBLock()); + + bool bSuccess = false; + + if (db->executeSQL(str(boost::format("SELECT Value FROM RPCData WHERE Key=%s;") + % db->escape(strKey))) && db->startIterRows()) + { + std::string strPublicKey, strPrivateKey; + + db->getStr("Value", strValue); + + db->endIterRows(); + + bSuccess = true; + } + + return bSuccess; +} + +bool Wallet::dataStore(const std::string& strKey, const std::string& strValue) +{ + Database* db = theApp->getWalletDB()->getDB(); + + ScopedLock sl(theApp->getWalletDB()->getDBLock()); + + bool bSuccess = false; + + return (db->executeSQL(str(boost::format("REPLACE INTO RPCData (Key, Value) VALUES (%s,%s);") + % db->escape(strKey) + % db->escape(strValue) + ))); + + return bSuccess; +} + bool Wallet::unitTest() { // Create 100 keys for each of 1,000 families and ensure all keys match diff --git a/src/Wallet.h b/src/Wallet.h index 982f80a91c..09ffa211d6 100644 --- a/src/Wallet.h +++ b/src/Wallet.h @@ -50,6 +50,11 @@ public: DH* getDh512() { return DHparams_dup(mDh512); } DH* getDh1024() { return DHparams_dup(mDh1024); } + // Local persistence of RPC clients + bool dataDelete(const std::string& strKey); + bool dataFetch(const std::string& strKey, std::string& strValue); + bool dataStore(const std::string& strKey, const std::string& strValue); + static bool unitTest(); }; diff --git a/src/main.cpp b/src/main.cpp index caa32cb01b..ce16372ced 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -45,6 +45,9 @@ void printHelp(const po::options_description& desc) cout << " account_wallet_set []" << endl; cout << " connect []" << endl; cout << " credit_set []" << endl; + cout << " data_delete " << endl; + cout << " data_fetch " << endl; + cout << " data_store " << endl; cout << " ledger" << endl; cout << " nickname_info " << endl; cout << " nickname_set [] []" << endl;