Merge branch 'master' of ssh://github.com/novacoin-project/novacoin
author0xDEADFACE <masmfan@gmail.com>
Sun, 14 Feb 2016 03:23:21 +0000 (19:23 -0800)
committer0xDEADFACE <masmfan@gmail.com>
Sun, 14 Feb 2016 03:23:21 +0000 (19:23 -0800)
12 files changed:
src/bitcoinrpc.cpp
src/bitcoinrpc.h
src/key.cpp
src/key.h
src/keystore.cpp
src/keystore.h
src/rpcwallet.cpp
src/version.h
src/wallet.cpp
src/wallet.h
src/walletdb.cpp
src/walletdb.h

index 92042d0..c6b64fe 100644 (file)
@@ -319,7 +319,8 @@ static const CRPCCommand vRPCCommands[] =
     { "newmalleablekey",        &newmalleablekey,        false,  false},
     { "adjustmalleablekey",     &adjustmalleablekey,     false,  false},
     { "adjustmalleablepubkey",  &adjustmalleablepubkey,  false,  false},
-    { "listmalleablepubkeys",   &listmalleablepubkeys,   false,  false},
+    { "listmalleableviews",     &listmalleableviews,     false,  false},
+    { "dumpmalleablekey",       &dumpmalleablekey,       false,  false},
     { "sendalert",              &sendalert,              false,  false},
 };
 
index 226007b..abadd8b 100644 (file)
@@ -209,7 +209,8 @@ extern json_spirit::Value mergecoins(const json_spirit::Array& params, bool fHel
 extern json_spirit::Value newmalleablekey(const json_spirit::Array& params, bool fHelp);
 extern json_spirit::Value adjustmalleablekey(const json_spirit::Array& params, bool fHelp);
 extern json_spirit::Value adjustmalleablepubkey(const json_spirit::Array& params, bool fHelp);
-extern json_spirit::Value listmalleablepubkeys(const json_spirit::Array& params, bool fHelp);
+extern json_spirit::Value listmalleableviews(const json_spirit::Array& params, bool fHelp);
+extern json_spirit::Value dumpmalleablekey(const json_spirit::Array& params, bool fHelp);
 
 extern json_spirit::Value getrawtransaction(const json_spirit::Array& params, bool fHelp); // in rcprawtransaction.cpp
 extern json_spirit::Value listunspent(const json_spirit::Array& params, bool fHelp);
index fe8573e..bf0f99d 100644 (file)
@@ -711,6 +711,15 @@ std::string CMalleablePubKey::ToString() const
     return EncodeBase58Check(vch);
 }
 
+std::vector<unsigned char> CMalleablePubKey::Raw() const
+{
+    CDataStream ssKey(SER_NETWORK, PROTOCOL_VERSION);
+    ssKey << *this;
+    std::vector<unsigned char> vch(ssKey.begin(), ssKey.end());
+
+    return vch;
+}
+
 bool CMalleablePubKey::SetString(const std::string& strMalleablePubKey)
 {
     std::vector<unsigned char> vchTemp;
@@ -771,12 +780,14 @@ CMalleableKey::CMalleableKey(const CSecret &L, const CSecret &H)
     SetSecrets(L, H);
 }
 
+/*
 CMalleableKey& CMalleableKey::operator=(const CMalleableKey &b)
 {
     SetSecrets(b.vchSecretL, b.vchSecretH);
 
     return (*this);
 }
+*/
 
 CMalleableKey::~CMalleableKey()
 {
@@ -982,6 +993,15 @@ std::string CMalleableKey::ToString() const
     return EncodeBase58Check(vch);
 }
 
+std::vector<unsigned char> CMalleableKey::Raw() const
+{
+    CDataStream ssKey(SER_NETWORK, PROTOCOL_VERSION);
+    ssKey << *this;
+    std::vector<unsigned char> vch(ssKey.begin(), ssKey.end());
+
+    return vch;
+}
+
 bool CMalleableKey::SetString(const std::string& strMutableKey)
 {
     std::vector<unsigned char> vchTemp;
@@ -1135,6 +1155,16 @@ bool CMalleableKeyView::SetString(const std::string& strMutableKey)
     return IsNull();
 }
 
