|
15 | 15 | #include "coincontrol.h" |
16 | 16 | #include "evo/providertx.h" |
17 | 17 | #include "guiinterfaceutil.h" |
18 | | -#include "masternode.h" |
19 | 18 | #include "policy/policy.h" |
20 | 19 | #include "sapling/key_io_sapling.h" |
21 | 20 | #include "script/sign.h" |
@@ -759,34 +758,6 @@ void CWallet::AddToSpends(const uint256& wtxid) |
759 | 758 | } |
760 | 759 | } |
761 | 760 |
|
762 | | -bool CWallet::GetVinAndKeysFromOutput(COutput out, CTxIn& txinRet, CPubKey& pubKeyRet, CKey& keyRet, bool fColdStake) |
763 | | -{ |
764 | | - // wait for reindex and/or import to finish |
765 | | - if (fImporting || fReindex) return false; |
766 | | - |
767 | | - CScript pubScript; |
768 | | - |
769 | | - txinRet = CTxIn(out.tx->GetHash(), out.i); |
770 | | - pubScript = out.tx->tx->vout[out.i].scriptPubKey; // the inputs PubKey |
771 | | - |
772 | | - CTxDestination address1; |
773 | | - ExtractDestination(pubScript, address1, fColdStake); |
774 | | - |
775 | | - const CKeyID* keyID = boost::get<CKeyID>(&address1); |
776 | | - if (!keyID) { |
777 | | - LogPrintf("CWallet::GetVinAndKeysFromOutput -- Address does not refer to a key\n"); |
778 | | - return false; |
779 | | - } |
780 | | - |
781 | | - if (!GetKey(*keyID, keyRet)) { |
782 | | - LogPrintf("CWallet::GetVinAndKeysFromOutput -- Private key for address is not known\n"); |
783 | | - return false; |
784 | | - } |
785 | | - |
786 | | - pubKeyRet = keyRet.GetPubKey(); |
787 | | - return true; |
788 | | -} |
789 | | - |
790 | 761 | bool CWallet::EncryptWallet(const SecureString& strWalletPassphrase) |
791 | 762 | { |
792 | 763 | if (IsCrypted()) |
@@ -2407,82 +2378,78 @@ static bool CheckTXAvailability(const CWalletTx* pcoin, |
2407 | 2378 | return CheckTXAvailabilityInternal(pcoin, fOnlySafe, nDepth, safeTx); |
2408 | 2379 | } |
2409 | 2380 |
|
2410 | | -bool CWallet::GetMasternodeVinAndKeys(CTxIn& txinRet, CPubKey& pubKeyRet, CKey& keyRet, std::string strTxHash, std::string strOutputIndex, std::string& strError) |
| 2381 | +bool CWallet::GetMasternodeVinAndKeys(CPubKey& pubKeyRet, |
| 2382 | + CKey& keyRet, |
| 2383 | + const COutPoint& collateralOut, |
| 2384 | + bool fValidateCollateral, |
| 2385 | + std::string& strError) |
2411 | 2386 | { |
2412 | 2387 | // wait for reindex and/or import to finish |
2413 | 2388 | if (fImporting || fReindex) return false; |
2414 | 2389 |
|
2415 | | - if (strTxHash.empty() || strOutputIndex.empty()) { |
2416 | | - strError = "Invalid masternode collateral hash or output index"; |
2417 | | - return error("%s: %s", __func__, strError); |
2418 | | - } |
2419 | | - |
2420 | | - int nOutputIndex; |
2421 | | - try { |
2422 | | - nOutputIndex = std::stoi(strOutputIndex.c_str()); |
2423 | | - } catch (const std::exception& e) { |
2424 | | - strError = "Invalid masternode output index"; |
2425 | | - return error("%s: %s on strOutputIndex", __func__, e.what()); |
2426 | | - } |
2427 | | - |
2428 | 2390 | // Find specific vin |
2429 | | - const uint256 txHash = uint256S(strTxHash); |
2430 | | - const CWalletTx* wtx = GetWalletTx(txHash); |
| 2391 | + const CWalletTx* wtx = GetWalletTx(collateralOut.hash); |
2431 | 2392 | if (!wtx) { |
2432 | 2393 | strError = "collateral tx not found in the wallet"; |
2433 | 2394 | return error("%s: %s", __func__, strError); |
2434 | 2395 | } |
2435 | 2396 |
|
2436 | 2397 | // Verify index limits |
2437 | | - if (nOutputIndex < 0 || nOutputIndex >= (int) wtx->tx->vout.size()) { |
| 2398 | + if (collateralOut.n < 0 || collateralOut.n >= (uint32_t) wtx->tx->vout.size()) { |
2438 | 2399 | strError = "Invalid masternode output index"; |
2439 | | - return error("%s: output index %d not found in %s", __func__, nOutputIndex, strTxHash); |
| 2400 | + return error("%s: output index %d not found in %s", __func__, collateralOut.n, collateralOut.hash.GetHex()); |
2440 | 2401 | } |
2441 | 2402 |
|
2442 | | - CTxOut txOut = wtx->tx->vout[nOutputIndex]; |
| 2403 | + CTxOut txOut = wtx->tx->vout[collateralOut.n]; |
2443 | 2404 |
|
2444 | 2405 | // Masternode collateral value |
2445 | 2406 | const auto& consensus = Params().GetConsensus(); |
2446 | 2407 | if (txOut.nValue != consensus.nMNCollateralAmt) { |
2447 | 2408 | strError = strprintf("Invalid collateral tx value, must be %s PIV", FormatMoney(Params().GetConsensus().nMNCollateralAmt)); |
2448 | | - return error("%s: tx %s, index %d not a masternode collateral", __func__, strTxHash, nOutputIndex); |
| 2409 | + return error("%s: tx %s, index %d not a masternode collateral", __func__, collateralOut.hash.GetHex(), collateralOut.n); |
2449 | 2410 | } |
2450 | 2411 |
|
2451 | | - int nDepth = 0; |
2452 | | - bool safeTx = false; |
2453 | | - { |
2454 | | - LOCK(cs_wallet); |
2455 | | - // Check availability |
2456 | | - if (!CheckTXAvailability(wtx, true, nDepth, safeTx, m_last_block_processed_height)) { |
2457 | | - strError = "Not available collateral transaction"; |
2458 | | - return error("%s: tx %s not available", __func__, strTxHash); |
| 2412 | + if (fValidateCollateral) { |
| 2413 | + int nDepth = 0; |
| 2414 | + { |
| 2415 | + LOCK(cs_wallet); |
| 2416 | + // Check availability |
| 2417 | + bool safeTx = false; |
| 2418 | + if (!CheckTXAvailability(wtx, true, nDepth, safeTx, m_last_block_processed_height)) { |
| 2419 | + strError = "Not available collateral transaction"; |
| 2420 | + return error("%s: tx %s not available", __func__, collateralOut.hash.GetHex()); |
| 2421 | + } |
| 2422 | + |
| 2423 | + // Skip spent coins |
| 2424 | + if (IsSpent(collateralOut.hash, collateralOut.n)) { |
| 2425 | + strError = "Error: collateral already spent"; |
| 2426 | + return error("%s: tx %s already spent", __func__, collateralOut.hash.GetHex()); |
| 2427 | + } |
2459 | 2428 | } |
2460 | 2429 |
|
2461 | | - // Skip spent coins |
2462 | | - if (IsSpent(txHash, nOutputIndex)) { |
2463 | | - strError = "Error: collateral already spent"; |
2464 | | - return error("%s: tx %s already spent", __func__, strTxHash); |
| 2430 | + // Depth must be at least MASTERNODE_MIN_CONFIRMATIONS |
| 2431 | + if (nDepth < consensus.MasternodeCollateralMinConf()) { |
| 2432 | + strError = strprintf("Collateral tx must have at least %d confirmations, has %d", |
| 2433 | + consensus.MasternodeCollateralMinConf(), nDepth); |
| 2434 | + return error("%s: %s", __func__, strError); |
2465 | 2435 | } |
2466 | 2436 | } |
2467 | 2437 |
|
2468 | | - // Depth must be at least MASTERNODE_MIN_CONFIRMATIONS |
2469 | | - if (nDepth < consensus.MasternodeCollateralMinConf()) { |
2470 | | - strError = strprintf("Collateral tx must have at least %d confirmations, has %d", consensus.MasternodeCollateralMinConf(), nDepth); |
2471 | | - return error("%s: %s", __func__, strError); |
| 2438 | + CTxDestination destCollateral; |
| 2439 | + ExtractDestination(txOut.scriptPubKey, destCollateral, false); |
| 2440 | + const CKeyID* keyID = boost::get<CKeyID>(&destCollateral); |
| 2441 | + if (!keyID) { |
| 2442 | + LogPrintf("%s: Address does not refer to a key\n", __func__); |
| 2443 | + return false; |
2472 | 2444 | } |
2473 | 2445 |
|
2474 | | - // utxo need to be mine. |
2475 | | - isminetype mine = IsMine(txOut); |
2476 | | - if (mine != ISMINE_SPENDABLE) { |
2477 | | - strError = "Invalid collateral transaction. Not from this wallet"; |
2478 | | - return error("%s: tx %s not mine", __func__, strTxHash); |
| 2446 | + if (!GetKey(*keyID, keyRet)) { |
| 2447 | + LogPrintf("%s: Private key for address is not known\n", __func__); |
| 2448 | + return false; |
2479 | 2449 | } |
2480 | 2450 |
|
2481 | | - return GetVinAndKeysFromOutput( |
2482 | | - COutput(wtx, nOutputIndex, nDepth, true, true, true), |
2483 | | - txinRet, |
2484 | | - pubKeyRet, |
2485 | | - keyRet); |
| 2451 | + pubKeyRet = keyRet.GetPubKey(); |
| 2452 | + return true; |
2486 | 2453 | } |
2487 | 2454 |
|
2488 | 2455 | CWallet::OutputAvailabilityResult CWallet::CheckOutputAvailability( |
|
0 commit comments