mirror of
https://github.com/twisterarmy/twister-core.git
synced 2025-01-25 22:14:15 +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 > 2) ConvertTo<Array>(params[2]);
|
||||
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 == "gettxout" && n > 1) ConvertTo<boost::int64_t>(params[1]);
|
||||
if (strMethod == "gettxout" && n > 2) ConvertTo<bool>(params[2]);
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include "init.h"
|
||||
#include "net.h"
|
||||
#include "wallet.h"
|
||||
#include "twister.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace boost;
|
||||
@ -145,9 +146,9 @@ Value getrawtransaction(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(
|
||||
"createrawtransaction <username> <pubKey>\n"
|
||||
"createrawtransaction <username> <pubKey> [signedByOldKey]\n"
|
||||
"Create a transaction registering a new user\n"
|
||||
"Returns hex-encoded raw transaction.\n"
|
||||
"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");
|
||||
|
||||
rawTx.pubKey << vch;
|
||||
if( params.size() > 2) {
|
||||
vector<unsigned char> vchSign(ParseHexV(params[2], "signedByOldKey"));
|
||||
rawTx.pubKey << vchSign;
|
||||
}
|
||||
|
||||
DoTxProofOfWork(rawTx);
|
||||
|
||||
@ -221,6 +226,13 @@ Value sendrawtransaction(const Array& params, bool fHelp)
|
||||
uint256 hashBlock;
|
||||
CTransaction tx2;
|
||||
fHave = GetTransaction(hashTx, tx2, hashBlock);
|
||||
|
||||
// treat replacement as !fHave
|
||||
if( fHave && verifyDuplicateOrReplacementTx(tx, false, true) ) {
|
||||
printf("verifyDuplicateOrReplacementTx true\n");
|
||||
fHave = false;
|
||||
}
|
||||
|
||||
if (!fHave) {
|
||||
// push to local node
|
||||
CValidationState state;
|
||||
@ -255,6 +267,9 @@ Value sendnewusertransaction(const Array& params, bool fHelp)
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "username must be string");
|
||||
string strUsername = params[0].get_str();
|
||||
|
||||
CKeyID oldKeyID;
|
||||
bool replaceKey = pwalletMain->GetKeyIdBeingReplaced(strUsername, oldKeyID);
|
||||
|
||||
CKeyID keyID;
|
||||
if( !pwalletMain->GetKeyIdFromUsername(strUsername, keyID) )
|
||||
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;
|
||||
uint256 hashBlock;
|
||||
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");
|
||||
if( replaceKey && !userInTxIndex )
|
||||
throw JSONRPCError(RPC_WALLET_INVALID_ACCOUNT_NAME, "Error: key replacemente requires old key in tx database");
|
||||
|
||||
Array createTxParams;
|
||||
createTxParams.push_back(strUsername);
|
||||
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);
|
||||
|
||||
if( replaceKey ) {
|
||||
pwalletMain->ForgetReplacementMap(strUsername);
|
||||
}
|
||||
|
||||
std::string strTxHex = txValue.get_str();
|
||||
Array sendTxParams;
|
||||
sendTxParams.push_back(strTxHex);
|
||||
|
@ -90,9 +90,9 @@ Value getinfo(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(
|
||||
"createwalletuser <username>\n"
|
||||
"createwalletuser <username> [replacekey]\n"
|
||||
"Create a new key pair for user and add it to wallet\n"
|
||||
"Use sendnewusertransaction to publish it to the network.\n"
|
||||
"Returns key secret (keep it safe)");
|
||||
@ -101,18 +101,28 @@ Value createwalletuser(const Array& params, bool fHelp)
|
||||
|
||||
string strUsername = params[0].get_str();
|
||||
|
||||
bool replaceKey = false;
|
||||
if (params.size() > 1)
|
||||
replaceKey = params[1].get_bool();
|
||||
|
||||
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");
|
||||
if( !keyInWallet && replaceKey )
|
||||
throw JSONRPCError(RPC_WALLET_INVALID_ACCOUNT_NAME, "Error: replacekey given but old key not in wallet");
|
||||
|
||||
uint256 userhash = SerializeHash(strUsername);
|
||||
printf("createwalletuser: usernamehash(%s) = %s\n", strUsername.c_str(), userhash.GetHex().c_str());
|
||||
|
||||
CTransaction txOut;
|
||||
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");
|
||||
|
||||
if( replaceKey && !pwalletMain->MoveKeyForReplacement(strUsername) )
|
||||
throw JSONRPCError(RPC_WALLET_ERROR, "Error: moving key for replacement");
|
||||
|
||||
// Generate a new key that is added to wallet
|
||||
CPubKey newKey = pwalletMain->GenerateNewKey(strUsername);
|
||||
keyID = newKey.GetID();
|
||||
|
@ -436,22 +436,16 @@ void stopSessionTorrent()
|
||||
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()) {
|
||||
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();
|
||||
}
|
||||
|
||||
CKey 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();
|
||||
}
|
||||
|
||||
@ -468,6 +462,23 @@ std::string createSignature(std::string const &strMessage, std::string const &st
|
||||
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)
|
||||
{
|
||||
{
|
||||
|
@ -2,6 +2,7 @@
|
||||
#define TWISTER_H
|
||||
|
||||
#include "util.h"
|
||||
#include "key.h"
|
||||
#include <boost/thread.hpp>
|
||||
|
||||
#define LIBTORRENT_PORT_OFFSET 1000
|
||||
@ -19,6 +20,7 @@ public:
|
||||
void startSessionTorrent(boost::thread_group& threadGroup);
|
||||
void stopSessionTorrent();
|
||||
|
||||
std::string createSignature(std::string const &strMessage, CKeyID &keyID);
|
||||
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);
|
||||
|
||||
|
@ -121,6 +121,41 @@ bool CWallet::GetUsernameFromKeyId(CKeyID keyid, std::string &username)
|
||||
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)
|
||||
{
|
||||
return CCryptoKeyStore::AddCryptedKey(vchPubKey, vchCryptedSecret);
|
||||
|
@ -84,6 +84,7 @@ public:
|
||||
|
||||
std::set<int64> setKeyPool;
|
||||
std::map<CKeyID, CKeyMetadata> mapKeyMetadata;
|
||||
std::map<CKeyID, string> mapKeyReplacement;
|
||||
|
||||
typedef std::map<unsigned int, CMasterKey> MasterKeyMap;
|
||||
MasterKeyMap mapMasterKeys;
|
||||
@ -200,6 +201,10 @@ public:
|
||||
// get the current wallet format (the oldest client version guaranteed to understand this wallet)
|
||||
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.
|
||||
* @note called with lock cs_wallet held.
|
||||
*/
|
||||
|
@ -11,7 +11,7 @@ n = int(sys.argv[2])
|
||||
datadir = "/tmp/twister%d" % n
|
||||
port = "%d" % (30000+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
|
||||
rpccfg1 = rpcline + "40001"
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user