+std::vector<unsigned char> CMalleableKeyView::Raw() const
+{
+    CDataStream ssKey(SER_NETWORK, PROTOCOL_VERSION);
+    ssKey << *this;
+    std::vector<unsigned char> vch(ssKey.begin(), ssKey.end());
+
+    return vch;
+}
+
+
 bool CMalleableKeyView::IsNull() const
 {
     return nVersion != CURRENT_VERSION;
index a829834..1ce14f8 100644 (file)
--- a/src/key.h
+++ b/src/key.h
@@ -235,10 +235,21 @@ public:
 
     bool operator==(const CMalleablePubKey &b);
     bool operator!=(const CMalleablePubKey &b) { return !(*this == b); }
+    CMalleablePubKey& operator=(const CMalleablePubKey& mpk) {
+        nVersion = mpk.nVersion;
+        pubKeyL = mpk.pubKeyL;
+        pubKeyH = mpk.pubKeyH;
+        return *this;
+    }
 
     std::string ToString() const;
     bool SetString(const std::string& strMalleablePubKey);
-    uint256 GetID() const;
+
+    CKeyID GetID() const {
+        return pubKeyL.GetID();
+    }
+
+    std::vector<unsigned char> Raw() const;
 
     CPubKey& GetL() { return pubKeyL; }
     CPubKey& GetH() { return pubKeyH; }
@@ -260,7 +271,6 @@ public:
     CMalleableKey();
     CMalleableKey(const CMalleableKey &b);
     CMalleableKey(const CSecret &L, const CSecret &H);
-    CMalleableKey& operator=(const CMalleableKey &b);
     ~CMalleableKey();
 
     IMPLEMENT_SERIALIZE(
@@ -272,6 +282,13 @@ public:
 
     std::string ToString() const;
     bool SetString(const std::string& strMalleablePubKey);
+    std::vector<unsigned char> Raw() const;
+    CMalleableKey& operator=(const CMalleableKey& mk) {
+        nVersion = mk.nVersion;
+        vchSecretL = mk.vchSecretL;
+        vchSecretH = mk.vchSecretH;
+        return *this;
+    }
 
     void Reset();
     void MakeNewKeys();
@@ -279,6 +296,9 @@ public:
     bool SetSecrets(const CSecret &pvchSecretL, const CSecret &pvchSecretH);
     void GetSecrets(CSecret &pvchSecretL, CSecret &pvchSecretH) const;
 
+    CKeyID GetID() const {
+        return GetMalleablePubKey().GetID();
+    }
     CMalleablePubKey GetMalleablePubKey() const;
     bool CheckKeyVariant(const CPubKey &R, const CPubKey &vchPubKeyVariant) const;
     bool CheckKeyVariant(const CPubKey &R, const CPubKey &vchPubKeyVariant, CKey &privKeyVariant) const;
@@ -313,7 +333,17 @@ public:
     bool IsNull() const;
     std::string ToString() const;
     bool SetString(const std::string& strMalleablePubKey);
+    std::vector<unsigned char> Raw() const;
+    CMalleableKeyView& operator=(const CMalleableKeyView& mkv) {
+        nVersion = mkv.nVersion;
+        vchSecretL = mkv.vchSecretL;
+        vchPubKeyH = mkv.vchPubKeyH;
+        return *this;
+    }
 
+    CKeyID GetID() const {
+        return GetMalleablePubKey().GetID();
+    }
     CMalleablePubKey GetMalleablePubKey() const;
     bool CheckKeyVariant(const CPubKey &R, const CPubKey &vchPubKeyVariant) const;
 
index fdba291..fdbecba 100644 (file)
@@ -29,6 +29,15 @@ bool CBasicKeyStore::AddKey(const CKey& key)
     return true;
 }
 
+bool CBasicKeyStore::AddMalleableKey(const CMalleableKey& mKey)
+{
+    {
+        LOCK(cs_KeyStore);
+        mapMalleableKeys[CMalleableKeyView(mKey)] = mKey;
+    }
+    return true;
+}
+
 bool CBasicKeyStore::AddCScript(const CScript& redeemScript)
 {
     if (redeemScript.size() > MAX_SCRIPT_ELEMENT_SIZE)
@@ -102,19 +111,6 @@ bool CBasicKeyStore::HaveWatchOnly() const
     return (!setWatchOnly.empty());
 }
 
-CCryptoKeyStore::CCryptoKeyStore() : fUseCrypto(false)
-{
-    std::string strMalleableKey = GetArg("-masterkey", "");
-    CMalleableKey malleableKey;
-    if (strMalleableKey != "")
-        malleableKey.SetString(strMalleableKey);
-    else
-        malleableKey.MakeNewKeys();
-
-    const CMalleableKeyView& keyView(malleableKey);
-    mapMalleableKeys[keyView] = malleableKey;
-}
-
 bool CCryptoKeyStore::SetCrypted()
 {
     {
index 7d49735..2193060 100644 (file)
@@ -39,6 +39,10 @@ public:
     // Add a key to the store.
     virtual bool AddKey(const CKey& key) =0;
 
+    // Add a malleable key to store.
+    virtual bool AddMalleableKey(const CMalleableKey& mKey) =0;
+    virtual bool GetMalleableKey(const CMalleableKeyView &keyView, CMalleableKey &mKey) const =0;
+
     // Check whether a key corresponding to a given address is present in the store.
     virtual bool HaveKey(const CKeyID &address) const =0;
     virtual bool GetKey(const CKeyID &address, CKey& keyOut) const =0;
@@ -67,7 +71,7 @@ public:
 
     virtual bool CheckOwnership(const CPubKey &pubKeyVariant, const CPubKey &R) const =0;
     virtual bool CreatePrivKey(const CPubKey &pubKeyVariant, const CPubKey &R, CKey &privKey) const =0;
-    virtual void ListMalleablePubKeys(std::list<CMalleablePubKey> &malleablePubKeyList) const =0;
+    virtual void ListMalleableViews(std::list<CMalleableKeyView> &malleableViewList) const =0;
 };
 
 typedef std::map<CKeyID, std::pair<CSecret, bool> > KeyMap;
@@ -87,6 +91,21 @@ protected:
 
 public:
     bool AddKey(const CKey& key);
+    bool AddMalleableKey(const CMalleableKey& mKey);
+    bool GetMalleableKey(const CMalleableKeyView &keyView, CMalleableKey &mKey) const
+    {
+        {
+            LOCK(cs_KeyStore);
+            MalleableKeyMap::const_iterator mi = mapMalleableKeys.find(keyView);
+            if (mi != mapMalleableKeys.end())
+            {
+                mKey = mi->second;
+                return true;
+            }
+        }
+        return false;
+    }
+
     bool HaveKey(const CKeyID &address) const
     {
         bool result;
@@ -158,14 +177,14 @@ public:
         return false;
     }
 
-    void ListMalleablePubKeys(std::list<CMalleablePubKey> &malleablePubKeyList) const
+    void ListMalleableViews(std::list<CMalleableKeyView> &malleableViewList) const
     {
-        malleablePubKeyList.clear();
+        malleableViewList.clear();
 
         {
             LOCK(cs_KeyStore);
             for (MalleableKeyMap::const_iterator mi = mapMalleableKeys.begin(); mi != mapMalleableKeys.end(); mi++)
-                malleablePubKeyList.push_back(mi->first.GetMalleablePubKey());
+                malleableViewList.push_back(CMalleableKeyView(mi->first));
         }
     }
 };
@@ -196,7 +215,7 @@ protected:
     bool Unlock(const CKeyingMaterial& vMasterKeyIn);
 
 public:
-    CCryptoKeyStore();
+    CCryptoKeyStore() : fUseCrypto(false) { }
 
     bool IsCrypted() const
     {
index 6a7a3b1..8b3780e 100644 (file)
@@ -1866,17 +1866,39 @@ Value newmalleablekey(const Array& params, bool fHelp)
             "newmalleablekey\n"
             "Make a malleable public/private key pair.\n");
 
-    CMalleableKey malleableKey;
-    malleableKey.MakeNewKeys();
-    CMalleablePubKey malleablePubKey = malleableKey.GetMalleablePubKey();
+    if (!fTestNet)
+        throw runtime_error("This feature has been disabled for mainNet clients");
+
+    CMalleableKeyView keyView = pwalletMain->GenerateNewMalleableKey();
+
+    CMalleableKey mKey;
+    if (!pwalletMain->GetMalleableKey(keyView, mKey))
+        throw runtime_error("Unable to generate new malleable key");
+
+    Object result;
+    result.push_back(Pair("PublicPair", mKey.GetMalleablePubKey().ToString()));
+    result.push_back(Pair("KeyView", keyView.ToString()));
+
+    return result;
+}
+
+Value dumpmalleablekey(const Array& params, bool fHelp)
+{
+    if (fHelp || params.size() != 1)
+        throw runtime_error (
+            "dumpmalleablekey <Key view>\n"
+            "Dump the private and public key pairs, which correspond to provided key view.\n");
 
-    CDataStream ssPublicBytes(SER_NETWORK, PROTOCOL_VERSION);
-    ssPublicBytes << malleablePubKey;
+    CMalleableKey mKey;
+    CMalleableKeyView keyView;
+    keyView.SetString(params[0].get_str());
+
+    if (!pwalletMain->GetMalleableKey(keyView, mKey))
+        throw runtime_error("There is no such item in the wallet");
 
     Object result;
-    result.push_back(Pair("PrivatePair", malleableKey.ToString()));
-    result.push_back(Pair("PublicPair", malleablePubKey.ToString()));
-    result.push_back(Pair("PublicBytes", HexStr(ssPublicBytes.begin(), ssPublicBytes.end())));
+    result.push_back(Pair("PrivatePair", mKey.ToString()));
+    result.push_back(Pair("PublicPair", mKey.GetMalleablePubKey().ToString()));
 
     return result;
 }
