- begin refactoring twister_utils.h

- new rpc commands getdefaultuser/setdefaultuser (why is it not setting default on creation?)
- putdht now receives a generic json value parameter
This commit is contained in:
Miguel Freitas 2013-09-28 17:17:14 -03:00
parent adeeb15213
commit ea32a5a117
10 changed files with 238 additions and 120 deletions

View File

@ -12,7 +12,7 @@
#include "bitcoinrpc.h"
#include "db.h"
#include "twister.h"
#include "twister_utils.h"
#include <boost/algorithm/string.hpp>
#include <boost/asio.hpp>
@ -252,6 +252,8 @@ static const CRPCCommand vRPCCommands[] =
{ "unfollow", &unfollow, false, true },
{ "getfollowing", &getfollowing, false, true },
{ "listusernamespartial", &listusernamespartial, false, true },
{ "getdefaultuser", &getdefaultuser, false, true },
{ "setdefaultuser", &setdefaultuser, false, true },
};
CRPCTable::CRPCTable()
@ -1156,6 +1158,20 @@ void ConvertTo(Value& value, bool fAllowNull=false)
}
}
void ConvertToValue(Value& value)
{
if (value.type() == str_type)
{
// reinterpret string as unquoted json value
Value value2;
string strJSON = value.get_str();
if (!read_string(strJSON, value2))
throw runtime_error(string("Error parsing JSON:")+strJSON);
value = value2;
}
}
// Convert strings to command-specific RPC representation
Array RPCConvertValues(const std::string &strMethod, const std::vector<std::string> &strParams)
{
@ -1210,6 +1226,7 @@ Array RPCConvertValues(const std::string &strMethod, const std::vector<std::stri
if (strMethod == "importprivkey" && n > 2) ConvertTo<bool>(params[2]);
if (strMethod == "verifychain" && n > 0) ConvertTo<boost::int64_t>(params[0]);
if (strMethod == "verifychain" && n > 1) ConvertTo<boost::int64_t>(params[1]);
if (strMethod == "dhtput" && n > 3) ConvertToValue(params[3]);
if (strMethod == "dhtput" && n > 5) ConvertTo<boost::int64_t>(params[5]);
if (strMethod == "newpostmsg" && n > 1) ConvertTo<boost::int64_t>(params[1]);
if (strMethod == "newpostmsg" && n > 4) ConvertTo<boost::int64_t>(params[4]);

View File

@ -204,5 +204,7 @@ extern json_spirit::Value follow(const json_spirit::Array& params, bool fHelp);
extern json_spirit::Value unfollow(const json_spirit::Array& params, bool fHelp);
extern json_spirit::Value getfollowing(const json_spirit::Array& params, bool fHelp);
extern json_spirit::Value listusernamespartial(const json_spirit::Array& params, bool fHelp);
extern json_spirit::Value getdefaultuser(const json_spirit::Array& params, bool fHelp);
extern json_spirit::Value setdefaultuser(const json_spirit::Array& params, bool fHelp);
#endif

View File

@ -140,6 +140,53 @@ Value listwalletusers(const Array& params, bool fHelp)
return ret;
}
Value setdefaultuser(const Array& params, bool fHelp)
{
if (fHelp || params.size() != 1)
throw runtime_error(
"setdefaultuser <username>\n"
"Set default user to use (must exist)");
EnsureWalletIsUnlocked();
string strUsername = params[0].get_str();
CKeyID keyID;
if( !pwalletMain->GetKeyIdFromUsername(strUsername, keyID) )
throw JSONRPCError(RPC_WALLET_INVALID_ACCOUNT_NAME, "Error: username does not exist in wallet");
CPubKey vchPubKey;
if( !pwalletMain->GetPubKey( keyID, vchPubKey) )
throw JSONRPCError(RPC_WALLET_ERROR, "Error recovering pubkey from wallet");
if( !pwalletMain->SetDefaultKey(vchPubKey) )
throw JSONRPCError(RPC_WALLET_ERROR, "Error setting default key");
return Value();
}
Value getdefaultuser(const Array& params, bool fHelp)
{
if (fHelp || params.size() != 0)
throw runtime_error(
"getdefaultuser\n"
"Get default user being used");
EnsureWalletIsUnlocked();
CPubKey vchPubKey = pwalletMain->vchDefaultKey;
if( !vchPubKey.IsValid() )
throw JSONRPCError(RPC_WALLET_ERROR, "Error: default user key is invalid");
CKeyID keyID = vchPubKey.GetID();
std::string username;
if( !pwalletMain->GetUsernameFromKeyId(keyID, username) )
throw JSONRPCError(RPC_WALLET_ERROR, "Error converting keyID to username");
return username;
}
Value signmessage(const Array& params, bool fHelp)
{

View File

@ -1,5 +1,7 @@
#include "twister.h"
#include "twister_utils.h"
#include "main.h"
#include "init.h"
#include "bitcoinrpc.h"
@ -52,68 +54,6 @@ sha1_hash dhtTargetHash(std::string const &username, std::string const &resource
return hasher(buf.data(), buf.size()).final();
}
int load_file(std::string const& filename, std::vector<char>& v, int limit)
{
FILE* f = fopen(filename.c_str(), "rb");
if (f == NULL)
return -1;
int r = fseek(f, 0, SEEK_END);
if (r != 0) {
fclose(f);
return -1;
}
long s = ftell(f);
if (s < 0) {
fclose(f);
return -1;
}
if (s > limit) {
fclose(f);
return -2;
}
r = fseek(f, 0, SEEK_SET);
if (r != 0) {
fclose(f);
return -1;
}
v.resize(s);
if (s == 0) {
fclose(f);
return 0;
}
r = fread(&v[0], 1, v.size(), f);
if (r < 0) {
fclose(f);
return -1;
}
fclose(f);
if (r != s) return -3;
return 0;
}
int save_file(std::string const& filename, std::vector<char>& v)
{
using namespace libtorrent;
// TODO: don't use internal file type here. use fopen()
file f;
error_code ec;
if (!f.open(filename, file::write_only, ec)) return -1;
if (ec) return -1;
file::iovec_t b = {&v[0], v.size()};
size_type written = f.writev(0, &b, 1, ec);
if (written != int(v.size())) return -3;
if (ec) return -3;
return 0;
}
torrent_handle startTorrentUser(std::string const &username)
{
if( !m_userTorrent.count(username) ) {
@ -775,55 +715,6 @@ int getBestHeight()
return nBestHeight;
}
Value entryToJson(const entry &e)
{
Array lst;
Object o;
switch( e.type() ) {
case entry::int_t:
return e.integer();
case entry::string_t:
return e.string();
case entry::list_t:
for (entry::list_type::const_iterator i = e.list().begin(); i != e.list().end(); ++i) {
lst.push_back( entryToJson(*i) );
}
return lst;
case entry::dictionary_t:
for (entry::dictionary_type::const_iterator i = e.dict().begin(); i != e.dict().end(); ++i) {
o.push_back(Pair(i->first, entryToJson(i->second)));
}
return o;
default:
return string("<uninitialized>");
}
}
entry jsonToEntry(const Value &v)
{
entry::list_type lst;
entry::dictionary_type dict;
switch( v.type() ) {
case int_type:
return v.get_int();
case str_type:
return v.get_str();
case array_type:
for (Array::const_iterator i = v.get_array().begin(); i != v.get_array().end(); ++i) {
lst.push_back( jsonToEntry(*i) );
}
return lst;
case obj_type:
for (Object::const_iterator i = v.get_obj().begin(); i != v.get_obj().end(); ++i) {
dict[ i->name_ ] = jsonToEntry(i->value_);
}
return dict;
default:
return string("<uninitialized>");
}
}
Value dhtput(const Array& params, bool fHelp)
{
if (fHelp || params.size() < 5 || params.size() > 6)
@ -836,7 +727,7 @@ Value dhtput(const Array& params, bool fHelp)
string strUsername = params[0].get_str();
string strResource = params[1].get_str();
string strMulti = params[2].get_str();
string strValue = params[3].get_str();
entry value = jsonToEntry(params[3]);
string strSigUser = params[4].get_str();
// Test for private key here to avoid going into dht
@ -851,12 +742,13 @@ Value dhtput(const Array& params, bool fHelp)
if( !multi && params.size() != 6 )
throw JSONRPCError(RPC_WALLET_ERROR, "Seq parameter required for single");
int seq = params[5].get_int();
int seq = -1;
if( params.size() == 6 )
seq = params[5].get_int();
if( !multi && strUsername != strSigUser )
throw JSONRPCError(RPC_WALLET_ERROR, "Username must be the same as sig_user for single");
entry value = entry::string_type(strValue);
boost::int64_t timeutc = GetAdjustedTime();
ses->dht_putData(strUsername, strResource, multi, value, strSigUser, timeutc, seq);

View File

@ -27,7 +27,4 @@ bool validatePostNumberForUser(std::string const &username, int k);
int getBestHeight();
int load_file(std::string const& filename, std::vector<char>& v, int limit = 8000000);
#endif // TWISTER_H

127
src/twister_utils.cpp Normal file
View File

@ -0,0 +1,127 @@
#include "twister_utils.h"
#include <libtorrent/session.hpp>
#include <stdio.h>
using namespace std;
twister_utils::twister_utils()
{
}
int load_file(std::string const& filename, std::vector<char>& v, int limit)
{
FILE* f = fopen(filename.c_str(), "rb");
if (f == NULL)
return -1;
int r = fseek(f, 0, SEEK_END);
if (r != 0) {
fclose(f);
return -1;
}
long s = ftell(f);
if (s < 0) {
fclose(f);
return -1;
}
if (s > limit) {
fclose(f);
return -2;
}
r = fseek(f, 0, SEEK_SET);
if (r != 0) {
fclose(f);
return -1;
}
v.resize(s);
if (s == 0) {
fclose(f);
return 0;
}
r = fread(&v[0], 1, v.size(), f);
if (r < 0) {
fclose(f);
return -1;
}
fclose(f);
if (r != s) return -3;
return 0;
}
int save_file(std::string const& filename, std::vector<char>& v)
{
using namespace libtorrent;
// TODO: don't use internal file type here. use fopen()
file f;
error_code ec;
if (!f.open(filename, file::write_only, ec)) return -1;
if (ec) return -1;
file::iovec_t b = {&v[0], v.size()};
size_type written = f.writev(0, &b, 1, ec);
if (written != int(v.size())) return -3;
if (ec) return -3;
return 0;
}
using namespace json_spirit;
using namespace libtorrent;
Value entryToJson(const entry &e)
{
Array lst;
Object o;
switch( e.type() ) {
case entry::int_t:
return e.integer();
case entry::string_t:
return e.string();
case entry::list_t:
for (entry::list_type::const_iterator i = e.list().begin(); i != e.list().end(); ++i) {
lst.push_back( entryToJson(*i) );
}
return lst;
case entry::dictionary_t:
for (entry::dictionary_type::const_iterator i = e.dict().begin(); i != e.dict().end(); ++i) {
o.push_back(Pair(i->first, entryToJson(i->second)));
}
return o;
default:
return string("<uninitialized>");
}
}
entry jsonToEntry(const Value &v)
{
entry::list_type lst;
entry::dictionary_type dict;
switch( v.type() ) {
case int_type:
return v.get_int();
case str_type:
return v.get_str();
case array_type:
for (Array::const_iterator i = v.get_array().begin(); i != v.get_array().end(); ++i) {
lst.push_back( jsonToEntry(*i) );
}
return lst;
case obj_type:
for (Object::const_iterator i = v.get_obj().begin(); i != v.get_obj().end(); ++i) {
dict[ i->name_ ] = jsonToEntry(i->value_);
}
return dict;
default:
return string("<uninitialized>");
}
}

22
src/twister_utils.h Normal file
View File

@ -0,0 +1,22 @@
#ifndef TWISTER_UTILS_H
#define TWISTER_UTILS_H
#include "json_spirit.h"
#include "libtorrent/entry.hpp"
#include <string>
#include <vector>
class twister_utils
{
public:
twister_utils();
};
int load_file(std::string const& filename, std::vector<char>& v, int limit = 8000000);
int save_file(std::string const& filename, std::vector<char>& v);
json_spirit::Value entryToJson(const libtorrent::entry &e);
libtorrent::entry jsonToEntry(const json_spirit::Value &v);
#endif // TWISTER_UTILS_H

View File

@ -110,6 +110,17 @@ bool CWallet::GetKeyIdFromUsername(std::string username, CKeyID &keyid)
return false;
}
bool CWallet::GetUsernameFromKeyId(CKeyID keyid, std::string &username)
{
for (std::map<CKeyID, CKeyMetadata>::const_iterator it = mapKeyMetadata.begin(); it != mapKeyMetadata.end(); it++) {
if (it->first == keyid) {
username = it->second.username;
return true;
}
}
return false;
}
bool CWallet::LoadCryptedKey(const CPubKey &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret)
{
return CCryptoKeyStore::AddCryptedKey(vchPubKey, vchCryptedSecret);

View File

@ -133,6 +133,7 @@ public:
bool LoadKeyMetadata(const CPubKey &pubkey, const CKeyMetadata &metadata);
// Search metadata for a given username
bool GetKeyIdFromUsername(std::string username, CKeyID &keyid);
bool GetUsernameFromKeyId(CKeyID keyid, std::string &username);
bool LoadMinVersion(int nVersion) { nWalletVersion = nVersion; nWalletMaxVersion = std::max(nWalletMaxVersion, nVersion); return true; }

View File

@ -197,7 +197,8 @@ HEADERS += \
src/leveldb.h \
src/threadsafety.h \
src/limitedmap.h \
src/twister.h
src/twister.h \
src/twister_utils.h
# src/qt/bitcoingui.h
# src/qt/transactiontablemodel.h \
@ -270,7 +271,8 @@ SOURCES += \ #src/qt/bitcoin.cpp \
src/noui.cpp \
src/leveldb.cpp \
src/txdb.cpp \
src/twister.cpp
src/twister.cpp \
src/twister_utils.cpp
# src/qt/guiutil.cpp \
# src/qt/bitcoingui.cpp \