More wallet work and RPC work. The first real newcoin RPC "createfamily"

(to create a family of accounts) works.
This commit is contained in:
JoelKatz
2011-12-29 02:02:30 -08:00
parent ca33205b83
commit 8c5918b576
9 changed files with 142 additions and 26 deletions

View File

@@ -57,8 +57,6 @@ void Application::run()
theApp->setDB(new SqliteDatabase(filename.c_str()));
mDatabase->connect();
return; // TEMPORARY
if(theConfig.PEER_PORT)
{
mPeerDoor=new PeerDoor(mIOService);
@@ -74,6 +72,8 @@ void Application::run()
std::cout << "Before Run." << std::endl;
mIOService.run(); // This blocks
// temporary
return;
mWallet.load();
//BOOST_LOG_TRIVIAL(info) << "Done.";

View File

@@ -2,7 +2,6 @@
#include <openssl/bn.h>
#include <openssl/ecdsa.h>
#include <openssl/pem.h>
#include <openssl/rand.h>
// Functions to add CKey support for deterministic EC keys

View File

@@ -8,7 +8,7 @@ using namespace std;
using namespace boost::asio::ip;
RPCDoor::RPCDoor(boost::asio::io_service& io_service) :
mAcceptor(io_service, tcp::endpoint(boost::asio::ip::address_v4::loopback(), theConfig.RPC_PORT))
mAcceptor(io_service, tcp::endpoint(boost::asio::ip::address_v4::loopback(), theConfig.RPC_PORT))
{
startListening();
@@ -24,7 +24,7 @@ void RPCDoor::startListening()
boost::asio::placeholders::error));
}
bool RPCDoor::isClientAllowed(std::string ip)
bool RPCDoor::isClientAllowed(const std::string& ip)
{
if(ip=="127.0.0.1") return(true);
return(false);
@@ -45,4 +45,4 @@ void RPCDoor::handleConnect(RPCServer::pointer new_connection,
}else cout << "Error: " << error;//BOOST_LOG_TRIVIAL(info) << "Error: " << error;
startListening();
}
}

View File

@@ -12,7 +12,7 @@ class RPCDoor
void handleConnect(RPCServer::pointer new_connection,
const boost::system::error_code& error);
bool isClientAllowed(std::string ip);
bool isClientAllowed(const std::string& ip);
public:
RPCDoor(boost::asio::io_service& io_service);
};

View File