@@ -1933,25 +1955,25 @@ Value adjustmalleablepubkey(const Array& params, bool fHelp)
     result.push_back(Pair("PubkeyVariant", HexStr(vchPubKeyVariant.Raw())));
     result.push_back(Pair("KeyVariantID", CBitcoinAddress(vchPubKeyVariant.GetID()).ToString()));
 
-
     return result;
 }
 
-Value listmalleablepubkeys(const Array& params, bool fHelp)
+Value listmalleableviews(const Array& params, bool fHelp)
 {
     if (fHelp || params.size() != 0)
         throw runtime_error(
-            "listmalleablepubkeys\n"
-            "Get list of malleable public keys.\n");
+            "listmalleableviews\n"
+            "Get list of views for generated malleable keys.\n");
 
-    std::list<CMalleablePubKey> keyList;
-    pwalletMain->ListMalleablePubKeys(keyList);
+    std::list<CMalleableKeyView> keyViewList;
+    pwalletMain->ListMalleableViews(keyViewList);
 
     Array result;
-    BOOST_FOREACH(const CMalleablePubKey &key, keyList)
+    BOOST_FOREACH(const CMalleableKeyView &keyView, keyViewList)
     {
-        result.push_back(key.ToString());
+        result.push_back(keyView.ToString());
     }
 
     return result;
 }
