mirror of
https://github.com/XRPLF/rippled.git
synced 2025-11-20 11:05:54 +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()));
|
theApp->setDB(new SqliteDatabase(filename.c_str()));
|
||||||
mDatabase->connect();
|
mDatabase->connect();
|
||||||
|
|
||||||
return; // TEMPORARY
|
|
||||||
|
|
||||||
if(theConfig.PEER_PORT)
|
if(theConfig.PEER_PORT)
|
||||||
{
|
{
|
||||||
mPeerDoor=new PeerDoor(mIOService);
|
mPeerDoor=new PeerDoor(mIOService);
|
||||||
@@ -74,6 +72,8 @@ void Application::run()
|
|||||||
std::cout << "Before Run." << std::endl;
|
std::cout << "Before Run." << std::endl;
|
||||||
mIOService.run(); // This blocks
|
mIOService.run(); // This blocks
|
||||||
|
|
||||||
|
// temporary
|
||||||
|
return;
|
||||||
mWallet.load();
|
mWallet.load();
|
||||||
|
|
||||||
//BOOST_LOG_TRIVIAL(info) << "Done.";
|
//BOOST_LOG_TRIVIAL(info) << "Done.";
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
#include <openssl/bn.h>
|
#include <openssl/bn.h>
|
||||||
#include <openssl/ecdsa.h>
|
#include <openssl/ecdsa.h>
|
||||||
#include <openssl/pem.h>
|
#include <openssl/pem.h>
|
||||||
#include <openssl/rand.h>
|
|
||||||
|
|
||||||
// Functions to add CKey support for deterministic EC keys
|
// Functions to add CKey support for deterministic EC keys
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ using namespace std;
|
|||||||
using namespace boost::asio::ip;
|
using namespace boost::asio::ip;
|
||||||
|
|
||||||
RPCDoor::RPCDoor(boost::asio::io_service& io_service) :
|
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();
|
startListening();
|
||||||
@@ -24,7 +24,7 @@ void RPCDoor::startListening()
|
|||||||
boost::asio::placeholders::error));
|
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);
|
if(ip=="127.0.0.1") return(true);
|
||||||
return(false);
|
return(false);
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ class RPCDoor
|
|||||||
void handleConnect(RPCServer::pointer new_connection,
|
void handleConnect(RPCServer::pointer new_connection,
|
||||||
const boost::system::error_code& error);
|
const boost::system::error_code& error);
|
||||||
|
|
||||||
bool isClientAllowed(std::string ip);
|
bool isClientAllowed(const std::string& ip);
|
||||||
public:
|
public:
|
||||||
RPCDoor(boost::asio::io_service& io_service);
|
RPCDoor(boost::asio::io_service& io_service);
|
||||||
};
|
};
|
||||||
@@ -11,6 +11,7 @@
|
|||||||
#include "HttpReply.h"
|
#include "HttpReply.h"
|
||||||
#include "Application.h"
|
#include "Application.h"
|
||||||
#include "RPC.h"
|
#include "RPC.h"
|
||||||
|
#include "Wallet.h"
|
||||||
#include "Conversion.h"
|
#include "Conversion.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -44,7 +45,7 @@ void RPCServer::handle_read(const boost::system::error_code& e,
|
|||||||
|
|
||||||
if(result)
|
if(result)
|
||||||
{
|
{
|
||||||
// mReplyStr=handleRequest(mIncomingRequest.mBody);
|
mReplyStr=handleRequest(mIncomingRequest.mBody);
|
||||||
sendReply();
|
sendReply();
|
||||||
}
|
}
|
||||||
else if(!result)
|
else if(!result)
|
||||||
@@ -103,17 +104,76 @@ std::string RPCServer::handleRequest(const std::string& requestStr)
|
|||||||
return( HTTPReply(200, strReply) );
|
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)
|
Json::Value RPCServer::doCommand(const std::string& command, Json::Value& params)
|
||||||
{
|
{
|
||||||
|
std::cerr << "RPC:" << command << std::endl;
|
||||||
if(command== "stop")
|
if(command== "stop")
|
||||||
{
|
{
|
||||||
mSocket.get_io_service().stop();
|
mSocket.get_io_service().stop();
|
||||||
|
|
||||||
return "newcoin server stopping";
|
return "newcoin server stopping";
|
||||||
}
|
|
||||||
if(command=="send")
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
}
|
||||||
if(command== "addUNL")
|
if(command== "addUNL")
|
||||||
{
|
{
|
||||||
@@ -132,6 +192,12 @@ Json::Value RPCServer::doCommand(const std::string& command, Json::Value& params
|
|||||||
theApp->getUNL().dumpUNL(str);
|
theApp->getUNL().dumpUNL(str);
|
||||||
return(str.c_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";
|
return "unknown command";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,6 +29,13 @@ class RPCServer : public boost::enable_shared_from_this<RPCServer>
|
|||||||
|
|
||||||
Json::Value doCommand(const std::string& command, Json::Value& params);
|
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:
|
public:
|
||||||
typedef boost::shared_ptr<RPCServer> pointer;
|
typedef boost::shared_ptr<RPCServer> pointer;
|
||||||
|
|
||||||
|
|||||||
53
Wallet.cpp
53
Wallet.cpp
@@ -1,6 +1,9 @@
|
|||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
#include "openssl/rand.h"
|
||||||
|
#include "openssl/ec.h"
|
||||||
|
|
||||||
#include "boost/lexical_cast.hpp"
|
#include "boost/lexical_cast.hpp"
|
||||||
|
|
||||||
#include "Wallet.h"
|
#include "Wallet.h"
|
||||||
@@ -37,14 +40,7 @@ LocalAccountFamily::LocalAccountFamily(const uint160& family, const EC_GROUP* gr
|
|||||||
mFamily(family), mLastSeq(0), mRootPrivateKey(NULL)
|
mFamily(family), mLastSeq(0), mRootPrivateKey(NULL)
|
||||||
{
|
{
|
||||||
mRootPubKey=EC_POINT_dup(pubKey, group);
|
mRootPubKey=EC_POINT_dup(pubKey, group);
|
||||||
#ifdef DEBUG
|
mName=family.GetHex().substr(0, 4);
|
||||||
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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LocalAccountFamily::~LocalAccountFamily()
|
LocalAccountFamily::~LocalAccountFamily()
|
||||||
@@ -80,7 +76,6 @@ void LocalAccountFamily::lock()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::string LocalAccountFamily::getPubKeyHex() const
|
std::string LocalAccountFamily::getPubKeyHex() const
|
||||||
{
|
{
|
||||||
EC_GROUP *grp=EC_GROUP_new_by_curve_name(NID_secp256k1);
|
EC_GROUP *grp=EC_GROUP_new_by_curve_name(NID_secp256k1);
|
||||||
@@ -100,6 +95,32 @@ std::string LocalAccountFamily::getPubKeyHex() const
|
|||||||
return ret;
|
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()
|
std::string LocalAccountFamily::getSQLFields()
|
||||||
{
|
{
|
||||||
return "(FamilyName,RootPubKey,Seq,Name,Comment)";
|
return "(FamilyName,RootPubKey,Seq,Name,Comment)";
|
||||||
@@ -143,6 +164,12 @@ uint160 Wallet::addFamily(const uint256& key, bool lock)
|
|||||||
return fam->getFamily();
|
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)
|
uint160 Wallet::addFamily(const std::string& payPhrase, bool lock)
|
||||||
{
|
{
|
||||||
return addFamily(CKey::PassPhraseToKey(payPhrase), lock);
|
return addFamily(CKey::PassPhraseToKey(payPhrase), lock);
|
||||||
@@ -230,6 +257,14 @@ std::string Wallet::getPubKeyHex(const uint160& famBase)
|
|||||||
return fit->second->getPubKeyHex();
|
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)
|
LocalAccount::pointer Wallet::getLocalAccount(const uint160& family, int seq)
|
||||||
{
|
{
|
||||||
std::map<uint160, LocalAccountFamily::pointer>::iterator fit=families.find(family);
|
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);
|
uint160 getAccount(int seq);
|
||||||
|
|
||||||
std::string getPubKeyHex() const; // The text name of the public key
|
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();
|
static std::string getSQLFields();
|
||||||
std::string getSQL() const;
|
std::string getSQL() const;
|
||||||
|
|
||||||
|
static bool isHexPrivateKey(const std::string&);
|
||||||
|
static bool isHexPublicKey(const std::string&);
|
||||||
};
|
};
|
||||||
|
|
||||||
class LocalAccount
|
class LocalAccount
|
||||||
@@ -145,6 +148,7 @@ public:
|
|||||||
uint160 addFamily(const std::string& passPhrase, bool lock);
|
uint160 addFamily(const std::string& passPhrase, bool lock);
|
||||||
uint160 addFamily(const uint256& passPhrase, bool lock);
|
uint160 addFamily(const uint256& passPhrase, bool lock);
|
||||||
uint160 addFamily(const std::string& pubKey);
|
uint160 addFamily(const std::string& pubKey);
|
||||||
|
uint160 addFamily(uint256& privKey);
|
||||||
|
|
||||||
void delFamily(const uint160& familyName);
|
void delFamily(const uint160& familyName);
|
||||||
|
|
||||||
@@ -156,6 +160,7 @@ public:
|
|||||||
LocalAccount::pointer getLocalAccount(const uint160& famBase, int seq);
|
LocalAccount::pointer getLocalAccount(const uint160& famBase, int seq);
|
||||||
LocalAccount::pointer getLocalAccount(const uint160& acctID);
|
LocalAccount::pointer getLocalAccount(const uint160& acctID);
|
||||||
std::string getPubKeyHex(const uint160& famBase);
|
std::string getPubKeyHex(const uint160& famBase);
|
||||||
|
std::string getShortName(const uint160& famBase);
|
||||||
|
|
||||||
static bool unitTest();
|
static bool unitTest();
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -296,7 +296,7 @@ public:
|
|||||||
{
|
{
|
||||||
char psz[sizeof(pn)*2 + 1];
|
char psz[sizeof(pn)*2 + 1];
|
||||||
for (int i = 0; i < sizeof(pn); i++)
|
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);
|
return std::string(psz, psz + sizeof(pn)*2);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -314,7 +314,11 @@ public:
|
|||||||
psz += 2;
|
psz += 2;
|
||||||
|
|
||||||
// hex string to uint
|
// 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;
|
const char* pbegin = psz;
|
||||||
while (phexdigit[*psz] || *psz == '0')
|
while (phexdigit[*psz] || *psz == '0')
|
||||||
psz++;
|
psz++;
|
||||||
|
|||||||
Reference in New Issue
Block a user