// mapWallet
//
+CWallet::CWallet()
+{
+ SetNull();
+}
+
+CWallet::CWallet(std::string strWalletFileIn)
+{
+ SetNull();
+
+ strWalletFile = strWalletFileIn;
+ fFileBacked = true;
+}
+
+void CWallet::SetNull()
+{
+ nWalletVersion = FEATURE_BASE;
+ nWalletMaxVersion = FEATURE_BASE;
+ fFileBacked = false;
+ nMasterKeyMaxID = 0;
+ pwalletdbEncryption = NULL;
+ pwalletdbDecryption = NULL;
+ nNextResend = 0;
+ nLastResend = 0;
+ nOrderPosNext = 0;
+ nKernelsTried = 0;
+ nCoinDaysTried = 0;
+ nTimeFirstKey = 0;
+}
+
struct CompareValueOnly
{
bool operator()(const pair<int64_t, pair<const CWalletTx*, unsigned int> >& t1,
return true;
}
+bool CWallet::LoadMinVersion(int nVersion)
+{
+ nWalletVersion = nVersion;
+ nWalletMaxVersion = max(nWalletMaxVersion, nVersion);
+ return true;
+}
+
bool CWallet::AddCScript(const CScript& redeemScript)
{
if (!CCryptoKeyStore::AddCScript(redeemScript))
auto mi2 = mapMalleableKeys.begin();
while (mi2 != mapMalleableKeys.end())
{
- const CSecret &vchSecretH = mi2->second;
- const CMalleableKeyView &keyView = mi2->first;
+ const auto &vchSecretH = mi2->second;
+ const auto &keyView = mi2->first;
pwalletdbDecryption->EraseCryptedMalleableKey(keyView);
pwalletdbDecryption->WriteMalleableKey(keyView, vchSecretH, mapKeyMetadata[CBitcoinAddress(keyView.GetMalleablePubKey())]);
mi2++;
for (auto it = mapWallet.begin(); it != mapWallet.end(); ++it)
{
CWalletTx* wtx = &((*it).second);
- txOrdered.insert(make_pair(wtx->nOrderPos, TxPair(wtx, (CAccountingEntry*)0)));
+ txOrdered.insert({ wtx->nOrderPos, { wtx, (CAccountingEntry*)0 } });
}
acentries.clear();
walletdb.ListAccountCreditDebit(strAccount, acentries);
for(auto& entry : acentries)
{
- txOrdered.insert(make_pair(entry.nOrderPos, TxPair((CWalletTx*)0, &entry)));
+ txOrdered.insert({ entry.nOrderPos, { (CWalletTx*)0, &entry } });
}
return txOrdered;
{
LOCK(cs_wallet);
// Inserts only if not already there, returns tx inserted or tx found
- auto ret = mapWallet.insert(make_pair(hash, wtxIn));
+ auto ret = mapWallet.insert({ hash, wtxIn });
auto& wtx = (*ret.first).second;
wtx.BindWallet(this);
bool fInsertedNew = ret.second;
return MINE_NO;
}
+
+CWalletTx::CWalletTx()
+{
+ Init(NULL);
+}
+
+CWalletTx::CWalletTx(const CWallet* pwalletIn)
+{
+ Init(pwalletIn);
+}
+
+CWalletTx::CWalletTx(const CWallet* pwalletIn, const CMerkleTx& txIn) : CMerkleTx(txIn)
+{
+ Init(pwalletIn);
+}
+
+CWalletTx::CWalletTx(const CWallet* pwalletIn, const CTransaction& txIn) : CMerkleTx(txIn)
+{
+ Init(pwalletIn);
+}
+
+void CWalletTx::Init(const CWallet* pwalletIn)
+{
+ pwallet = pwalletIn;
+ vtxPrev.clear();
+ mapValue.clear();
+ vOrderForm.clear();
+ fTimeReceivedIsTxTime = false;
+ nTimeReceived = 0;
+ nTimeSmart = 0;
+ fFromMe = false;
+ strFromAccount.clear();
+ vfSpent.clear();
+ fDebitCached = false;
+ fWatchDebitCached = false;
+ fCreditCached = false;
+ fWatchCreditCached = false;
+ fAvailableCreditCached = false;
+ fAvailableWatchCreditCached = false;
+ fImmatureCreditCached = false;
+ fImmatureWatchCreditCached = false;
+ fChangeCached = false;
+ nDebitCached = 0;
+ nWatchDebitCached = 0;
+ nCreditCached = 0;
+ nWatchCreditCached = 0;
+ nAvailableCreditCached = 0;
+ nAvailableWatchCreditCached = 0;
+ nImmatureCreditCached = 0;
+ nImmatureWatchCreditCached = 0;
+ nChangeCached = 0;
+ nOrderPos = -1;
+}
+
// marks certain txout's as spent
// returns true if any update took place
bool CWalletTx::UpdateSpent(const vector<char>& vfNewSpent)
int64_t CWallet::GetDebit(const CTransaction& tx, const isminefilter& filter) const
{
- int64_t nDebit = 0;
+ CBigNum nDebit = 0;
for(const CTxIn& txin : tx.vin)
{
- nDebit += GetDebit(txin, filter);
- if (!MoneyRange(nDebit))
+ auto nValue = GetDebit(txin, filter);
+ nDebit += nValue;
+ if (!MoneyRange(nValue) || !MoneyRange(nDebit))
throw runtime_error("CWallet::GetDebit() : value out of range");
}
- return nDebit;
+ return nDebit.getint64();
}
int64_t CWallet::GetCredit(const CTransaction& tx, const isminefilter& filter) const
{
- int64_t nCredit = 0;
+ CBigNum nCredit = 0;
for(const CTxOut& txout : tx.vout)
{
- nCredit += GetCredit(txout, filter);
- if (!MoneyRange(nCredit))
+ auto nValue = GetCredit(txout, filter);
+ nCredit += nValue;
+ if (!MoneyRange(nValue) || !MoneyRange(nCredit))
throw runtime_error("CWallet::GetCredit() : value out of range");
}
- return nCredit;
+ return nCredit.getint64();
}
int64_t CWallet::GetChange(const CTransaction& tx) const
{
- int64_t nChange = 0;
+ CBigNum nChange = 0;
for(const CTxOut& txout : tx.vout)
{
- nChange += GetChange(txout);
- if (!MoneyRange(nChange))
+ int64_t nValue = GetChange(txout);
+ nChange += nValue;
+ if (!MoneyRange(nValue) || !MoneyRange(nChange))
throw runtime_error("CWallet::GetChange() : value out of range");
}
- return nChange;
+ return nChange.getint64();
}
int64_t CWalletTx::GetTxTime() const
return nAvailableCreditCached;
}
- int64_t nCredit = 0;
- for (unsigned int i = 0; i < vout.size(); i++)
+ CBigNum nCredit = 0;
+ for (uint32_t i = 0; i < vout.size(); i++)
{
if (!IsSpent(i))
{
const CTxOut &txout = vout[i];
- nCredit += pwallet->GetCredit(txout, MINE_SPENDABLE);
- if (!MoneyRange(nCredit))
+ int64_t nValue = pwallet->GetCredit(txout, MINE_SPENDABLE);
+ nCredit += nValue;
+ if (!MoneyRange(nValue) || !MoneyRange(nCredit))
throw runtime_error("CWalletTx::GetAvailableCredit() : value out of range");
}
}
- nAvailableCreditCached = nCredit;
+ nAvailableCreditCached = nCredit.getint64();
fAvailableCreditCached = true;
- return nCredit;
+ return nCredit.getint64();
}
int64_t CWalletTx::GetAvailableWatchCredit(bool fUseCache) const
return nAvailableWatchCreditCached;
}
- int64_t nCredit = 0;
+ CBigNum nCredit = 0;
for (unsigned int i = 0; i < vout.size(); i++)
{
if (!IsSpent(i))
{
const CTxOut &txout = vout[i];
- nCredit += pwallet->GetCredit(txout, MINE_WATCH_ONLY);
- if (!MoneyRange(nCredit))
+ int64_t nValue = pwallet->GetCredit(txout, MINE_WATCH_ONLY);
+ nCredit += nValue;
+ if (!MoneyRange(nValue) || !MoneyRange(nCredit))
throw runtime_error("CWalletTx::GetAvailableCredit() : value out of range");
}
}
- nAvailableWatchCreditCached = nCredit;
+ nAvailableWatchCreditCached = nCredit.getint64();
fAvailableWatchCreditCached = true;
- return nCredit;
+ return nCredit.getint64();
}
int64_t CWalletTx::GetChange() const
// If we are debited by the transaction, add the output as a "sent" entry
if (nDebit > 0)
- listSent.push_back(make_pair(address, txout.nValue));
+ listSent.push_back({ address, txout.nValue });
// If we are receiving the output, add it as a "received" entry
if (fIsMine & filter)
- listReceived.push_back(make_pair(address, txout.nValue));
+ listReceived.push_back({ address, txout.nValue });
}
}
// Don't rebroadcast if newer than nTime:
if (wtx.nTimeReceived > nTime)
continue;
- mapSorted.insert(make_pair(wtx.nTimeReceived, &wtx));
+ mapSorted.insert({ wtx.nTimeReceived, &wtx });
}
for(auto& item : mapSorted)
{
continue;
auto n = pcoin->vout[i].nValue;
- auto coin = make_pair(n,make_pair(pcoin, i));
+ auto coin = make_pair(n, make_pair(pcoin, i));
if (n == nTargetValue)
{
if(!out.fSpendable)
continue;
nValueRet += out.tx->vout[out.i].nValue;
- setCoinsRet.insert(make_pair(out.tx, out.i));
+ setCoinsRet.insert({ out.tx, out.i });
}
return (nValueRet >= nTargetValue);
}
continue;
auto n = pcoin->vout[i].nValue;
- auto coin = make_pair(n,make_pair(pcoin, i));
+ auto coin = make_pair(n, make_pair(pcoin, i));
if (n >= nTargetValue)
{
wtxNew.vin.push_back(CTxIn(coin.first->GetHash(),coin.second));
// Sign
- int nIn = 0;
+ uint32_t nIn = 0;
for(const auto& coin : setCoins)
if (!SignSignature(*this, *coin.first, wtxNew, nIn++))
return false;
bool CWallet::CreateTransaction(CScript scriptPubKey, int64_t nValue, CWalletTx& wtxNew, CReserveKey& reservekey, int64_t& nFeeRet, const CCoinControl* coinControl)
{
vector< pair<CScript, int64_t> > vecSend;
- vecSend.push_back(make_pair(scriptPubKey, nValue));
+ vecSend.push_back({ scriptPubKey, nValue });
return CreateTransaction(vecSend, wtxNew, reservekey, nFeeRet, coinControl);
}
if (wtxNew.vout[0].nValue <= 0)
return false;
- for (unsigned int i = 0; i < wtxNew.vin.size(); i++) {
+ for (uint32_t i = 0; i < wtxNew.vin.size(); i++) {
const CWalletTx *txin = vwtxPrev[i];
// Sign all scripts again
}
// Sign
- int nIn = 0;
+ uint32_t nIn = 0;
for(const CWalletTx* pcoin : vwtxPrev)
{
if (!SignSignature(*this, *pcoin, txNew, nIn++))
}
// Limit size
- unsigned int nBytes = ::GetSerializeSize(txNew, SER_NETWORK, PROTOCOL_VERSION);
+ auto nBytes = ::GetSerializeSize(txNew, SER_NETWORK, PROTOCOL_VERSION);
if (nBytes >= MAX_BLOCK_SIZE_GEN/5)
return error("CreateCoinStake : exceeded coinstake size limit\n");
printf("\n");
}
+void CWallet::Inventory(const uint256 &hash)
+{
+ {
+ LOCK(cs_wallet);
+ auto mi = mapRequestCount.find(hash);
+ if (mi != mapRequestCount.end())
+ (*mi).second++;
+ }
+}
+
bool CWallet::GetTransaction(const uint256 &hashTx, CWalletTx& wtx)
{
{
{
CWalletTx *pcoin = &walletEntry.second;
- if (pcoin->vin.size() > 0 && IsMine(pcoin->vin[0]))
+ if (pcoin->vin.size() > 0)
{
+ bool any_mine = false;
// group all input addresses with each other
for(CTxIn txin : pcoin->vin)
{
CBitcoinAddress address;
+ if(!IsMine(txin)) // If this input isn't mine, ignore it
+ continue;
if(!ExtractAddress(*this, mapWallet[txin.prevout.hash].vout[txin.prevout.n].scriptPubKey, address))
continue;
grouping.insert(address);
+ any_mine = true;
}
// group change with input addresses
+ if (any_mine)
+ {
for(CTxOut txout : pcoin->vout)
if (IsChange(txout))
{
- auto tx = mapWallet[pcoin->vin[0].prevout.hash];
CBitcoinAddress txoutAddr;
if(!ExtractAddress(*this, txout.scriptPubKey, txoutAddr))
continue;
grouping.insert(txoutAddr);
}
- groupings.insert(grouping);
- grouping.clear();
+ }
+ if (!grouping.empty())
+ {
+ groupings.insert(grouping);
+ grouping.clear();
+ }
}
// group lone addrs by themselves