+
index c19ad48..e7e3e32 100644 (file)
@@ -30,7 +30,7 @@ static const int DATABASE_VERSION = 70507;
 // network protocol versioning
 //
 
-static const int PROTOCOL_VERSION = 60016;
+static const int PROTOCOL_VERSION = 60017;
 
 // earlier versions not supported as of Feb 2012, and are disconnected
 static const int MIN_PROTO_VERSION = 209;
index d31b2e0..5c46a1b 100644 (file)
@@ -57,6 +57,28 @@ CPubKey CWallet::GenerateNewKey()
     return key.GetPubKey();
 }
 
+CMalleableKeyView CWallet::GenerateNewMalleableKey()
+{
+    RandAddSeedPerfmon();
+
+    // Compressed public keys were introduced in version 0.6.0
+    SetMinVersion(FEATURE_MALLKEY);
+
+    CMalleableKey mKey;
+    mKey.MakeNewKeys();
+    const CMalleableKeyView &keyView(mKey);
+
+    // Create new metadata
+    int64_t nCreationTime = GetTime();
+    mapMalleableKeyMetadata[keyView] = CKeyMetadata(nCreationTime);
+    if (!nTimeFirstKey || nCreationTime < nTimeFirstKey)
+        nTimeFirstKey = nCreationTime;
+
+    if (!AddMalleableKey(mKey))
+        throw std::runtime_error("CWallet::GenerateNewMalleableKey() : AddMalleableKey failed");
+    return CMalleableKeyView(mKey);
+}
+
 bool CWallet::AddKey(const CKey& key)
 {
     CPubKey pubkey = key.GetPubKey();
@@ -69,6 +91,18 @@ bool CWallet::AddKey(const CKey& key)
     return true;
 }
 
