mirror of
https://github.com/twisterarmy/twister-core.git
synced 2025-01-11 15:27:57 +00:00
support key replacement from json rpc. seems to work.
This commit is contained in:
parent
6f48cf1dc1
commit
0071cb31db
@ -1218,6 +1218,7 @@ Array RPCConvertValues(const std::string &strMethod, const std::vector<std::stri
|
|||||||
if (strMethod == "listunspent" && n > 1) ConvertTo<boost::int64_t>(params[1]);
|
if (strMethod == "listunspent" && n > 1) ConvertTo<boost::int64_t>(params[1]);
|
||||||
if (strMethod == "listunspent" && n > 2) ConvertTo<Array>(params[2]);
|
if (strMethod == "listunspent" && n > 2) ConvertTo<Array>(params[2]);
|
||||||
if (strMethod == "getblock" && n > 1) ConvertTo<bool>(params[1]);
|
if (strMethod == "getblock" && n > 1) ConvertTo<bool>(params[1]);
|
||||||
|
if (strMethod == "createwalletuser" && n > 1) ConvertTo<bool>(params[1]);
|
||||||
if (strMethod == "getrawtransaction" && n > 1) ConvertTo<boost::int64_t>(params[1]);
|
if (strMethod == "getrawtransaction" && n > 1) ConvertTo<boost::int64_t>(params[1]);
|
||||||
if (strMethod == "gettxout" && n > 1) ConvertTo<boost::int64_t>(params[1]);
|
if (strMethod == "gettxout" && n > 1) ConvertTo<boost::int64_t>(params[1]);
|
||||||
if (strMethod == "gettxout" && n > 2) ConvertTo<bool>(params[2]);
|
if (strMethod == "gettxout" && n > 2) ConvertTo<bool>(params[2]);
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
#include "init.h"
|
#include "init.h"
|
||||||
#include "net.h"
|
#include "net.h"
|
||||||
#include "wallet.h"
|
#include "wallet.h"
|
||||||
|
#include "twister.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace boost;
|
using namespace boost;
|
||||||
@ -145,9 +146,9 @@ Value getrawtransaction(const Array& params, bool fHelp)
|
|||||||
|
|
||||||
Value createrawtransaction(const Array& params, bool fHelp)
|
Value createrawtransaction(const Array& params, bool fHelp)
|
||||||
{
|
{
|
||||||
if (fHelp || params.size() != 2)
|
if (fHelp || (params.size() != 2 && params.size() != 3))
|
||||||
throw runtime_error(
|
throw runtime_error(
|
||||||
"createrawtransaction <username> <pubKey>\n"
|
"createrawtransaction <username> <pubKey> [signedByOldKey]\n"
|
||||||
"Create a transaction registering a new user\n"
|
"Create a transaction registering a new user\n"
|
||||||
"Returns hex-encoded raw transaction.\n"
|
"Returns hex-encoded raw transaction.\n"
|
||||||
"it is not stored in the wallet or transmitted to the network.");
|
"it is not stored in the wallet or transmitted to the network.");
|
||||||
@ -165,6 +166,10 @@ Value createrawtransaction(const Array& params, bool fHelp)
|
|||||||
throw JSONRPCError(RPC_INTERNAL_ERROR, "pubkey is not valid");
|
throw JSONRPCError(RPC_INTERNAL_ERROR, "pubkey is not valid");
|
||||||
|
|
||||||
rawTx.pubKey << vch;
|
rawTx.pubKey << vch;
|
||||||
|
if( params.size() > 2) {
|
||||||
|
vector<unsigned char> vchSign(ParseHexV(params[2], "signedByOldKey"));
|
||||||
|
rawTx.pubKey << vchSign;
|
||||||
|
}
|
||||||
|
|
||||||
DoTxProofOfWork(rawTx);
|
DoTxProofOfWork(rawTx);
|
||||||
|
|
||||||
@ -221,6 +226,13 @@ Value sendrawtransaction(const Array& params, bool fHelp)
|
|||||||
uint256 hashBlock;
|
uint256 hashBlock;
|
||||||
CTransaction tx2;
|
CTransaction tx2;
|
||||||
fHave = GetTransaction(hashTx, tx2, hashBlock);
|
fHave = GetTransaction(hashTx, tx2, hashBlock);
|
||||||
|
|
||||||
|
// treat replacement as !fHave
|
||||||
|
if( fHave && verifyDuplicateOrReplacementTx(tx, false, true) ) {
|
||||||
|
printf("verifyDuplicateOrReplacementTx true\n");
|
||||||
|
fHave = false;
|
||||||
|
}
|
||||||
|
|
||||||
if (!fHave) {
|
if (!fHave) {
|
||||||
// push to local node
|
// push to local node
|
||||||
CValidationState state;
|
CValidationState state;
|
||||||
@ -255,6 +267,9 @@ Value sendnewusertransaction(const Array& params, bool fHelp)
|
|||||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "username must be string");
|
throw JSONRPCError(RPC_INVALID_PARAMETER, "username must be string");
|
||||||
string strUsername = params[0].get_str();
|
string strUsername = params[0].get_str();
|
||||||
|
|
||||||
|
CKeyID oldKeyID;
|
||||||
|
bool replaceKey = pwalletMain->GetKeyIdBeingReplaced(strUsername, oldKeyID);
|
||||||
|
|
||||||
CKeyID keyID;
|
CKeyID keyID;
|
||||||
if( !pwalletMain->GetKeyIdFromUsername(strUsername, keyID) )
|
if( !pwalletMain->GetKeyIdFromUsername(strUsername, keyID) )
|
||||||
throw JSONRPCError(RPC_WALLET_INVALID_ACCOUNT_NAME, "Error: username must exist in wallet");
|
throw JSONRPCError(RPC_WALLET_INVALID_ACCOUNT_NAME, "Error: username must exist in wallet");
|
||||||
@ -267,14 +282,27 @@ Value sendnewusertransaction(const Array& params, bool fHelp)
|
|||||||
CTransaction txOut;
|
CTransaction txOut;
|
||||||
uint256 hashBlock;
|
uint256 hashBlock;
|
||||||
uint256 userhash = SerializeHash(strUsername);
|
uint256 userhash = SerializeHash(strUsername);
|
||||||
if( GetTransaction(userhash, txOut, hashBlock) )
|
bool userInTxIndex = GetTransaction(userhash, txOut, hashBlock);
|
||||||
|
if( !replaceKey && userInTxIndex )
|
||||||
throw JSONRPCError(RPC_WALLET_INVALID_ACCOUNT_NAME, "Error: this username exists in tx database");
|
throw JSONRPCError(RPC_WALLET_INVALID_ACCOUNT_NAME, "Error: this username exists in tx database");
|
||||||
|
if( replaceKey && !userInTxIndex )
|
||||||
|
throw JSONRPCError(RPC_WALLET_INVALID_ACCOUNT_NAME, "Error: key replacemente requires old key in tx database");
|
||||||
|
|
||||||
Array createTxParams;
|
Array createTxParams;
|
||||||
createTxParams.push_back(strUsername);
|
createTxParams.push_back(strUsername);
|
||||||
createTxParams.push_back(HexStr(pubkey));
|
createTxParams.push_back(HexStr(pubkey));
|
||||||
|
if( replaceKey ) {
|
||||||
|
string newPubKey((const char *)pubkey.begin(), static_cast<size_t>(pubkey.size()));
|
||||||
|
string signedByOldKey;
|
||||||
|
signedByOldKey = createSignature(newPubKey, oldKeyID);
|
||||||
|
createTxParams.push_back(HexStr(signedByOldKey));
|
||||||
|
}
|
||||||
Value txValue = createrawtransaction(createTxParams, false);
|
Value txValue = createrawtransaction(createTxParams, false);
|
||||||
|
|
||||||
|
if( replaceKey ) {
|
||||||
|
pwalletMain->ForgetReplacementMap(strUsername);
|
||||||
|
}
|
||||||
|
|
||||||
std::string strTxHex = txValue.get_str();
|
std::string strTxHex = txValue.get_str();
|
||||||
Array sendTxParams;
|
Array sendTxParams;
|
||||||
sendTxParams.push_back(strTxHex);
|
sendTxParams.push_back(strTxHex);
|
||||||
|
@ -90,9 +90,9 @@ Value getinfo(const Array& params, bool fHelp)
|
|||||||
|
|
||||||
Value createwalletuser(const Array& params, bool fHelp)
|
Value createwalletuser(const Array& params, bool fHelp)
|
||||||
{
|
{
|
||||||
if (fHelp || params.size() != 1)
|
if (fHelp || (params.size() != 1 && params.size() != 2))
|
||||||
throw runtime_error(
|
throw runtime_error(
|
||||||
"createwalletuser <username>\n"
|
"createwalletuser <username> [replacekey]\n"
|
||||||
"Create a new key pair for user and add it to wallet\n"
|
"Create a new key pair for user and add it to wallet\n"
|
||||||
"Use sendnewusertransaction to publish it to the network.\n"
|
"Use sendnewusertransaction to publish it to the network.\n"
|
||||||
"Returns key secret (keep it safe)");
|
"Returns key secret (keep it safe)");
|
||||||
@ -101,18 +101,28 @@ Value createwalletuser(const Array& params, bool fHelp)
|
|||||||
|
|
||||||
string strUsername = params[0].get_str();
|
string strUsername = params[0].get_str();
|
||||||
|
|
||||||
|
bool replaceKey = false;
|
||||||
|
if (params.size() > 1)
|
||||||
|
replaceKey = params[1].get_bool();
|
||||||
|
|
||||||
CKeyID keyID;
|
CKeyID keyID;
|
||||||
if( pwalletMain->GetKeyIdFromUsername(strUsername, keyID) )
|
bool keyInWallet = pwalletMain->GetKeyIdFromUsername(strUsername, keyID);
|
||||||
|
if( keyInWallet && !replaceKey )
|
||||||
throw JSONRPCError(RPC_WALLET_INVALID_ACCOUNT_NAME, "Error: this username exists in wallet");
|
throw JSONRPCError(RPC_WALLET_INVALID_ACCOUNT_NAME, "Error: this username exists in wallet");
|
||||||
|
if( !keyInWallet && replaceKey )
|
||||||
|
throw JSONRPCError(RPC_WALLET_INVALID_ACCOUNT_NAME, "Error: replacekey given but old key not in wallet");
|
||||||
|
|
||||||
uint256 userhash = SerializeHash(strUsername);
|
uint256 userhash = SerializeHash(strUsername);
|
||||||
printf("createwalletuser: usernamehash(%s) = %s\n", strUsername.c_str(), userhash.GetHex().c_str());
|
printf("createwalletuser: usernamehash(%s) = %s\n", strUsername.c_str(), userhash.GetHex().c_str());
|
||||||
|
|
||||||
CTransaction txOut;
|
CTransaction txOut;
|
||||||
uint256 hashBlock;
|
uint256 hashBlock;
|
||||||
if( GetTransaction(userhash, txOut, hashBlock) )
|
if( GetTransaction(userhash, txOut, hashBlock) && !replaceKey )
|
||||||
throw JSONRPCError(RPC_WALLET_INVALID_ACCOUNT_NAME, "Error: this username exists in tx database");
|
throw JSONRPCError(RPC_WALLET_INVALID_ACCOUNT_NAME, "Error: this username exists in tx database");
|
||||||
|
|
||||||
|
if( replaceKey && !pwalletMain->MoveKeyForReplacement(strUsername) )
|
||||||
|
throw JSONRPCError(RPC_WALLET_ERROR, "Error: moving key for replacement");
|
||||||
|
|
||||||
// Generate a new key that is added to wallet
|
// Generate a new key that is added to wallet
|
||||||
CPubKey newKey = pwalletMain->GenerateNewKey(strUsername);
|
CPubKey newKey = pwalletMain->GenerateNewKey(strUsername);
|
||||||
keyID = newKey.GetID();
|
keyID = newKey.GetID();
|
||||||
|
@ -436,22 +436,16 @@ void stopSessionTorrent()
|
|||||||
printf("libtorrent + dht stopped\n");
|
printf("libtorrent + dht stopped\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string createSignature(std::string const &strMessage, std::string const &strUsername)
|
std::string createSignature(std::string const &strMessage, CKeyID &keyID)
|
||||||
{
|
{
|
||||||
if (pwalletMain->IsLocked()) {
|
if (pwalletMain->IsLocked()) {
|
||||||
printf("createSignature: Error please enter the wallet passphrase with walletpassphrase first.\n");
|
printf("createSignature: Error please enter the wallet passphrase with walletpassphrase first.\n");
|
||||||
return std::string();
|
return std::string();
|
||||||
}
|
}
|
||||||
|
|
||||||
CKeyID keyID;
|
|
||||||
if( !pwalletMain->GetKeyIdFromUsername(strUsername, keyID) ) {
|
|
||||||
printf("createSignature: user '%s' unknown.\n", strUsername.c_str());
|
|
||||||
return std::string();
|
|
||||||
}
|
|
||||||
|
|
||||||
CKey key;
|
CKey key;
|
||||||
if (!pwalletMain->GetKey(keyID, key)) {
|
if (!pwalletMain->GetKey(keyID, key)) {
|
||||||
printf("createSignature: private key not available for user '%s'.\n", strUsername.c_str());
|
printf("createSignature: private key not available for given keyid.\n");
|
||||||
return std::string();
|
return std::string();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -468,6 +462,23 @@ std::string createSignature(std::string const &strMessage, std::string const &st
|
|||||||
return std::string((const char *)&vchSig[0], vchSig.size());
|
return std::string((const char *)&vchSig[0], vchSig.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string createSignature(std::string const &strMessage, std::string const &strUsername)
|
||||||
|
{
|
||||||
|
if (pwalletMain->IsLocked()) {
|
||||||
|
printf("createSignature: Error please enter the wallet passphrase with walletpassphrase first.\n");
|
||||||
|
return std::string();
|
||||||
|
}
|
||||||
|
|
||||||
|
CKeyID keyID;
|
||||||
|
if( !pwalletMain->GetKeyIdFromUsername(strUsername, keyID) ) {
|
||||||
|
printf("createSignature: user '%s' unknown.\n", strUsername.c_str());
|
||||||
|
return std::string();
|
||||||
|
}
|
||||||
|
|
||||||
|
return createSignature( strMessage, keyID );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool getUserPubKey(std::string const &strUsername, CPubKey &pubkey)
|
bool getUserPubKey(std::string const &strUsername, CPubKey &pubkey)
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
#define TWISTER_H
|
#define TWISTER_H
|
||||||
|
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
#include "key.h"
|
||||||
#include <boost/thread.hpp>
|
#include <boost/thread.hpp>
|
||||||
|
|
||||||
#define LIBTORRENT_PORT_OFFSET 1000
|
#define LIBTORRENT_PORT_OFFSET 1000
|
||||||
@ -19,6 +20,7 @@ public:
|
|||||||
void startSessionTorrent(boost::thread_group& threadGroup);
|
void startSessionTorrent(boost::thread_group& threadGroup);
|
||||||
void stopSessionTorrent();
|
void stopSessionTorrent();
|
||||||
|
|
||||||
|
std::string createSignature(std::string const &strMessage, CKeyID &keyID);
|
||||||
std::string createSignature(std::string const &strMessage, std::string const &strUsername);
|
std::string createSignature(std::string const &strMessage, std::string const &strUsername);
|
||||||
bool verifySignature(std::string const &strMessage, std::string const &strUsername, std::string const &strSign);
|
bool verifySignature(std::string const &strMessage, std::string const &strUsername, std::string const &strSign);
|
||||||
|
|
||||||
|
@ -121,6 +121,41 @@ bool CWallet::GetUsernameFromKeyId(CKeyID keyid, std::string &username)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CWallet::MoveKeyForReplacement(std::string username)
|
||||||
|
{
|
||||||
|
for (std::map<CKeyID, CKeyMetadata>::iterator it = mapKeyMetadata.begin(); it != mapKeyMetadata.end(); it++) {
|
||||||
|
if (it->second.username == username) {
|
||||||
|
mapKeyReplacement.insert(make_pair(it->first, username));
|
||||||
|
mapKeyMetadata.erase(it);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CWallet::GetKeyIdBeingReplaced(std::string username, CKeyID &keyid)
|
||||||
|
{
|
||||||
|
for (std::map<CKeyID, string>::const_iterator it = mapKeyReplacement.begin(); it != mapKeyReplacement.end(); it++) {
|
||||||
|
if (it->second == username) {
|
||||||
|
keyid = it->first;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CWallet::ForgetReplacementMap(std::string username)
|
||||||
|
{
|
||||||
|
for (std::map<CKeyID, string>::iterator it = mapKeyReplacement.begin(); it != mapKeyReplacement.end(); it++) {
|
||||||
|
if (it->second == username) {
|
||||||
|
mapKeyReplacement.erase(it);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool CWallet::LoadCryptedKey(const CPubKey &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret)
|
bool CWallet::LoadCryptedKey(const CPubKey &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret)
|
||||||
{
|
{
|
||||||
return CCryptoKeyStore::AddCryptedKey(vchPubKey, vchCryptedSecret);
|
return CCryptoKeyStore::AddCryptedKey(vchPubKey, vchCryptedSecret);
|
||||||
|
@ -84,6 +84,7 @@ public:
|
|||||||
|
|
||||||
std::set<int64> setKeyPool;
|
std::set<int64> setKeyPool;
|
||||||
std::map<CKeyID, CKeyMetadata> mapKeyMetadata;
|
std::map<CKeyID, CKeyMetadata> mapKeyMetadata;
|
||||||
|
std::map<CKeyID, string> mapKeyReplacement;
|
||||||
|
|
||||||
typedef std::map<unsigned int, CMasterKey> MasterKeyMap;
|
typedef std::map<unsigned int, CMasterKey> MasterKeyMap;
|
||||||
MasterKeyMap mapMasterKeys;
|
MasterKeyMap mapMasterKeys;
|
||||||
@ -200,6 +201,10 @@ public:
|
|||||||
// get the current wallet format (the oldest client version guaranteed to understand this wallet)
|
// get the current wallet format (the oldest client version guaranteed to understand this wallet)
|
||||||
int GetVersion() { return nWalletVersion; }
|
int GetVersion() { return nWalletVersion; }
|
||||||
|
|
||||||
|
bool MoveKeyForReplacement(std::string username);
|
||||||
|
bool GetKeyIdBeingReplaced(std::string username, CKeyID &keyid);
|
||||||
|
bool ForgetReplacementMap(std::string username);
|
||||||
|
|
||||||
/** Address book entry changed.
|
/** Address book entry changed.
|
||||||
* @note called with lock cs_wallet held.
|
* @note called with lock cs_wallet held.
|
||||||
*/
|
*/
|
||||||
|
@ -11,7 +11,7 @@ n = int(sys.argv[2])
|
|||||||
datadir = "/tmp/twister%d" % n
|
datadir = "/tmp/twister%d" % n
|
||||||
port = "%d" % (30000+n)
|
port = "%d" % (30000+n)
|
||||||
rpcport = "%d" % (40000+n)
|
rpcport = "%d" % (40000+n)
|
||||||
rpcline = " -rpcuser=user -rpcpassword=pwd -rpcport="
|
rpcline = " -rpcuser=user -rpcpassword=pwd -rpcallowip=127.0.0.1 -rpcport="
|
||||||
rpccfg = rpcline + rpcport
|
rpccfg = rpcline + rpcport
|
||||||
rpccfg1 = rpcline + "40001"
|
rpccfg1 = rpcline + "40001"
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user