mirror of
https://github.com/XRPLF/rippled.git
synced 2025-11-19 18:45:52 +00:00
More wallet work and RPC work. The first real newcoin RPC "createfamily"
(to create a family of accounts) works.
This commit is contained in:
@@ -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.";
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
@@ -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 ¶ms)
|
||||
{ // getaccount <family> <number>
|
||||
}
|
||||
|
||||
Json::Value RPCServer::doGetNewAccount(Json::Value ¶ms)
|
||||
{ // getnewaccount <family>
|
||||
}
|
||||
|
||||
Json::Value RPCServer::doLock(Json::Value ¶ms)
|
||||
{ // lock <family>
|
||||
// lock
|
||||
}
|
||||
|
||||
Json::Value RPCServer::doUnlock(Json::Value ¶ms)
|
||||
{ // unlock <hexPrivateKey>
|
||||
// unlock "<pass phrase>"
|
||||
}
|
||||
|
||||
Json::Value RPCServer::doInfo(Json::Value ¶ms)
|
||||
{ // 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";
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
53
Wallet.cpp
53
Wallet.cpp
@@ -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);
|
||||
|
||||
7
Wallet.h
7
Wallet.h
@@ -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();
|
||||
};
|
||||
|
||||
@@ -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++;
|
||||
|
||||
Reference in New Issue
Block a user