+bool CWallet::AddMalleableKey(const CMalleableKey& mKey)
+{
+    CMalleableKeyView keyView = CMalleableKeyView(mKey);
+    if (!CCryptoKeyStore::AddMalleableKey(mKey))
+        return false;
+    if (!fFileBacked)
+        return true;
+    if (!IsCrypted())
+        return CWalletDB(strWalletFile).WriteMalleableKey(keyView, mKey, mapMalleableKeyMetadata[keyView]);
+    return true;
+}
+
 bool CWallet::AddCryptedKey(const CPubKey &vchPubKey, const vector<unsigned char> &vchCryptedSecret)
 {
     if (!CCryptoKeyStore::AddCryptedKey(vchPubKey, vchCryptedSecret))
@@ -101,6 +135,15 @@ bool CWallet::LoadKeyMetadata(const CPubKey &pubkey, const CKeyMetadata &meta)
     return true;
 }
 
+bool CWallet::LoadMalleableKeyMetadata(const CMalleableKeyView &keyView, const CKeyMetadata &metadata)
+{
+    if (metadata.nCreateTime && (!nTimeFirstKey || metadata.nCreateTime < nTimeFirstKey))
+        nTimeFirstKey = metadata.nCreateTime;
+
+    mapMalleableKeyMetadata[keyView] = metadata;
+    return true;
+}
+
 bool CWallet::AddCScript(const CScript& redeemScript)
 {
     if (!CCryptoKeyStore::AddCScript(redeemScript))
index 8480b3b..20abe44 100644 (file)
@@ -37,7 +37,8 @@ enum WalletFeature
 
     FEATURE_WALLETCRYPT = 40000, // wallet encryption
     FEATURE_COMPRPUBKEY = 60000, // compressed public keys
-    FEATURE_LATEST = 60000
+    FEATURE_MALLKEY = 60017,
+    FEATURE_LATEST = 60017
 };
 
 /** A key pool entry */
@@ -95,6 +96,7 @@ public:
 
     std::set<int64_t> setKeyPool;
     std::map<CKeyID, CKeyMetadata> mapKeyMetadata;
+    std::map<CMalleableKeyView, CKeyMetadata> mapMalleableKeyMetadata;
 
     typedef std::map<unsigned int, CMasterKey> MasterKeyMap;
     MasterKeyMap mapMasterKeys;
@@ -148,12 +150,18 @@ public:
     // keystore implementation
     // Generate a new key
     CPubKey GenerateNewKey();
+    CMalleableKeyView GenerateNewMalleableKey();
     // Adds a key to the store, and saves it to disk.
     bool AddKey(const CKey& key);
