1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2014 The Bitcoin Core developers
3 // Distributed under the MIT software license, see the accompanying
4 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
6 #include "wallet/wallet.h"
8 #include "checkpoints.h"
9 #include "coincontrol.h"
10 #include "consensus/upgrades.h"
11 #include "consensus/validation.h"
12 #include "consensus/consensus.h"
18 #include "rpc/protocol.h"
19 #include "script/script.h"
20 #include "script/sign.h"
22 #include "utilmoneystr.h"
23 #include "zcash/Note.hpp"
26 #include "zcash/zip32.h"
27 #include "cc/StakeGuard.h"
28 #include "pbaas/pbaas.h"
32 #include <boost/algorithm/string/replace.hpp>
33 #include <boost/filesystem.hpp>
34 #include <boost/thread.hpp>
37 using namespace libzcash;
42 CFeeRate payTxFee(DEFAULT_TRANSACTION_FEE);
43 CAmount maxTxFee = DEFAULT_TRANSACTION_MAXFEE;
44 unsigned int nTxConfirmTarget = DEFAULT_TX_CONFIRM_TARGET;
45 bool bSpendZeroConfChange = true;
46 bool fSendFreeTransactions = false;
47 bool fPayAtLeastCustomFee = true;
48 #include "komodo_defs.h"
50 extern int32_t USE_EXTERNAL_PUBKEY;
51 extern std::string NOTARY_PUBKEY;
52 extern int32_t KOMODO_EXCHANGEWALLET;
53 extern char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN];
54 extern uint160 ASSETCHAINS_CHAINID;
55 extern int32_t VERUS_MIN_STAKEAGE;
56 CBlockIndex *komodo_chainactive(int32_t height);
57 extern std::string DONATION_PUBKEY;
60 * Fees smaller than this (in satoshi) are considered zero fee (for transaction creation)
61 * Override with -mintxfee
63 CFeeRate CWallet::minTxFee = CFeeRate(1000);
65 /** @defgroup mapWallet
70 struct CompareValueOnly
72 bool operator()(const pair<CAmount, pair<const CWalletTx*, unsigned int> >& t1,
73 const pair<CAmount, pair<const CWalletTx*, unsigned int> >& t2) const
75 return t1.first < t2.first;
79 std::string JSOutPoint::ToString() const
81 return strprintf("JSOutPoint(%s, %d, %d)", hash.ToString().substr(0,10), js, n);
84 std::string COutput::ToString() const
86 return strprintf("COutput(%s, %d, %d) [%s]", tx->GetHash().ToString(), i, nDepth, FormatMoney(tx->vout[i].nValue));
89 const CWalletTx* CWallet::GetWalletTx(const uint256& hash) const
92 std::map<uint256, CWalletTx>::const_iterator it = mapWallet.find(hash);
93 if (it == mapWallet.end())
98 // Generate a new spending key and return its public payment address
99 libzcash::SproutPaymentAddress CWallet::GenerateNewSproutZKey()
101 AssertLockHeld(cs_wallet); // mapSproutZKeyMetadata
103 auto k = SproutSpendingKey::random();
104 auto addr = k.address();
106 // Check for collision, even though it is unlikely to ever occur
107 if (CCryptoKeyStore::HaveSproutSpendingKey(addr))
108 throw std::runtime_error("CWallet::GenerateNewSproutZKey(): Collision detected");
110 // Create new metadata
111 int64_t nCreationTime = GetTime();
112 mapSproutZKeyMetadata[addr] = CKeyMetadata(nCreationTime);
114 if (!AddSproutZKey(k))
115 throw std::runtime_error("CWallet::GenerateNewSproutZKey(): AddSproutZKey failed");
119 // Generate a new Sapling spending key and return its public payment address
120 SaplingPaymentAddress CWallet::GenerateNewSaplingZKey()
122 AssertLockHeld(cs_wallet); // mapSaplingZKeyMetadata
124 // Create new metadata
125 int64_t nCreationTime = GetTime();
126 CKeyMetadata metadata(nCreationTime);
128 // Try to get the seed
130 if (!GetHDSeed(seed))
131 throw std::runtime_error("CWallet::GenerateNewSaplingZKey(): HD seed not found");
133 auto m = libzcash::SaplingExtendedSpendingKey::Master(seed);
134 uint32_t bip44CoinType = Params().BIP44CoinType();
136 // We use a fixed keypath scheme of m/32'/coin_type'/account'
138 auto m_32h = m.Derive(32 | ZIP32_HARDENED_KEY_LIMIT);
139 // Derive m/32'/coin_type'
140 auto m_32h_cth = m_32h.Derive(bip44CoinType | ZIP32_HARDENED_KEY_LIMIT);
142 // Derive account key at next index, skip keys already known to the wallet
143 libzcash::SaplingExtendedSpendingKey xsk;
146 xsk = m_32h_cth.Derive(hdChain.saplingAccountCounter | ZIP32_HARDENED_KEY_LIMIT);
147 metadata.hdKeypath = "m/32'/" + std::to_string(bip44CoinType) + "'/" + std::to_string(hdChain.saplingAccountCounter) + "'";
148 metadata.seedFp = hdChain.seedFp;
149 // Increment childkey index
150 hdChain.saplingAccountCounter++;
151 } while (HaveSaplingSpendingKey(xsk.expsk.full_viewing_key()));
153 // Update the chain model in the database
154 if (fFileBacked && !CWalletDB(strWalletFile).WriteHDChain(hdChain))
155 throw std::runtime_error("CWallet::GenerateNewSaplingZKey(): Writing HD chain model failed");
157 auto ivk = xsk.expsk.full_viewing_key().in_viewing_key();
158 mapSaplingZKeyMetadata[ivk] = metadata;
160 auto addr = xsk.DefaultAddress();
161 if (!AddSaplingZKey(xsk, addr)) {
162 throw std::runtime_error("CWallet::GenerateNewSaplingZKey(): AddSaplingZKey failed");
164 // return default sapling payment address.
168 // Add spending key to keystore
169 bool CWallet::AddSaplingZKey(
170 const libzcash::SaplingExtendedSpendingKey &sk,
171 const libzcash::SaplingPaymentAddress &defaultAddr)
173 AssertLockHeld(cs_wallet); // mapSaplingZKeyMetadata
175 if (!CCryptoKeyStore::AddSaplingSpendingKey(sk, defaultAddr)) {
184 auto ivk = sk.expsk.full_viewing_key().in_viewing_key();
185 return CWalletDB(strWalletFile).WriteSaplingZKey(ivk, sk, mapSaplingZKeyMetadata[ivk]);
191 // Add payment address -> incoming viewing key map entry
192 bool CWallet::AddSaplingIncomingViewingKey(
193 const libzcash::SaplingIncomingViewingKey &ivk,
194 const libzcash::SaplingPaymentAddress &addr)
196 AssertLockHeld(cs_wallet); // mapSaplingZKeyMetadata
198 if (!CCryptoKeyStore::AddSaplingIncomingViewingKey(ivk, addr)) {
207 return CWalletDB(strWalletFile).WriteSaplingPaymentAddress(addr, ivk);
214 // Add spending key to keystore and persist to disk
215 bool CWallet::AddSproutZKey(const libzcash::SproutSpendingKey &key)
217 AssertLockHeld(cs_wallet); // mapSproutZKeyMetadata
218 auto addr = key.address();
220 if (!CCryptoKeyStore::AddSproutSpendingKey(key))
223 // check if we need to remove from viewing keys
224 if (HaveSproutViewingKey(addr))
225 RemoveSproutViewingKey(key.viewing_key());
231 return CWalletDB(strWalletFile).WriteZKey(addr,
233 mapSproutZKeyMetadata[addr]);
238 CPubKey CWallet::GenerateNewKey()
240 AssertLockHeld(cs_wallet); // mapKeyMetadata
241 bool fCompressed = CanSupportFeature(FEATURE_COMPRPUBKEY); // default to compressed public keys if we want 0.6.0 wallets
244 secret.MakeNewKey(fCompressed);
246 // Compressed public keys were introduced in version 0.6.0
248 SetMinVersion(FEATURE_COMPRPUBKEY);
250 CPubKey pubkey = secret.GetPubKey();
251 assert(secret.VerifyPubKey(pubkey));
253 // Create new metadata
254 int64_t nCreationTime = GetTime();
255 mapKeyMetadata[pubkey.GetID()] = CKeyMetadata(nCreationTime);
256 if (!nTimeFirstKey || nCreationTime < nTimeFirstKey)
257 nTimeFirstKey = nCreationTime;
259 if (!AddKeyPubKey(secret, pubkey))
260 throw std::runtime_error("CWallet::GenerateNewKey(): AddKey failed");
264 bool CWallet::AddKeyPubKey(const CKey& secret, const CPubKey &pubkey)
266 AssertLockHeld(cs_wallet); // mapKeyMetadata
267 if (!CCryptoKeyStore::AddKeyPubKey(secret, pubkey))
270 // check if we need to remove from watch-only
272 script = GetScriptForDestination(pubkey.GetID());
273 if (HaveWatchOnly(script))
274 RemoveWatchOnly(script);
279 return CWalletDB(strWalletFile).WriteKey(pubkey,
281 mapKeyMetadata[pubkey.GetID()]);
286 bool CWallet::AddCryptedKey(const CPubKey &vchPubKey,
287 const vector<unsigned char> &vchCryptedSecret)
290 if (!CCryptoKeyStore::AddCryptedKey(vchPubKey, vchCryptedSecret))
296 if (pwalletdbEncryption)
297 return pwalletdbEncryption->WriteCryptedKey(vchPubKey,
299 mapKeyMetadata[vchPubKey.GetID()]);
301 return CWalletDB(strWalletFile).WriteCryptedKey(vchPubKey,
303 mapKeyMetadata[vchPubKey.GetID()]);
309 bool CWallet::AddCryptedSproutSpendingKey(
310 const libzcash::SproutPaymentAddress &address,
311 const libzcash::ReceivingKey &rk,
312 const std::vector<unsigned char> &vchCryptedSecret)
314 if (!CCryptoKeyStore::AddCryptedSproutSpendingKey(address, rk, vchCryptedSecret))
320 if (pwalletdbEncryption) {
321 return pwalletdbEncryption->WriteCryptedZKey(address,
324 mapSproutZKeyMetadata[address]);
326 return CWalletDB(strWalletFile).WriteCryptedZKey(address,
329 mapSproutZKeyMetadata[address]);
335 bool CWallet::AddCryptedSaplingSpendingKey(const libzcash::SaplingExtendedFullViewingKey &extfvk,
336 const std::vector<unsigned char> &vchCryptedSecret,
337 const libzcash::SaplingPaymentAddress &defaultAddr)
339 if (!CCryptoKeyStore::AddCryptedSaplingSpendingKey(extfvk, vchCryptedSecret, defaultAddr))
345 if (pwalletdbEncryption) {
346 return pwalletdbEncryption->WriteCryptedSaplingZKey(extfvk,
348 mapSaplingZKeyMetadata[extfvk.fvk.in_viewing_key()]);
350 return CWalletDB(strWalletFile).WriteCryptedSaplingZKey(extfvk,
352 mapSaplingZKeyMetadata[extfvk.fvk.in_viewing_key()]);
358 bool CWallet::LoadKeyMetadata(const CPubKey &pubkey, const CKeyMetadata &meta)
360 AssertLockHeld(cs_wallet); // mapKeyMetadata
361 if (meta.nCreateTime && (!nTimeFirstKey || meta.nCreateTime < nTimeFirstKey))
362 nTimeFirstKey = meta.nCreateTime;
364 mapKeyMetadata[pubkey.GetID()] = meta;
368 bool CWallet::LoadZKeyMetadata(const SproutPaymentAddress &addr, const CKeyMetadata &meta)
370 AssertLockHeld(cs_wallet); // mapSproutZKeyMetadata
371 mapSproutZKeyMetadata[addr] = meta;
375 bool CWallet::LoadCryptedKey(const CPubKey &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret)
377 return CCryptoKeyStore::AddCryptedKey(vchPubKey, vchCryptedSecret);
380 bool CWallet::LoadCryptedZKey(const libzcash::SproutPaymentAddress &addr, const libzcash::ReceivingKey &rk, const std::vector<unsigned char> &vchCryptedSecret)
382 return CCryptoKeyStore::AddCryptedSproutSpendingKey(addr, rk, vchCryptedSecret);
385 bool CWallet::LoadCryptedSaplingZKey(
386 const libzcash::SaplingExtendedFullViewingKey &extfvk,
387 const std::vector<unsigned char> &vchCryptedSecret)
389 return CCryptoKeyStore::AddCryptedSaplingSpendingKey(extfvk, vchCryptedSecret, extfvk.DefaultAddress());
392 bool CWallet::LoadSaplingZKeyMetadata(const libzcash::SaplingIncomingViewingKey &ivk, const CKeyMetadata &meta)
394 AssertLockHeld(cs_wallet); // mapSaplingZKeyMetadata
395 mapSaplingZKeyMetadata[ivk] = meta;
399 bool CWallet::LoadSaplingZKey(const libzcash::SaplingExtendedSpendingKey &key)
401 return CCryptoKeyStore::AddSaplingSpendingKey(key, key.DefaultAddress());
404 bool CWallet::LoadSaplingPaymentAddress(
405 const libzcash::SaplingPaymentAddress &addr,
406 const libzcash::SaplingIncomingViewingKey &ivk)
408 return CCryptoKeyStore::AddSaplingIncomingViewingKey(ivk, addr);
411 bool CWallet::LoadZKey(const libzcash::SproutSpendingKey &key)
413 return CCryptoKeyStore::AddSproutSpendingKey(key);
416 bool CWallet::AddSproutViewingKey(const libzcash::SproutViewingKey &vk)
418 if (!CCryptoKeyStore::AddSproutViewingKey(vk)) {
421 nTimeFirstKey = 1; // No birthday information for viewing keys.
425 return CWalletDB(strWalletFile).WriteSproutViewingKey(vk);
428 bool CWallet::RemoveSproutViewingKey(const libzcash::SproutViewingKey &vk)
430 AssertLockHeld(cs_wallet);
431 if (!CCryptoKeyStore::RemoveSproutViewingKey(vk)) {
435 if (!CWalletDB(strWalletFile).EraseSproutViewingKey(vk)) {
443 bool CWallet::LoadSproutViewingKey(const libzcash::SproutViewingKey &vk)
445 return CCryptoKeyStore::AddSproutViewingKey(vk);
448 bool CWallet::AddCScript(const CScript& redeemScript)
450 if (!CCryptoKeyStore::AddCScript(redeemScript))
454 return CWalletDB(strWalletFile).WriteCScript(Hash160(redeemScript), redeemScript);
457 bool CWallet::LoadCScript(const CScript& redeemScript)
459 /* A sanity check was added in pull #3843 to avoid adding redeemScripts
460 * that never can be redeemed. However, old wallets may still contain
461 * these. Do not add them to the wallet and warn. */
462 if (redeemScript.size() > MAX_SCRIPT_ELEMENT_SIZE)
464 std::string strAddr = EncodeDestination(CScriptID(redeemScript));
465 LogPrintf("%s: Warning: This wallet contains a redeemScript of size %i which exceeds maximum size %i thus can never be redeemed. Do not use address %s.\n",
466 __func__, redeemScript.size(), MAX_SCRIPT_ELEMENT_SIZE, strAddr);
470 return CCryptoKeyStore::AddCScript(redeemScript);
473 bool CWallet::AddWatchOnly(const CScript &dest)
475 if (!CCryptoKeyStore::AddWatchOnly(dest))
477 nTimeFirstKey = 1; // No birthday information for watch-only keys.
478 NotifyWatchonlyChanged(true);
481 return CWalletDB(strWalletFile).WriteWatchOnly(dest);
484 bool CWallet::RemoveWatchOnly(const CScript &dest)
486 AssertLockHeld(cs_wallet);
487 if (!CCryptoKeyStore::RemoveWatchOnly(dest))
489 if (!HaveWatchOnly())
490 NotifyWatchonlyChanged(false);
492 if (!CWalletDB(strWalletFile).EraseWatchOnly(dest))
498 bool CWallet::LoadWatchOnly(const CScript &dest)
500 return CCryptoKeyStore::AddWatchOnly(dest);
503 bool CWallet::Unlock(const SecureString& strWalletPassphrase)
506 CKeyingMaterial vMasterKey;
510 BOOST_FOREACH(const MasterKeyMap::value_type& pMasterKey, mapMasterKeys)
512 if(!crypter.SetKeyFromPassphrase(strWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod))
514 if (!crypter.Decrypt(pMasterKey.second.vchCryptedKey, vMasterKey))
515 continue; // try another master key
516 if (CCryptoKeyStore::Unlock(vMasterKey))
523 bool CWallet::ChangeWalletPassphrase(const SecureString& strOldWalletPassphrase, const SecureString& strNewWalletPassphrase)
525 bool fWasLocked = IsLocked();
532 CKeyingMaterial vMasterKey;
533 BOOST_FOREACH(MasterKeyMap::value_type& pMasterKey, mapMasterKeys)
535 if(!crypter.SetKeyFromPassphrase(strOldWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod))
537 if (!crypter.Decrypt(pMasterKey.second.vchCryptedKey, vMasterKey))
539 if (CCryptoKeyStore::Unlock(vMasterKey))
541 int64_t nStartTime = GetTimeMillis();
542 crypter.SetKeyFromPassphrase(strNewWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod);
543 pMasterKey.second.nDeriveIterations = pMasterKey.second.nDeriveIterations * (100 / ((double)(GetTimeMillis() - nStartTime)));
545 nStartTime = GetTimeMillis();
546 crypter.SetKeyFromPassphrase(strNewWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod);
547 pMasterKey.second.nDeriveIterations = (pMasterKey.second.nDeriveIterations + pMasterKey.second.nDeriveIterations * 100 / ((double)(GetTimeMillis() - nStartTime))) / 2;
549 if (pMasterKey.second.nDeriveIterations < 25000)
550 pMasterKey.second.nDeriveIterations = 25000;
552 LogPrintf("Wallet passphrase changed to an nDeriveIterations of %i\n", pMasterKey.second.nDeriveIterations);
554 if (!crypter.SetKeyFromPassphrase(strNewWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod))
556 if (!crypter.Encrypt(vMasterKey, pMasterKey.second.vchCryptedKey))
558 CWalletDB(strWalletFile).WriteMasterKey(pMasterKey.first, pMasterKey.second);
569 void CWallet::ChainTip(const CBlockIndex *pindex,
570 const CBlock *pblock,
571 SproutMerkleTree sproutTree,
572 SaplingMerkleTree saplingTree,
576 IncrementNoteWitnesses(pindex, pblock, sproutTree, saplingTree);
578 DecrementNoteWitnesses(pindex);
580 UpdateSaplingNullifierNoteMapForBlock(pblock);
583 void CWallet::SetBestChain(const CBlockLocator& loc)
585 CWalletDB walletdb(strWalletFile);
586 SetBestChainINTERNAL(walletdb, loc);
589 std::set<std::pair<libzcash::PaymentAddress, uint256>> CWallet::GetNullifiersForAddresses(
590 const std::set<libzcash::PaymentAddress> & addresses)
592 std::set<std::pair<libzcash::PaymentAddress, uint256>> nullifierSet;
593 // Sapling ivk -> list of addrs map
594 // (There may be more than one diversified address for a given ivk.)
595 std::map<libzcash::SaplingIncomingViewingKey, std::vector<libzcash::SaplingPaymentAddress>> ivkMap;
596 for (const auto & addr : addresses) {
597 auto saplingAddr = boost::get<libzcash::SaplingPaymentAddress>(&addr);
598 if (saplingAddr != nullptr) {
599 libzcash::SaplingIncomingViewingKey ivk;
600 this->GetSaplingIncomingViewingKey(*saplingAddr, ivk);
601 ivkMap[ivk].push_back(*saplingAddr);
604 for (const auto & txPair : mapWallet) {
606 for (const auto & noteDataPair : txPair.second.mapSproutNoteData) {
607 auto & noteData = noteDataPair.second;
608 auto & nullifier = noteData.nullifier;
609 auto & address = noteData.address;
610 if (nullifier && addresses.count(address)) {
611 nullifierSet.insert(std::make_pair(address, nullifier.get()));
615 for (const auto & noteDataPair : txPair.second.mapSaplingNoteData) {
616 auto & noteData = noteDataPair.second;
617 auto & nullifier = noteData.nullifier;
618 auto & ivk = noteData.ivk;
619 if (nullifier && ivkMap.count(ivk)) {
620 for (const auto & addr : ivkMap[ivk]) {
621 nullifierSet.insert(std::make_pair(addr, nullifier.get()));
629 bool CWallet::IsNoteSproutChange(
630 const std::set<std::pair<libzcash::PaymentAddress, uint256>> & nullifierSet,
631 const PaymentAddress & address,
632 const JSOutPoint & jsop)
634 // A Note is marked as "change" if the address that received it
635 // also spent Notes in the same transaction. This will catch,
637 // - Change created by spending fractions of Notes (because
638 // z_sendmany sends change to the originating z-address).
639 // - "Chaining Notes" used to connect JoinSplits together.
640 // - Notes created by consolidation transactions (e.g. using
641 // z_mergetoaddress).
642 // - Notes sent from one address to itself.
643 for (const JSDescription & jsd : mapWallet[jsop.hash].vjoinsplit) {
644 for (const uint256 & nullifier : jsd.nullifiers) {
645 if (nullifierSet.count(std::make_pair(address, nullifier))) {
653 bool CWallet::IsNoteSaplingChange(const std::set<std::pair<libzcash::PaymentAddress, uint256>> & nullifierSet,
654 const libzcash::PaymentAddress & address,
655 const SaplingOutPoint & op)
657 // A Note is marked as "change" if the address that received it
658 // also spent Notes in the same transaction. This will catch,
660 // - Change created by spending fractions of Notes (because
661 // z_sendmany sends change to the originating z-address).
662 // - Notes created by consolidation transactions (e.g. using
663 // z_mergetoaddress).
664 // - Notes sent from one address to itself.
665 for (const SpendDescription &spend : mapWallet[op.hash].vShieldedSpend) {
666 if (nullifierSet.count(std::make_pair(address, spend.nullifier))) {
673 bool CWallet::SetMinVersion(enum WalletFeature nVersion, CWalletDB* pwalletdbIn, bool fExplicit)
675 LOCK(cs_wallet); // nWalletVersion
676 if (nWalletVersion >= nVersion)
679 // when doing an explicit upgrade, if we pass the max version permitted, upgrade all the way
680 if (fExplicit && nVersion > nWalletMaxVersion)
681 nVersion = FEATURE_LATEST;
683 nWalletVersion = nVersion;
685 if (nVersion > nWalletMaxVersion)
686 nWalletMaxVersion = nVersion;
690 CWalletDB* pwalletdb = pwalletdbIn ? pwalletdbIn : new CWalletDB(strWalletFile);
691 if (nWalletVersion > 40000)
692 pwalletdb->WriteMinVersion(nWalletVersion);
700 bool CWallet::SetMaxVersion(int nVersion)
702 LOCK(cs_wallet); // nWalletVersion, nWalletMaxVersion
703 // cannot downgrade below current version
704 if (nWalletVersion > nVersion)
707 nWalletMaxVersion = nVersion;
712 set<uint256> CWallet::GetConflicts(const uint256& txid) const
715 AssertLockHeld(cs_wallet);
717 std::map<uint256, CWalletTx>::const_iterator it = mapWallet.find(txid);
718 if (it == mapWallet.end())
720 const CWalletTx& wtx = it->second;
722 std::pair<TxSpends::const_iterator, TxSpends::const_iterator> range;
724 BOOST_FOREACH(const CTxIn& txin, wtx.vin)
726 if (mapTxSpends.count(txin.prevout) <= 1)
727 continue; // No conflict if zero or one spends
728 range = mapTxSpends.equal_range(txin.prevout);
729 for (TxSpends::const_iterator it = range.first; it != range.second; ++it)
730 result.insert(it->second);
733 std::pair<TxNullifiers::const_iterator, TxNullifiers::const_iterator> range_n;
735 for (const JSDescription& jsdesc : wtx.vjoinsplit) {
736 for (const uint256& nullifier : jsdesc.nullifiers) {
737 if (mapTxSproutNullifiers.count(nullifier) <= 1) {
738 continue; // No conflict if zero or one spends
740 range_n = mapTxSproutNullifiers.equal_range(nullifier);
741 for (TxNullifiers::const_iterator it = range_n.first; it != range_n.second; ++it) {
742 result.insert(it->second);
747 std::pair<TxNullifiers::const_iterator, TxNullifiers::const_iterator> range_o;
749 for (const SpendDescription &spend : wtx.vShieldedSpend) {
750 uint256 nullifier = spend.nullifier;
751 if (mapTxSaplingNullifiers.count(nullifier) <= 1) {
752 continue; // No conflict if zero or one spends
754 range_o = mapTxSaplingNullifiers.equal_range(nullifier);
755 for (TxNullifiers::const_iterator it = range_o.first; it != range_o.second; ++it) {
756 result.insert(it->second);
762 void CWallet::Flush(bool shutdown)
764 bitdb.Flush(shutdown);
767 bool CWallet::Verify(const string& walletFile, string& warningString, string& errorString)
769 if (!bitdb.Open(GetDataDir()))
771 // try moving the database env out of the way
772 boost::filesystem::path pathDatabase = GetDataDir() / "database";
773 boost::filesystem::path pathDatabaseBak = GetDataDir() / strprintf("database.%d.bak", GetTime());
775 boost::filesystem::rename(pathDatabase, pathDatabaseBak);
776 LogPrintf("Moved old %s to %s. Retrying.\n", pathDatabase.string(), pathDatabaseBak.string());
777 } catch (const boost::filesystem::filesystem_error&) {
778 // failure is ok (well, not really, but it's not worse than what we started with)
782 if (!bitdb.Open(GetDataDir())) {
783 // if it still fails, it probably means we can't even create the database env
784 string msg = strprintf(_("Error initializing wallet database environment %s!"), GetDataDir());
790 if (GetBoolArg("-salvagewallet", false))
792 // Recover readable keypairs:
793 if (!CWalletDB::Recover(bitdb, walletFile, true))
797 if (boost::filesystem::exists(GetDataDir() / walletFile))
799 CDBEnv::VerifyResult r = bitdb.Verify(walletFile, CWalletDB::Recover);
800 if (r == CDBEnv::RECOVER_OK)
802 warningString += strprintf(_("Warning: wallet.dat corrupt, data salvaged!"
803 " Original wallet.dat saved as wallet.{timestamp}.bak in %s; if"
804 " your balance or transactions are incorrect you should"
805 " restore from a backup."), GetDataDir());
807 if (r == CDBEnv::RECOVER_FAIL)
808 errorString += _("wallet.dat corrupt, salvage failed");
815 void CWallet::SyncMetaData(pair<typename TxSpendMap<T>::iterator, typename TxSpendMap<T>::iterator> range)
817 // We want all the wallet transactions in range to have the same metadata as
818 // the oldest (smallest nOrderPos).
819 // So: find smallest nOrderPos:
821 int nMinOrderPos = std::numeric_limits<int>::max();
822 const CWalletTx* copyFrom = NULL;
823 for (typename TxSpendMap<T>::iterator it = range.first; it != range.second; ++it)
825 const uint256& hash = it->second;
826 int n = mapWallet[hash].nOrderPos;
827 if (n < nMinOrderPos)
830 copyFrom = &mapWallet[hash];
833 // Now copy data from copyFrom to rest:
834 for (typename TxSpendMap<T>::iterator it = range.first; it != range.second; ++it)
836 const uint256& hash = it->second;
837 CWalletTx* copyTo = &mapWallet[hash];
838 if (copyFrom == copyTo) continue;
839 copyTo->mapValue = copyFrom->mapValue;
840 // mapSproutNoteData and mapSaplingNoteData not copied on purpose
841 // (it is always set correctly for each CWalletTx)
842 copyTo->vOrderForm = copyFrom->vOrderForm;
843 // fTimeReceivedIsTxTime not copied on purpose
844 // nTimeReceived not copied on purpose
845 copyTo->nTimeSmart = copyFrom->nTimeSmart;
846 copyTo->fFromMe = copyFrom->fFromMe;
847 copyTo->strFromAccount = copyFrom->strFromAccount;
848 // nOrderPos not copied on purpose
849 // cached members not copied on purpose
854 * Outpoint is spent if any non-conflicted transaction
857 bool CWallet::IsSpent(const uint256& hash, unsigned int n) const
859 const COutPoint outpoint(hash, n);
860 pair<TxSpends::const_iterator, TxSpends::const_iterator> range;
861 range = mapTxSpends.equal_range(outpoint);
863 for (TxSpends::const_iterator it = range.first; it != range.second; ++it)
865 const uint256& wtxid = it->second;
866 std::map<uint256, CWalletTx>::const_iterator mit = mapWallet.find(wtxid);
867 if (mit != mapWallet.end() && mit->second.GetDepthInMainChain() >= 0)
868 return true; // Spent
874 * Note is spent if any non-conflicted transaction
877 bool CWallet::IsSproutSpent(const uint256& nullifier) const {
878 pair<TxNullifiers::const_iterator, TxNullifiers::const_iterator> range;
879 range = mapTxSproutNullifiers.equal_range(nullifier);
881 for (TxNullifiers::const_iterator it = range.first; it != range.second; ++it) {
882 const uint256& wtxid = it->second;
883 std::map<uint256, CWalletTx>::const_iterator mit = mapWallet.find(wtxid);
884 if (mit != mapWallet.end() && mit->second.GetDepthInMainChain() >= 0) {
885 return true; // Spent
891 bool CWallet::IsSaplingSpent(const uint256& nullifier) const {
892 pair<TxNullifiers::const_iterator, TxNullifiers::const_iterator> range;
893 range = mapTxSaplingNullifiers.equal_range(nullifier);
895 for (TxNullifiers::const_iterator it = range.first; it != range.second; ++it) {
896 const uint256& wtxid = it->second;
897 std::map<uint256, CWalletTx>::const_iterator mit = mapWallet.find(wtxid);
898 if (mit != mapWallet.end() && mit->second.GetDepthInMainChain() >= 0) {
899 return true; // Spent
905 void CWallet::AddToTransparentSpends(const COutPoint& outpoint, const uint256& wtxid)
907 mapTxSpends.insert(make_pair(outpoint, wtxid));
909 pair<TxSpends::iterator, TxSpends::iterator> range;
910 range = mapTxSpends.equal_range(outpoint);
911 SyncMetaData<COutPoint>(range);
914 void CWallet::AddToSproutSpends(const uint256& nullifier, const uint256& wtxid)
916 mapTxSproutNullifiers.insert(make_pair(nullifier, wtxid));
918 pair<TxNullifiers::iterator, TxNullifiers::iterator> range;
919 range = mapTxSproutNullifiers.equal_range(nullifier);
920 SyncMetaData<uint256>(range);
923 void CWallet::AddToSaplingSpends(const uint256& nullifier, const uint256& wtxid)
925 mapTxSaplingNullifiers.insert(make_pair(nullifier, wtxid));
927 pair<TxNullifiers::iterator, TxNullifiers::iterator> range;
928 range = mapTxSaplingNullifiers.equal_range(nullifier);
929 SyncMetaData<uint256>(range);
932 void CWallet::AddToSpends(const uint256& wtxid)
934 assert(mapWallet.count(wtxid));
935 CWalletTx& thisTx = mapWallet[wtxid];
936 if (thisTx.IsCoinBase()) // Coinbases don't spend anything!
939 for (const CTxIn& txin : thisTx.vin) {
940 AddToTransparentSpends(txin.prevout, wtxid);
942 for (const JSDescription& jsdesc : thisTx.vjoinsplit) {
943 for (const uint256& nullifier : jsdesc.nullifiers) {
944 AddToSproutSpends(nullifier, wtxid);
947 for (const SpendDescription &spend : thisTx.vShieldedSpend) {
948 AddToSaplingSpends(spend.nullifier, wtxid);
952 void CWallet::ClearNoteWitnessCache()
955 for (std::pair<const uint256, CWalletTx>& wtxItem : mapWallet) {
956 for (mapSproutNoteData_t::value_type& item : wtxItem.second.mapSproutNoteData) {
957 item.second.witnesses.clear();
958 item.second.witnessHeight = -1;
960 for (mapSaplingNoteData_t::value_type& item : wtxItem.second.mapSaplingNoteData) {
961 item.second.witnesses.clear();
962 item.second.witnessHeight = -1;
965 nWitnessCacheSize = 0;
966 //fprintf(stderr,"Clear witness cache\n");
969 template<typename NoteDataMap>
970 void CopyPreviousWitnesses(NoteDataMap& noteDataMap, int indexHeight, int64_t nWitnessCacheSize)
972 for (auto& item : noteDataMap) {
973 auto* nd = &(item.second);
974 // Only increment witnesses that are behind the current height
975 if (nd->witnessHeight < indexHeight) {
976 // Check the validity of the cache
977 // The only time a note witnessed above the current height
978 // would be invalid here is during a reindex when blocks
979 // have been decremented, and we are incrementing the blocks
980 // immediately after.
981 assert(nWitnessCacheSize >= nd->witnesses.size());
982 // Witnesses being incremented should always be either -1
983 // (never incremented or decremented) or one below indexHeight
984 assert((nd->witnessHeight == -1) || (nd->witnessHeight == indexHeight - 1));
985 // Copy the witness for the previous block if we have one
986 if (nd->witnesses.size() > 0) {
987 nd->witnesses.push_front(nd->witnesses.front());
989 if (nd->witnesses.size() > WITNESS_CACHE_SIZE) {
990 nd->witnesses.pop_back();
996 template<typename NoteDataMap>
997 void AppendNoteCommitment(NoteDataMap& noteDataMap, int indexHeight, int64_t nWitnessCacheSize, const uint256& note_commitment)
999 for (auto& item : noteDataMap) {
1000 auto* nd = &(item.second);
1001 if (nd->witnessHeight < indexHeight && nd->witnesses.size() > 0) {
1002 // Check the validity of the cache
1003 // See comment in CopyPreviousWitnesses about validity.
1004 assert(nWitnessCacheSize >= nd->witnesses.size());
1005 nd->witnesses.front().append(note_commitment);
1010 template<typename OutPoint, typename NoteData, typename Witness>
1011 void WitnessNoteIfMine(std::map<OutPoint, NoteData>& noteDataMap, int indexHeight, int64_t nWitnessCacheSize, const OutPoint& key, const Witness& witness)
1013 if (noteDataMap.count(key) && noteDataMap[key].witnessHeight < indexHeight) {
1014 auto* nd = &(noteDataMap[key]);
1015 if (nd->witnesses.size() > 0) {
1016 // We think this can happen because we write out the
1017 // witness cache state after every block increment or
1018 // decrement, but the block index itself is written in
1019 // batches. So if the node crashes in between these two
1020 // operations, it is possible for IncrementNoteWitnesses
1021 // to be called again on previously-cached blocks. This
1022 // doesn't affect existing cached notes because of the
1023 // NoteData::witnessHeight checks. See #1378 for details.
1024 LogPrintf("Inconsistent witness cache state found for %s\n- Cache size: %d\n- Top (height %d): %s\n- New (height %d): %s\n",
1025 key.ToString(), nd->witnesses.size(),
1027 nd->witnesses.front().root().GetHex(),
1029 witness.root().GetHex());
1030 nd->witnesses.clear();
1032 nd->witnesses.push_front(witness);
1033 // Set height to one less than pindex so it gets incremented
1034 nd->witnessHeight = indexHeight - 1;
1035 // Check the validity of the cache
1036 assert(nWitnessCacheSize >= nd->witnesses.size());
1041 template<typename NoteDataMap>
1042 void UpdateWitnessHeights(NoteDataMap& noteDataMap, int indexHeight, int64_t nWitnessCacheSize)
1044 for (auto& item : noteDataMap) {
1045 auto* nd = &(item.second);
1046 if (nd->witnessHeight < indexHeight) {
1047 nd->witnessHeight = indexHeight;
1048 // Check the validity of the cache
1049 // See comment in CopyPreviousWitnesses about validity.
1050 assert(nWitnessCacheSize >= nd->witnesses.size());
1055 void CWallet::IncrementNoteWitnesses(const CBlockIndex* pindex,
1056 const CBlock* pblockIn,
1057 SproutMerkleTree& sproutTree,
1058 SaplingMerkleTree& saplingTree)
1061 for (std::pair<const uint256, CWalletTx>& wtxItem : mapWallet) {
1062 ::CopyPreviousWitnesses(wtxItem.second.mapSproutNoteData, pindex->GetHeight(), nWitnessCacheSize);
1063 ::CopyPreviousWitnesses(wtxItem.second.mapSaplingNoteData, pindex->GetHeight(), nWitnessCacheSize);
1066 if (nWitnessCacheSize < WITNESS_CACHE_SIZE) {
1067 nWitnessCacheSize += 1;
1070 const CBlock* pblock {pblockIn};
1073 ReadBlockFromDisk(block, pindex, false);
1077 for (const CTransaction& tx : pblock->vtx) {
1078 auto hash = tx.GetHash();
1079 bool txIsOurs = mapWallet.count(hash);
1081 for (size_t i = 0; i < tx.vjoinsplit.size(); i++) {
1082 const JSDescription& jsdesc = tx.vjoinsplit[i];
1083 for (uint8_t j = 0; j < jsdesc.commitments.size(); j++) {
1084 const uint256& note_commitment = jsdesc.commitments[j];
1085 sproutTree.append(note_commitment);
1087 // Increment existing witnesses
1088 for (std::pair<const uint256, CWalletTx>& wtxItem : mapWallet) {
1089 ::AppendNoteCommitment(wtxItem.second.mapSproutNoteData, pindex->GetHeight(), nWitnessCacheSize, note_commitment);
1092 // If this is our note, witness it
1094 JSOutPoint jsoutpt {hash, i, j};
1095 ::WitnessNoteIfMine(mapWallet[hash].mapSproutNoteData, pindex->GetHeight(), nWitnessCacheSize, jsoutpt, sproutTree.witness());
1100 for (uint32_t i = 0; i < tx.vShieldedOutput.size(); i++) {
1101 const uint256& note_commitment = tx.vShieldedOutput[i].cm;
1102 saplingTree.append(note_commitment);
1104 // Increment existing witnesses
1105 for (std::pair<const uint256, CWalletTx>& wtxItem : mapWallet) {
1106 ::AppendNoteCommitment(wtxItem.second.mapSaplingNoteData, pindex->GetHeight(), nWitnessCacheSize, note_commitment);
1109 // If this is our note, witness it
1111 SaplingOutPoint outPoint {hash, i};
1112 ::WitnessNoteIfMine(mapWallet[hash].mapSaplingNoteData, pindex->GetHeight(), nWitnessCacheSize, outPoint, saplingTree.witness());
1117 // Update witness heights
1118 for (std::pair<const uint256, CWalletTx>& wtxItem : mapWallet) {
1119 ::UpdateWitnessHeights(wtxItem.second.mapSproutNoteData, pindex->GetHeight(), nWitnessCacheSize);
1120 ::UpdateWitnessHeights(wtxItem.second.mapSaplingNoteData, pindex->GetHeight(), nWitnessCacheSize);
1123 // For performance reasons, we write out the witness cache in
1124 // CWallet::SetBestChain() (which also ensures that overall consistency
1125 // of the wallet.dat is maintained).
1128 template<typename NoteDataMap>
1129 bool DecrementNoteWitnesses(NoteDataMap& noteDataMap, int indexHeight, int64_t nWitnessCacheSize)
1131 extern int32_t KOMODO_REWIND;
1133 for (auto& item : noteDataMap) {
1134 auto* nd = &(item.second);
1135 // Only decrement witnesses that are not above the current height
1136 if (nd->witnessHeight <= indexHeight) {
1137 // Check the validity of the cache
1138 // See comment below (this would be invalid if there were a
1139 // prior decrement).
1140 assert(nWitnessCacheSize >= nd->witnesses.size());
1141 // Witnesses being decremented should always be either -1
1142 // (never incremented or decremented) or equal to the height
1143 // of the block being removed (indexHeight)
1144 if (!((nd->witnessHeight == -1) || (nd->witnessHeight == indexHeight)))
1146 printf("at height %d\n", indexHeight);
1149 if (nd->witnesses.size() > 0) {
1150 nd->witnesses.pop_front();
1152 // indexHeight is the height of the block being removed, so
1153 // the new witness cache height is one below it.
1154 nd->witnessHeight = indexHeight - 1;
1156 // Check the validity of the cache
1157 // Technically if there are notes witnessed above the current
1158 // height, their cache will now be invalid (relative to the new
1159 // value of nWitnessCacheSize). However, this would only occur
1160 // during a reindex, and by the time the reindex reaches the tip
1161 // of the chain again, the existing witness caches will be valid
1163 // We don't set nWitnessCacheSize to zero at the start of the
1164 // reindex because the on-disk blocks had already resulted in a
1165 // chain that didn't trigger the assertion below.
1166 if (nd->witnessHeight < indexHeight) {
1167 // Subtract 1 to compare to what nWitnessCacheSize will be after
1169 assert((nWitnessCacheSize - 1) >= nd->witnesses.size());
1172 assert(KOMODO_REWIND != 0 || nWitnessCacheSize > 0);
1176 void CWallet::DecrementNoteWitnesses(const CBlockIndex* pindex)
1179 for (std::pair<const uint256, CWalletTx>& wtxItem : mapWallet) {
1180 if (!::DecrementNoteWitnesses(wtxItem.second.mapSproutNoteData, pindex->GetHeight(), nWitnessCacheSize))
1182 if (!::DecrementNoteWitnesses(wtxItem.second.mapSaplingNoteData, pindex->GetHeight(), nWitnessCacheSize))
1185 nWitnessCacheSize -= 1;
1186 // TODO: If nWitnessCache is zero, we need to regenerate the caches (#1302)
1187 assert(nWitnessCacheSize > 0);
1189 // For performance reasons, we write out the witness cache in
1190 // CWallet::SetBestChain() (which also ensures that overall consistency
1191 // of the wallet.dat is maintained).
1194 bool CWallet::EncryptWallet(const SecureString& strWalletPassphrase)
1199 CKeyingMaterial vMasterKey;
1201 vMasterKey.resize(WALLET_CRYPTO_KEY_SIZE);
1202 GetRandBytes(&vMasterKey[0], WALLET_CRYPTO_KEY_SIZE);
1204 CMasterKey kMasterKey;
1206 kMasterKey.vchSalt.resize(WALLET_CRYPTO_SALT_SIZE);
1207 GetRandBytes(&kMasterKey.vchSalt[0], WALLET_CRYPTO_SALT_SIZE);
1210 int64_t nStartTime = GetTimeMillis();
1211 crypter.SetKeyFromPassphrase(strWalletPassphrase, kMasterKey.vchSalt, 25000, kMasterKey.nDerivationMethod);
1212 kMasterKey.nDeriveIterations = 2500000 / ((double)(GetTimeMillis() - nStartTime));
1214 nStartTime = GetTimeMillis();
1215 crypter.SetKeyFromPassphrase(strWalletPassphrase, kMasterKey.vchSalt, kMasterKey.nDeriveIterations, kMasterKey.nDerivationMethod);
1216 kMasterKey.nDeriveIterations = (kMasterKey.nDeriveIterations + kMasterKey.nDeriveIterations * 100 / ((double)(GetTimeMillis() - nStartTime))) / 2;
1218 if (kMasterKey.nDeriveIterations < 25000)
1219 kMasterKey.nDeriveIterations = 25000;
1221 LogPrintf("Encrypting Wallet with an nDeriveIterations of %i\n", kMasterKey.nDeriveIterations);
1223 if (!crypter.SetKeyFromPassphrase(strWalletPassphrase, kMasterKey.vchSalt, kMasterKey.nDeriveIterations, kMasterKey.nDerivationMethod))
1225 if (!crypter.Encrypt(vMasterKey, kMasterKey.vchCryptedKey))
1230 mapMasterKeys[++nMasterKeyMaxID] = kMasterKey;
1233 assert(!pwalletdbEncryption);
1234 pwalletdbEncryption = new CWalletDB(strWalletFile);
1235 if (!pwalletdbEncryption->TxnBegin()) {
1236 delete pwalletdbEncryption;
1237 pwalletdbEncryption = NULL;
1240 pwalletdbEncryption->WriteMasterKey(nMasterKeyMaxID, kMasterKey);
1243 if (!EncryptKeys(vMasterKey))
1246 pwalletdbEncryption->TxnAbort();
1247 delete pwalletdbEncryption;
1249 // We now probably have half of our keys encrypted in memory, and half not...
1250 // die and let the user reload the unencrypted wallet.
1254 // Encryption was introduced in version 0.4.0
1255 SetMinVersion(FEATURE_WALLETCRYPT, pwalletdbEncryption, true);
1259 if (!pwalletdbEncryption->TxnCommit()) {
1260 delete pwalletdbEncryption;
1261 // We now have keys encrypted in memory, but not on disk...
1262 // die to avoid confusion and let the user reload the unencrypted wallet.
1266 delete pwalletdbEncryption;
1267 pwalletdbEncryption = NULL;
1271 Unlock(strWalletPassphrase);
1275 // Need to completely rewrite the wallet file; if we don't, bdb might keep
1276 // bits of the unencrypted private key in slack space in the database file.
1277 CDB::Rewrite(strWalletFile);
1280 NotifyStatusChanged(this);
1285 int64_t CWallet::IncOrderPosNext(CWalletDB *pwalletdb)
1287 AssertLockHeld(cs_wallet); // nOrderPosNext
1288 int64_t nRet = nOrderPosNext++;
1290 pwalletdb->WriteOrderPosNext(nOrderPosNext);
1292 CWalletDB(strWalletFile).WriteOrderPosNext(nOrderPosNext);
1297 CWallet::TxItems CWallet::OrderedTxItems(std::list<CAccountingEntry>& acentries, std::string strAccount)
1299 AssertLockHeld(cs_wallet); // mapWallet
1300 CWalletDB walletdb(strWalletFile);
1302 // First: get all CWalletTx and CAccountingEntry into a sorted-by-order multimap.
1305 // Note: maintaining indices in the database of (account,time) --> txid and (account, time) --> acentry
1306 // would make this much faster for applications that do this a lot.
1307 for (map<uint256, CWalletTx>::iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
1309 CWalletTx* wtx = &((*it).second);
1310 txOrdered.insert(make_pair(wtx->nOrderPos, TxPair(wtx, (CAccountingEntry*)0)));
1313 walletdb.ListAccountCreditDebit(strAccount, acentries);
1314 BOOST_FOREACH(CAccountingEntry& entry, acentries)
1316 txOrdered.insert(make_pair(entry.nOrderPos, TxPair((CWalletTx*)0, &entry)));
1322 // looks through all wallet UTXOs and checks to see if any qualify to stake the block at the current height. it always returns the qualified
1323 // UTXO with the smallest coin age if there is more than one, as larger coin age will win more often and is worth saving
1324 // each attempt consists of taking a VerusHash of the following values:
1325 // ASSETCHAINS_MAGIC, nHeight, txid, voutNum
1326 bool CWallet::VerusSelectStakeOutput(CBlock *pBlock, arith_uint256 &hashResult, CTransaction &stakeSource, int32_t &voutNum, int32_t nHeight, uint32_t &bnTarget) const
1328 arith_uint256 target;
1329 arith_uint256 curHash;
1330 vector<COutput> vecOutputs;
1331 COutput *pwinner = NULL;
1332 CBlockIndex *pastBlockIndex;
1333 txnouttype whichType;
1334 std:vector<std::vector<unsigned char>> vSolutions;
1336 pBlock->nNonce.SetPOSTarget(bnTarget, pBlock->nVersion);
1337 target.SetCompact(bnTarget);
1339 auto consensusParams = Params().GetConsensus();
1340 CValidationState state;
1342 pwalletMain->AvailableCoins(vecOutputs, true, NULL, false, !consensusParams.fCoinbaseMustBeProtected);
1344 if (pastBlockIndex = komodo_chainactive(nHeight - 100))
1346 uint256 pastHash = pastBlockIndex->GetVerusEntropyHash();
1350 BOOST_FOREACH(COutput &txout, vecOutputs)
1352 if (txout.fSpendable && (UintToArith256(txout.tx->GetVerusPOSHash(&(pBlock->nNonce), txout.i, nHeight, pastHash)) <= target) && (txout.nDepth >= VERUS_MIN_STAKEAGE))
1354 CDataStream s(SER_NETWORK, PROTOCOL_VERSION);
1355 int32_t txSize = GetSerializeSize(s, *(CTransaction *)txout.tx);
1357 //printf("Serialized size of transaction %s is %lu\n", txout.tx->GetHash().GetHex().c_str(), txSize);
1358 if (txSize > MAX_TX_SIZE_FOR_STAKING)
1360 LogPrintf("Transaction %s is too large to stake. Serialized size == %lu\n", txout.tx->GetHash().GetHex().c_str(), txSize);
1363 CCoinsViewCache view(pcoinsTip);
1364 CMutableTransaction checkStakeTx = CreateNewContextualCMutableTransaction(consensusParams, nHeight);
1365 uint256 txHash = txout.tx->GetHash();
1366 checkStakeTx.vin.push_back(CTxIn(COutPoint(txHash, txout.i)));
1368 if (txSize <= MAX_TX_SIZE_FOR_STAKING &&
1369 (!pwinner || UintToArith256(curNonce) > UintToArith256(pBlock->nNonce)) &&
1370 (Solver(txout.tx->vout[txout.i].scriptPubKey, whichType, vSolutions) && (whichType == TX_PUBKEY || whichType == TX_PUBKEYHASH)) &&
1371 !cheatList.IsUTXOInList(COutPoint(txHash, txout.i), nHeight <= 100 ? 1 : nHeight-100) &&
1372 view.AccessCoins(txHash) &&
1373 Consensus::CheckTxInputs(checkStakeTx, state, view, nHeight, consensusParams))
1375 //printf("Found PoS block\nnNonce: %s\n", pBlock->nNonce.GetHex().c_str());
1377 curNonce = pBlock->nNonce;
1378 srcIndex = (nHeight - txout.nDepth) - 1;
1384 stakeSource = *(pwinner->tx);
1385 voutNum = pwinner->i;
1386 pBlock->nNonce = curNonce;
1388 if (CConstVerusSolutionVector::activationHeight.ActiveVersion(nHeight) == CActivationHeight::SOLUTION_VERUSV3)
1390 CDataStream txStream = CDataStream(SER_NETWORK, PROTOCOL_VERSION);
1393 // 1. PBaaS header for this block
1394 // 2. source transaction
1395 // 3. block index of base MMR being used
1396 // 4. source tx block index for proof
1397 // 5. full merkle proof of source tx up to prior MMR root
1398 // 6. block hash of block of entropyhash
1399 // 7. proof of block hash (not full header) in the MMR for the block height of the entropy hash block
1400 // all that data includes enough information to verify
1401 // prior MMR, blockhash, transaction, entropy hash, and block indexes match
1402 // also checks root match & block power
1403 auto view = chainActive.GetMMV();
1404 pBlock->AddUpdatePBaaSHeader(view.GetRoot());
1406 txStream << *(CTransaction *)pwinner->tx;
1408 // start with the tx proof
1409 CMerkleBranch branch(pwinner->tx->nIndex, pwinner->tx->vMerkleBranch);
1411 // add the Merkle proof bridge to the MMR
1412 chainActive[srcIndex]->AddMerkleProofBridge(branch);
1414 // use the block that we got entropy hash from as the validating block
1415 // which immediately provides all but unspent proof for PoS block
1416 view.resize(pastBlockIndex->GetHeight());
1418 view.GetProof(branch, srcIndex);
1420 // store block height of MMR root, block index of entry, and full blockchain proof of transaction with that root
1421 txStream << pastBlockIndex->GetHeight();
1422 txStream << srcIndex;
1425 // now we get a fresh branch for the block proof
1426 branch = CMerkleBranch();
1428 // prove the block 100 blocks ago with its coincident MMR
1429 // it must hash to the same value with a different path, providing both a consistency check and
1430 // an asserted MMR root for the n - 100 block if matched
1431 pastBlockIndex->AddBlockProofBridge(branch);
1432 view.GetProof(branch, pastBlockIndex->GetHeight());
1434 // block proof of the same block using the MMR of that block height, so we don't need to add additional data
1435 // beyond the block hash.
1436 txStream << pastBlockIndex->GetBlockHash();
1439 std::vector<unsigned char> stx(txStream.begin(), txStream.end());
1441 // printf("\nFound Stake transaction... all proof serialized size == %lu\n", stx.size());
1443 CVerusSolutionVector(pBlock->nSolution).ResizeExtraData(stx.size());
1445 pBlock->SetExtraData(stx.data(), stx.size());
1453 int32_t CWallet::VerusStakeTransaction(CBlock *pBlock, CMutableTransaction &txNew, uint32_t &bnTarget, arith_uint256 &hashResult, uint8_t *utxosig, CPubKey pk) const
1455 CTransaction stakeSource;
1456 int32_t voutNum, siglen = 0;
1458 txnouttype whichType;
1459 std::vector<std::vector<unsigned char>> vSolutions;
1461 CBlockIndex *tipindex = chainActive.LastTip();
1462 uint32_t stakeHeight = tipindex->GetHeight() + 1;
1463 bool extendedStake = stakeHeight >= Params().GetConsensus().vUpgrades[Consensus::UPGRADE_SAPLING].nActivationHeight;
1468 bnTarget = lwmaGetNextPOSRequired(tipindex, Params().GetConsensus());
1470 if (!VerusSelectStakeOutput(pBlock, hashResult, stakeSource, voutNum, stakeHeight, bnTarget) ||
1471 !Solver(stakeSource.vout[voutNum].scriptPubKey, whichType, vSolutions))
1473 LogPrintf("Searched for eligible staking transactions, no winners found\n");
1478 SignatureData sigdata;
1480 auto consensusBranchId = CurrentEpochBranchId(stakeHeight, Params().GetConsensus());
1482 const CKeyStore& keystore = *pwalletMain;
1483 txNew.vin.resize(1);
1484 txNew.vout.resize(1);
1485 txfee = extendedStake ? DEFAULT_STAKE_TXFEE : 0;
1486 txNew.vin[0].prevout.hash = stakeSource.GetHash();
1487 txNew.vin[0].prevout.n = voutNum;
1489 if (whichType == TX_PUBKEY)
1491 txNew.vout[0].scriptPubKey << ToByteVector(vSolutions[0]) << OP_CHECKSIG;
1493 pk = CPubKey(vSolutions[0]);
1495 else if (whichType == TX_PUBKEYHASH)
1497 txNew.vout[0].scriptPubKey << OP_DUP << OP_HASH160 << ToByteVector(vSolutions[0]) << OP_EQUALVERIFY << OP_CHECKSIG;
1498 if (extendedStake && !pk.IsValid())
1500 // we need a pubkey, so try to get one from the key ID, if not there, fail
1501 if (!keystore.GetPubKey(CKeyID(uint160(vSolutions[0])), pk))
1508 // if we are staking with the extended format, add the opreturn data required
1511 // set expiry to time out after 100 blocks, so we can remove the transaction if it orphans
1512 txNew.nExpiryHeight = stakeHeight + 100;
1514 uint256 srcBlock = uint256();
1515 CBlockIndex *pSrcIndex;
1517 txNew.vout.push_back(CTxOut());
1518 CTxOut &txOut1 = txNew.vout[1];
1520 if (!GetTransaction(stakeSource.GetHash(), stakeSource, srcBlock))
1523 BlockMap::const_iterator it = mapBlockIndex.find(srcBlock);
1524 if (it == mapBlockIndex.end() || (pSrcIndex = it->second) == 0)
1527 // !! DISABLE THIS FOR RELEASE: THIS MAKES A CHEAT TRANSACTION FOR EVERY STAKE FOR TESTING
1528 //CMutableTransaction cheat;
1529 //cheat = CMutableTransaction(txNew);
1530 //printf("TESTING ONLY: THIS SHOULD NOT BE ENABLED FOR RELEASE - MAKING CHEAT TRANSACTION FOR TESTING\n");
1531 //cheat.vout[1].scriptPubKey << OP_RETURN
1532 // << CStakeParams(pSrcIndex->GetHeight(), tipindex->GetHeight() + 1, pSrcIndex->GetBlockHash(), pk).AsVector();
1535 txOut1.scriptPubKey << OP_RETURN
1536 << CStakeParams(pSrcIndex->GetHeight(), tipindex->GetHeight() + 1, tipindex->GetBlockHash(), pk).AsVector();
1538 // !! DISABLE THIS FOR RELEASE: REMOVE THIS TOO
1539 //nValue = cheat.vout[0].nValue = stakeSource.vout[voutNum].nValue - txfee;
1540 //cheat.nLockTime = 0;
1541 //CTransaction cheatConst(cheat);
1542 //SignatureData cheatSig;
1543 //if (!ProduceSignature(TransactionSignatureCreator(&keystore, &cheatConst, 0, nValue, SIGHASH_ALL), stakeSource.vout[voutNum].scriptPubKey, cheatSig, consensusBranchId))
1544 // fprintf(stderr,"failed to create cheat test signature\n");
1548 // UpdateTransaction(cheat,0,cheatSig);
1549 // cheatList.Add(CTxHolder(CTransaction(cheat), tipindex->GetHeight() + 1));
1554 nValue = txNew.vout[0].nValue = stakeSource.vout[voutNum].nValue - txfee;
1556 txNew.nLockTime = 0;
1557 CTransaction txNewConst(txNew);
1558 signSuccess = ProduceSignature(TransactionSignatureCreator(&keystore, &txNewConst, 0, nValue, SIGHASH_ALL), stakeSource.vout[voutNum].scriptPubKey, sigdata, consensusBranchId);
1560 fprintf(stderr,"failed to create signature\n");
1564 UpdateTransaction(txNew,0,sigdata);
1565 ptr = (uint8_t *)&sigdata.scriptSig[0];
1566 siglen = sigdata.scriptSig.size();
1567 for (int i=0; i<siglen; i++)
1568 utxosig[i] = ptr[i];//, fprintf(stderr,"%02x",ptr[i]);
1573 void CWallet::MarkDirty()
1577 BOOST_FOREACH(PAIRTYPE(const uint256, CWalletTx)& item, mapWallet)
1578 item.second.MarkDirty();
1583 * Ensure that every note in the wallet (for which we possess a spending key)
1584 * has a cached nullifier.
1586 bool CWallet::UpdateNullifierNoteMap()
1594 ZCNoteDecryption dec;
1595 for (std::pair<const uint256, CWalletTx>& wtxItem : mapWallet) {
1596 for (mapSproutNoteData_t::value_type& item : wtxItem.second.mapSproutNoteData) {
1597 if (!item.second.nullifier) {
1598 if (GetNoteDecryptor(item.second.address, dec)) {
1599 auto i = item.first.js;
1600 auto hSig = wtxItem.second.vjoinsplit[i].h_sig(
1601 *pzcashParams, wtxItem.second.joinSplitPubKey);
1602 item.second.nullifier = GetSproutNoteNullifier(
1603 wtxItem.second.vjoinsplit[i],
1604 item.second.address,
1612 // TODO: Sapling. This method is only called from RPC walletpassphrase, which is currently unsupported
1613 // as RPC encryptwallet is hidden behind two flags: -developerencryptwallet -experimentalfeatures
1615 UpdateNullifierNoteMapWithTx(wtxItem.second);
1622 * Update mapSproutNullifiersToNotes and mapSaplingNullifiersToNotes
1623 * with the cached nullifiers in this tx.
1625 void CWallet::UpdateNullifierNoteMapWithTx(const CWalletTx& wtx)
1629 for (const mapSproutNoteData_t::value_type& item : wtx.mapSproutNoteData) {
1630 if (item.second.nullifier) {
1631 mapSproutNullifiersToNotes[*item.second.nullifier] = item.first;
1635 for (const mapSaplingNoteData_t::value_type& item : wtx.mapSaplingNoteData) {
1636 if (item.second.nullifier) {
1637 mapSaplingNullifiersToNotes[*item.second.nullifier] = item.first;
1644 * Update mapSaplingNullifiersToNotes, computing the nullifier from a cached witness if necessary.
1646 void CWallet::UpdateSaplingNullifierNoteMapWithTx(CWalletTx& wtx) {
1649 for (mapSaplingNoteData_t::value_type &item : wtx.mapSaplingNoteData) {
1650 SaplingOutPoint op = item.first;
1651 SaplingNoteData nd = item.second;
1653 if (nd.witnesses.empty()) {
1654 // If there are no witnesses, erase the nullifier and associated mapping.
1655 if (item.second.nullifier) {
1656 mapSaplingNullifiersToNotes.erase(item.second.nullifier.get());
1658 item.second.nullifier = boost::none;
1661 uint64_t position = nd.witnesses.front().position();
1662 SaplingFullViewingKey fvk = mapSaplingFullViewingKeys.at(nd.ivk);
1663 OutputDescription output = wtx.vShieldedOutput[op.n];
1664 auto optPlaintext = SaplingNotePlaintext::decrypt(output.encCiphertext, nd.ivk, output.ephemeralKey, output.cm);
1665 if (!optPlaintext) {
1666 // An item in mapSaplingNoteData must have already been successfully decrypted,
1667 // otherwise the item would not exist in the first place.
1670 auto optNote = optPlaintext.get().note(nd.ivk);
1674 auto optNullifier = optNote.get().nullifier(fvk, position);
1675 if (!optNullifier) {
1676 // This should not happen. If it does, maybe the position has been corrupted or miscalculated?
1679 uint256 nullifier = optNullifier.get();
1680 mapSaplingNullifiersToNotes[nullifier] = op;
1681 item.second.nullifier = nullifier;
1687 * Iterate over transactions in a block and update the cached Sapling nullifiers
1688 * for transactions which belong to the wallet.
1690 void CWallet::UpdateSaplingNullifierNoteMapForBlock(const CBlock *pblock) {
1693 for (const CTransaction& tx : pblock->vtx) {
1694 auto hash = tx.GetHash();
1695 bool txIsOurs = mapWallet.count(hash);
1697 UpdateSaplingNullifierNoteMapWithTx(mapWallet[hash]);
1702 bool CWallet::AddToWallet(const CWalletTx& wtxIn, bool fFromLoadWallet, CWalletDB* pwalletdb)
1704 uint256 hash = wtxIn.GetHash();
1706 if (fFromLoadWallet)
1708 mapWallet[hash] = wtxIn;
1709 mapWallet[hash].BindWallet(this);
1710 UpdateNullifierNoteMapWithTx(mapWallet[hash]);
1716 // Inserts only if not already there, returns tx inserted or tx found
1717 pair<map<uint256, CWalletTx>::iterator, bool> ret = mapWallet.insert(make_pair(hash, wtxIn));
1718 CWalletTx& wtx = (*ret.first).second;
1719 wtx.BindWallet(this);
1720 UpdateNullifierNoteMapWithTx(wtx);
1721 bool fInsertedNew = ret.second;
1724 wtx.nTimeReceived = GetAdjustedTime();
1725 wtx.nOrderPos = IncOrderPosNext(pwalletdb);
1727 wtx.nTimeSmart = wtx.nTimeReceived;
1728 if (!wtxIn.hashBlock.IsNull())
1730 if (mapBlockIndex.count(wtxIn.hashBlock))
1732 int64_t latestNow = wtx.nTimeReceived;
1733 int64_t latestEntry = 0;
1735 // Tolerate times up to the last timestamp in the wallet not more than 5 minutes into the future
1736 int64_t latestTolerated = latestNow + 300;
1737 std::list<CAccountingEntry> acentries;
1738 TxItems txOrdered = OrderedTxItems(acentries);
1739 for (TxItems::reverse_iterator it = txOrdered.rbegin(); it != txOrdered.rend(); ++it)
1741 CWalletTx *const pwtx = (*it).second.first;
1744 CAccountingEntry *const pacentry = (*it).second.second;
1748 nSmartTime = pwtx->nTimeSmart;
1750 nSmartTime = pwtx->nTimeReceived;
1753 nSmartTime = pacentry->nTime;
1754 if (nSmartTime <= latestTolerated)
1756 latestEntry = nSmartTime;
1757 if (nSmartTime > latestNow)
1758 latestNow = nSmartTime;
1764 int64_t blocktime = mapBlockIndex[wtxIn.hashBlock]->GetBlockTime();
1765 wtx.nTimeSmart = std::max(latestEntry, std::min(blocktime, latestNow));
1768 LogPrintf("AddToWallet(): found %s in block %s not in index\n",
1769 wtxIn.GetHash().ToString(),
1770 wtxIn.hashBlock.ToString());
1775 bool fUpdated = false;
1779 if (!wtxIn.hashBlock.IsNull() && wtxIn.hashBlock != wtx.hashBlock)
1781 wtx.hashBlock = wtxIn.hashBlock;
1784 if (wtxIn.nIndex != -1 && (wtxIn.vMerkleBranch != wtx.vMerkleBranch || wtxIn.nIndex != wtx.nIndex))
1786 wtx.vMerkleBranch = wtxIn.vMerkleBranch;
1787 wtx.nIndex = wtxIn.nIndex;
1790 if (UpdatedNoteData(wtxIn, wtx)) {
1793 if (wtxIn.fFromMe && wtxIn.fFromMe != wtx.fFromMe)
1795 wtx.fFromMe = wtxIn.fFromMe;
1801 LogPrintf("AddToWallet %s %s%s\n", wtxIn.GetHash().ToString(), (fInsertedNew ? "new" : ""), (fUpdated ? "update" : ""));
1804 if (fInsertedNew || fUpdated)
1805 if (!wtx.WriteToDisk(pwalletdb))
1808 // Break debit/credit balance caches:
1811 // Notify UI of new or updated transaction
1812 NotifyTransactionChanged(this, hash, fInsertedNew ? CT_NEW : CT_UPDATED);
1814 // notify an external script when a wallet transaction comes in or is updated
1815 std::string strCmd = GetArg("-walletnotify", "");
1817 if ( !strCmd.empty())
1819 boost::replace_all(strCmd, "%s", wtxIn.GetHash().GetHex());
1820 boost::thread t(runCommand, strCmd); // thread runs free
1827 bool CWallet::UpdatedNoteData(const CWalletTx& wtxIn, CWalletTx& wtx)
1829 bool unchangedSproutFlag = (wtxIn.mapSproutNoteData.empty() || wtxIn.mapSproutNoteData == wtx.mapSproutNoteData);
1830 if (!unchangedSproutFlag) {
1831 auto tmp = wtxIn.mapSproutNoteData;
1832 // Ensure we keep any cached witnesses we may already have
1833 for (const std::pair <JSOutPoint, SproutNoteData> nd : wtx.mapSproutNoteData) {
1834 if (tmp.count(nd.first) && nd.second.witnesses.size() > 0) {
1835 tmp.at(nd.first).witnesses.assign(
1836 nd.second.witnesses.cbegin(), nd.second.witnesses.cend());
1838 tmp.at(nd.first).witnessHeight = nd.second.witnessHeight;
1840 // Now copy over the updated note data
1841 wtx.mapSproutNoteData = tmp;
1844 bool unchangedSaplingFlag = (wtxIn.mapSaplingNoteData.empty() || wtxIn.mapSaplingNoteData == wtx.mapSaplingNoteData);
1845 if (!unchangedSaplingFlag) {
1846 auto tmp = wtxIn.mapSaplingNoteData;
1847 // Ensure we keep any cached witnesses we may already have
1849 for (const std::pair <SaplingOutPoint, SaplingNoteData> nd : wtx.mapSaplingNoteData) {
1850 if (tmp.count(nd.first) && nd.second.witnesses.size() > 0) {
1851 tmp.at(nd.first).witnesses.assign(
1852 nd.second.witnesses.cbegin(), nd.second.witnesses.cend());
1854 tmp.at(nd.first).witnessHeight = nd.second.witnessHeight;
1857 // Now copy over the updated note data
1858 wtx.mapSaplingNoteData = tmp;
1861 return !unchangedSproutFlag || !unchangedSaplingFlag;
1865 * Add a transaction to the wallet, or update it.
1866 * pblock is optional, but should be provided if the transaction is known to be in a block.
1867 * If fUpdate is true, existing transactions will be updated.
1869 bool CWallet::AddToWalletIfInvolvingMe(const CTransaction& tx, const CBlock* pblock, bool fUpdate)
1872 AssertLockHeld(cs_wallet);
1873 bool fExisted = mapWallet.count(tx.GetHash()) != 0;
1874 if (fExisted && !fUpdate) return false;
1875 auto sproutNoteData = FindMySproutNotes(tx);
1876 auto saplingNoteDataAndAddressesToAdd = FindMySaplingNotes(tx);
1877 auto saplingNoteData = saplingNoteDataAndAddressesToAdd.first;
1878 auto addressesToAdd = saplingNoteDataAndAddressesToAdd.second;
1879 for (const auto &addressToAdd : addressesToAdd) {
1880 if (!AddSaplingIncomingViewingKey(addressToAdd.second, addressToAdd.first)) {
1884 if (fExisted || IsMine(tx) || IsFromMe(tx) || sproutNoteData.size() > 0 || saplingNoteData.size() > 0)
1886 CWalletTx wtx(this,tx);
1888 if (sproutNoteData.size() > 0) {
1889 wtx.SetSproutNoteData(sproutNoteData);
1892 if (saplingNoteData.size() > 0) {
1893 wtx.SetSaplingNoteData(saplingNoteData);
1896 // Get merkle branch if transaction was found in a block
1898 wtx.SetMerkleBranch(*pblock);
1900 // Do not flush the wallet here for performance reasons
1901 // this is safe, as in case of a crash, we rescan the necessary blocks on startup through our SetBestChain-mechanism
1902 CWalletDB walletdb(strWalletFile, "r+", false);
1904 return AddToWallet(wtx, false, &walletdb);
1910 void CWallet::SyncTransaction(const CTransaction& tx, const CBlock* pblock)
1912 LOCK2(cs_main, cs_wallet);
1913 if (!AddToWalletIfInvolvingMe(tx, pblock, true))
1914 return; // Not one of ours
1916 MarkAffectedTransactionsDirty(tx);
1919 void CWallet::MarkAffectedTransactionsDirty(const CTransaction& tx)
1921 // If a transaction changes 'conflicted' state, that changes the balance
1922 // available of the outputs it spends. So force those to be
1923 // recomputed, also:
1924 BOOST_FOREACH(const CTxIn& txin, tx.vin)
1926 if (mapWallet.count(txin.prevout.hash))
1927 mapWallet[txin.prevout.hash].MarkDirty();
1929 for (const JSDescription& jsdesc : tx.vjoinsplit) {
1930 for (const uint256& nullifier : jsdesc.nullifiers) {
1931 if (mapSproutNullifiersToNotes.count(nullifier) &&
1932 mapWallet.count(mapSproutNullifiersToNotes[nullifier].hash)) {
1933 mapWallet[mapSproutNullifiersToNotes[nullifier].hash].MarkDirty();
1938 for (const SpendDescription &spend : tx.vShieldedSpend) {
1939 uint256 nullifier = spend.nullifier;
1940 if (mapSaplingNullifiersToNotes.count(nullifier) &&
1941 mapWallet.count(mapSaplingNullifiersToNotes[nullifier].hash)) {
1942 mapWallet[mapSaplingNullifiersToNotes[nullifier].hash].MarkDirty();
1947 void CWallet::EraseFromWallet(const uint256 &hash)
1953 if (mapWallet.erase(hash))
1954 CWalletDB(strWalletFile).EraseTx(hash);
1959 void CWallet::RescanWallet()
1963 CBlockIndex *start = chainActive.Height() > 0 ? chainActive[1] : NULL;
1965 ScanForWalletTransactions(start, true);
1966 needsRescan = false;
1972 * Returns a nullifier if the SpendingKey is available
1973 * Throws std::runtime_error if the decryptor doesn't match this note
1975 boost::optional<uint256> CWallet::GetSproutNoteNullifier(const JSDescription &jsdesc,
1976 const libzcash::SproutPaymentAddress &address,
1977 const ZCNoteDecryption &dec,
1978 const uint256 &hSig,
1981 boost::optional<uint256> ret;
1982 auto note_pt = libzcash::SproutNotePlaintext::decrypt(
1984 jsdesc.ciphertexts[n],
1985 jsdesc.ephemeralKey,
1988 auto note = note_pt.note(address);
1989 // SpendingKeys are only available if:
1990 // - We have them (this isn't a viewing key)
1991 // - The wallet is unlocked
1992 libzcash::SproutSpendingKey key;
1993 if (GetSproutSpendingKey(address, key)) {
1994 ret = note.nullifier(key);
2000 * Finds all output notes in the given transaction that have been sent to
2001 * PaymentAddresses in this wallet.
2003 * It should never be necessary to call this method with a CWalletTx, because
2004 * the result of FindMySproutNotes (for the addresses available at the time) will
2005 * already have been cached in CWalletTx.mapSproutNoteData.
2007 mapSproutNoteData_t CWallet::FindMySproutNotes(const CTransaction &tx) const
2009 LOCK(cs_SpendingKeyStore);
2010 uint256 hash = tx.GetHash();
2012 mapSproutNoteData_t noteData;
2013 for (size_t i = 0; i < tx.vjoinsplit.size(); i++) {
2014 auto hSig = tx.vjoinsplit[i].h_sig(*pzcashParams, tx.joinSplitPubKey);
2015 for (uint8_t j = 0; j < tx.vjoinsplit[i].ciphertexts.size(); j++) {
2016 for (const NoteDecryptorMap::value_type& item : mapNoteDecryptors) {
2018 auto address = item.first;
2019 JSOutPoint jsoutpt {hash, i, j};
2020 auto nullifier = GetSproutNoteNullifier(
2026 SproutNoteData nd {address, *nullifier};
2027 noteData.insert(std::make_pair(jsoutpt, nd));
2029 SproutNoteData nd {address};
2030 noteData.insert(std::make_pair(jsoutpt, nd));
2033 } catch (const note_decryption_failed &err) {
2034 // Couldn't decrypt with this decryptor
2035 } catch (const std::exception &exc) {
2036 // Unexpected failure
2037 LogPrintf("FindMySproutNotes(): Unexpected error while testing decrypt:\n");
2038 LogPrintf("%s\n", exc.what());
2048 * Finds all output notes in the given transaction that have been sent to
2049 * SaplingPaymentAddresses in this wallet.
2051 * It should never be necessary to call this method with a CWalletTx, because
2052 * the result of FindMySaplingNotes (for the addresses available at the time) will
2053 * already have been cached in CWalletTx.mapSaplingNoteData.
2055 std::pair<mapSaplingNoteData_t, SaplingIncomingViewingKeyMap> CWallet::FindMySaplingNotes(const CTransaction &tx) const
2057 LOCK(cs_SpendingKeyStore);
2058 uint256 hash = tx.GetHash();
2060 mapSaplingNoteData_t noteData;
2061 SaplingIncomingViewingKeyMap viewingKeysToAdd;
2063 // Protocol Spec: 4.19 Block Chain Scanning (Sapling)
2064 for (uint32_t i = 0; i < tx.vShieldedOutput.size(); ++i) {
2065 const OutputDescription output = tx.vShieldedOutput[i];
2066 for (auto it = mapSaplingFullViewingKeys.begin(); it != mapSaplingFullViewingKeys.end(); ++it) {
2067 SaplingIncomingViewingKey ivk = it->first;
2068 auto result = SaplingNotePlaintext::decrypt(output.encCiphertext, ivk, output.ephemeralKey, output.cm);
2072 auto address = ivk.address(result.get().d);
2073 if (address && mapSaplingIncomingViewingKeys.count(address.get()) == 0) {
2074 viewingKeysToAdd[address.get()] = ivk;
2076 // We don't cache the nullifier here as computing it requires knowledge of the note position
2077 // in the commitment tree, which can only be determined when the transaction has been mined.
2078 SaplingOutPoint op {hash, i};
2081 noteData.insert(std::make_pair(op, nd));
2086 return std::make_pair(noteData, viewingKeysToAdd);
2089 bool CWallet::IsSproutNullifierFromMe(const uint256& nullifier) const
2093 if (mapSproutNullifiersToNotes.count(nullifier) &&
2094 mapWallet.count(mapSproutNullifiersToNotes.at(nullifier).hash)) {
2101 bool CWallet::IsSaplingNullifierFromMe(const uint256& nullifier) const
2105 if (mapSaplingNullifiersToNotes.count(nullifier) &&
2106 mapWallet.count(mapSaplingNullifiersToNotes.at(nullifier).hash)) {
2113 void CWallet::GetSproutNoteWitnesses(std::vector<JSOutPoint> notes,
2114 std::vector<boost::optional<SproutWitness>>& witnesses,
2115 uint256 &final_anchor)
2118 witnesses.resize(notes.size());
2119 boost::optional<uint256> rt;
2121 for (JSOutPoint note : notes) {
2122 if (mapWallet.count(note.hash) &&
2123 mapWallet[note.hash].mapSproutNoteData.count(note) &&
2124 mapWallet[note.hash].mapSproutNoteData[note].witnesses.size() > 0) {
2125 witnesses[i] = mapWallet[note.hash].mapSproutNoteData[note].witnesses.front();
2127 rt = witnesses[i]->root();
2129 assert(*rt == witnesses[i]->root());
2134 // All returned witnesses have the same anchor
2140 void CWallet::GetSaplingNoteWitnesses(std::vector<SaplingOutPoint> notes,
2141 std::vector<boost::optional<SaplingWitness>>& witnesses,
2142 uint256 &final_anchor)
2145 witnesses.resize(notes.size());
2146 boost::optional<uint256> rt;
2148 for (SaplingOutPoint note : notes) {
2149 if (mapWallet.count(note.hash) &&
2150 mapWallet[note.hash].mapSaplingNoteData.count(note) &&
2151 mapWallet[note.hash].mapSaplingNoteData[note].witnesses.size() > 0) {
2152 witnesses[i] = mapWallet[note.hash].mapSaplingNoteData[note].witnesses.front();
2154 rt = witnesses[i]->root();
2156 assert(*rt == witnesses[i]->root());
2161 // All returned witnesses have the same anchor
2167 isminetype CWallet::IsMine(const CTxIn &txin) const
2171 map<uint256, CWalletTx>::const_iterator mi = mapWallet.find(txin.prevout.hash);
2172 if (mi != mapWallet.end())
2174 const CWalletTx& prev = (*mi).second;
2175 if (txin.prevout.n < prev.vout.size())
2176 return (::IsMine(*this, prev.vout[txin.prevout.n].scriptPubKey));
2182 CAmount CWallet::GetDebit(const CTxIn &txin, const isminefilter& filter) const
2186 map<uint256, CWalletTx>::const_iterator mi = mapWallet.find(txin.prevout.hash);
2187 if (mi != mapWallet.end())
2189 const CWalletTx& prev = (*mi).second;
2190 if (txin.prevout.n < prev.vout.size())
2191 if (::IsMine(*this, prev.vout[txin.prevout.n].scriptPubKey) & filter)
2192 return prev.vout[txin.prevout.n].nValue; // komodo_interest?
2198 isminetype CWallet::IsMine(const CTxOut& txout) const
2200 return ::IsMine(*this, txout.scriptPubKey);
2203 CAmount CWallet::GetCredit(const CTxOut& txout, const isminefilter& filter) const
2205 if (!MoneyRange(txout.nValue))
2206 throw std::runtime_error("CWallet::GetCredit(): value out of range");
2207 return ((IsMine(txout) & filter) ? txout.nValue : 0);
2210 bool CWallet::IsChange(const CTxOut& txout) const
2212 // TODO: fix handling of 'change' outputs. The assumption is that any
2213 // payment to a script that is ours, but is not in the address book
2214 // is change. That assumption is likely to break when we implement multisignature
2215 // wallets that return change back into a multi-signature-protected address;
2216 // a better way of identifying which outputs are 'the send' and which are
2217 // 'the change' will need to be implemented (maybe extend CWalletTx to remember
2218 // which output, if any, was change).
2219 if (::IsMine(*this, txout.scriptPubKey))
2221 CTxDestination address;
2222 if (!ExtractDestination(txout.scriptPubKey, address))
2226 if (!mapAddressBook.count(address))
2232 CAmount CWallet::GetChange(const CTxOut& txout) const
2234 if (!MoneyRange(txout.nValue))
2235 throw std::runtime_error("CWallet::GetChange(): value out of range");
2236 return (IsChange(txout) ? txout.nValue : 0);
2239 typedef vector<unsigned char> valtype;
2240 unsigned int HaveKeys(const vector<valtype>& pubkeys, const CKeyStore& keystore);
2242 bool CWallet::IsMine(const CTransaction& tx)
2244 for (int i = 0; i < tx.vout.size(); i++)
2252 // special case handling for non-standard/Verus OP_RETURN script outputs, which need the transaction
2253 // to determine ownership
2254 isminetype CWallet::IsMine(const CTransaction& tx, uint32_t voutNum)
2256 vector<valtype> vSolutions;
2257 txnouttype whichType;
2258 const CScriptExt scriptPubKey = CScriptExt(tx.vout[voutNum].scriptPubKey);
2260 if (!Solver(scriptPubKey, whichType, vSolutions)) {
2261 if (this->HaveWatchOnly(scriptPubKey))
2262 return ISMINE_WATCH_ONLY;
2268 CScriptExt subscript;
2269 int voutNext = voutNum + 1;
2273 case TX_NONSTANDARD:
2277 case TX_CRYPTOCONDITION:
2278 // for now, default is that the first value returned will be the script, subsequent values will be
2279 // pubkeys. if we have the first pub key in our wallet, we consider this spendable
2280 if (vSolutions.size() > 1)
2282 keyID = CPubKey(vSolutions[1]).GetID();
2283 if (this->HaveKey(keyID))
2284 return ISMINE_SPENDABLE;
2289 keyID = CPubKey(vSolutions[0]).GetID();
2290 if (this->HaveKey(keyID))
2291 return ISMINE_SPENDABLE;
2295 keyID = CKeyID(uint160(vSolutions[0]));
2296 if (this->HaveKey(keyID))
2297 return ISMINE_SPENDABLE;
2301 scriptID = CScriptID(uint160(vSolutions[0]));
2302 if (this->GetCScript(scriptID, subscript))
2304 // if this is a CLTV, handle it differently
2305 if (subscript.IsCheckLockTimeVerify())
2307 return (::IsMine(*this, subscript));
2311 isminetype ret = ::IsMine(*this, subscript);
2312 if (ret == ISMINE_SPENDABLE)
2316 else if (tx.vout.size() > (voutNum + 1) &&
2317 tx.vout.back().scriptPubKey.size() > 7 &&
2318 tx.vout.back().scriptPubKey[0] == OP_RETURN)
2320 // get the opret script from next vout, verify that the front is CLTV and hash matches
2321 // if so, remove it and use the solver
2323 std::vector<uint8_t> opretData;
2324 CScript::const_iterator it = tx.vout.back().scriptPubKey.begin() + 1;
2325 if (tx.vout.back().scriptPubKey.GetOp2(it, op, &opretData))
2327 if (opretData.size() > 0 && opretData[0] == OPRETTYPE_TIMELOCK)
2329 CScript opretScript = CScript(opretData.begin() + 1, opretData.end());
2331 if (CScriptID(opretScript) == scriptID &&
2332 opretScript.IsCheckLockTimeVerify())
2334 // if we find that this is ours, we need to add this script to the wallet,
2335 // and we can then recognize this transaction
2336 isminetype t = ::IsMine(*this, opretScript);
2339 this->AddCScript(opretScript);
2349 // Only consider transactions "mine" if we own ALL the
2350 // keys involved. Multi-signature transactions that are
2351 // partially owned (somebody else has a key that can spend
2352 // them) enable spend-out-from-under-you attacks, especially
2353 // in shared-wallet situations.
2354 vector<valtype> keys(vSolutions.begin()+1, vSolutions.begin()+vSolutions.size()-1);
2355 if (HaveKeys(keys, *this) == keys.size())
2356 return ISMINE_SPENDABLE;
2360 if (this->HaveWatchOnly(scriptPubKey))
2361 return ISMINE_WATCH_ONLY;
2366 bool CWallet::IsFromMe(const CTransaction& tx) const
2368 if (GetDebit(tx, ISMINE_ALL) > 0) {
2371 for (const JSDescription& jsdesc : tx.vjoinsplit) {
2372 for (const uint256& nullifier : jsdesc.nullifiers) {
2373 if (IsSproutNullifierFromMe(nullifier)) {
2378 for (const SpendDescription &spend : tx.vShieldedSpend) {
2379 if (IsSaplingNullifierFromMe(spend.nullifier)) {
2386 CAmount CWallet::GetDebit(const CTransaction& tx, const isminefilter& filter) const
2389 BOOST_FOREACH(const CTxIn& txin, tx.vin)
2391 nDebit += GetDebit(txin, filter);
2392 if (!MoneyRange(nDebit))
2393 throw std::runtime_error("CWallet::GetDebit(): value out of range");
2398 CAmount CWallet::GetCredit(const CTransaction& tx, int32_t voutNum, const isminefilter& filter) const
2400 if (voutNum >= tx.vout.size() || !MoneyRange(tx.vout[voutNum].nValue))
2401 throw std::runtime_error("CWallet::GetCredit(): value out of range");
2402 return ((IsMine(tx.vout[voutNum]) & filter) ? tx.vout[voutNum].nValue : 0);
2405 CAmount CWallet::GetReserveCredit(const CTransaction& tx, int32_t voutNum, const isminefilter& filter) const
2407 return ((IsMine(tx.vout[voutNum]) & filter) ? tx.vout[voutNum].ReserveOutValue() : 0);
2410 CAmount CWallet::GetReserveCredit(const CTransaction& tx, const isminefilter& filter) const
2412 CAmount nCredit = 0;
2413 for (int i = 0; i < tx.vout.size(); i++)
2415 nCredit += GetReserveCredit(tx, i, filter);
2420 CAmount CWallet::GetCredit(const CTransaction& tx, const isminefilter& filter) const
2422 CAmount nCredit = 0;
2423 for (int i = 0; i < tx.vout.size(); i++)
2425 nCredit += GetCredit(tx, i, filter);
2430 CAmount CWallet::GetChange(const CTransaction& tx) const
2432 CAmount nChange = 0;
2433 BOOST_FOREACH(const CTxOut& txout, tx.vout)
2435 nChange += GetChange(txout);
2436 if (!MoneyRange(nChange))
2437 throw std::runtime_error("CWallet::GetChange(): value out of range");
2442 bool CWallet::IsHDFullyEnabled() const
2444 // Only Sapling addresses are HD for now
2448 void CWallet::GenerateNewSeed()
2452 auto seed = HDSeed::Random(HD_WALLET_SEED_LENGTH);
2454 int64_t nCreationTime = GetTime();
2456 // If the wallet is encrypted and locked, this will fail.
2457 if (!SetHDSeed(seed))
2458 throw std::runtime_error(std::string(__func__) + ": SetHDSeed failed");
2460 // store the key creation time together with
2461 // the child index counter in the database
2462 // as a hdchain object
2463 CHDChain newHdChain;
2464 newHdChain.nVersion = CHDChain::VERSION_HD_BASE;
2465 newHdChain.seedFp = seed.Fingerprint();
2466 newHdChain.nCreateTime = nCreationTime;
2467 SetHDChain(newHdChain, false);
2470 bool CWallet::SetHDSeed(const HDSeed& seed)
2472 if (!CCryptoKeyStore::SetHDSeed(seed)) {
2483 return CWalletDB(strWalletFile).WriteHDSeed(seed);
2489 bool CWallet::SetCryptedHDSeed(const uint256& seedFp, const std::vector<unsigned char> &vchCryptedSecret)
2491 if (!CCryptoKeyStore::SetCryptedHDSeed(seedFp, vchCryptedSecret)) {
2501 if (pwalletdbEncryption)
2502 return pwalletdbEncryption->WriteCryptedHDSeed(seedFp, vchCryptedSecret);
2504 return CWalletDB(strWalletFile).WriteCryptedHDSeed(seedFp, vchCryptedSecret);
2509 void CWallet::SetHDChain(const CHDChain& chain, bool memonly)
2512 if (!memonly && fFileBacked && !CWalletDB(strWalletFile).WriteHDChain(chain))
2513 throw std::runtime_error(std::string(__func__) + ": writing chain failed");
2518 bool CWallet::LoadHDSeed(const HDSeed& seed)
2520 return CBasicKeyStore::SetHDSeed(seed);
2523 bool CWallet::LoadCryptedHDSeed(const uint256& seedFp, const std::vector<unsigned char>& seed)
2525 return CCryptoKeyStore::SetCryptedHDSeed(seedFp, seed);
2528 void CWalletTx::SetSproutNoteData(mapSproutNoteData_t ¬eData)
2530 mapSproutNoteData.clear();
2531 for (const std::pair<JSOutPoint, SproutNoteData> nd : noteData) {
2532 if (nd.first.js < vjoinsplit.size() &&
2533 nd.first.n < vjoinsplit[nd.first.js].ciphertexts.size()) {
2534 // Store the address and nullifier for the Note
2535 mapSproutNoteData[nd.first] = nd.second;
2537 // If FindMySproutNotes() was used to obtain noteData,
2538 // this should never happen
2539 throw std::logic_error("CWalletTx::SetSproutNoteData(): Invalid note");
2544 void CWalletTx::SetSaplingNoteData(mapSaplingNoteData_t ¬eData)
2546 mapSaplingNoteData.clear();
2547 for (const std::pair<SaplingOutPoint, SaplingNoteData> nd : noteData) {
2548 if (nd.first.n < vShieldedOutput.size()) {
2549 mapSaplingNoteData[nd.first] = nd.second;
2551 throw std::logic_error("CWalletTx::SetSaplingNoteData(): Invalid note");
2556 int64_t CWalletTx::GetTxTime() const
2558 int64_t n = nTimeSmart;
2559 return n ? n : nTimeReceived;
2562 int CWalletTx::GetRequestCount() const
2564 // Returns -1 if it wasn't being tracked
2567 LOCK(pwallet->cs_wallet);
2571 if (!hashBlock.IsNull())
2573 map<uint256, int>::const_iterator mi = pwallet->mapRequestCount.find(hashBlock);
2574 if (mi != pwallet->mapRequestCount.end())
2575 nRequests = (*mi).second;
2580 // Did anyone request this transaction?
2581 map<uint256, int>::const_iterator mi = pwallet->mapRequestCount.find(GetHash());
2582 if (mi != pwallet->mapRequestCount.end())
2584 nRequests = (*mi).second;
2586 // How about the block it's in?
2587 if (nRequests == 0 && !hashBlock.IsNull())
2589 map<uint256, int>::const_iterator mi = pwallet->mapRequestCount.find(hashBlock);
2590 if (mi != pwallet->mapRequestCount.end())
2591 nRequests = (*mi).second;
2593 nRequests = 1; // If it's in someone else's block it must have got out
2601 // GetAmounts will determine the transparent debits and credits for a given wallet tx.
2602 void CWalletTx::GetAmounts(list<COutputEntry>& listReceived,
2603 list<COutputEntry>& listSent, CAmount& nFee, string& strSentAccount, const isminefilter& filter) const
2606 listReceived.clear();
2608 strSentAccount = strFromAccount;
2610 // Is this tx sent/signed by me?
2611 CAmount nDebit = GetDebit(filter);
2612 bool isFromMyTaddr = nDebit > 0; // debit>0 means we signed/sent this transaction
2614 // Compute fee if we sent this transaction.
2615 if (isFromMyTaddr) {
2616 CAmount nValueOut = GetValueOut(); // transparent outputs plus all Sprout vpub_old and negative Sapling valueBalance
2617 CAmount nValueIn = GetShieldedValueIn();
2618 nFee = nDebit - nValueOut + nValueIn;
2621 // Create output entry for vpub_old/new, if we sent utxos from this transaction
2622 if (isFromMyTaddr) {
2623 CAmount myVpubOld = 0;
2624 CAmount myVpubNew = 0;
2625 for (const JSDescription& js : vjoinsplit) {
2626 bool fMyJSDesc = false;
2629 for (const uint256& nullifier : js.nullifiers) {
2630 if (pwallet->IsSproutNullifierFromMe(nullifier)) {
2636 // Check output side
2638 for (const std::pair<JSOutPoint, SproutNoteData> nd : this->mapSproutNoteData) {
2639 if (nd.first.js < vjoinsplit.size() && nd.first.n < vjoinsplit[nd.first.js].ciphertexts.size()) {
2647 myVpubOld += js.vpub_old;
2648 myVpubNew += js.vpub_new;
2651 if (!MoneyRange(js.vpub_old) || !MoneyRange(js.vpub_new) || !MoneyRange(myVpubOld) || !MoneyRange(myVpubNew)) {
2652 throw std::runtime_error("CWalletTx::GetAmounts: value out of range");
2656 // Create an output for the value taken from or added to the transparent value pool by JoinSplits
2657 if (myVpubOld > myVpubNew) {
2658 COutputEntry output = {CNoDestination(), myVpubOld - myVpubNew, (int)vout.size()};
2659 listSent.push_back(output);
2660 } else if (myVpubNew > myVpubOld) {
2661 COutputEntry output = {CNoDestination(), myVpubNew - myVpubOld, (int)vout.size()};
2662 listReceived.push_back(output);
2666 // If we sent utxos from this transaction, create output for value taken from (negative valueBalance)
2667 // or added (positive valueBalance) to the transparent value pool by Sapling shielding and unshielding.
2668 if (isFromMyTaddr) {
2669 if (valueBalance < 0) {
2670 COutputEntry output = {CNoDestination(), -valueBalance, (int) vout.size()};
2671 listSent.push_back(output);
2672 } else if (valueBalance > 0) {
2673 COutputEntry output = {CNoDestination(), valueBalance, (int) vout.size()};
2674 listReceived.push_back(output);
2679 for (unsigned int i = 0; i < vout.size(); ++i)
2681 const CTxOut& txout = vout[i];
2682 isminetype fIsMine = pwallet->IsMine(txout);
2683 // Only need to handle txouts if AT LEAST one of these is true:
2684 // 1) they debit from us (sent)
2685 // 2) the output is to us (received)
2688 // Don't report 'change' txouts
2689 if (!(filter & ISMINE_CHANGE) && pwallet->IsChange(txout))
2692 else if (!(fIsMine & filter))
2695 // In either case, we need to get the destination address
2696 CTxDestination address;
2697 if (!ExtractDestination(txout.scriptPubKey, address))
2699 //LogPrintf("CWalletTx::GetAmounts: Unknown transaction type found, txid %s\n",this->GetHash().ToString()); complains on the opreturns
2700 address = CNoDestination();
2703 COutputEntry output = {address, txout.nValue, (int)i};
2705 // If we are debited by the transaction, add the output as a "sent" entry
2707 listSent.push_back(output);
2709 // If we are receiving the output, add it as a "received" entry
2710 if (fIsMine & filter)
2711 listReceived.push_back(output);
2716 void CWalletTx::GetAccountAmounts(const string& strAccount, CAmount& nReceived,
2717 CAmount& nSent, CAmount& nFee, const isminefilter& filter) const
2719 nReceived = nSent = nFee = 0;
2722 string strSentAccount;
2723 list<COutputEntry> listReceived;
2724 list<COutputEntry> listSent;
2725 GetAmounts(listReceived, listSent, allFee, strSentAccount, filter);
2727 if (strAccount == strSentAccount)
2729 BOOST_FOREACH(const COutputEntry& s, listSent)
2734 LOCK(pwallet->cs_wallet);
2735 BOOST_FOREACH(const COutputEntry& r, listReceived)
2737 if (pwallet->mapAddressBook.count(r.destination))
2739 map<CTxDestination, CAddressBookData>::const_iterator mi = pwallet->mapAddressBook.find(r.destination);
2740 if (mi != pwallet->mapAddressBook.end() && (*mi).second.name == strAccount)
2741 nReceived += r.amount;
2743 else if (strAccount.empty())
2745 nReceived += r.amount;
2752 bool CWalletTx::WriteToDisk(CWalletDB *pwalletdb)
2754 return pwalletdb->WriteTx(GetHash(), *this);
2757 void CWallet::WitnessNoteCommitment(std::vector<uint256> commitments,
2758 std::vector<boost::optional<SproutWitness>>& witnesses,
2759 uint256 &final_anchor)
2761 witnesses.resize(commitments.size());
2762 CBlockIndex* pindex = chainActive.Genesis();
2763 SproutMerkleTree tree;
2767 ReadBlockFromDisk(block, pindex,1);
2769 BOOST_FOREACH(const CTransaction& tx, block.vtx)
2771 BOOST_FOREACH(const JSDescription& jsdesc, tx.vjoinsplit)
2773 BOOST_FOREACH(const uint256 ¬e_commitment, jsdesc.commitments)
2775 tree.append(note_commitment);
2777 BOOST_FOREACH(boost::optional<SproutWitness>& wit, witnesses) {
2779 wit->append(note_commitment);
2784 BOOST_FOREACH(uint256& commitment, commitments) {
2785 if (note_commitment == commitment) {
2786 witnesses.at(i) = tree.witness();
2794 uint256 current_anchor = tree.root();
2796 // Consistency check: we should be able to find the current tree
2797 // in our CCoins view.
2798 SproutMerkleTree dummy_tree;
2799 assert(pcoinsTip->GetSproutAnchorAt(current_anchor, dummy_tree));
2801 pindex = chainActive.Next(pindex);
2804 // TODO: #93; Select a root via some heuristic.
2805 final_anchor = tree.root();
2807 BOOST_FOREACH(boost::optional<SproutWitness>& wit, witnesses) {
2809 assert(final_anchor == wit->root());
2815 * Scan the block chain (starting in pindexStart) for transactions
2816 * from or to us. If fUpdate is true, found transactions that already
2817 * exist in the wallet will be updated.
2819 int CWallet::ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate)
2822 int64_t nNow = GetTime();
2823 const CChainParams& chainParams = Params();
2825 CBlockIndex* pindex = pindexStart;
2827 std::vector<uint256> myTxHashes;
2830 LOCK2(cs_main, cs_wallet);
2832 // no need to read and scan block, if block was created before
2833 // our wallet birthday (as adjusted for block time variability)
2834 while (pindex && nTimeFirstKey && (pindex->GetBlockTime() < (nTimeFirstKey - 7200)))
2835 pindex = chainActive.Next(pindex);
2837 ShowProgress(_("Rescanning..."), 0); // show rescan progress in GUI as dialog or on splashscreen, if -rescan on startup
2838 double dProgressStart = Checkpoints::GuessVerificationProgress(chainParams.Checkpoints(), pindex, false);
2839 double dProgressTip = Checkpoints::GuessVerificationProgress(chainParams.Checkpoints(), chainActive.LastTip(), false);
2842 if (pindex->GetHeight() % 100 == 0 && dProgressTip - dProgressStart > 0.0)
2843 ShowProgress(_("Rescanning..."), std::max(1, std::min(99, (int)((Checkpoints::GuessVerificationProgress(chainParams.Checkpoints(), pindex, false) - dProgressStart) / (dProgressTip - dProgressStart) * 100))));
2846 ReadBlockFromDisk(block, pindex,1);
2847 BOOST_FOREACH(CTransaction& tx, block.vtx)
2849 if (AddToWalletIfInvolvingMe(tx, &block, fUpdate)) {
2850 myTxHashes.push_back(tx.GetHash());
2855 SproutMerkleTree sproutTree;
2856 SaplingMerkleTree saplingTree;
2857 // This should never fail: we should always be able to get the tree
2858 // state on the path to the tip of our chain
2859 assert(pcoinsTip->GetSproutAnchorAt(pindex->hashSproutAnchor, sproutTree));
2860 if (pindex->pprev) {
2861 if (NetworkUpgradeActive(pindex->pprev->GetHeight(), Params().GetConsensus(), Consensus::UPGRADE_SAPLING)) {
2862 assert(pcoinsTip->GetSaplingAnchorAt(pindex->pprev->hashFinalSaplingRoot, saplingTree));
2865 // Increment note witness caches
2866 ChainTip(pindex, &block, sproutTree, saplingTree, true);
2868 pindex = chainActive.Next(pindex);
2869 if (GetTime() >= nNow + 60) {
2871 LogPrintf("Still rescanning. At block %d. Progress=%f\n", pindex->GetHeight(), Checkpoints::GuessVerificationProgress(chainParams.Checkpoints(), pindex));
2875 // After rescanning, persist Sapling note data that might have changed, e.g. nullifiers.
2876 // Do not flush the wallet here for performance reasons.
2877 CWalletDB walletdb(strWalletFile, "r+", false);
2878 for (auto hash : myTxHashes) {
2879 CWalletTx wtx = mapWallet[hash];
2880 if (!wtx.mapSaplingNoteData.empty()) {
2881 if (!wtx.WriteToDisk(&walletdb)) {
2882 LogPrintf("Rescanning... WriteToDisk failed to update Sapling note data for: %s\n", hash.ToString());
2887 ShowProgress(_("Rescanning..."), 100); // hide progress dialog in GUI
2892 void CWallet::ReacceptWalletTransactions()
2894 // If transactions aren't being broadcasted, don't let them into local mempool either
2895 if (!fBroadcastTransactions)
2897 LOCK2(cs_main, cs_wallet);
2898 std::map<int64_t, CWalletTx*> mapSorted;
2900 // Sort pending wallet transactions based on their initial wallet insertion order
2901 BOOST_FOREACH(PAIRTYPE(const uint256, CWalletTx)& item, mapWallet)
2903 const uint256& wtxid = item.first;
2904 CWalletTx& wtx = item.second;
2905 assert(wtx.GetHash() == wtxid);
2907 int nDepth = wtx.GetDepthInMainChain();
2909 if (!wtx.IsCoinBase() && nDepth < 0) {
2910 mapSorted.insert(std::make_pair(wtx.nOrderPos, &wtx));
2914 std::vector<uint256> vwtxh;
2916 // Try to add wallet transactions to memory pool
2917 BOOST_FOREACH(PAIRTYPE(const int64_t, CWalletTx*)& item, mapSorted)
2919 CWalletTx& wtx = *(item.second);
2922 CValidationState state;
2923 // attempt to add them, but don't set any DOS level
2924 if (!::AcceptToMemoryPool(mempool, state, wtx, false, NULL, true, 0))
2927 bool invalid = state.IsInvalid(nDoS);
2929 // log rejection and deletion
2930 // printf("ERROR reaccepting wallet transaction %s to mempool, reason: %s, DoS: %d\n", wtx.GetHash().ToString().c_str(), state.GetRejectReason().c_str(), nDoS);
2932 if (!wtx.IsCoinBase() && invalid && nDoS > 0)
2934 LogPrintf("erasing transaction %s\n", wtx.GetHash().GetHex().c_str());
2935 vwtxh.push_back(wtx.GetHash());
2939 for (auto hash : vwtxh)
2941 EraseFromWallet(hash);
2945 bool CWalletTx::RelayWalletTransaction()
2949 fprintf(stderr,"unexpected null pwallet in RelayWalletTransaction\n");
2952 assert(pwallet->GetBroadcastTransactions());
2955 if (GetDepthInMainChain() == 0)
2957 // if tx is expired, dont relay
2958 LogPrintf("Relaying wtx %s\n", GetHash().ToString());
2959 RelayTransaction((CTransaction)*this);
2966 set<uint256> CWalletTx::GetConflicts() const
2968 set<uint256> result;
2969 if (pwallet != NULL)
2971 uint256 myHash = GetHash();
2972 result = pwallet->GetConflicts(myHash);
2973 result.erase(myHash);
2978 CAmount CWalletTx::GetDebit(const isminefilter& filter) const
2984 if(filter & ISMINE_SPENDABLE)
2987 debit += nDebitCached;
2990 nDebitCached = pwallet->GetDebit(*this, ISMINE_SPENDABLE);
2991 fDebitCached = true;
2992 debit += nDebitCached;
2995 if(filter & ISMINE_WATCH_ONLY)
2997 if(fWatchDebitCached)
2998 debit += nWatchDebitCached;
3001 nWatchDebitCached = pwallet->GetDebit(*this, ISMINE_WATCH_ONLY);
3002 fWatchDebitCached = true;
3003 debit += nWatchDebitCached;
3009 CAmount CWalletTx::GetReserveDebit(const isminefilter& filter) const
3015 if(filter & ISMINE_SPENDABLE)
3017 if (fReserveDebitCached)
3018 debit += nReserveDebitCached;
3021 nReserveDebitCached = pwallet->GetDebit(*this, ISMINE_SPENDABLE);
3022 fReserveDebitCached = true;
3023 debit += nReserveDebitCached;
3026 if(filter & ISMINE_WATCH_ONLY)
3028 if(fWatchReserveDebitCached)
3029 debit += nWatchReserveDebitCached;
3032 nWatchReserveDebitCached = pwallet->GetDebit(*this, ISMINE_WATCH_ONLY);
3033 fWatchReserveDebitCached = true;
3034 debit += nWatchReserveDebitCached;
3040 CAmount CWalletTx::GetCredit(const isminefilter& filter) const
3042 // Must wait until coinbase is safely deep enough in the chain before valuing it
3043 if (IsCoinBase() && GetBlocksToMaturity() > 0)
3047 if (filter & ISMINE_SPENDABLE)
3049 // GetBalance can assume transactions in mapWallet won't change
3051 credit += nCreditCached;
3054 nCreditCached = pwallet->GetCredit(*this, ISMINE_SPENDABLE);
3055 fCreditCached = true;
3056 credit += nCreditCached;
3059 if (filter & ISMINE_WATCH_ONLY)
3061 if (fWatchCreditCached)
3062 credit += nWatchCreditCached;
3065 nWatchCreditCached = pwallet->GetCredit(*this, ISMINE_WATCH_ONLY);
3066 fWatchCreditCached = true;
3067 credit += nWatchCreditCached;
3073 bool CWalletTx::HasMatureCoins() const
3075 // Must wait until coinbase is safely deep enough in the chain before valuing it
3076 if (!(IsCoinBase() && GetBlocksToMaturity() > 0))
3082 for (auto oneout : vout)
3084 if (oneout.scriptPubKey.IsInstantSpend())
3093 CAmount CWalletTx::GetReserveCredit(const isminefilter& filter) const
3095 // Must wait until coinbase is safely deep enough in the chain before valuing it
3096 if (IsCoinBase() && GetBlocksToMaturity() > 0)
3100 if (filter & ISMINE_SPENDABLE)
3102 // GetBalance can assume transactions in mapWallet won't change
3103 if (fReserveCreditCached)
3104 credit += nReserveCreditCached;
3107 nReserveCreditCached = pwallet->GetReserveCredit(*this, ISMINE_SPENDABLE);
3108 fReserveCreditCached = true;
3109 credit += nReserveCreditCached;
3112 if (filter & ISMINE_WATCH_ONLY)
3114 if (fWatchReserveCreditCached)
3115 credit += nWatchReserveCreditCached;
3118 nWatchReserveCreditCached = pwallet->GetReserveCredit(*this, ISMINE_WATCH_ONLY);
3119 fWatchReserveCreditCached = true;
3120 credit += nWatchReserveCreditCached;
3126 CAmount CWalletTx::GetImmatureCredit(bool fUseCache) const
3128 if (IsCoinBase() && GetBlocksToMaturity() > 0 && IsInMainChain())
3130 if (fUseCache && fImmatureCreditCached)
3131 return nImmatureCreditCached;
3132 nImmatureCreditCached = pwallet->GetCredit(*this, ISMINE_SPENDABLE);
3133 fImmatureCreditCached = true;
3134 return nImmatureCreditCached;
3140 CAmount CWalletTx::GetImmatureReserveCredit(bool fUseCache) const
3142 if (IsCoinBase() && GetBlocksToMaturity() > 0 && IsInMainChain())
3144 if (fUseCache && fImmatureReserveCreditCached)
3145 return nImmatureReserveCreditCached;
3146 nImmatureReserveCreditCached = pwallet->GetReserveCredit(*this, ISMINE_SPENDABLE);
3147 fImmatureReserveCreditCached = true;
3148 return nImmatureReserveCreditCached;
3154 CAmount CWalletTx::GetAvailableCredit(bool fUseCache) const
3159 // Must wait until coinbase is safely deep enough in the chain before valuing it
3160 if (IsCoinBase() && GetBlocksToMaturity() > 0)
3163 if (fUseCache && fAvailableCreditCached)
3164 return nAvailableCreditCached;
3166 CAmount nCredit = 0;
3167 uint256 hashTx = GetHash();
3168 for (unsigned int i = 0; i < vout.size(); i++)
3170 if (!pwallet->IsSpent(hashTx, i))
3172 nCredit += pwallet->GetCredit(*this, i, ISMINE_SPENDABLE);
3173 if (!MoneyRange(nCredit))
3174 throw std::runtime_error("CWalletTx::GetAvailableCredit() : value out of range");
3178 nAvailableCreditCached = nCredit;
3179 fAvailableCreditCached = true;
3183 CAmount CWalletTx::GetAvailableReserveCredit(bool fUseCache) const
3188 // Must wait until coinbase is safely deep enough in the chain before valuing it
3189 if (IsCoinBase() && GetBlocksToMaturity() > 0)
3192 if (fUseCache && fAvailableReserveCreditCached)
3193 return nAvailableReserveCreditCached;
3195 CAmount nCredit = 0;
3196 uint256 hashTx = GetHash();
3197 for (unsigned int i = 0; i < vout.size(); i++)
3199 if (!pwallet->IsSpent(hashTx, i))
3201 nCredit += pwallet->GetReserveCredit(*this, i, ISMINE_SPENDABLE);
3205 nAvailableReserveCreditCached = nCredit;
3206 fAvailableReserveCreditCached = true;
3210 CAmount CWalletTx::GetImmatureWatchOnlyCredit(const bool& fUseCache) const
3212 if (IsCoinBase() && GetBlocksToMaturity() > 0 && IsInMainChain())
3214 if (fUseCache && fImmatureWatchCreditCached)
3215 return nImmatureWatchCreditCached;
3216 nImmatureWatchCreditCached = pwallet->GetCredit(*this, ISMINE_WATCH_ONLY);
3217 fImmatureWatchCreditCached = true;
3218 return nImmatureWatchCreditCached;
3224 CAmount CWalletTx::GetImmatureWatchOnlyReserveCredit(const bool& fUseCache) const
3226 if (IsCoinBase() && GetBlocksToMaturity() > 0 && IsInMainChain())
3228 if (fUseCache && fImmatureWatchReserveCreditCached)
3229 return nImmatureWatchReserveCreditCached;
3230 nImmatureWatchReserveCreditCached = pwallet->GetReserveCredit(*this, ISMINE_WATCH_ONLY);
3231 fImmatureWatchReserveCreditCached = true;
3232 return nImmatureWatchReserveCreditCached;
3238 CAmount CWalletTx::GetAvailableWatchOnlyCredit(const bool& fUseCache) const
3243 // Must wait until coinbase is safely deep enough in the chain before valuing it
3244 if (IsCoinBase() && GetBlocksToMaturity() > 0)
3247 if (fUseCache && fAvailableWatchCreditCached)
3248 return nAvailableWatchCreditCached;
3250 CAmount nCredit = 0;
3251 for (unsigned int i = 0; i < vout.size(); i++)
3253 if (!pwallet->IsSpent(GetHash(), i))
3255 nCredit += pwallet->GetCredit(*this, i, ISMINE_WATCH_ONLY);
3256 if (!MoneyRange(nCredit))
3257 throw std::runtime_error("CWalletTx::GetAvailableCredit() : value out of range");
3261 nAvailableWatchCreditCached = nCredit;
3262 fAvailableWatchCreditCached = true;
3266 CAmount CWalletTx::GetAvailableWatchOnlyReserveCredit(const bool& fUseCache) const
3271 // Must wait until coinbase is safely deep enough in the chain before valuing it
3272 if (IsCoinBase() && GetBlocksToMaturity() > 0)
3275 if (fUseCache && fAvailableWatchReserveCreditCached)
3276 return nAvailableWatchReserveCreditCached;
3278 CAmount nCredit = 0;
3279 for (unsigned int i = 0; i < vout.size(); i++)
3281 if (!pwallet->IsSpent(GetHash(), i))
3283 nCredit += pwallet->GetReserveCredit(*this, i, ISMINE_WATCH_ONLY);
3284 if (!MoneyRange(nCredit))
3285 throw std::runtime_error("CWalletTx::GetAvailableCredit() : value out of range");
3289 nAvailableWatchReserveCreditCached = nCredit;
3290 fAvailableWatchReserveCreditCached = true;
3294 CAmount CWalletTx::GetChange() const
3297 return nChangeCached;
3298 nChangeCached = pwallet->GetChange(*this);
3299 fChangeCached = true;
3300 return nChangeCached;
3303 bool CWalletTx::IsTrusted() const
3305 // Quick answer in most cases
3306 if (!CheckFinalTx(*this))
3308 int nDepth = GetDepthInMainChain();
3313 if (!bSpendZeroConfChange || !IsFromMe(ISMINE_ALL)) // using wtx's cached debit
3316 // Trusted if all inputs are from us and are in the mempool:
3317 BOOST_FOREACH(const CTxIn& txin, vin)
3319 // Transactions not sent by us: not trusted
3320 const CWalletTx* parent = pwallet->GetWalletTx(txin.prevout.hash);
3323 const CTxOut& parentOut = parent->vout[txin.prevout.n];
3324 if (pwallet->IsMine(parentOut) != ISMINE_SPENDABLE)
3330 std::vector<uint256> CWallet::ResendWalletTransactionsBefore(int64_t nTime)
3332 std::vector<uint256> result;
3335 // Sort them in chronological order
3336 multimap<unsigned int, CWalletTx*> mapSorted;
3337 uint32_t now = (uint32_t)time(NULL);
3338 std::vector<uint256> vwtxh;
3339 BOOST_FOREACH(PAIRTYPE(const uint256, CWalletTx)& item, mapWallet)
3341 CWalletTx& wtx = item.second;
3342 // Don't rebroadcast if newer than nTime:
3343 if (wtx.nTimeReceived > nTime)
3345 if ( (wtx.nLockTime >= LOCKTIME_THRESHOLD && wtx.nLockTime < now-KOMODO_MAXMEMPOOLTIME) || wtx.hashBlock.IsNull() )
3347 //LogPrintf("skip Relaying wtx %s nLockTime %u vs now.%u\n", wtx.GetHash().ToString(),(uint32_t)wtx.nLockTime,now);
3348 //vwtxh.push_back(wtx.GetHash());
3351 mapSorted.insert(make_pair(wtx.nTimeReceived, &wtx));
3353 BOOST_FOREACH(PAIRTYPE(const unsigned int, CWalletTx*)& item, mapSorted)
3355 if ( item.second != 0 )
3357 CWalletTx &wtx = *item.second;
3358 if (wtx.RelayWalletTransaction())
3359 result.push_back(wtx.GetHash());
3362 for (auto hash : vwtxh)
3364 EraseFromWallets(hash);
3369 void CWallet::ResendWalletTransactions(int64_t nBestBlockTime)
3371 // Do this infrequently and randomly to avoid giving away
3372 // that these are our transactions.
3373 if (GetTime() < nNextResend || !fBroadcastTransactions)
3375 bool fFirst = (nNextResend == 0);
3376 nNextResend = GetTime() + GetRand(30 * 60);
3380 // Only do it if there's been a new block since last time
3381 if (nBestBlockTime < nLastResend)
3383 nLastResend = GetTime();
3385 // Rebroadcast unconfirmed txes older than 5 minutes before the last
3387 std::vector<uint256> relayed = ResendWalletTransactionsBefore(nBestBlockTime-5*60);
3388 if (!relayed.empty())
3389 LogPrintf("%s: rebroadcast %u unconfirmed transactions\n", __func__, relayed.size());
3392 /** @} */ // end of mapWallet
3397 /** @defgroup Actions
3403 CAmount CWallet::GetBalance() const
3407 LOCK2(cs_main, cs_wallet);
3408 for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
3410 const CWalletTx* pcoin = &(*it).second;
3411 if (pcoin->IsTrusted())
3412 nTotal += pcoin->GetAvailableCredit();
3419 CAmount CWallet::GetReserveBalance() const
3423 LOCK2(cs_main, cs_wallet);
3424 for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
3426 const CWalletTx* pcoin = &(*it).second;
3427 if (pcoin->IsTrusted())
3428 nTotal += pcoin->GetAvailableReserveCredit();
3435 CAmount CWallet::GetUnconfirmedBalance() const
3439 LOCK2(cs_main, cs_wallet);
3440 for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
3442 const CWalletTx* pcoin = &(*it).second;
3443 if (!CheckFinalTx(*pcoin) || (!pcoin->IsTrusted() && pcoin->GetDepthInMainChain() == 0))
3444 nTotal += pcoin->GetAvailableCredit();
3450 CAmount CWallet::GetUnconfirmedReserveBalance() const
3454 LOCK2(cs_main, cs_wallet);
3455 for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
3457 const CWalletTx* pcoin = &(*it).second;
3458 if (!CheckFinalTx(*pcoin) || (!pcoin->IsTrusted() && pcoin->GetDepthInMainChain() == 0))
3459 nTotal += pcoin->GetAvailableReserveCredit();
3465 CAmount CWallet::GetImmatureBalance() const
3469 LOCK2(cs_main, cs_wallet);
3470 for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
3472 const CWalletTx* pcoin = &(*it).second;
3473 nTotal += pcoin->GetImmatureCredit();
3479 CAmount CWallet::GetImmatureReserveBalance() const
3483 LOCK2(cs_main, cs_wallet);
3484 for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
3486 const CWalletTx* pcoin = &(*it).second;
3487 nTotal += pcoin->GetImmatureReserveCredit();
3493 CAmount CWallet::GetWatchOnlyBalance() const
3497 LOCK2(cs_main, cs_wallet);
3498 for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
3500 const CWalletTx* pcoin = &(*it).second;
3501 if (pcoin->IsTrusted())
3502 nTotal += pcoin->GetAvailableWatchOnlyCredit();
3509 CAmount CWallet::GetWatchOnlyReserveBalance() const
3513 LOCK2(cs_main, cs_wallet);
3514 for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
3516 const CWalletTx* pcoin = &(*it).second;
3517 if (pcoin->IsTrusted())
3518 nTotal += pcoin->GetAvailableWatchOnlyReserveCredit();
3525 CAmount CWallet::GetUnconfirmedWatchOnlyBalance() const
3529 LOCK2(cs_main, cs_wallet);
3530 for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
3532 const CWalletTx* pcoin = &(*it).second;
3533 if (!CheckFinalTx(*pcoin) || (!pcoin->IsTrusted() && pcoin->GetDepthInMainChain() == 0))
3534 nTotal += pcoin->GetAvailableWatchOnlyCredit();
3540 CAmount CWallet::GetUnconfirmedWatchOnlyReserveBalance() const
3544 LOCK2(cs_main, cs_wallet);
3545 for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
3547 const CWalletTx* pcoin = &(*it).second;
3548 if (!CheckFinalTx(*pcoin) || (!pcoin->IsTrusted() && pcoin->GetDepthInMainChain() == 0))
3549 nTotal += pcoin->GetAvailableWatchOnlyReserveCredit();
3555 CAmount CWallet::GetImmatureWatchOnlyBalance() const
3559 LOCK2(cs_main, cs_wallet);
3560 for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
3562 const CWalletTx* pcoin = &(*it).second;
3563 nTotal += pcoin->GetImmatureWatchOnlyCredit();
3569 CAmount CWallet::GetImmatureWatchOnlyReserveBalance() const
3573 LOCK2(cs_main, cs_wallet);
3574 for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
3576 const CWalletTx* pcoin = &(*it).second;
3577 nTotal += pcoin->GetImmatureWatchOnlyReserveCredit();
3584 * populate vCoins with vector of available COutputs.
3586 uint64_t komodo_interestnew(int32_t txheight,uint64_t nValue,uint32_t nLockTime,uint32_t tiptime);
3587 uint64_t komodo_accrued_interest(int32_t *txheightp,uint32_t *locktimep,uint256 hash,int32_t n,int32_t checkheight,uint64_t checkvalue,int32_t tipheight);
3589 void CWallet::AvailableCoins(vector<COutput>& vCoins, bool fOnlyConfirmed, const CCoinControl *coinControl, bool fIncludeZeroValue, bool fIncludeCoinBase) const
3591 uint64_t interest,*ptr;
3595 LOCK2(cs_main, cs_wallet);
3596 for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
3598 const uint256& wtxid = it->first;
3599 const CWalletTx* pcoin = &(*it).second;
3601 if (!CheckFinalTx(*pcoin))
3604 if (fOnlyConfirmed && !pcoin->IsTrusted())
3607 if (pcoin->IsCoinBase() && !fIncludeCoinBase)
3610 if (pcoin->IsCoinBase() && pcoin->GetBlocksToMaturity() > 0)
3613 int nDepth = pcoin->GetDepthInMainChain();
3617 for (int i = 0; i < pcoin->vout.size(); i++)
3619 isminetype mine = IsMine(pcoin->vout[i]);
3620 if (!(IsSpent(wtxid, i)) && mine != ISMINE_NO &&
3621 !IsLockedCoin((*it).first, i) && (pcoin->vout[i].nValue > 0 || fIncludeZeroValue) &&
3622 (!coinControl || !coinControl->HasSelected() || coinControl->IsSelected((*it).first, i)))
3624 if ( KOMODO_EXCHANGEWALLET == 0 )
3626 uint32_t locktime; int32_t txheight; CBlockIndex *tipindex;
3627 if ( ASSETCHAINS_SYMBOL[0] == 0 && chainActive.LastTip() != 0 && chainActive.LastTip()->GetHeight() >= 60000 )
3629 if ( pcoin->vout[i].nValue >= 10*COIN )
3631 if ( (tipindex= chainActive.LastTip()) != 0 )
3633 komodo_accrued_interest(&txheight,&locktime,wtxid,i,0,pcoin->vout[i].nValue,(int32_t)tipindex->GetHeight());
3634 interest = komodo_interestnew(txheight,pcoin->vout[i].nValue,locktime,tipindex->nTime);
3635 } else interest = 0;
3636 //interest = komodo_interestnew(chainActive.LastTip()->GetHeight()+1,pcoin->vout[i].nValue,pcoin->nLockTime,chainActive.LastTip()->nTime);
3637 if ( interest != 0 )
3639 //printf("wallet nValueRet %.8f += interest %.8f ht.%d lock.%u/%u tip.%u\n",(double)pcoin->vout[i].nValue/COIN,(double)interest/COIN,txheight,locktime,pcoin->nLockTime,tipindex->nTime);
3640 //fprintf(stderr,"wallet nValueRet %.8f += interest %.8f ht.%d lock.%u tip.%u\n",(double)pcoin->vout[i].nValue/COIN,(double)interest/COIN,chainActive.LastTip()->GetHeight()+1,pcoin->nLockTime,chainActive.LastTip()->nTime);
3641 //ptr = (uint64_t *)&pcoin->vout[i].nValue;
3642 //(*ptr) += interest;
3643 ptr = (uint64_t *)&pcoin->vout[i].interest;
3645 //pcoin->vout[i].nValue += interest;
3649 ptr = (uint64_t *)&pcoin->vout[i].interest;
3655 ptr = (uint64_t *)&pcoin->vout[i].interest;
3661 ptr = (uint64_t *)&pcoin->vout[i].interest;
3665 vCoins.push_back(COutput(pcoin, i, nDepth, (mine & ISMINE_SPENDABLE) != ISMINE_NO));
3672 void CWallet::AvailableReserveCoins(vector<COutput>& vCoins, bool fOnlyConfirmed, const CCoinControl *coinControl, bool fIncludeCoinBase) const
3677 LOCK2(cs_main, cs_wallet);
3678 for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
3680 const uint256& wtxid = it->first;
3681 const CWalletTx* pcoin = &(*it).second;
3683 if (!CheckFinalTx(*pcoin))
3686 if (fOnlyConfirmed && !pcoin->IsTrusted())
3689 if (pcoin->IsCoinBase() && !fIncludeCoinBase)
3692 if (pcoin->IsCoinBase() && pcoin->GetBlocksToMaturity() > 0)
3695 int nDepth = pcoin->GetDepthInMainChain();
3699 for (int i = 0; i < pcoin->vout.size(); i++)
3701 // NOTE: we assume that only zero value outputs can be reserve outputs
3702 isminetype mine = IsMine(pcoin->vout[i]);
3703 if (!(IsSpent(wtxid, i)) && mine != ISMINE_NO &&
3704 !IsLockedCoin((*it).first, i) && pcoin->vout[i].nValue == 0 &&
3705 (!coinControl || !coinControl->HasSelected() || coinControl->IsSelected((*it).first, i)))
3708 if (::IsPayToCryptoCondition(pcoin->vout[i].scriptPubKey, p) && p.IsValid() && p.evalCode == EVAL_RESERVE_OUTPUT)
3710 vCoins.push_back(COutput(pcoin, i, nDepth, (mine & ISMINE_SPENDABLE) != ISMINE_NO));
3718 static void ApproximateBestSubset(vector<pair<CAmount, pair<const CWalletTx*,unsigned int> > >vValue, const CAmount& nTotalLower, const CAmount& nTargetValue,vector<char>& vfBest, CAmount& nBest, int iterations = 1000)
3720 vector<char> vfIncluded;
3722 vfBest.assign(vValue.size(), true);
3723 nBest = nTotalLower;
3725 seed_insecure_rand();
3727 for (int nRep = 0; nRep < iterations && nBest != nTargetValue; nRep++)
3729 vfIncluded.assign(vValue.size(), false);
3731 bool fReachedTarget = false;
3732 for (int nPass = 0; nPass < 2 && !fReachedTarget; nPass++)
3734 for (unsigned int i = 0; i < vValue.size(); i++)
3736 //The solver here uses a randomized algorithm,
3737 //the randomness serves no real security purpose but is just
3738 //needed to prevent degenerate behavior and it is important
3739 //that the rng is fast. We do not use a constant random sequence,
3740 //because there may be some privacy improvement by making
3741 //the selection random.
3742 if (nPass == 0 ? insecure_rand()&1 : !vfIncluded[i])
3744 nTotal += vValue[i].first;
3745 vfIncluded[i] = true;
3746 if (nTotal >= nTargetValue)
3748 fReachedTarget = true;
3752 vfBest = vfIncluded;
3754 nTotal -= vValue[i].first;
3755 vfIncluded[i] = false;
3763 bool CWallet::SelectCoinsMinConf(const CAmount& nTargetValue, int nConfMine, int nConfTheirs, vector<COutput> vCoins,set<pair<const CWalletTx*,unsigned int> >& setCoinsRet, CAmount& nValueRet) const
3765 int32_t count = 0; //uint64_t lowest_interest = 0;
3766 setCoinsRet.clear();
3767 //memset(interests,0,sizeof(interests));
3769 // List of values less than target
3770 pair<CAmount, pair<const CWalletTx*,unsigned int> > coinLowestLarger;
3771 coinLowestLarger.first = std::numeric_limits<CAmount>::max();
3772 coinLowestLarger.second.first = NULL;
3773 vector<pair<CAmount, pair<const CWalletTx*,unsigned int> > > vValue;
3774 CAmount nTotalLower = 0;
3776 random_shuffle(vCoins.begin(), vCoins.end(), GetRandInt);
3778 BOOST_FOREACH(const COutput &output, vCoins)
3780 if (!output.fSpendable)
3783 const CWalletTx *pcoin = output.tx;
3785 if (output.nDepth < (pcoin->IsFromMe(ISMINE_ALL) ? nConfMine : nConfTheirs))
3789 CAmount n = pcoin->vout[i].nValue;
3791 pair<CAmount,pair<const CWalletTx*,unsigned int> > coin = make_pair(n,make_pair(pcoin, i));
3793 if (n == nTargetValue)
3795 setCoinsRet.insert(coin.second);
3796 nValueRet += coin.first;
3797 //if ( KOMODO_EXCHANGEWALLET == 0 )
3798 // *interestp += pcoin->vout[i].interest;
3801 else if (n < nTargetValue + CENT)
3803 vValue.push_back(coin);
3805 //if ( KOMODO_EXCHANGEWALLET == 0 && count < sizeof(interests)/sizeof(*interests) )
3807 //fprintf(stderr,"count.%d %.8f\n",count,(double)pcoin->vout[i].interest/COIN);
3808 //interests[count++] = pcoin->vout[i].interest;
3810 if ( nTotalLower > 4*nTargetValue + CENT )
3812 //fprintf(stderr,"why bother with all the utxo if we have double what is needed?\n");
3816 else if (n < coinLowestLarger.first)
3818 coinLowestLarger = coin;
3819 //if ( KOMODO_EXCHANGEWALLET == 0 )
3820 // lowest_interest = pcoin->vout[i].interest;
3824 if (nTotalLower == nTargetValue)
3826 for (unsigned int i = 0; i < vValue.size(); ++i)
3828 setCoinsRet.insert(vValue[i].second);
3829 nValueRet += vValue[i].first;
3830 //if ( KOMODO_EXCHANGEWALLET == 0 && i < count )
3831 // *interestp += interests[i];
3836 if (nTotalLower < nTargetValue)
3838 if (coinLowestLarger.second.first == NULL)
3840 setCoinsRet.insert(coinLowestLarger.second);
3841 nValueRet += coinLowestLarger.first;
3842 //if ( KOMODO_EXCHANGEWALLET == 0 )
3843 // *interestp += lowest_interest;
3847 // Solve subset sum by stochastic approximation
3848 sort(vValue.rbegin(), vValue.rend(), CompareValueOnly());
3849 vector<char> vfBest;
3852 ApproximateBestSubset(vValue, nTotalLower, nTargetValue, vfBest, nBest, 1000);
3853 if (nBest != nTargetValue && nTotalLower >= nTargetValue + CENT)
3854 ApproximateBestSubset(vValue, nTotalLower, nTargetValue + CENT, vfBest, nBest, 1000);
3856 // If we have a bigger coin and (either the stochastic approximation didn't find a good solution,
3857 // or the next bigger coin is closer), return the bigger coin
3858 if (coinLowestLarger.second.first &&
3859 ((nBest != nTargetValue && nBest < nTargetValue + CENT) || coinLowestLarger.first <= nBest))
3861 setCoinsRet.insert(coinLowestLarger.second);
3862 nValueRet += coinLowestLarger.first;
3863 //if ( KOMODO_EXCHANGEWALLET == 0 )
3864 // *interestp += lowest_interest;
3867 for (unsigned int i = 0; i < vValue.size(); i++)
3870 setCoinsRet.insert(vValue[i].second);
3871 nValueRet += vValue[i].first;
3872 //if ( KOMODO_EXCHANGEWALLET == 0 && i < count )
3873 // *interestp += interests[i];
3876 LogPrint("selectcoins", "SelectCoins() best subset: ");
3877 for (unsigned int i = 0; i < vValue.size(); i++)
3879 LogPrint("selectcoins", "%s", FormatMoney(vValue[i].first));
3880 LogPrint("selectcoins", "total %s\n", FormatMoney(nBest));
3886 bool CWallet::SelectCoins(const CAmount& nTargetValue, set<pair<const CWalletTx*,unsigned int> >& setCoinsRet, CAmount& nValueRet, bool& fOnlyCoinbaseCoinsRet, bool& fNeedCoinbaseCoinsRet, const CCoinControl* coinControl) const
3888 // Output parameter fOnlyCoinbaseCoinsRet is set to true when the only available coins are coinbase utxos.
3889 uint64_t tmp; int32_t retval;
3890 //if ( interestp == 0 )
3892 // interestp = &tmp;
3895 vector<COutput> vCoinsNoCoinbase, vCoinsWithCoinbase;
3896 AvailableCoins(vCoinsNoCoinbase, true, coinControl, false, false);
3897 AvailableCoins(vCoinsWithCoinbase, true, coinControl, false, true);
3898 fOnlyCoinbaseCoinsRet = vCoinsNoCoinbase.size() == 0 && vCoinsWithCoinbase.size() > 0;
3900 // If coinbase utxos can only be sent to zaddrs, exclude any coinbase utxos from coin selection.
3901 bool fProtectCoinbase = Params().GetConsensus().fCoinbaseMustBeProtected;
3902 vector<COutput> vCoins = (fProtectCoinbase) ? vCoinsNoCoinbase : vCoinsWithCoinbase;
3904 // Output parameter fNeedCoinbaseCoinsRet is set to true if coinbase utxos need to be spent to meet target amount
3905 if (fProtectCoinbase && vCoinsWithCoinbase.size() > vCoinsNoCoinbase.size()) {
3907 for (const COutput& out : vCoinsNoCoinbase) {
3908 if (!out.fSpendable) {
3911 value += out.tx->vout[out.i].nValue;
3912 if ( KOMODO_EXCHANGEWALLET == 0 )
3913 value += out.tx->vout[out.i].interest;
3915 if (value <= nTargetValue) {
3916 CAmount valueWithCoinbase = 0;
3917 for (const COutput& out : vCoinsWithCoinbase) {
3918 if (!out.fSpendable) {
3921 valueWithCoinbase += out.tx->vout[out.i].nValue;
3922 if ( KOMODO_EXCHANGEWALLET == 0 )
3923 valueWithCoinbase += out.tx->vout[out.i].interest;
3925 fNeedCoinbaseCoinsRet = (valueWithCoinbase >= nTargetValue);
3928 // coin control -> return all selected outputs (we want all selected to go into the transaction for sure)
3929 if (coinControl && coinControl->HasSelected() && !coinControl->fAllowOtherInputs)
3931 BOOST_FOREACH(const COutput& out, vCoins)
3933 if (!out.fSpendable)
3935 nValueRet += out.tx->vout[out.i].nValue;
3936 //if ( KOMODO_EXCHANGEWALLET == 0 )
3937 // *interestp += out.tx->vout[out.i].interest;
3938 setCoinsRet.insert(make_pair(out.tx, out.i));
3940 return (nValueRet >= nTargetValue);
3942 // calculate value from preset inputs and store them
3943 set<pair<const CWalletTx*, uint32_t> > setPresetCoins;
3944 CAmount nValueFromPresetInputs = 0;
3946 std::vector<COutPoint> vPresetInputs;
3948 coinControl->ListSelected(vPresetInputs);
3949 BOOST_FOREACH(const COutPoint& outpoint, vPresetInputs)
3951 map<uint256, CWalletTx>::const_iterator it = mapWallet.find(outpoint.hash);
3952 if (it != mapWallet.end())
3954 const CWalletTx* pcoin = &it->second;
3955 // Clearly invalid input, fail
3956 if (pcoin->vout.size() <= outpoint.n)
3958 nValueFromPresetInputs += pcoin->vout[outpoint.n].nValue;
3959 if ( KOMODO_EXCHANGEWALLET == 0 )
3960 nValueFromPresetInputs += pcoin->vout[outpoint.n].interest;
3961 setPresetCoins.insert(make_pair(pcoin, outpoint.n));
3963 return false; // TODO: Allow non-wallet inputs
3966 // remove preset inputs from vCoins
3967 for (vector<COutput>::iterator it = vCoins.begin(); it != vCoins.end() && coinControl && coinControl->HasSelected();)
3969 if (setPresetCoins.count(make_pair(it->tx, it->i)))
3970 it = vCoins.erase(it);
3975 if ( nTargetValue <= nValueFromPresetInputs )
3977 else if ( SelectCoinsMinConf(nTargetValue, 1, 6, vCoins, setCoinsRet, nValueRet) != 0 )
3979 else if ( SelectCoinsMinConf(nTargetValue, 1, 1, vCoins, setCoinsRet, nValueRet) != 0 )
3981 else if ( bSpendZeroConfChange && SelectCoinsMinConf(nTargetValue, 0, 1, vCoins, setCoinsRet, nValueRet) != 0 )
3983 // because SelectCoinsMinConf clears the setCoinsRet, we now add the possible inputs to the coinset
3984 setCoinsRet.insert(setPresetCoins.begin(), setPresetCoins.end());
3985 // add preset inputs to the total value selected
3986 nValueRet += nValueFromPresetInputs;
3990 bool CWallet::SelectReserveCoinsMinConf(const CAmount& nTargetValue, int nConfMine, int nConfTheirs, vector<COutput> vCoins,set<pair<const CWalletTx*,unsigned int> >& setCoinsRet, CAmount& nValueRet) const
3992 int32_t count = 0; //uint64_t lowest_interest = 0;
3993 setCoinsRet.clear();
3994 //memset(interests,0,sizeof(interests));
3996 // List of values less than target
3997 pair<CAmount, pair<const CWalletTx*,unsigned int> > coinLowestLarger;
3998 coinLowestLarger.first = std::numeric_limits<CAmount>::max();
3999 coinLowestLarger.second.first = NULL;
4000 vector<pair<CAmount, pair<const CWalletTx*,unsigned int> > > vValue;
4001 CAmount nTotalLower = 0;
4003 random_shuffle(vCoins.begin(), vCoins.end(), GetRandInt);
4005 BOOST_FOREACH(const COutput &output, vCoins)
4007 if (!output.fSpendable)
4010 const CWalletTx *pcoin = output.tx;
4012 if (output.nDepth < (pcoin->IsFromMe(ISMINE_ALL) ? nConfMine : nConfTheirs))
4016 CAmount n = pcoin->vout[i].scriptPubKey.ReserveOutValue();
4018 pair<CAmount,pair<const CWalletTx*,unsigned int> > coin = make_pair(n,make_pair(pcoin, i));
4020 if (n == nTargetValue)
4022 setCoinsRet.insert(coin.second);
4023 nValueRet += coin.first;
4024 //if ( KOMODO_EXCHANGEWALLET == 0 )
4025 // *interestp += pcoin->vout[i].interest;
4028 else if (n < nTargetValue + CENT)
4030 vValue.push_back(coin);
4033 if ( nTotalLower > 4*nTargetValue + CENT )
4035 //fprintf(stderr,"why bother with all the utxo if we have double what is needed?\n");
4039 else if (n < coinLowestLarger.first)
4041 coinLowestLarger = coin;
4045 if (nTotalLower == nTargetValue)
4047 for (unsigned int i = 0; i < vValue.size(); ++i)
4049 setCoinsRet.insert(vValue[i].second);
4050 nValueRet += vValue[i].first;
4055 if (nTotalLower < nTargetValue)
4057 if (coinLowestLarger.second.first == NULL)
4059 setCoinsRet.insert(coinLowestLarger.second);
4060 nValueRet += coinLowestLarger.first;
4064 // Solve subset sum by stochastic approximation
4065 sort(vValue.rbegin(), vValue.rend(), CompareValueOnly());
4066 vector<char> vfBest;
4069 ApproximateBestSubset(vValue, nTotalLower, nTargetValue, vfBest, nBest, 1000);
4070 if (nBest != nTargetValue && nTotalLower >= nTargetValue + CENT)
4071 ApproximateBestSubset(vValue, nTotalLower, nTargetValue + CENT, vfBest, nBest, 1000);
4073 // If we have a bigger coin and (either the stochastic approximation didn't find a good solution,
4074 // or the next bigger coin is closer), return the bigger coin
4075 if (coinLowestLarger.second.first &&
4076 ((nBest != nTargetValue && nBest < nTargetValue + CENT) || coinLowestLarger.first <= nBest))
4078 setCoinsRet.insert(coinLowestLarger.second);
4079 nValueRet += coinLowestLarger.first;
4082 for (unsigned int i = 0; i < vValue.size(); i++)
4085 setCoinsRet.insert(vValue[i].second);
4086 nValueRet += vValue[i].first;
4089 LogPrint("selectcoins", "SelectCoins() best subset: ");
4090 for (unsigned int i = 0; i < vValue.size(); i++)
4092 LogPrint("selectcoins", "%s", FormatMoney(vValue[i].first));
4093 LogPrint("selectcoins", "total %s\n", FormatMoney(nBest));
4099 bool CWallet::SelectReserveCoins(const CAmount& nTargetValue, set<pair<const CWalletTx*,unsigned int> >& setCoinsRet, CAmount& nValueRet, bool& fOnlyCoinbaseCoinsRet, bool& fNeedCoinbaseCoinsRet, const CCoinControl* coinControl) const
4101 // Output parameter fOnlyCoinbaseCoinsRet is set to true when the only available coins are coinbase utxos.
4102 uint64_t tmp; int32_t retval;
4103 //if ( interestp == 0 )
4105 // interestp = &tmp;
4108 vector<COutput> vCoinsNoCoinbase, vCoinsWithCoinbase;
4109 AvailableReserveCoins(vCoinsNoCoinbase, true, coinControl, false);
4110 AvailableReserveCoins(vCoinsWithCoinbase, true, coinControl, true);
4111 fOnlyCoinbaseCoinsRet = vCoinsNoCoinbase.size() == 0 && vCoinsWithCoinbase.size() > 0;
4113 // If coinbase utxos can only be sent to zaddrs, exclude any coinbase utxos from coin selection.
4114 bool fProtectCoinbase = Params().GetConsensus().fCoinbaseMustBeProtected;
4115 vector<COutput> vCoins = (fProtectCoinbase) ? vCoinsNoCoinbase : vCoinsWithCoinbase;
4117 // Output parameter fNeedCoinbaseCoinsRet is set to true if coinbase utxos need to be spent to meet target amount
4118 if (fProtectCoinbase && vCoinsWithCoinbase.size() > vCoinsNoCoinbase.size()) {
4120 for (const COutput& out : vCoinsNoCoinbase) {
4121 if (!out.fSpendable) {
4124 value += out.tx->vout[out.i].ReserveOutValue();
4126 if (value <= nTargetValue) {
4127 CAmount valueWithCoinbase = 0;
4128 for (const COutput& out : vCoinsWithCoinbase) {
4129 if (!out.fSpendable) {
4132 valueWithCoinbase += out.tx->vout[out.i].ReserveOutValue();
4134 fNeedCoinbaseCoinsRet = (valueWithCoinbase >= nTargetValue);
4137 // coin control -> return all selected outputs (we want all selected to go into the transaction for sure)
4138 if (coinControl && coinControl->HasSelected() && !coinControl->fAllowOtherInputs)
4140 BOOST_FOREACH(const COutput& out, vCoins)
4142 if (!out.fSpendable)
4144 nValueRet += out.tx->vout[out.i].ReserveOutValue();
4145 setCoinsRet.insert(make_pair(out.tx, out.i));
4147 return (nValueRet >= nTargetValue);
4149 // calculate value from preset inputs and store them
4150 set<pair<const CWalletTx*, uint32_t> > setPresetCoins;
4151 CAmount nValueFromPresetInputs = 0;
4153 std::vector<COutPoint> vPresetInputs;
4155 coinControl->ListSelected(vPresetInputs);
4156 BOOST_FOREACH(const COutPoint& outpoint, vPresetInputs)
4158 map<uint256, CWalletTx>::const_iterator it = mapWallet.find(outpoint.hash);
4159 if (it != mapWallet.end())
4161 const CWalletTx* pcoin = &it->second;
4162 // Clearly invalid input, fail
4163 if (pcoin->vout.size() <= outpoint.n)
4165 nValueFromPresetInputs += pcoin->vout[outpoint.n].ReserveOutValue();
4166 setPresetCoins.insert(make_pair(pcoin, outpoint.n));
4168 return false; // TODO: Allow non-wallet inputs
4171 // remove preset inputs from vCoins
4172 for (vector<COutput>::iterator it = vCoins.begin(); it != vCoins.end() && coinControl && coinControl->HasSelected();)
4174 if (setPresetCoins.count(make_pair(it->tx, it->i)))
4175 it = vCoins.erase(it);
4180 if ( nTargetValue <= nValueFromPresetInputs )
4182 else if ( SelectReserveCoinsMinConf(nTargetValue, 1, 6, vCoins, setCoinsRet, nValueRet) != 0 )
4184 else if ( SelectReserveCoinsMinConf(nTargetValue, 1, 1, vCoins, setCoinsRet, nValueRet) != 0 )
4186 else if ( bSpendZeroConfChange && SelectReserveCoinsMinConf(nTargetValue, 0, 1, vCoins, setCoinsRet, nValueRet) != 0 )
4188 // because SelectCoinsMinConf clears the setCoinsRet, we now add the possible inputs to the coinset
4189 setCoinsRet.insert(setPresetCoins.begin(), setPresetCoins.end());
4190 // add preset inputs to the total value selected
4191 nValueRet += nValueFromPresetInputs;
4195 bool CWallet::FundTransaction(CMutableTransaction& tx, CAmount &nFeeRet, int& nChangePosRet, std::string& strFailReason)
4197 vector<CRecipient> vecSend;
4199 // Turn the txout set into a CRecipient vector
4200 BOOST_FOREACH(const CTxOut& txOut, tx.vout)
4202 CRecipient recipient = {txOut.scriptPubKey, txOut.nValue, false};
4203 vecSend.push_back(recipient);
4206 CCoinControl coinControl;
4207 coinControl.fAllowOtherInputs = true;
4208 BOOST_FOREACH(const CTxIn& txin, tx.vin)
4209 coinControl.Select(txin.prevout);
4211 CReserveKey reservekey(this);
4214 if (!CreateTransaction(vecSend, wtx, reservekey, nFeeRet, nChangePosRet, strFailReason, &coinControl, false))
4217 if (nChangePosRet != -1)
4218 tx.vout.insert(tx.vout.begin() + nChangePosRet, wtx.vout[nChangePosRet]);
4220 // Add new txins (keeping original txin scriptSig/order)
4221 BOOST_FOREACH(const CTxIn& txin, wtx.vin)
4224 BOOST_FOREACH(const CTxIn& origTxIn, tx.vin)
4226 if (txin.prevout.hash == origTxIn.prevout.hash && txin.prevout.n == origTxIn.prevout.n)
4233 tx.vin.push_back(txin);
4239 bool CWallet::CreateTransaction(const vector<CRecipient>& vecSend, CWalletTx& wtxNew, CReserveKey& reservekey, CAmount& nFeeRet,
4240 int& nChangePosRet, std::string& strFailReason, const CCoinControl* coinControl, bool sign)
4242 uint64_t interest2 = 0; CAmount nValue = 0; unsigned int nSubtractFeeFromAmount = 0;
4243 BOOST_FOREACH (const CRecipient& recipient, vecSend)
4245 if (nValue < 0 || recipient.nAmount < 0)
4247 strFailReason = _("Transaction amounts must be positive");
4250 nValue += recipient.nAmount;
4252 if (recipient.fSubtractFeeFromAmount)
4253 nSubtractFeeFromAmount++;
4255 if (vecSend.empty() || nValue < 0)
4257 strFailReason = _("Transaction amounts must be positive");
4261 wtxNew.fTimeReceivedIsTxTime = true;
4262 wtxNew.BindWallet(this);
4263 int nextBlockHeight = chainActive.Height() + 1;
4265 CMutableTransaction txNew = CreateNewContextualCMutableTransaction(Params().GetConsensus(), nextBlockHeight);
4266 txNew.nLockTime = (uint32_t)chainActive.LastTip()->nTime + 1; // set to a time close to now
4268 // Activates after Overwinter network upgrade
4269 if (NetworkUpgradeActive(nextBlockHeight, Params().GetConsensus(), Consensus::UPGRADE_OVERWINTER)) {
4270 if (txNew.nExpiryHeight >= TX_EXPIRY_HEIGHT_THRESHOLD){
4271 strFailReason = _("nExpiryHeight must be less than TX_EXPIRY_HEIGHT_THRESHOLD.");
4276 unsigned int max_tx_size = MAX_TX_SIZE_AFTER_SAPLING;
4277 if (!NetworkUpgradeActive(nextBlockHeight, Params().GetConsensus(), Consensus::UPGRADE_SAPLING)) {
4278 max_tx_size = MAX_TX_SIZE_BEFORE_SAPLING;
4281 // Discourage fee sniping.
4283 // However because of a off-by-one-error in previous versions we need to
4284 // neuter it by setting nLockTime to at least one less than nBestHeight.
4285 // Secondly currently propagation of transactions created for block heights
4286 // corresponding to blocks that were just mined may be iffy - transactions
4287 // aren't re-accepted into the mempool - we additionally neuter the code by
4288 // going ten blocks back. Doesn't yet do anything for sniping, but does act
4289 // to shake out wallet bugs like not showing nLockTime'd transactions at
4291 txNew.nLockTime = std::max(0, chainActive.Height() - 10);
4293 // Secondly occasionally randomly pick a nLockTime even further back, so
4294 // that transactions that are delayed after signing for whatever reason,
4295 // e.g. high-latency mix networks and some CoinJoin implementations, have
4297 if (GetRandInt(10) == 0)
4298 txNew.nLockTime = std::max(0, (int)txNew.nLockTime - GetRandInt(100));
4300 assert(txNew.nLockTime <= (unsigned int)chainActive.Height());
4301 assert(txNew.nLockTime < LOCKTIME_THRESHOLD);
4304 LOCK2(cs_main, cs_wallet);
4312 wtxNew.fFromMe = true;
4316 CAmount nTotalValue = nValue;
4317 if (nSubtractFeeFromAmount == 0)
4318 nTotalValue += nFeeRet;
4319 double dPriority = 0;
4320 // vouts to the payees
4321 BOOST_FOREACH (const CRecipient& recipient, vecSend)
4323 CTxOut txout(recipient.nAmount, recipient.scriptPubKey);
4325 if (recipient.fSubtractFeeFromAmount)
4327 txout.nValue -= nFeeRet / nSubtractFeeFromAmount; // Subtract fee equally from each selected recipient
4329 if (fFirst) // first receiver pays the remainder not divisible by output count
4332 txout.nValue -= nFeeRet % nSubtractFeeFromAmount;
4336 if (txout.IsDust(::minRelayTxFee))
4338 if (recipient.fSubtractFeeFromAmount && nFeeRet > 0)
4340 if (txout.nValue < 0)
4341 strFailReason = _("The transaction amount is too small to pay the fee");
4343 strFailReason = _("The transaction amount is too small to send after the fee has been deducted");
4346 strFailReason = _("Transaction amount too small");
4349 txNew.vout.push_back(txout);
4352 // Choose coins to use
4353 set<pair<const CWalletTx*,unsigned int> > setCoins;
4354 CAmount nValueIn = 0;
4355 bool fOnlyCoinbaseCoins = false;
4356 bool fNeedCoinbaseCoins = false;
4358 if (!SelectCoins(nTotalValue, setCoins, nValueIn, fOnlyCoinbaseCoins, fNeedCoinbaseCoins, coinControl))
4360 if (fOnlyCoinbaseCoins && Params().GetConsensus().fCoinbaseMustBeProtected) {
4361 strFailReason = _("Coinbase funds can only be sent to a zaddr");
4362 } else if (fNeedCoinbaseCoins) {
4363 strFailReason = _("Insufficient funds, coinbase funds can only be spent after they have been sent to a zaddr");
4365 strFailReason = _("Insufficient funds");
4369 BOOST_FOREACH(PAIRTYPE(const CWalletTx*, unsigned int) pcoin, setCoins)
4371 CAmount nCredit = pcoin.first->vout[pcoin.second].nValue;
4372 //The coin age after the next block (depth+1) is used instead of the current,
4373 //reflecting an assumption the user would accept a bit more delay for
4374 //a chance at a free transaction.
4375 //But mempool inputs might still be in the mempool, so their age stays 0
4376 //fprintf(stderr,"nCredit %.8f interest %.8f\n",(double)nCredit/COIN,(double)pcoin.first->vout[pcoin.second].interest/COIN);
4377 if ( KOMODO_EXCHANGEWALLET == 0 && ASSETCHAINS_SYMBOL[0] == 0 )
4379 interest2 += pcoin.first->vout[pcoin.second].interest;
4380 //fprintf(stderr,"%.8f ",(double)pcoin.first->vout[pcoin.second].interest/COIN);
4382 int age = pcoin.first->GetDepthInMainChain();
4385 dPriority += (double)nCredit * age;
4387 //if ( KOMODO_EXCHANGEWALLET != 0 )
4389 //fprintf(stderr,"KOMODO_EXCHANGEWALLET disable interest sum %.8f, interest2 %.8f\n",(double)interest/COIN,(double)interest2/COIN);
4390 //interest = 0; // interest2 also
4392 if ( ASSETCHAINS_SYMBOL[0] == 0 && DONATION_PUBKEY.size() == 66 && interest2 > 5000 )
4394 CScript scriptDonation = CScript() << ParseHex(DONATION_PUBKEY) << OP_CHECKSIG;
4395 CTxOut newTxOut(interest2,scriptDonation);
4396 int32_t nDonationPosRet = txNew.vout.size() - 1; // dont change first or last
4397 vector<CTxOut>::iterator position = txNew.vout.begin()+nDonationPosRet;
4398 txNew.vout.insert(position, newTxOut);
4401 CAmount nChange = (nValueIn - nValue + interest2);
4402 //fprintf(stderr,"wallet change %.8f (%.8f - %.8f) interest2 %.8f total %.8f\n",(double)nChange/COIN,(double)nValueIn/COIN,(double)nValue/COIN,(double)interest2/COIN,(double)nTotalValue/COIN);
4403 if (nSubtractFeeFromAmount == 0)
4408 // Fill a vout to ourself
4409 // TODO: pass in scriptChange instead of reservekey so
4410 // change transaction isn't always pay-to-bitcoin-address
4411 CScript scriptChange;
4413 // coin control: send change to custom address
4414 if (coinControl && !boost::get<CNoDestination>(&coinControl->destChange))
4415 scriptChange = GetScriptForDestination(coinControl->destChange);
4417 // no coin control: send change to newly generated address
4420 // Note: We use a new key here to keep it from being obvious which side is the change.
4421 // The drawback is that by not reusing a previous key, the change may be lost if a
4422 // backup is restored, if the backup doesn't have the new private key for the change.
4423 // If we reused the old key, it would be possible to add code to look for and
4424 // rediscover unknown transactions that were written with keys of ours to recover
4425 // post-backup change.
4427 // Reserve a new key pair from key pool
4429 extern int32_t USE_EXTERNAL_PUBKEY; extern std::string NOTARY_PUBKEY;
4430 if ( USE_EXTERNAL_PUBKEY == 0 )
4433 ret = reservekey.GetReservedKey(vchPubKey);
4434 assert(ret); // should never fail, as we just unlocked
4435 scriptChange = GetScriptForDestination(vchPubKey.GetID());
4439 //fprintf(stderr,"use notary pubkey\n");
4440 scriptChange = CScript() << ParseHex(NOTARY_PUBKEY) << OP_CHECKSIG;
4444 CTxOut newTxOut(nChange, scriptChange);
4446 // We do not move dust-change to fees, because the sender would end up paying more than requested.
4447 // This would be against the purpose of the all-inclusive feature.
4448 // So instead we raise the change and deduct from the recipient.
4449 if (nSubtractFeeFromAmount > 0 && newTxOut.IsDust(::minRelayTxFee))
4451 CAmount nDust = newTxOut.GetDustThreshold(::minRelayTxFee) - newTxOut.nValue;
4452 newTxOut.nValue += nDust; // raise change until no more dust
4453 for (unsigned int i = 0; i < vecSend.size(); i++) // subtract from first recipient
4455 if (vecSend[i].fSubtractFeeFromAmount)
4457 txNew.vout[i].nValue -= nDust;
4458 if (txNew.vout[i].IsDust(::minRelayTxFee))
4460 strFailReason = _("The transaction amount is too small to send after the fee has been deducted");
4468 // Never create dust outputs; if we would, just
4469 // add the dust to the fee.
4470 if (newTxOut.IsDust(::minRelayTxFee))
4473 reservekey.ReturnKey();
4477 nChangePosRet = txNew.vout.size() - 1; // dont change first or last
4478 vector<CTxOut>::iterator position = txNew.vout.begin()+nChangePosRet;
4479 txNew.vout.insert(position, newTxOut);
4481 } else reservekey.ReturnKey();
4485 // Note how the sequence number is set to max()-1 so that the
4486 // nLockTime set above actually works.
4487 BOOST_FOREACH(const PAIRTYPE(const CWalletTx*,unsigned int)& coin, setCoins)
4488 txNew.vin.push_back(CTxIn(coin.first->GetHash(),coin.second,CScript(),
4489 std::numeric_limits<unsigned int>::max()-1));
4491 // Check mempooltxinputlimit to avoid creating a transaction which the local mempool rejects
4492 size_t limit = (size_t)GetArg("-mempooltxinputlimit", 0);
4495 if (NetworkUpgradeActive(chainActive.Height() + 1, Params().GetConsensus(), Consensus::UPGRADE_OVERWINTER)) {
4500 size_t n = txNew.vin.size();
4502 strFailReason = _(strprintf("Too many transparent inputs %zu > limit %zu", n, limit).c_str());
4507 // Grab the current consensus branch ID
4508 auto consensusBranchId = CurrentEpochBranchId(chainActive.Height() + 1, Params().GetConsensus());
4512 CTransaction txNewConst(txNew);
4513 BOOST_FOREACH(const PAIRTYPE(const CWalletTx*,unsigned int)& coin, setCoins)
4516 const CScript& scriptPubKey = coin.first->vout[coin.second].scriptPubKey;
4517 SignatureData sigdata;
4519 signSuccess = ProduceSignature(TransactionSignatureCreator(this, &txNewConst, nIn, coin.first->vout[coin.second].nValue, SIGHASH_ALL), scriptPubKey, sigdata, consensusBranchId);
4521 signSuccess = ProduceSignature(DummySignatureCreator(this), scriptPubKey, sigdata, consensusBranchId);
4525 strFailReason = _("Signing transaction failed");
4528 UpdateTransaction(txNew, nIn, sigdata);
4534 unsigned int nBytes = ::GetSerializeSize(txNew, SER_NETWORK, PROTOCOL_VERSION);
4536 // Remove scriptSigs if we used dummy signatures for fee calculation
4538 BOOST_FOREACH (CTxIn& vin, txNew.vin)
4539 vin.scriptSig = CScript();
4542 // Embed the constructed transaction data in wtxNew.
4543 *static_cast<CTransaction*>(&wtxNew) = CTransaction(txNew);
4546 if (nBytes >= max_tx_size)
4548 strFailReason = _("Transaction too large");
4552 dPriority = wtxNew.ComputePriority(dPriority, nBytes);
4554 // Can we complete this as a free transaction?
4555 if (fSendFreeTransactions && nBytes <= MAX_FREE_TRANSACTION_CREATE_SIZE)
4557 // Not enough fee: enough priority?
4558 double dPriorityNeeded = mempool.estimatePriority(nTxConfirmTarget);
4559 // Not enough mempool history to estimate: use hard-coded AllowFree.
4560 if (dPriorityNeeded <= 0 && AllowFree(dPriority))
4563 // Small enough, and priority high enough, to send for free
4564 if (dPriorityNeeded > 0 && dPriority >= dPriorityNeeded)
4568 CAmount nFeeNeeded = GetMinimumFee(nBytes, nTxConfirmTarget, mempool);
4569 if ( nFeeNeeded < 5000 )
4572 // If we made it here and we aren't even able to meet the relay fee on the next pass, give up
4573 // because we must be at the maximum allowed fee.
4574 if (nFeeNeeded < ::minRelayTxFee.GetFee(nBytes))
4576 strFailReason = _("Transaction too large for fee policy");
4580 if (nFeeRet >= nFeeNeeded)
4581 break; // Done, enough fee included.
4583 // Include more fee and try again.
4584 nFeeRet = nFeeNeeded;
4593 CAmount ConvertReserveAmount(CAmount inAmount, CAmount reservePrice)
4595 arith_uint256 satoshiden(100000000);
4596 arith_uint256 bigAmount(inAmount);
4597 arith_uint256 bigPrice(reservePrice);
4598 return ((bigAmount * bigPrice) / satoshiden).GetLow64();
4601 // almost the same as CreateTransaction with the difference being that input and output are assumed to be the
4602 // reserve currency of this chain, represented as reserve outputs for both input and output. That means that all
4603 // outputs must be reserve consuming outputs. Fee converted from reserve, which is the difference between reserve
4604 // input and reserve output, is calculated based on the current reserve conversion price.
4605 bool CWallet::CreateReserveTransaction(const vector<CRecipient>& vecSend, CWalletTx& wtxNew, CReserveKey& reservekey, CAmount& nFeeRet,
4606 int& nChangePosRet, std::string& strFailReason, const CCoinControl* coinControl, bool sign)
4609 unsigned int nSubtractFeeFromAmount = 0;
4611 // reserve transactions can only be created on fractional reserve currency blockchains
4612 if (IsVerusActive())
4614 strFailReason = _("Transactions that accept reserve currency input can only be created on PBaaS blockchains");
4618 // make sure that there are recipients, all recipients expect reserve inputs, and amounts are all non-negative
4619 BOOST_FOREACH (const CRecipient& recipient, vecSend)
4623 if (recipient.scriptPubKey.IsPayToCryptoCondition(p) && p.IsValid() && p.vData.size() > 0)
4627 case EVAL_RESERVE_OUTPUT:
4629 ro = CReserveOutput(p.vData[0]);
4632 strFailReason = _("Invalid reserve output");
4637 case EVAL_RESERVE_TRANSFER:
4639 CReserveTransfer rt(p.vData[0]);
4642 strFailReason = _("Invalid reserve transfer");
4645 // conversion on a PBaaS reserve chain implies native input
4646 if (rt.flags & CReserveTransfer::CONVERT)
4648 strFailReason = _(("Reserve transaction outputs created using " + std::string( __func__) + " must have no native output value").c_str());
4651 ro = static_cast<CReserveOutput>(rt);
4654 case EVAL_RESERVE_EXCHANGE:
4656 CReserveExchange re(p.vData[0]);
4659 strFailReason = _("Invalid reserve exchange");
4662 // conversion to reserve implies native input
4663 if (re.flags & CReserveExchange::TO_RESERVE)
4665 strFailReason = _(("Reserve transaction outputs created using " + std::string( __func__) + " must have no native output value").c_str());
4668 ro = static_cast<CReserveOutput>(re);
4673 strFailReason = _("All reserve transaction outputs must accommodate reserve currency input");
4678 else if (!recipient.scriptPubKey.IsOpReturn() || recipient.nAmount != 0)
4680 strFailReason = _(("Reserve transaction outputs created using " + std::string( __func__) + " must have no native output value").c_str());
4686 nValue += ro.nValue;
4689 if (ro.nValue < 0 || nValue < 0 || recipient.nAmount < 0)
4691 strFailReason = _("Transaction amounts must not be negative");
4695 if (recipient.fSubtractFeeFromAmount)
4696 nSubtractFeeFromAmount++;
4699 if (vecSend.empty() || nValue < 0)
4701 strFailReason = _("Transaction amounts must not be negative");
4705 wtxNew.fTimeReceivedIsTxTime = true;
4706 wtxNew.BindWallet(this);
4707 int nextBlockHeight = chainActive.Height() + 1;
4708 CMutableTransaction txNew = CreateNewContextualCMutableTransaction(Params().GetConsensus(), nextBlockHeight);
4709 txNew.nLockTime = (uint32_t)chainActive.LastTip()->nTime + 1; // set to a time close to now
4711 if (txNew.nExpiryHeight >= TX_EXPIRY_HEIGHT_THRESHOLD){
4712 strFailReason = _("nExpiryHeight must be less than TX_EXPIRY_HEIGHT_THRESHOLD.");
4716 unsigned int max_tx_size = MAX_TX_SIZE_AFTER_SAPLING;
4718 // Discourage fee sniping.
4720 // However because of a off-by-one-error in previous versions we need to
4721 // neuter it by setting nLockTime to at least one less than nBestHeight.
4722 // Secondly currently propagation of transactions created for block heights
4723 // corresponding to blocks that were just mined may be iffy - transactions
4724 // aren't re-accepted into the mempool - we additionally neuter the code by
4725 // going ten blocks back. Doesn't yet do anything for sniping, but does act
4726 // to shake out wallet bugs like not showing nLockTime'd transactions at
4728 txNew.nLockTime = std::max(0, chainActive.Height() - 10);
4730 // Secondly occasionally randomly pick a nLockTime even further back, so
4731 // that transactions that are delayed after signing for whatever reason,
4732 // e.g. high-latency mix networks and some CoinJoin implementations, have
4734 if (GetRandInt(10) == 0)
4735 txNew.nLockTime = std::max(0, (int)txNew.nLockTime - GetRandInt(100));
4737 assert(txNew.nLockTime <= (unsigned int)chainActive.Height());
4738 assert(txNew.nLockTime < LOCKTIME_THRESHOLD);
4741 LOCK2(cs_main, cs_wallet);
4749 wtxNew.fFromMe = true;
4753 // TODO: keep this up to date with connect block and coinbase transaction rule
4754 CCurrencyState curReserveState;
4756 cpp_dec_float_50 priceInReserve = curReserveState.GetPriceInReserve();
4757 CAmount reservePrice;
4758 if (!CCurrencyState::to_int64(priceInReserve, reservePrice))
4760 strFailReason = _("Invalid fractional reserve price");
4764 // dust threshold of reserve is different than native coin, convert
4765 CAmount dustThreshold;
4767 CAmount nTotalValue = nValue;
4768 if (nSubtractFeeFromAmount == 0)
4769 nTotalValue += nFeeRet;
4770 double dPriority = 0;
4771 // vouts to the payees
4772 BOOST_FOREACH (const CRecipient& recipient, vecSend)
4774 // native output value for a reserve output is generally 0. fees are paid by converting from
4775 // reserve token and the difference between input and output in reserve is the fee
4776 // the actual reserve token output value is in the scriptPubKey as extended CC information
4777 CTxOut txout(0, recipient.scriptPubKey);
4779 // here, if we know that it isn't an opret, it will have an output that expects reserve input
4780 if (!recipient.scriptPubKey.IsOpReturn())
4784 // already validated above
4785 txout.scriptPubKey.IsPayToCryptoCondition(p);
4789 CReserveTransfer rt;
4790 CReserveExchange re;
4794 case EVAL_RESERVE_OUTPUT:
4796 ro = CReserveOutput(p.vData[0]);
4800 case EVAL_RESERVE_TRANSFER:
4802 rt = CReserveTransfer(p.vData[0]);
4806 case EVAL_RESERVE_EXCHANGE:
4808 re = CReserveExchange(p.vData[0]);
4813 strFailReason = _("Bad reserve output");
4817 if (recipient.fSubtractFeeFromAmount)
4819 CAmount subFee = nFeeRet / nSubtractFeeFromAmount; // Subtract fee equally from each selected recipient
4821 if (fFirst) // first receiver pays the remainder not divisible by output count
4824 subFee += nFeeRet % nSubtractFeeFromAmount;
4829 case EVAL_RESERVE_OUTPUT:
4831 ro.nValue -= subFee;
4833 p.vData[0] = ro.AsVector();
4836 case EVAL_RESERVE_TRANSFER:
4838 rt.nValue -= subFee;
4840 p.vData[0] = rt.AsVector();
4843 case EVAL_RESERVE_EXCHANGE:
4845 re.nValue -= subFee;
4847 p.vData[0] = re.AsVector();
4851 strFailReason = _("Bad reserve output");
4855 txout.scriptPubKey = txout.scriptPubKey.ReplaceCCParams(p);
4858 dustThreshold = txout.GetDustThreshold(::minRelayTxFee);
4860 if (newVal < dustThreshold)
4862 if (recipient.fSubtractFeeFromAmount && nFeeRet > 0)
4865 strFailReason = _("The transaction amount is too small to pay the fee");
4867 strFailReason = _("The transaction amount is too small to send after the fee has been deducted");
4870 strFailReason = _("Transaction amount too small");
4875 txNew.vout.push_back(txout);
4878 // Choose coins to use
4879 set<pair<const CWalletTx*,unsigned int> > setCoins;
4880 CAmount nValueIn = 0;
4881 bool fOnlyCoinbaseCoins = false;
4882 bool fNeedCoinbaseCoins = false;
4884 if (!SelectReserveCoins(nTotalValue, setCoins, nValueIn, fOnlyCoinbaseCoins, fNeedCoinbaseCoins, coinControl))
4886 if (fOnlyCoinbaseCoins && Params().GetConsensus().fCoinbaseMustBeProtected) {
4887 strFailReason = _("Coinbase funds can only be sent to a zaddr");
4888 } else if (fNeedCoinbaseCoins) {
4889 strFailReason = _("Insufficient funds, coinbase funds can only be spent after they have been sent to a zaddr");
4891 strFailReason = _("Insufficient funds");
4895 BOOST_FOREACH(PAIRTYPE(const CWalletTx*, unsigned int) pcoin, setCoins)
4897 CAmount nCredit = pcoin.first->vout[pcoin.second].ReserveOutValue();
4898 //The coin age after the next block (depth+1) is used instead of the current,
4899 //reflecting an assumption the user would accept a bit more delay for
4900 //a chance at a free transaction.
4901 //But mempool inputs might still be in the mempool, so their age stays 0
4902 int age = pcoin.first->GetDepthInMainChain();
4905 dPriority += (double)nCredit * age;
4908 CAmount nChange = (nValueIn - nValue);
4910 if (nSubtractFeeFromAmount == 0)
4915 // Fill a vout to ourself
4918 // coin control: send change to custom address
4920 // reserve tokens can currently only be sent to public keys or addresses that are in the current wallet
4921 // since reserve token outputs are CCs by definition
4922 if (coinControl && !boost::get<CNoDestination>(&coinControl->destChange))
4924 if (!boost::get<CPubKey>(&coinControl->destChange))
4926 strFailReason = _("Change address must be public key");
4929 vchPubKey = *(boost::get<CPubKey>(&coinControl->destChange));
4933 // no coin control: send change to newly generated address
4935 // Note: We use a new key here to keep it from being obvious which side is the change.
4936 // The drawback is that by not reusing a previous key, the change may be lost if a
4937 // backup is restored, if the backup doesn't have the new private key for the change.
4938 // If we reused the old key, it would be possible to add code to look for and
4939 // rediscover unknown transactions that were written with keys of ours to recover
4940 // post-backup change.
4942 // Reserve a new key pair from key pool
4943 extern int32_t USE_EXTERNAL_PUBKEY; extern std::string NOTARY_PUBKEY;
4944 if ( USE_EXTERNAL_PUBKEY == 0 )
4947 ret = reservekey.GetReservedKey(vchPubKey);
4948 assert(ret); // should never fail, as we just unlocked
4952 //fprintf(stderr,"use notary pubkey\n");
4953 vchPubKey = CPubKey(ParseHex(NOTARY_PUBKEY));
4957 // we will send using a reserve output, fee will be paid by converting from reserve
4959 CCcontract_info *cp;
4960 cp = CCinit(&CC, EVAL_RESERVE_OUTPUT);
4962 std::vector<CTxDestination> dests = std::vector<CTxDestination>({vchPubKey.GetID()});
4964 // create the transfer object
4965 CReserveOutput ro(CReserveOutput::VALID, nChange);
4967 // We do not move dust-change to fees, because the sender would end up paying more than requested.
4968 // This would be against the purpose of the all-inclusive feature.
4969 // So instead we raise the change and deduct from the recipient.
4971 // adjust the output amount if possible
4972 if (nSubtractFeeFromAmount > 0 && ro.nValue < dustThreshold)
4974 CAmount nDust = dustThreshold - ro.nValue;
4976 ro.nValue += nDust; // raise change until no more dust
4978 for (unsigned int i = 0; i < vecSend.size(); i++) // subtract from first recipient
4980 if (vecSend[i].fSubtractFeeFromAmount)
4982 CAmount nValue = txNew.vout[i].ReserveOutValue() - nDust;
4983 if (nValue < dustThreshold)
4985 strFailReason = _("The transaction amount is too small to send after the fee has been deducted");
4988 txNew.vout[i].SetReserveOutValue(nValue);
4994 // native amount in the output should be 0
4995 CTxOut newTxOut = MakeCC1of1Vout(EVAL_RESERVE_OUTPUT, 0, vchPubKey, dests, ro);
4997 // Never create reserve dust outputs; if we would, just
4998 // add the dust to the fee.
4999 if (ro.nValue < newTxOut.GetDustThreshold(::minRelayTxFee))
5002 reservekey.ReturnKey();
5006 nChangePosRet = txNew.vout.size() - 1; // dont change first or last
5007 vector<CTxOut>::iterator position = txNew.vout.begin()+nChangePosRet;
5008 txNew.vout.insert(position, newTxOut);
5010 } else reservekey.ReturnKey();
5014 // Note how the sequence number is set to max()-1 so that the
5015 // nLockTime set above actually works.
5016 BOOST_FOREACH(const PAIRTYPE(const CWalletTx*,unsigned int)& coin, setCoins)
5017 txNew.vin.push_back(CTxIn(coin.first->GetHash(),coin.second,CScript(),
5018 std::numeric_limits<unsigned int>::max()-1));
5020 // Check mempooltxinputlimit to avoid creating a transaction which the local mempool rejects
5021 size_t limit = (size_t)GetArg("-mempooltxinputlimit", 0);
5024 if (NetworkUpgradeActive(chainActive.Height() + 1, Params().GetConsensus(), Consensus::UPGRADE_OVERWINTER)) {
5029 size_t n = txNew.vin.size();
5031 strFailReason = _(strprintf("Too many transparent inputs %zu > limit %zu", n, limit).c_str());
5036 // Grab the current consensus branch ID
5037 auto consensusBranchId = CurrentEpochBranchId(chainActive.Height() + 1, Params().GetConsensus());
5041 CTransaction txNewConst(txNew);
5042 BOOST_FOREACH(const PAIRTYPE(const CWalletTx*,unsigned int)& coin, setCoins)
5045 const CScript& scriptPubKey = coin.first->vout[coin.second].scriptPubKey;
5046 SignatureData sigdata;
5048 signSuccess = ProduceSignature(TransactionSignatureCreator(this, &txNewConst, nIn, coin.first->vout[coin.second].nValue, SIGHASH_ALL), scriptPubKey, sigdata, consensusBranchId);
5050 signSuccess = ProduceSignature(DummySignatureCreator(this), scriptPubKey, sigdata, consensusBranchId);
5054 strFailReason = _("Signing transaction failed");
5057 UpdateTransaction(txNew, nIn, sigdata);
5063 unsigned int nBytes = ::GetSerializeSize(txNew, SER_NETWORK, PROTOCOL_VERSION);
5065 // Remove scriptSigs if we used dummy signatures for fee calculation
5067 BOOST_FOREACH (CTxIn& vin, txNew.vin)
5068 vin.scriptSig = CScript();
5071 // Embed the constructed transaction data in wtxNew.
5072 *static_cast<CTransaction*>(&wtxNew) = CTransaction(txNew);
5075 if (nBytes >= max_tx_size)
5077 strFailReason = _("Transaction too large");
5081 dPriority = wtxNew.ComputePriority(dPriority, nBytes);
5083 // Can we complete this as a free transaction?
5084 if (fSendFreeTransactions && nBytes <= MAX_FREE_TRANSACTION_CREATE_SIZE)
5086 // Not enough fee: enough priority?
5087 double dPriorityNeeded = mempool.estimatePriority(nTxConfirmTarget);
5088 // Not enough mempool history to estimate: use hard-coded AllowFree.
5089 if (dPriorityNeeded <= 0 && AllowFree(dPriority))
5092 // Small enough, and priority high enough, to send for free
5093 if (dPriorityNeeded > 0 && dPriority >= dPriorityNeeded)
5097 CAmount nFeeNeeded = GetMinimumFee(nBytes, nTxConfirmTarget, mempool);
5098 if ( nFeeNeeded < 5000 )
5101 // If we made it here and we aren't even able to meet the relay fee on the next pass, give up
5102 // because we must be at the maximum allowed fee.
5103 if (nFeeNeeded < ::minRelayTxFee.GetFee(nBytes))
5105 strFailReason = _("Transaction too large for fee policy");
5109 if (nFeeRet >= nFeeNeeded)
5110 break; // Done, enough fee included.
5112 // Include more fee and try again.
5113 nFeeRet = nFeeNeeded;
5123 * Call after CreateTransaction unless you want to abort
5125 bool CWallet::CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey)
5128 LOCK2(cs_main, cs_wallet);
5129 LogPrintf("CommitTransaction:\n%s", wtxNew.ToString());
5131 // This is only to keep the database open to defeat the auto-flush for the
5132 // duration of this scope. This is the only place where this optimization
5133 // maybe makes sense; please don't do it anywhere else.
5134 CWalletDB* pwalletdb = fFileBacked ? new CWalletDB(strWalletFile,"r+") : NULL;
5136 // Take key pair from key pool so it won't be used again
5137 reservekey.KeepKey();
5139 // Add tx to wallet, because if it has change it's also ours,
5140 // otherwise just for transaction history.
5141 AddToWallet(wtxNew, false, pwalletdb);
5143 // Notify that old coins are spent
5144 set<CWalletTx*> setCoins;
5145 BOOST_FOREACH(const CTxIn& txin, wtxNew.vin)
5147 CWalletTx &coin = mapWallet[txin.prevout.hash];
5148 coin.BindWallet(this);
5149 NotifyTransactionChanged(this, coin.GetHash(), CT_UPDATED);
5156 // Track how many getdata requests our transaction gets
5157 mapRequestCount[wtxNew.GetHash()] = 0;
5159 if (fBroadcastTransactions)
5162 if (!wtxNew.AcceptToMemoryPool(false))
5164 fprintf(stderr,"commit failed\n");
5165 // This must not fail. The transaction has already been signed and recorded.
5166 LogPrintf("CommitTransaction(): Error: Transaction not valid\n");
5169 wtxNew.RelayWalletTransaction();
5175 CAmount CWallet::GetMinimumFee(unsigned int nTxBytes, unsigned int nConfirmTarget, const CTxMemPool& pool)
5177 // payTxFee is user-set "I want to pay this much"
5178 CAmount nFeeNeeded = payTxFee.GetFee(nTxBytes);
5179 // user selected total at least (default=true)
5180 if (fPayAtLeastCustomFee && nFeeNeeded > 0 && nFeeNeeded < payTxFee.GetFeePerK())
5181 nFeeNeeded = payTxFee.GetFeePerK();
5182 // User didn't set: use -txconfirmtarget to estimate...
5183 if (nFeeNeeded == 0)
5184 nFeeNeeded = pool.estimateFee(nConfirmTarget).GetFee(nTxBytes);
5185 // ... unless we don't have enough mempool data, in which case fall
5186 // back to a hard-coded fee
5187 if (nFeeNeeded == 0)
5188 nFeeNeeded = minTxFee.GetFee(nTxBytes);
5189 // prevent user from paying a non-sense fee (like 1 satoshi): 0 < fee < minRelayFee
5190 if (nFeeNeeded < ::minRelayTxFee.GetFee(nTxBytes))
5191 nFeeNeeded = ::minRelayTxFee.GetFee(nTxBytes);
5192 // But always obey the maximum
5193 if (nFeeNeeded > maxTxFee)
5194 nFeeNeeded = maxTxFee;
5199 void komodo_prefetch(FILE *fp);
5201 DBErrors CWallet::LoadWallet(bool& fFirstRunRet)
5205 fFirstRunRet = false;
5206 if ( 0 ) // doesnt help
5208 fprintf(stderr,"loading wallet %s %u\n",strWalletFile.c_str(),(uint32_t)time(NULL));
5210 if ( (fp= fopen(strWalletFile.c_str(),"rb")) != 0 )
5212 komodo_prefetch(fp);
5216 //fprintf(stderr,"prefetched wallet %s %u\n",strWalletFile.c_str(),(uint32_t)time(NULL));
5217 DBErrors nLoadWalletRet = CWalletDB(strWalletFile,"cr+").LoadWallet(this);
5218 //fprintf(stderr,"loaded wallet %s %u\n",strWalletFile.c_str(),(uint32_t)time(NULL));
5219 if (nLoadWalletRet == DB_NEED_REWRITE)
5221 if (CDB::Rewrite(strWalletFile, "\x04pool"))
5225 // Note: can't top-up keypool here, because wallet is locked.
5226 // User will be prompted to unlock wallet the next operation
5227 // that requires a new key.
5231 if (nLoadWalletRet != DB_LOAD_OK)
5232 return nLoadWalletRet;
5233 fFirstRunRet = !vchDefaultKey.IsValid();
5235 uiInterface.LoadWallet(this);
5241 DBErrors CWallet::ZapWalletTx(std::vector<CWalletTx>& vWtx)
5245 DBErrors nZapWalletTxRet = CWalletDB(strWalletFile,"cr+").ZapWalletTx(this, vWtx);
5246 if (nZapWalletTxRet == DB_NEED_REWRITE)
5248 if (CDB::Rewrite(strWalletFile, "\x04pool"))
5252 // Note: can't top-up keypool here, because wallet is locked.
5253 // User will be prompted to unlock wallet the next operation
5254 // that requires a new key.
5258 if (nZapWalletTxRet != DB_LOAD_OK)
5259 return nZapWalletTxRet;
5265 bool CWallet::SetAddressBook(const CTxDestination& address, const string& strName, const string& strPurpose)
5267 bool fUpdated = false;
5269 LOCK(cs_wallet); // mapAddressBook
5270 std::map<CTxDestination, CAddressBookData>::iterator mi = mapAddressBook.find(address);
5271 fUpdated = mi != mapAddressBook.end();
5272 mapAddressBook[address].name = strName;
5273 if (!strPurpose.empty()) /* update purpose only if requested */
5274 mapAddressBook[address].purpose = strPurpose;
5276 NotifyAddressBookChanged(this, address, strName, ::IsMine(*this, address) != ISMINE_NO,
5277 strPurpose, (fUpdated ? CT_UPDATED : CT_NEW) );
5280 if (!strPurpose.empty() && !CWalletDB(strWalletFile).WritePurpose(EncodeDestination(address), strPurpose))
5282 return CWalletDB(strWalletFile).WriteName(EncodeDestination(address), strName);
5285 bool CWallet::DelAddressBook(const CTxDestination& address)
5288 LOCK(cs_wallet); // mapAddressBook
5292 // Delete destdata tuples associated with address
5293 std::string strAddress = EncodeDestination(address);
5294 BOOST_FOREACH(const PAIRTYPE(string, string) &item, mapAddressBook[address].destdata)
5296 CWalletDB(strWalletFile).EraseDestData(strAddress, item.first);
5299 mapAddressBook.erase(address);
5302 NotifyAddressBookChanged(this, address, "", ::IsMine(*this, address) != ISMINE_NO, "", CT_DELETED);
5306 CWalletDB(strWalletFile).ErasePurpose(EncodeDestination(address));
5307 return CWalletDB(strWalletFile).EraseName(EncodeDestination(address));
5310 bool CWallet::SetDefaultKey(const CPubKey &vchPubKey)
5314 if (!CWalletDB(strWalletFile).WriteDefaultKey(vchPubKey))
5317 vchDefaultKey = vchPubKey;
5322 * Mark old keypool keys as used,
5323 * and generate all new keys
5325 bool CWallet::NewKeyPool()
5329 CWalletDB walletdb(strWalletFile);
5330 BOOST_FOREACH(int64_t nIndex, setKeyPool)
5331 walletdb.ErasePool(nIndex);
5337 int64_t nKeys = max(GetArg("-keypool", 100), (int64_t)0);
5338 for (int i = 0; i < nKeys; i++)
5340 int64_t nIndex = i+1;
5341 walletdb.WritePool(nIndex, CKeyPool(GenerateNewKey()));
5342 setKeyPool.insert(nIndex);
5344 LogPrintf("CWallet::NewKeyPool wrote %d new keys\n", nKeys);
5349 bool CWallet::TopUpKeyPool(unsigned int kpSize)
5357 CWalletDB walletdb(strWalletFile);
5360 unsigned int nTargetSize;
5362 nTargetSize = kpSize;
5364 nTargetSize = max(GetArg("-keypool", 100), (int64_t) 0);
5366 while (setKeyPool.size() < (nTargetSize + 1))
5369 if (!setKeyPool.empty())
5370 nEnd = *(--setKeyPool.end()) + 1;
5371 if (!walletdb.WritePool(nEnd, CKeyPool(GenerateNewKey())))
5372 throw runtime_error("TopUpKeyPool(): writing generated key failed");
5373 setKeyPool.insert(nEnd);
5374 LogPrintf("keypool added key %d, size=%u\n", nEnd, setKeyPool.size());
5380 void CWallet::ReserveKeyFromKeyPool(int64_t& nIndex, CKeyPool& keypool)
5383 keypool.vchPubKey = CPubKey();
5390 // Get the oldest key
5391 if(setKeyPool.empty())
5394 CWalletDB walletdb(strWalletFile);
5396 nIndex = *(setKeyPool.begin());
5397 setKeyPool.erase(setKeyPool.begin());
5398 if (!walletdb.ReadPool(nIndex, keypool))
5399 throw runtime_error("ReserveKeyFromKeyPool(): read failed");
5400 if (!HaveKey(keypool.vchPubKey.GetID()))
5401 throw runtime_error("ReserveKeyFromKeyPool(): unknown key in key pool");
5402 assert(keypool.vchPubKey.IsValid());
5403 //LogPrintf("keypool reserve %d\n", nIndex);
5407 void CWallet::KeepKey(int64_t nIndex)
5409 // Remove from key pool
5412 CWalletDB walletdb(strWalletFile);
5413 walletdb.ErasePool(nIndex);
5415 LogPrintf("keypool keep %d\n", nIndex);
5418 void CWallet::ReturnKey(int64_t nIndex)
5420 // Return to key pool
5423 setKeyPool.insert(nIndex);
5425 //LogPrintf("keypool return %d\n", nIndex);
5428 bool CWallet::GetKeyFromPool(CPubKey& result)
5434 ReserveKeyFromKeyPool(nIndex, keypool);
5437 if (IsLocked()) return false;
5438 result = GenerateNewKey();
5442 result = keypool.vchPubKey;
5447 int64_t CWallet::GetOldestKeyPoolTime()
5451 ReserveKeyFromKeyPool(nIndex, keypool);
5455 return keypool.nTime;
5458 std::map<CTxDestination, CAmount> CWallet::GetAddressBalances()
5460 map<CTxDestination, CAmount> balances;
5464 BOOST_FOREACH(PAIRTYPE(uint256, CWalletTx) walletEntry, mapWallet)
5466 CWalletTx *pcoin = &walletEntry.second;
5468 if (!CheckFinalTx(*pcoin) || !pcoin->IsTrusted())
5471 if (pcoin->IsCoinBase() && pcoin->GetBlocksToMaturity() > 0)
5474 int nDepth = pcoin->GetDepthInMainChain();
5475 if (nDepth < (pcoin->IsFromMe(ISMINE_ALL) ? 0 : 1))
5478 for (unsigned int i = 0; i < pcoin->vout.size(); i++)
5480 CTxDestination addr;
5481 if (!IsMine(pcoin->vout[i]))
5483 if(!ExtractDestination(pcoin->vout[i].scriptPubKey, addr))
5486 CAmount n = IsSpent(walletEntry.first, i) ? 0 : pcoin->vout[i].nValue;
5488 if (!balances.count(addr))
5490 balances[addr] += n;
5498 set< set<CTxDestination> > CWallet::GetAddressGroupings()
5500 AssertLockHeld(cs_wallet); // mapWallet
5501 set< set<CTxDestination> > groupings;
5502 set<CTxDestination> grouping;
5504 BOOST_FOREACH(PAIRTYPE(uint256, CWalletTx) walletEntry, mapWallet)
5506 CWalletTx *pcoin = &walletEntry.second;
5508 if (pcoin->vin.size() > 0)
5510 bool any_mine = false;
5511 // group all input addresses with each other
5512 BOOST_FOREACH(CTxIn txin, pcoin->vin)
5514 CTxDestination address;
5515 if(!IsMine(txin)) /* If this input isn't mine, ignore it */
5517 if(!ExtractDestination(mapWallet[txin.prevout.hash].vout[txin.prevout.n].scriptPubKey, address))
5519 grouping.insert(address);
5523 // group change with input addresses
5526 BOOST_FOREACH(CTxOut txout, pcoin->vout)
5527 if (IsChange(txout))
5529 CTxDestination txoutAddr;
5530 if(!ExtractDestination(txout.scriptPubKey, txoutAddr))
5532 grouping.insert(txoutAddr);
5535 if (grouping.size() > 0)
5537 groupings.insert(grouping);
5542 // group lone addrs by themselves
5543 for (unsigned int i = 0; i < pcoin->vout.size(); i++)
5544 if (IsMine(pcoin->vout[i]))
5546 CTxDestination address;
5547 if(!ExtractDestination(pcoin->vout[i].scriptPubKey, address))
5549 grouping.insert(address);
5550 groupings.insert(grouping);
5555 set< set<CTxDestination>* > uniqueGroupings; // a set of pointers to groups of addresses
5556 map< CTxDestination, set<CTxDestination>* > setmap; // map addresses to the unique group containing it
5557 BOOST_FOREACH(set<CTxDestination> grouping, groupings)
5559 // make a set of all the groups hit by this new group
5560 set< set<CTxDestination>* > hits;
5561 map< CTxDestination, set<CTxDestination>* >::iterator it;
5562 BOOST_FOREACH(CTxDestination address, grouping)
5563 if ((it = setmap.find(address)) != setmap.end())
5564 hits.insert((*it).second);
5566 // merge all hit groups into a new single group and delete old groups
5567 set<CTxDestination>* merged = new set<CTxDestination>(grouping);
5568 BOOST_FOREACH(set<CTxDestination>* hit, hits)
5570 merged->insert(hit->begin(), hit->end());
5571 uniqueGroupings.erase(hit);
5574 uniqueGroupings.insert(merged);
5577 BOOST_FOREACH(CTxDestination element, *merged)
5578 setmap[element] = merged;
5581 set< set<CTxDestination> > ret;
5582 BOOST_FOREACH(set<CTxDestination>* uniqueGrouping, uniqueGroupings)
5584 ret.insert(*uniqueGrouping);
5585 delete uniqueGrouping;
5591 std::set<CTxDestination> CWallet::GetAccountAddresses(const std::string& strAccount) const
5594 set<CTxDestination> result;
5595 BOOST_FOREACH(const PAIRTYPE(CTxDestination, CAddressBookData)& item, mapAddressBook)
5597 const CTxDestination& address = item.first;
5598 const string& strName = item.second.name;
5599 if (strName == strAccount)
5600 result.insert(address);
5605 bool CReserveKey::GetReservedKey(CPubKey& pubkey)
5610 pwallet->ReserveKeyFromKeyPool(nIndex, keypool);
5612 vchPubKey = keypool.vchPubKey;
5617 assert(vchPubKey.IsValid());
5622 void CReserveKey::KeepKey()
5625 pwallet->KeepKey(nIndex);
5627 vchPubKey = CPubKey();
5630 void CReserveKey::ReturnKey()
5633 pwallet->ReturnKey(nIndex);
5635 vchPubKey = CPubKey();
5638 void CWallet::GetAllReserveKeys(set<CKeyID>& setAddress) const
5642 CWalletDB walletdb(strWalletFile);
5644 LOCK2(cs_main, cs_wallet);
5645 BOOST_FOREACH(const int64_t& id, setKeyPool)
5648 if (!walletdb.ReadPool(id, keypool))
5649 throw runtime_error("GetAllReserveKeyHashes(): read failed");
5650 assert(keypool.vchPubKey.IsValid());
5651 CKeyID keyID = keypool.vchPubKey.GetID();
5652 if (!HaveKey(keyID))
5653 throw runtime_error("GetAllReserveKeyHashes(): unknown key in key pool");
5654 setAddress.insert(keyID);
5658 void CWallet::UpdatedTransaction(const uint256 &hashTx)
5662 // Only notify UI if this transaction is in this wallet
5663 map<uint256, CWalletTx>::const_iterator mi = mapWallet.find(hashTx);
5664 if (mi != mapWallet.end())
5665 NotifyTransactionChanged(this, hashTx, CT_UPDATED);
5669 void CWallet::LockCoin(COutPoint& output)
5671 AssertLockHeld(cs_wallet); // setLockedCoins
5672 setLockedCoins.insert(output);
5675 void CWallet::UnlockCoin(COutPoint& output)
5677 AssertLockHeld(cs_wallet); // setLockedCoins
5678 setLockedCoins.erase(output);
5681 void CWallet::UnlockAllCoins()
5683 AssertLockHeld(cs_wallet); // setLockedCoins
5684 setLockedCoins.clear();
5687 bool CWallet::IsLockedCoin(uint256 hash, unsigned int n) const
5689 AssertLockHeld(cs_wallet); // setLockedCoins
5690 COutPoint outpt(hash, n);
5692 return (setLockedCoins.count(outpt) > 0);
5695 void CWallet::ListLockedCoins(std::vector<COutPoint>& vOutpts)
5697 AssertLockHeld(cs_wallet); // setLockedCoins
5698 for (std::set<COutPoint>::iterator it = setLockedCoins.begin();
5699 it != setLockedCoins.end(); it++) {
5700 COutPoint outpt = (*it);
5701 vOutpts.push_back(outpt);
5706 // Note Locking Operations
5708 void CWallet::LockNote(const JSOutPoint& output)
5710 AssertLockHeld(cs_wallet); // setLockedSproutNotes
5711 setLockedSproutNotes.insert(output);
5714 void CWallet::UnlockNote(const JSOutPoint& output)
5716 AssertLockHeld(cs_wallet); // setLockedSproutNotes
5717 setLockedSproutNotes.erase(output);
5720 void CWallet::UnlockAllSproutNotes()
5722 AssertLockHeld(cs_wallet); // setLockedSproutNotes
5723 setLockedSproutNotes.clear();
5726 bool CWallet::IsLockedNote(const JSOutPoint& outpt) const
5728 AssertLockHeld(cs_wallet); // setLockedSproutNotes
5730 return (setLockedSproutNotes.count(outpt) > 0);
5733 std::vector<JSOutPoint> CWallet::ListLockedSproutNotes()
5735 AssertLockHeld(cs_wallet); // setLockedSproutNotes
5736 std::vector<JSOutPoint> vOutpts(setLockedSproutNotes.begin(), setLockedSproutNotes.end());
5740 void CWallet::LockNote(const SaplingOutPoint& output)
5742 AssertLockHeld(cs_wallet);
5743 setLockedSaplingNotes.insert(output);
5746 void CWallet::UnlockNote(const SaplingOutPoint& output)
5748 AssertLockHeld(cs_wallet);
5749 setLockedSaplingNotes.erase(output);
5752 void CWallet::UnlockAllSaplingNotes()
5754 AssertLockHeld(cs_wallet);
5755 setLockedSaplingNotes.clear();
5758 bool CWallet::IsLockedNote(const SaplingOutPoint& output) const
5760 AssertLockHeld(cs_wallet);
5761 return (setLockedSaplingNotes.count(output) > 0);
5764 std::vector<SaplingOutPoint> CWallet::ListLockedSaplingNotes()
5766 AssertLockHeld(cs_wallet);
5767 std::vector<SaplingOutPoint> vOutputs(setLockedSaplingNotes.begin(), setLockedSaplingNotes.end());
5771 /** @} */ // end of Actions
5773 class CAffectedKeysVisitor : public boost::static_visitor<void> {
5775 const CKeyStore &keystore;
5776 std::vector<CKeyID> &vKeys;
5779 CAffectedKeysVisitor(const CKeyStore &keystoreIn, std::vector<CKeyID> &vKeysIn) : keystore(keystoreIn), vKeys(vKeysIn) {}
5781 void Process(const CScript &script) {
5783 std::vector<CTxDestination> vDest;
5785 if (ExtractDestinations(script, type, vDest, nRequired)) {
5786 BOOST_FOREACH(const CTxDestination &dest, vDest)
5787 boost::apply_visitor(*this, dest);
5791 void operator()(const CKeyID &keyId) {
5792 if (keystore.HaveKey(keyId))
5793 vKeys.push_back(keyId);
5796 void operator()(const CPubKey &key) {
5797 CKeyID keyId = key.GetID();
5798 if (keystore.HaveKey(keyId))
5799 vKeys.push_back(keyId);
5802 void operator()(const CScriptID &scriptId) {
5804 if (keystore.GetCScript(scriptId, script))
5808 void operator()(const CNoDestination &none) {}
5811 void CWallet::GetKeyBirthTimes(std::map<CKeyID, int64_t> &mapKeyBirth) const {
5812 AssertLockHeld(cs_wallet); // mapKeyMetadata
5813 mapKeyBirth.clear();
5815 // get birth times for keys with metadata
5816 for (std::map<CKeyID, CKeyMetadata>::const_iterator it = mapKeyMetadata.begin(); it != mapKeyMetadata.end(); it++)
5817 if (it->second.nCreateTime)
5818 mapKeyBirth[it->first] = it->second.nCreateTime;
5820 // map in which we'll infer heights of other keys
5821 CBlockIndex *pindexMax = chainActive[std::max(0, chainActive.Height() - 144)]; // the tip can be reorganised; use a 144-block safety margin
5822 std::map<CKeyID, CBlockIndex*> mapKeyFirstBlock;
5823 std::set<CKeyID> setKeys;
5825 BOOST_FOREACH(const CKeyID &keyid, setKeys) {
5826 if (mapKeyBirth.count(keyid) == 0)
5827 mapKeyFirstBlock[keyid] = pindexMax;
5831 // if there are no such keys, we're done
5832 if (mapKeyFirstBlock.empty())
5835 // find first block that affects those keys, if there are any left
5836 std::vector<CKeyID> vAffected;
5837 for (std::map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); it++) {
5838 // iterate over all wallet transactions...
5839 const CWalletTx &wtx = (*it).second;
5840 BlockMap::const_iterator blit = mapBlockIndex.find(wtx.hashBlock);
5841 if (blit != mapBlockIndex.end() && chainActive.Contains(blit->second)) {
5842 // ... which are already in a block
5843 int nHeight = blit->second->GetHeight();
5844 BOOST_FOREACH(const CTxOut &txout, wtx.vout) {
5845 // iterate over all their outputs
5846 CAffectedKeysVisitor(*this, vAffected).Process(txout.scriptPubKey);
5847 BOOST_FOREACH(const CKeyID &keyid, vAffected) {
5848 // ... and all their affected keys
5849 std::map<CKeyID, CBlockIndex*>::iterator rit = mapKeyFirstBlock.find(keyid);
5850 if (rit != mapKeyFirstBlock.end() && nHeight < rit->second->GetHeight())
5851 rit->second = blit->second;
5858 // Extract block timestamps for those keys
5859 for (std::map<CKeyID, CBlockIndex*>::const_iterator it = mapKeyFirstBlock.begin(); it != mapKeyFirstBlock.end(); it++)
5860 mapKeyBirth[it->first] = it->second->GetBlockTime() - 7200; // block times can be 2h off
5863 bool CWallet::AddDestData(const CTxDestination &dest, const std::string &key, const std::string &value)
5865 if (boost::get<CNoDestination>(&dest))
5868 mapAddressBook[dest].destdata.insert(std::make_pair(key, value));
5871 return CWalletDB(strWalletFile).WriteDestData(EncodeDestination(dest), key, value);
5874 bool CWallet::EraseDestData(const CTxDestination &dest, const std::string &key)
5876 if (!mapAddressBook[dest].destdata.erase(key))
5880 return CWalletDB(strWalletFile).EraseDestData(EncodeDestination(dest), key);
5883 bool CWallet::LoadDestData(const CTxDestination &dest, const std::string &key, const std::string &value)
5885 mapAddressBook[dest].destdata.insert(std::make_pair(key, value));
5889 bool CWallet::GetDestData(const CTxDestination &dest, const std::string &key, std::string *value) const
5891 std::map<CTxDestination, CAddressBookData>::const_iterator i = mapAddressBook.find(dest);
5892 if(i != mapAddressBook.end())
5894 CAddressBookData::StringMap::const_iterator j = i->second.destdata.find(key);
5895 if(j != i->second.destdata.end())
5905 CKeyPool::CKeyPool()
5910 CKeyPool::CKeyPool(const CPubKey& vchPubKeyIn)
5913 vchPubKey = vchPubKeyIn;
5916 CWalletKey::CWalletKey(int64_t nExpires)
5918 nTimeCreated = (nExpires ? GetTime() : 0);
5919 nTimeExpires = nExpires;
5922 int CMerkleTx::SetMerkleBranch(const CBlock& block)
5924 AssertLockHeld(cs_main);
5927 // Update the tx's hashBlock
5928 hashBlock = block.GetHash();
5930 // Locate the transaction
5931 for (nIndex = 0; nIndex < (int)block.vtx.size(); nIndex++)
5932 if (block.vtx[nIndex] == *(CTransaction*)this)
5934 if (nIndex == (int)block.vtx.size())
5936 vMerkleBranch.clear();
5938 LogPrintf("ERROR: SetMerkleBranch(): couldn't find tx in block\n");
5942 // Fill in merkle branch
5943 vMerkleBranch = block.GetMerkleBranch(nIndex);
5945 // Is the tx in a block that's in the main chain
5946 BlockMap::iterator mi = mapBlockIndex.find(hashBlock);
5947 if (mi == mapBlockIndex.end())
5949 const CBlockIndex* pindex = (*mi).second;
5950 if (!pindex || !chainActive.Contains(pindex))
5953 return chainActive.Height() - pindex->GetHeight() + 1;
5956 int CMerkleTx::GetDepthInMainChainINTERNAL(const CBlockIndex* &pindexRet) const
5958 if (hashBlock.IsNull() || nIndex == -1)
5960 AssertLockHeld(cs_main);
5962 // Find the block it claims to be in
5963 BlockMap::iterator mi = mapBlockIndex.find(hashBlock);
5964 if (mi == mapBlockIndex.end())
5966 CBlockIndex* pindex = (*mi).second;
5967 if (!pindex || !chainActive.Contains(pindex))
5970 // Make sure the merkle branch connects to this block
5971 if (!fMerkleVerified)
5973 if (CBlock::CheckMerkleBranch(GetHash(), vMerkleBranch, nIndex) != pindex->hashMerkleRoot)
5975 fMerkleVerified = true;
5979 return chainActive.Height() - pindex->GetHeight() + 1;
5982 int CMerkleTx::GetDepthInMainChain(const CBlockIndex* &pindexRet) const
5984 AssertLockHeld(cs_main);
5985 int nResult = GetDepthInMainChainINTERNAL(pindexRet);
5986 if (nResult == 0 && !mempool.exists(GetHash()))
5987 return -1; // Not in chain, not in mempool
5992 int CMerkleTx::GetBlocksToMaturity() const
5994 if ( ASSETCHAINS_SYMBOL[0] == 0 )
5995 COINBASE_MATURITY = _COINBASE_MATURITY;
5998 int32_t depth = GetDepthInMainChain();
5999 int32_t ut = UnlockTime(0);
6000 int32_t toMaturity = (ut - chainActive.Height()) < 0 ? 0 : ut - chainActive.Height();
6001 //printf("depth.%i, unlockTime.%i, toMaturity.%i\n", depth, ut, toMaturity);
6002 ut = (COINBASE_MATURITY - depth) < 0 ? 0 : COINBASE_MATURITY - depth;
6003 return(ut < toMaturity ? toMaturity : ut);
6006 bool CMerkleTx::AcceptToMemoryPool(bool fLimitFree, bool fRejectAbsurdFee)
6008 CValidationState state;
6009 return ::AcceptToMemoryPool(mempool, state, *this, fLimitFree, NULL, fRejectAbsurdFee);
6013 * Find notes in the wallet filtered by payment address, min depth and ability to spend.
6014 * These notes are decrypted and added to the output parameter vector, outEntries.
6016 void CWallet::GetFilteredNotes(
6017 std::vector<CSproutNotePlaintextEntry>& sproutEntries,
6018 std::vector<SaplingNoteEntry>& saplingEntries,
6019 std::string address,
6022 bool requireSpendingKey)
6024 std::set<PaymentAddress> filterAddresses;
6026 if (address.length() > 0) {
6027 filterAddresses.insert(DecodePaymentAddress(address));
6030 GetFilteredNotes(sproutEntries, saplingEntries, filterAddresses, minDepth, INT_MAX, ignoreSpent, requireSpendingKey);
6034 * Find notes in the wallet filtered by payment addresses, min depth, max depth,
6035 * if the note is spent, if a spending key is required, and if the notes are locked.
6036 * These notes are decrypted and added to the output parameter vector, outEntries.
6038 void CWallet::GetFilteredNotes(
6039 std::vector<CSproutNotePlaintextEntry>& sproutEntries,
6040 std::vector<SaplingNoteEntry>& saplingEntries,
6041 std::set<PaymentAddress>& filterAddresses,
6045 bool requireSpendingKey,
6048 LOCK2(cs_main, cs_wallet);
6050 for (auto & p : mapWallet) {
6051 CWalletTx wtx = p.second;
6053 // Filter the transactions before checking for notes
6054 if (!CheckFinalTx(wtx) ||
6055 wtx.GetBlocksToMaturity() > 0 ||
6056 wtx.GetDepthInMainChain() < minDepth ||
6057 wtx.GetDepthInMainChain() > maxDepth) {
6061 for (auto & pair : wtx.mapSproutNoteData) {
6062 JSOutPoint jsop = pair.first;
6063 SproutNoteData nd = pair.second;
6064 SproutPaymentAddress pa = nd.address;
6066 // skip notes which belong to a different payment address in the wallet
6067 if (!(filterAddresses.empty() || filterAddresses.count(pa))) {
6071 // skip note which has been spent
6072 if (ignoreSpent && nd.nullifier && IsSproutSpent(*nd.nullifier)) {
6076 // skip notes which cannot be spent
6077 if (requireSpendingKey && !HaveSproutSpendingKey(pa)) {
6081 // skip locked notes
6082 if (ignoreLocked && IsLockedNote(jsop)) {
6086 int i = jsop.js; // Index into CTransaction.vjoinsplit
6087 int j = jsop.n; // Index into JSDescription.ciphertexts
6089 // Get cached decryptor
6090 ZCNoteDecryption decryptor;
6091 if (!GetNoteDecryptor(pa, decryptor)) {
6092 // Note decryptors are created when the wallet is loaded, so it should always exist
6093 throw std::runtime_error(strprintf("Could not find note decryptor for payment address %s", EncodePaymentAddress(pa)));
6096 // determine amount of funds in the note
6097 auto hSig = wtx.vjoinsplit[i].h_sig(*pzcashParams, wtx.joinSplitPubKey);
6099 SproutNotePlaintext plaintext = SproutNotePlaintext::decrypt(
6101 wtx.vjoinsplit[i].ciphertexts[j],
6102 wtx.vjoinsplit[i].ephemeralKey,
6106 sproutEntries.push_back(CSproutNotePlaintextEntry{jsop, pa, plaintext, wtx.GetDepthInMainChain()});
6108 } catch (const note_decryption_failed &err) {
6109 // Couldn't decrypt with this spending key
6110 throw std::runtime_error(strprintf("Could not decrypt note for payment address %s", EncodePaymentAddress(pa)));
6111 } catch (const std::exception &exc) {
6112 // Unexpected failure
6113 throw std::runtime_error(strprintf("Error while decrypting note for payment address %s: %s", EncodePaymentAddress(pa), exc.what()));
6117 for (auto & pair : wtx.mapSaplingNoteData) {
6118 SaplingOutPoint op = pair.first;
6119 SaplingNoteData nd = pair.second;
6121 auto maybe_pt = SaplingNotePlaintext::decrypt(
6122 wtx.vShieldedOutput[op.n].encCiphertext,
6124 wtx.vShieldedOutput[op.n].ephemeralKey,
6125 wtx.vShieldedOutput[op.n].cm);
6126 assert(static_cast<bool>(maybe_pt));
6127 auto notePt = maybe_pt.get();
6129 auto maybe_pa = nd.ivk.address(notePt.d);
6130 assert(static_cast<bool>(maybe_pa));
6131 auto pa = maybe_pa.get();
6133 // skip notes which belong to a different payment address in the wallet
6134 if (!(filterAddresses.empty() || filterAddresses.count(pa))) {
6138 if (ignoreSpent && nd.nullifier && IsSaplingSpent(*nd.nullifier)) {
6142 // skip notes which cannot be spent
6143 if (requireSpendingKey) {
6144 libzcash::SaplingIncomingViewingKey ivk;
6145 libzcash::SaplingFullViewingKey fvk;
6146 if (!(GetSaplingIncomingViewingKey(pa, ivk) &&
6147 GetSaplingFullViewingKey(ivk, fvk) &&
6148 HaveSaplingSpendingKey(fvk))) {
6153 // skip locked notes
6154 // TODO: Add locking for Sapling notes
6155 // if (ignoreLocked && IsLockedNote(op)) {
6159 auto note = notePt.note(nd.ivk).get();
6160 saplingEntries.push_back(SaplingNoteEntry {
6161 op, pa, note, notePt.memo(), wtx.GetDepthInMainChain() });
6168 // Shielded key and address generalizations
6171 bool PaymentAddressBelongsToWallet::operator()(const libzcash::SproutPaymentAddress &zaddr) const
6173 return m_wallet->HaveSproutSpendingKey(zaddr) || m_wallet->HaveSproutViewingKey(zaddr);
6176 bool PaymentAddressBelongsToWallet::operator()(const libzcash::SaplingPaymentAddress &zaddr) const
6178 libzcash::SaplingIncomingViewingKey ivk;
6180 // If we have a SaplingExtendedSpendingKey in the wallet, then we will
6181 // also have the corresponding SaplingFullViewingKey.
6182 return m_wallet->GetSaplingIncomingViewingKey(zaddr, ivk) &&
6183 m_wallet->HaveSaplingFullViewingKey(ivk);
6186 bool PaymentAddressBelongsToWallet::operator()(const libzcash::InvalidEncoding& no) const
6191 bool HaveSpendingKeyForPaymentAddress::operator()(const libzcash::SproutPaymentAddress &zaddr) const
6193 return m_wallet->HaveSproutSpendingKey(zaddr);
6196 bool HaveSpendingKeyForPaymentAddress::operator()(const libzcash::SaplingPaymentAddress &zaddr) const
6198 libzcash::SaplingIncomingViewingKey ivk;
6199 libzcash::SaplingFullViewingKey fvk;
6201 return m_wallet->GetSaplingIncomingViewingKey(zaddr, ivk) &&
6202 m_wallet->GetSaplingFullViewingKey(ivk, fvk) &&
6203 m_wallet->HaveSaplingSpendingKey(fvk);
6206 bool HaveSpendingKeyForPaymentAddress::operator()(const libzcash::InvalidEncoding& no) const
6211 boost::optional<libzcash::SpendingKey> GetSpendingKeyForPaymentAddress::operator()(
6212 const libzcash::SproutPaymentAddress &zaddr) const
6214 libzcash::SproutSpendingKey k;
6215 if (m_wallet->GetSproutSpendingKey(zaddr, k)) {
6216 return libzcash::SpendingKey(k);
6222 boost::optional<libzcash::SpendingKey> GetSpendingKeyForPaymentAddress::operator()(
6223 const libzcash::SaplingPaymentAddress &zaddr) const
6225 libzcash::SaplingExtendedSpendingKey extsk;
6226 if (m_wallet->GetSaplingExtendedSpendingKey(zaddr, extsk)) {
6227 return libzcash::SpendingKey(extsk);
6233 boost::optional<libzcash::SpendingKey> GetSpendingKeyForPaymentAddress::operator()(
6234 const libzcash::InvalidEncoding& no) const
6236 // Defaults to InvalidEncoding
6237 return libzcash::SpendingKey();
6240 SpendingKeyAddResult AddSpendingKeyToWallet::operator()(const libzcash::SproutSpendingKey &sk) const {
6241 auto addr = sk.address();
6243 LogPrint("zrpc", "Importing zaddr %s...\n", EncodePaymentAddress(addr));
6245 if (m_wallet->HaveSproutSpendingKey(addr)) {
6246 return KeyAlreadyExists;
6247 } else if (m_wallet-> AddSproutZKey(sk)) {
6248 m_wallet->mapSproutZKeyMetadata[addr].nCreateTime = nTime;
6255 SpendingKeyAddResult AddSpendingKeyToWallet::operator()(const libzcash::SaplingExtendedSpendingKey &sk) const {
6256 auto fvk = sk.expsk.full_viewing_key();
6257 auto ivk = fvk.in_viewing_key();
6258 auto addr = sk.DefaultAddress();
6261 LogPrint("zrpc", "Importing zaddr %s...\n", EncodePaymentAddress(addr));
6263 // Don't throw error in case a key is already there
6264 if (m_wallet->HaveSaplingSpendingKey(fvk)) {
6265 return KeyAlreadyExists;
6267 if (!m_wallet-> AddSaplingZKey(sk, addr)) {
6271 // Sapling addresses can't have been used in transactions prior to activation.
6272 if (params.vUpgrades[Consensus::UPGRADE_SAPLING].nActivationHeight == Consensus::NetworkUpgrade::ALWAYS_ACTIVE) {
6273 m_wallet->mapSaplingZKeyMetadata[ivk].nCreateTime = nTime;
6275 // 154051200 seconds from epoch is Friday, 26 October 2018 00:00:00 GMT - definitely before Sapling activates
6276 m_wallet->mapSaplingZKeyMetadata[ivk].nCreateTime = std::max((int64_t) 154051200, nTime);
6279 m_wallet->mapSaplingZKeyMetadata[ivk].hdKeypath = hdKeypath.get();
6283 seedFp.SetHex(seedFpStr.get());
6284 m_wallet->mapSaplingZKeyMetadata[ivk].seedFp = seedFp;
6291 SpendingKeyAddResult AddSpendingKeyToWallet::operator()(const libzcash::InvalidEncoding& no) const {
6292 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid spending key");