]> Git Repo - VerusCoin.git/commitdiff
Fix ID wallet sync issue
authormiketout <[email protected]>
Fri, 9 Oct 2020 22:40:43 +0000 (00:40 +0200)
committermiketout <[email protected]>
Fri, 9 Oct 2020 22:40:43 +0000 (00:40 +0200)
src/pbaas/identity.cpp
src/script/standard.cpp
src/wallet/wallet.cpp

index 790c0c53d16f31f35e33adde8b33ce3fef30c497..0135e2356e7c0cd63fdf5423da0f6878aa9ddfa4 100644 (file)
@@ -1392,6 +1392,7 @@ bool ValidateIdentityCommitment(struct CCcontract_info *cp, Eval* eval, const CT
                     {
                         return eval->Error("Identity reservation output spend does not match commitment");
                     }
+
                     outputNum = i;
                 }
             }
@@ -1404,6 +1405,11 @@ bool ValidateIdentityCommitment(struct CCcontract_info *cp, Eval* eval, const CT
             return ValidateSpendingIdentityReservation(spendingTx, outputNum, eval->state, height, thisChain);
         }
     }
+    else
+    {
+        printf("%s: error getting transaction %s to spend\n", __func__, spendingTx.vin[nIn].prevout.hash.GetHex().c_str());
+    }
+    
     return true;
 }
 