+    bool AddMalleableKey(const CMalleableKey& mKey);
     // Adds a key to the store, without saving it to disk (used by LoadWallet)
     bool LoadKey(const CKey& key) { return CCryptoKeyStore::AddKey(key); }
     // Load metadata (used by LoadWallet)
     bool LoadKeyMetadata(const CPubKey &pubkey, const CKeyMetadata &metadata);
+    bool LoadMalleableKeyMetadata(const CMalleableKeyView &keyView, const CKeyMetadata &metadata);
+
+    // Load malleable key without saving it to disk (used by LoadWallet)
+    bool LoadMalleableKey(const CMalleableKey &mKey) { return CCryptoKeyStore::AddMalleableKey(mKey); }
 
     bool LoadMinVersion(int nVersion) { nWalletVersion = nVersion; nWalletMaxVersion = std::max(nWalletMaxVersion, nVersion); return true; }
 
index 050d2ee..64168ee 100644 (file)
@@ -220,6 +220,7 @@ ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue,
         // Taking advantage of the fact that pair serialization
         // is just the two items serialized one after the other
         ssKey >> strType;
+
         if (strType == "name")
         {
             string strAddress;
@@ -301,6 +302,36 @@ ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue,
             // so set the wallet birthday to the beginning of time.
             pwallet->nTimeFirstKey = 1;
         }
+        else if (strType == "malpair")
+        {
+            string strKey, strKeyView;
+
+            CMalleableKey mKey;
+            CMalleableKeyView keyView;
+
+            ssKey >> strKeyView;
+            ssValue >> strKey;
+
+            keyView.SetString(strKeyView);
+            mKey.SetString(strKey);
+
+            if (mKey.IsNull())
+            {
+                strErr = "Error reading wallet database: CMalleableKey is corrupt";
+                return false;
+            }
+            if (mKey.GetID() != keyView.GetID())
+            {
+                strErr = "Error reading wallet database: CMalleableKey view inconsistency";
+                return false;
+            }
+
+            if (!pwallet->LoadMalleableKey(mKey))
+            {
+                strErr = "Error reading wallet database: LoadMalleableKey failed";
+                return false;
+            }
+        }
         else if (strType == "key" || strType == "wkey")
         {
             vector<unsigned char> vchPubKey;
@@ -385,6 +416,20 @@ ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue,
             }
             wss.fIsEncrypted = true;
         }
+        else if (strType == "malmeta")
+        {
+            string strKeyView;
+            ssKey >> strKeyView;
+
+            CMalleableKeyView keyView;
+            keyView.SetString(strKeyView);
+
+            CKeyMetadata keyMeta;
+            ssValue >> keyMeta;
+            wss.nKeyMeta++;
+
+            pwallet->LoadMalleableKeyMetadata(keyView, keyMeta);
+        }
         else if (strType == "keymeta")
         {
             CPubKey vchPubKey;
@@ -452,7 +497,7 @@ ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue,
 static bool IsKeyType(string strType)
 {
     return (strType== "key" || strType == "wkey" ||
-            strType == "mkey" || strType == "ckey");
+            strType == "mkey" || strType == "ckey" || strType == "malpair");
 }
 
 DBErrors CWalletDB::LoadWallet(CWallet* pwallet)
index 6b6f55d..fe2b225 100644 (file)
@@ -95,6 +95,19 @@ public:
         return true;
     }
 
+    bool WriteMalleableKey(const CMalleableKeyView& keyView, const CMalleableKey& malleableKey, const CKeyMetadata &keyMeta)
+    {
+        nWalletDBUpdated++;
+        if(!Write(std::make_pair(std::string("malmeta"), keyView.ToString()), keyMeta))
+            return false;
+
+        if(!Write(std::make_pair(std::string("malpair"), keyView.ToString()), malleableKey.ToString(), false))
+            return false;
+
+        return true;
+    }
+
+
     bool WriteCryptedKey(const CPubKey& vchPubKey, const std::vector<unsigned char>& vchCryptedSecret, const CKeyMetadata &keyMeta)
     {
         nWalletDBUpdated++;