@@ -11,6 +11,7 @@
#include "HttpReply.h"
#include "Application.h"
#include "RPC.h"
#include "Wallet.h"
#include "Conversion.h"
/*
@@ -44,7 +45,7 @@ void RPCServer::handle_read(const boost::system::error_code& e,
if(result)
{
// mReplyStr=handleRequest(mIncomingRequest.mBody);
mReplyStr=handleRequest(mIncomingRequest.mBody);
sendReply();
}
else if(!result)
@@ -103,17 +104,76 @@ std::string RPCServer::handleRequest(const std::string& requestStr)
return( HTTPReply(200, strReply) );
}
Json::Value RPCServer::doCreateFamily(Json::Value& params)
{
// createfamily <hexPrivateKey>
// createfamily <hexPublicKey>
// createfamily "<pass phrase>"
// createfamily
std::string query;
uint160 family;
if(params.isConvertibleTo(Json::stringValue)) query=params.asString();
Json::Value ret(Json::objectValue);
if(query.empty())
{
uint256 privKey;
family=theApp->getWallet().addFamily(privKey);
ret["PrivateGenerator"]=privKey.GetHex();
}
else if(LocalAccountFamily::isHexPrivateKey(query))
{
uint256 pk;
pk.SetHex(query);
family=theApp->getWallet().addFamily(pk, false);
}
else if(LocalAccountFamily::isHexPublicKey(query))
family=theApp->getWallet().addFamily(query);
else
family=theApp->getWallet().addFamily(query, false);
if(!family)
JSONRPCError(500, "Invalid family specifier");
ret["FamilyIdentifier"]=family.GetHex();
ret["ShortName"]=theApp->getWallet().getShortName(family);
ret["PublicGenerator"]=theApp->getWallet().getPubKeyHex(family);
return ret;
}
Json::Value RPCServer::doGetAccount(Json::Value &params)
{ // getaccount <family> <number>
}
Json::Value RPCServer::doGetNewAccount(Json::Value &params)
{ // getnewaccount <family>
}
Json::Value RPCServer::doLock(Json::Value &params)
{ // lock <family>
// lock
}
Json::Value RPCServer::doUnlock(Json::Value &params)
{ // unlock <hexPrivateKey>
// unlock "<pass phrase>"
}
Json::Value RPCServer::doInfo(Json::Value &params)
{ // info <family>
// info <family> <number>
// info
}
Json::Value RPCServer::doCommand(const std::string& command, Json::Value& params)
{
std::cerr << "RPC:" << command << std::endl;
if(command== "stop")
{
mSocket.get_io_service().stop();
return "newcoin server stopping";
}
if(command=="send")
{
}
if(command== "addUNL")
{
@@ -132,6 +192,12 @@ Json::Value RPCServer::doCommand(const std::string& command, Json::Value& params
theApp->getUNL().dumpUNL(str);
return(str.c_str());
}
if(command=="createfamily") return doCreateFamily(params);
if(command=="getaccount") return doGetAccount(params);
if(command=="getnewaccount") return doGetNewAccount(params);
if(command=="lock") return doLock(params);
if(command=="unlock") return doUnlock(params);
if(command=="info") return doInfo(params);
return "unknown command";
}

View File

@@ -28,6 +28,13 @@ class RPCServer : public boost::enable_shared_from_this<RPCServer>
void sendReply();
Json::Value doCommand(const std::string& command, Json::Value& params);
Json::Value doCreateFamily(Json::Value& params);
Json::Value doGetAccount(Json::Value& params);
Json::Value doGetNewAccount(Json::Value& params);
Json::Value doLock(Json::Value& params);
Json::Value doUnlock(Json::Value& params);
Json::Value doInfo(Json::Value& params);
public:
typedef boost::shared_ptr<RPCServer> pointer;
@@ -44,4 +51,4 @@ public:
void connected();
};
};

View File

@@ -1,6 +1,9 @@
#include <string>
#include "openssl/rand.h"
#include "openssl/ec.h"
#include "boost/lexical_cast.hpp"
#include "Wallet.h"
@@ -37,14 +40,7 @@ LocalAccountFamily::LocalAccountFamily(const uint160& family, const EC_GROUP* gr
mFamily(family), mLastSeq(0), mRootPrivateKey(NULL)
{
mRootPubKey=EC_POINT_dup(pubKey, group);
#ifdef DEBUG
std::cerr << "LocalAccountFamily::LocalAccountFamily(" << family.GetHex() << "," << std::endl;
EC_GROUP *grp=EC_GROUP_new_by_curve_name(NID_secp256k1);
char *p2h=EC_POINT_point2hex(grp, pubKey, POINT_CONVERSION_COMPRESSED, NULL);
EC_GROUP_free(grp);
std::cerr << " " << p2h << ")" << std::endl;
OPENSSL_free(p2h);
#endif
mName=family.GetHex().substr(0, 4);
}
LocalAccountFamily::~LocalAccountFamily()
@@ -80,7 +76,6 @@ void LocalAccountFamily::lock()
}
}
std::string LocalAccountFamily::getPubKeyHex() const
{
EC_GROUP *grp=EC_GROUP_new_by_curve_name(NID_secp256k1);
@@ -100,6 +95,32 @@ std::string LocalAccountFamily::getPubKeyHex() const
return ret;
}
static bool isHex(char j)
{
if((j>='0') && (j<='9')) return true;
if((j>='A') && (j<='F')) return true;
if((j>='a') && (j<='f')) return true;
return false;
}
bool LocalAccountFamily::isHexPrivateKey(const std::string& s)
{ // 64 characters, all legal hex
if(s.size()!=64) return false;
for(int i=0; i<64; i++)
if(!isHex(s[i])) return false;
return true;
}
bool LocalAccountFamily::isHexPublicKey(const std::string& s)
{ // 66 characters, all legal hex, starts with '02' or '03'
if(s.size()!=66) return false;
if(s[0]!='0') return false;
if((s[1]!='2') && (s[2]!='3')) return false;
for(int i=3; i<66; i++)
if(!isHex(s[i])) return false;
return true;
}
std::string LocalAccountFamily::getSQLFields()
{
return "(FamilyName,RootPubKey,Seq,Name,Comment)";
@@ -143,6 +164,12 @@ uint160 Wallet::addFamily(const uint256& key, bool lock)
return fam->getFamily();
}
uint160 Wallet::addFamily(uint256& key)
{
RAND_bytes((unsigned char *) &key, sizeof(key));
return addFamily(key, false);
}
uint160 Wallet::addFamily(const std::string& payPhrase, bool lock)
{
return addFamily(CKey::PassPhraseToKey(payPhrase), lock);
@@ -230,6 +257,14 @@ std::string Wallet::getPubKeyHex(const uint160& famBase)
return fit->second->getPubKeyHex();
}
std::string Wallet::getShortName(const uint160& famBase)
{
std::map<uint160, LocalAccountFamily::pointer>::iterator fit=families.find(famBase);
if(fit==families.end()) return "";
assert(fit->second->getFamily()==famBase);
return fit->second->getShortName();
}
LocalAccount::pointer Wallet::getLocalAccount(const uint160& family, int seq)
{
std::map<uint160, LocalAccountFamily::pointer>::iterator fit=families.find(family);

View File

@@ -93,10 +93,13 @@ public:
uint160 getAccount(int seq);
std::string getPubKeyHex() const; // The text name of the public key
std::string getShortName() const; // The text name for the family
std::string getShortName() const { return mName; }
static std::string getSQLFields();
std::string getSQL() const;
static bool isHexPrivateKey(const std::string&);
static bool isHexPublicKey(const std::string&);
};
class LocalAccount
@@ -145,6 +148,7 @@ public:
uint160 addFamily(const std::string& passPhrase, bool lock);
uint160 addFamily(const uint256& passPhrase, bool lock);
uint160 addFamily(const std::string& pubKey);
uint160 addFamily(uint256& privKey);
void delFamily(const uint160& familyName);
@@ -156,6 +160,7 @@ public:
LocalAccount::pointer getLocalAccount(const uint160& famBase, int seq);
LocalAccount::pointer getLocalAccount(const uint160& acctID);
std::string getPubKeyHex(const uint160& famBase);
std::string getShortName(const uint160& famBase);
static bool unitTest();
};

View File

@@ -296,7 +296,7 @@ public:
{
char psz[sizeof(pn)*2 + 1];
for (int i = 0; i < sizeof(pn); i++)
sprintf(psz + i*2, "%02x", ((unsigned char*)pn)[sizeof(pn) - i - 1]);
sprintf(psz + i*2, "%02X", ((unsigned char*)pn)[sizeof(pn) - i - 1]);
return std::string(psz, psz + sizeof(pn)*2);
}
@@ -314,7 +314,11 @@ public:
psz += 2;
// hex string to uint
static char phexdigit[256] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,1,2,3,4,5,6,7,8,9,0,0,0,0,0,0, 0,0xa,0xb,0xc,0xd,0xe,0xf,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0xa,0xb,0xc,0xd,0xe,0xf,0,0,0,0,0,0,0,0,0 };
static char phexdigit[256] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,1,2,3,4,5,6,7,8,9,0,0,0,0,0,0, 0,0xa,0xb,0xc,0xd,0xe,0xf,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0xa,0xb,0xc,0xd,0xe,0xf,0,0,0,0,0,0,0,0,0 };
const char* pbegin = psz;
while (phexdigit[*psz] || *psz == '0')
psz++;