index 19e960ac208c04f34eb3a78c403cfa25ac1f156b..cc370ac6ac7f83dd1f50f91e34db3c5453b3e944 100644 (file)
@@ -562,7 +562,7 @@ bool ExtractDestinations(const CScript& scriptPubKey,
                          const CKeyStore *pKeyStore, 
                          bool *pCanSign, 
                          bool *pCanSpend,
-                         uint32_t lastIdHeight,
+                         uint32_t nHeight,
                          std::map<uint160, CKey> *pPrivKeys)
 {
     addressRet.clear();
@@ -579,12 +579,21 @@ bool ExtractDestinations(const CScript& scriptPubKey,
         CScript postfix = CScript(scriptPubKey.size() > scriptStart ? scriptPubKey.begin() + scriptStart : scriptPubKey.end(), scriptPubKey.end());
 
         // check again with only postfix subscript
-        return(ExtractDestinations(postfix, typeRet, addressRet, nRequiredRet, pKeyStore, pCanSign, pCanSpend, lastIdHeight, pPrivKeys));
+        return(ExtractDestinations(postfix, typeRet, addressRet, nRequiredRet, pKeyStore, pCanSign, pCanSpend, nHeight, pPrivKeys));
     }
 
     int canSpendCount = 0;
     bool canSign = false;
 
+    if (pCanSign)
+    {
+        *pCanSign = false;
+    }
+    if (pCanSpend)
+    {
+        *pCanSpend = false;
+    }
+
     COptCCParams master, p;
     bool ccValid;
     if (scriptPubKey.IsPayToCryptoCondition(p))
@@ -609,7 +618,7 @@ bool ExtractDestinations(const CScript& scriptPubKey,
                         std::pair<CIdentityMapKey, CIdentityMapValue> identity;
                         idSet.insert(destId);
 
-                        if (pKeyStore && pKeyStore->GetIdentity(destId, identity, lastIdHeight) && identity.second.IsValidUnrevoked())
+                        if (pKeyStore && pKeyStore->GetIdentity(destId, identity, nHeight - 1) && identity.second.IsValidUnrevoked())
                         {
                             int canSignCount = 0;
                             for (auto oneKey : identity.second.primaryAddresses)
@@ -705,7 +714,7 @@ bool ExtractDestinations(const CScript& scriptPubKey,
 
                                 //printf("checking: %s\n", EncodeDestination(dest).c_str());
 
-                                if (pKeyStore && pKeyStore->GetIdentity(destId, identity, lastIdHeight) && identity.second.IsValidUnrevoked())
+                                if (pKeyStore && pKeyStore->GetIdentity(destId, identity, nHeight - 1) && identity.second.IsValidUnrevoked())
                                 {
                                     int canSignCount = 0;
                                     for (auto oneKey : identity.second.primaryAddresses)
@@ -778,6 +787,14 @@ bool ExtractDestinations(const CScript& scriptPubKey,
                     // this kind of ID is defined as a CKeyID, since use of script hash type in CCs are reserved for IDs
                     addressRet.push_back(CKeyID(Hash160(subScr)));
                     nRequiredRet = 1;
+                    if (pCanSign)
+                    {
+                        *pCanSign = true;
+                    }
+                    if (pCanSpend)
+                    {
+                        *pCanSpend = true;
+                    }
                 }
                 else
                 {
@@ -803,6 +820,7 @@ bool ExtractDestinations(const CScript& scriptPubKey,
         if (typeRet == TX_MULTISIG)
         {
             nRequiredRet = vSolutions.front()[0];
+            int nHaveKeys = 0;
             for (unsigned int i = 1; i < vSolutions.size()-1; i++)
             {
                 CPubKey pubKey(vSolutions[i]);
@@ -811,10 +829,28 @@ bool ExtractDestinations(const CScript& scriptPubKey,
 
                 CTxDestination address = pubKey.GetID();
                 addressRet.push_back(address);
+
+                // if we were asked to see whether we can sign or spend, determine
+                if ((pCanSign || pCanSpend) && pKeyStore)
+                {
+                    if (pKeyStore->HaveKey(GetDestinationID(address)))
+                    {
+                        nHaveKeys++;
+                    }
+                }
             }
 
             if (addressRet.empty())
                 return false;
+
+            if (pCanSign && nHaveKeys)
+            {
+                *pCanSign = true;
+            }
+            if (pCanSpend && nHaveKeys >= nRequiredRet)
+            {
+                *pCanSpend = true;
+            }
         }
         else
         {
@@ -822,9 +858,23 @@ bool ExtractDestinations(const CScript& scriptPubKey,
             CTxDestination address;
             if (!ExtractDestination(scriptPubKey, address))
             {
-            return false;
+                return false;
             }
             addressRet.push_back(address);
+            if ((pCanSign || pCanSpend) && pKeyStore)
+            {
+                if (pKeyStore->HaveKey(GetDestinationID(address)))
+                {
+                    if (pCanSign)
+                    {
+                        *pCanSign = true;
+                    }
+                    if (pCanSpend)
+                    {
+                        *pCanSpend = true;
+                    }
+                }
+            }
         }
     }
     
index 85e428480c7f561d657bfcd441f75f3e899f9dbb..b04b22e38f23d0a29388f064775dec2945bf6d40 100644 (file)
@@ -2447,6 +2447,12 @@ bool CWallet::AddToWalletIfInvolvingMe(const CTransaction& tx, const CBlock* pbl
             }
         }
 
+        if (nHeight == 18591 || nHeight == 18594)
+        {
+            printf("%s: block %u\n", __func__, nHeight);
+            printf("\n");
+        }
+
         for (auto output : tx.vout)
         {
             bool canSpend = false;
@@ -2464,6 +2470,12 @@ bool CWallet::AddToWalletIfInvolvingMe(const CTransaction& tx, const CBlock* pbl
                                                                1, 
                                                                CIdentityMapKey::VALID);
 
+                    if (identity.name == "e")
+                    {
+                        printf("%s: checking ID e@ at height %u\n", __func__, nHeight);
+                        printf("\n");
+                    }
+
                     std::set<CKeyID> keySet;
                     CIdentityID idID(identity.GetID());
                     int blockOrder = 1;
@@ -2528,7 +2540,6 @@ bool CWallet::AddToWalletIfInvolvingMe(const CTransaction& tx, const CBlock* pbl
                             idHistory = std::pair<CIdentityMapKey, CIdentityMapValue>();
                             wasCanSignCanSpend = std::pair<bool, bool>({false, false});
                         }
-
                         else if (nHeight && idHistory.first.blockHeight == nHeight && idHistory.second.txid != identity.txid)
                         {
                             // this is one of more than one identity records in the same block
@@ -2695,14 +2706,17 @@ bool CWallet::AddToWalletIfInvolvingMe(const CTransaction& tx, const CBlock* pbl
                                             // this is safe, as in case of a crash, we rescan the necessary blocks on startup through our SetBestChain-mechanism
                                             CWalletDB walletdb(strWalletFile, "r+", false);
 
-                                            // must not be already present, and be a CC output to be correctly sent to an identity
-                                            if (GetWalletTx(newOut.first.txhash) == nullptr && newOut.second.script.IsPayToCryptoCondition())
+                                            txnouttype newTypeRet;
+                                            std::vector<CTxDestination> newAddressRet;
+                                            int newNRequired;
+                                            bool newCanSign, newCanSpend;
+                                            const CWalletTx *pWtx = GetWalletTx(newOut.first.txhash);
+
+                                            // must not be already present, and be a CC output, so we know it can be sent to an identity
+                                            if (pWtx == nullptr && newOut.second.script.IsPayToCryptoCondition())
                                             {
-                                                txnouttype newTypeRet;
-                                                std::vector<CTxDestination> newAddressRet;
-                                                int newNRequired;
-                                                bool newCanSign, newCanSpend;
-                                                if (!(ExtractDestinations(newOut.second.script, newTypeRet, newAddressRet, newNRequired, this, &newCanSign, &newCanSpend) || !newCanSign))
+                                                CWalletTx wtx;
+                                                if (!(ExtractDestinations(newOut.second.script, newTypeRet, newAddressRet, newNRequired, this, &newCanSign, &newCanSpend, nHeight == 0 ? INT_MAX : nHeight + 1) && newCanSign))
                                                 {
                                                     continue;
                                                 }
@@ -2710,7 +2724,7 @@ bool CWallet::AddToWalletIfInvolvingMe(const CTransaction& tx, const CBlock* pbl
                                                 CTransaction newTx;
                                                 if (myGetTransaction(newOut.first.txhash, newTx, blkHash))
                                                 {
-                                                    CWalletTx wtx(this, newTx);
+                                                    wtx = CWalletTx(this, newTx);
 
                                                     // Get merkle branch if transaction was found in a block
                                                     CBlock block;
@@ -2726,52 +2740,71 @@ bool CWallet::AddToWalletIfInvolvingMe(const CTransaction& tx, const CBlock* pbl
                                                     }
 
                                                     AddToWallet(wtx, false, &walletdb);
+                                                    pWtx = GetWalletTx(newOut.first.txhash);
+                                                }
+                                            }
+                                            else if (pWtx = GetWalletTx(newOut.first.txhash))
+                                            {
+                                                if (!(ExtractDestinations(newOut.second.script, newTypeRet, newAddressRet, newNRequired, this, &newCanSign, &newCanSpend, nHeight == 0 ? INT_MAX : nHeight + 1) && newCanSign))
+                                                {
+                                                    continue;
+                                                }
+                                            }
 
-                                                    // while we know there is an unspent index to this ID on the new transaction output, we don't know
-                                                    // if there are other outputs to this ID on the transaction, which are already spent. 
-                                                    // if so, we need to record the spends in the wallet as well, or it will add them but
-                                                    // not consider them spent.
-                                                    uint256 spendBlkHash;
-                                                    CTransaction spendTx;
-                                                    for (int i = 0; i < wtx.vout.size(); i++)
+                                            // now, if we are in the wallet, we need to see if we should record new spends
+                                            if (pWtx != nullptr && newOut.second.script.IsPayToCryptoCondition())
+                                            {
+                                                // while we know there is an unspent index to this ID on the new transaction output, we don't know
+                                                // if there are other outputs to this ID on the transaction, which are already spent. 
+                                                // if so, we need to record the spends in the wallet as well, or it will add them but
+                                                // not consider them spent.
+                                                uint256 spendBlkHash;
+                                                CTransaction spendTx;
+                                                std::vector<CTxOut> checkIfSpent = pWtx->vout;
+                                                for (int i = 0; i < checkIfSpent.size(); i++)
+                                                {
+                                                    if (newOut.first.index == i)
                                                     {
-                                                        if (newOut.first.index == i)
-                                                        {
-                                                            continue;
-                                                        }
+                                                        continue;
+                                                    }
 
-                                                        // check any output we can sign for being spent as well, so we can add the spend
-                                                        if (!(ExtractDestinations(wtx.vout[i].scriptPubKey, 
-                                                                                  newTypeRet, 
-                                                                                  newAddressRet, 
-                                                                                  newNRequired, 
-                                                                                  this, 
-                                                                                  &newCanSign, 
-                                                                                  &newCanSpend) || !newCanSign))
-                                                        {
-                                                            continue;
-                                                        }
+                                                    // check any output we can sign for being spent as well, so we can add the spend
+                                                    if (!(ExtractDestinations(checkIfSpent[i].scriptPubKey, 
+                                                                              newTypeRet, 
+                                                                              newAddressRet, 
+                                                                              newNRequired, 
+                                                                              this, 
+                                                                              &newCanSign, 
+                                                                              &newCanSpend,
+                                                                              nHeight == 0 ? INT_MAX : nHeight + 1) && newCanSign))
+                                                    {
+                                                        continue;
+                                                    }
 
-                                                        CSpentIndexValue spentInfo;
-                                                        CSpentIndexKey spentKey(newOut.first.txhash, i);
-                                                        if (GetSpentIndex(spentKey, spentInfo))
+                                                    CSpentIndexValue spentInfo;
+                                                    CSpentIndexKey spentKey(newOut.first.txhash, i);
+                                                    if (GetSpentIndex(spentKey, spentInfo))
+                                                    {
+                                                        if (GetWalletTx(spentInfo.txid) == nullptr &&
+                                                            spentInfo.blockHeight <= nHeight &&
+                                                            myGetTransaction(spentInfo.txid, spendTx, spendBlkHash) && !spendBlkHash.IsNull())
                                                         {
-                                                            if (GetWalletTx(spentInfo.txid) == nullptr &&
-                                                                spentInfo.blockHeight <= nHeight &&
-                                                                myGetTransaction(spentInfo.txid, spendTx, spendBlkHash) && !spendBlkHash.IsNull())
+                                                            CWalletTx spendWtx(this, spendTx);
+
+                                                            // Get merkle branch if transaction was found in a block
+                                                            CBlock spendBlock;
+                                                            auto spendBlkIndexIt = mapBlockIndex.find(spendBlkHash);
+                                                            if (spendBlkIndexIt != mapBlockIndex.end() && 
+                                                                chainActive.Contains(spendBlkIndexIt->second) &&
+                                                                ReadBlockFromDisk(spendBlock, spendBlkIndexIt->second, consensus))
                                                             {
-                                                                CWalletTx spendWtx(this, spendTx);
-
-                                                                // Get merkle branch if transaction was found in a block
-                                                                CBlock spendBlock;
-                                                                auto spendBlkIndexIt = mapBlockIndex.find(spendBlkHash);
-                                                                if (spendBlkIndexIt != mapBlockIndex.end() && 
-                                                                    chainActive.Contains(spendBlkIndexIt->second) &&
-                                                                    ReadBlockFromDisk(spendBlock, spendBlkIndexIt->second, consensus))
-                                                                {
-                                                                    spendWtx.SetMerkleBranch(spendBlock);
-                                                                    AddToWallet(spendWtx, false, &walletdb);
-                                                                }
+                                                                spendWtx.SetMerkleBranch(spendBlock);
+                                                                AddToWallet(spendWtx, false, &walletdb);
+
+                                                                // add these outputs to the outputs we need to check if spent
+                                                                // as long as we are adding spending transactions that are earlier
+                                                                // or up to this height, we follow the spends
+                                                                checkIfSpent.insert(checkIfSpent.end(), spendTx.vout.begin(), spendTx.vout.end());
                                                             }
                                                         }
                                                     }
@@ -2835,7 +2868,7 @@ bool CWallet::AddToWalletIfInvolvingMe(const CTransaction& tx, const CBlock* pbl
 
                                         // if the tx is spending from another in this wallet, we will not erase it
                                         // but check destinations before deciding not to erase IDs
-                                        if (IsFromMe(txidAndWtx.second))
+                                        if (IsFromMe(txidAndWtx.second, deleteSpentFrom - 1))
                                         {
                                             eraseTx = false;
                                         }
@@ -2857,7 +2890,7 @@ bool CWallet::AddToWalletIfInvolvingMe(const CTransaction& tx, const CBlock* pbl
                                             bool canSignOut = false;
                                             bool canSpendOut = false;
 
-                                            if (ExtractDestinations(txout.scriptPubKey, txType, addresses, minSigs, this, &canSignOut, &canSpendOut))
+                                            if (ExtractDestinations(txout.scriptPubKey, txType, addresses, minSigs, this, &canSignOut, &canSpendOut, nHeight == 0 ? INT_MAX : nHeight + 1))
                                             {
                                                 if (canSignOut || canSpendOut)
                                                 {
@@ -2912,7 +2945,7 @@ bool CWallet::AddToWalletIfInvolvingMe(const CTransaction& tx, const CBlock* pbl
                                             txnouttype txType;
                                             std::vector<CTxDestination> addresses;
                                             int minSigs;
-                                            if (ExtractDestinations(txout.scriptPubKey, txType, addresses, minSigs, this, &canSignOut, &canSpendOut))
+                                            if (ExtractDestinations(txout.scriptPubKey, txType, addresses, minSigs, this, &canSignOut, &canSpendOut, nHeight == 0 ? INT_MAX : nHeight + 1))
                                             {
                                                 if (canSignOut || canSpendOut)
                                                 {
@@ -3561,8 +3594,10 @@ bool CWallet::IsFromMe(const CTransaction& tx, uint32_t height) const
             {
                 const CWalletTx& prev = (*mi).second;
                 if (txin.prevout.n < prev.vout.size())
+                {
                     if (::IsMine(*this, prev.vout[txin.prevout.n].scriptPubKey, height) & ISMINE_ALL)
                         return true;
+                }
             }
         }
     }
This page took 0.04338 seconds and 4 git commands to generate.