mirror of
https://github.com/kvazar-network/kevacoin.git
synced 2025-01-12 16:17:53 +00:00
Merge pull request #5509
7f991e3
c++11: These look like user-defined literals. (Cory Fields)5a6155c
c++11: don't forward-declare types used in maps (Cory Fields)3447cf8
c++11: MOVEONLY: break circular dependency in wallet (Cory Fields)bbacd88
c++11: MOVEONLY: move function definitions out of the header (Cory Fields)a2b04dd
build: fix newer boost build with c++11 (Cory Fields)
This commit is contained in:
commit
31dedb463b
@ -156,11 +156,11 @@ public:
|
|||||||
vSeeds.push_back(CDNSSeedData("bitcoinstats.com", "seed.bitcoinstats.com"));
|
vSeeds.push_back(CDNSSeedData("bitcoinstats.com", "seed.bitcoinstats.com"));
|
||||||
vSeeds.push_back(CDNSSeedData("xf2.org", "bitseed.xf2.org"));
|
vSeeds.push_back(CDNSSeedData("xf2.org", "bitseed.xf2.org"));
|
||||||
|
|
||||||
base58Prefixes[PUBKEY_ADDRESS] = boost::assign::list_of(0);
|
base58Prefixes[PUBKEY_ADDRESS] = std::vector<unsigned char>(1,0);
|
||||||
base58Prefixes[SCRIPT_ADDRESS] = boost::assign::list_of(5);
|
base58Prefixes[SCRIPT_ADDRESS] = std::vector<unsigned char>(1,5);
|
||||||
base58Prefixes[SECRET_KEY] = boost::assign::list_of(128);
|
base58Prefixes[SECRET_KEY] = std::vector<unsigned char>(1,128);
|
||||||
base58Prefixes[EXT_PUBLIC_KEY] = boost::assign::list_of(0x04)(0x88)(0xB2)(0x1E);
|
base58Prefixes[EXT_PUBLIC_KEY] = boost::assign::list_of(0x04)(0x88)(0xB2)(0x1E).convert_to_container<std::vector<unsigned char> >();
|
||||||
base58Prefixes[EXT_SECRET_KEY] = boost::assign::list_of(0x04)(0x88)(0xAD)(0xE4);
|
base58Prefixes[EXT_SECRET_KEY] = boost::assign::list_of(0x04)(0x88)(0xAD)(0xE4).convert_to_container<std::vector<unsigned char> >();
|
||||||
|
|
||||||
convertSeed6(vFixedSeeds, pnSeed6_main, ARRAYLEN(pnSeed6_main));
|
convertSeed6(vFixedSeeds, pnSeed6_main, ARRAYLEN(pnSeed6_main));
|
||||||
|
|
||||||
@ -214,11 +214,11 @@ public:
|
|||||||
vSeeds.push_back(CDNSSeedData("bluematt.me", "testnet-seed.bluematt.me"));
|
vSeeds.push_back(CDNSSeedData("bluematt.me", "testnet-seed.bluematt.me"));
|
||||||
vSeeds.push_back(CDNSSeedData("bitcoin.schildbach.de", "testnet-seed.bitcoin.schildbach.de"));
|
vSeeds.push_back(CDNSSeedData("bitcoin.schildbach.de", "testnet-seed.bitcoin.schildbach.de"));
|
||||||
|
|
||||||
base58Prefixes[PUBKEY_ADDRESS] = boost::assign::list_of(111);
|
base58Prefixes[PUBKEY_ADDRESS] = std::vector<unsigned char>(1,111);
|
||||||
base58Prefixes[SCRIPT_ADDRESS] = boost::assign::list_of(196);
|
base58Prefixes[SCRIPT_ADDRESS] = std::vector<unsigned char>(1,196);
|
||||||
base58Prefixes[SECRET_KEY] = boost::assign::list_of(239);
|
base58Prefixes[SECRET_KEY] = std::vector<unsigned char>(1,239);
|
||||||
base58Prefixes[EXT_PUBLIC_KEY] = boost::assign::list_of(0x04)(0x35)(0x87)(0xCF);
|
base58Prefixes[EXT_PUBLIC_KEY] = boost::assign::list_of(0x04)(0x35)(0x87)(0xCF).convert_to_container<std::vector<unsigned char> >();
|
||||||
base58Prefixes[EXT_SECRET_KEY] = boost::assign::list_of(0x04)(0x35)(0x83)(0x94);
|
base58Prefixes[EXT_SECRET_KEY] = boost::assign::list_of(0x04)(0x35)(0x83)(0x94).convert_to_container<std::vector<unsigned char> >();
|
||||||
|
|
||||||
convertSeed6(vFixedSeeds, pnSeed6_test, ARRAYLEN(pnSeed6_test));
|
convertSeed6(vFixedSeeds, pnSeed6_test, ARRAYLEN(pnSeed6_test));
|
||||||
|
|
||||||
|
@ -7,8 +7,6 @@
|
|||||||
|
|
||||||
#include "crypter.h"
|
#include "crypter.h"
|
||||||
#include "key.h"
|
#include "key.h"
|
||||||
#include "script/script.h"
|
|
||||||
#include "script/standard.h"
|
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
#include <boost/foreach.hpp>
|
#include <boost/foreach.hpp>
|
||||||
|
@ -8,14 +8,13 @@
|
|||||||
|
|
||||||
#include "key.h"
|
#include "key.h"
|
||||||
#include "pubkey.h"
|
#include "pubkey.h"
|
||||||
|
#include "script/script.h"
|
||||||
|
#include "script/standard.h"
|
||||||
#include "sync.h"
|
#include "sync.h"
|
||||||
|
|
||||||
#include <boost/signals2/signal.hpp>
|
#include <boost/signals2/signal.hpp>
|
||||||
#include <boost/variant.hpp>
|
#include <boost/variant.hpp>
|
||||||
|
|
||||||
class CScript;
|
|
||||||
class CScriptID;
|
|
||||||
|
|
||||||
/** A virtual base class for key stores */
|
/** A virtual base class for key stores */
|
||||||
class CKeyStore
|
class CKeyStore
|
||||||
{
|
{
|
||||||
|
@ -282,21 +282,21 @@ BOOST_AUTO_TEST_CASE(strprintf_numbers)
|
|||||||
{
|
{
|
||||||
int64_t s64t = -9223372036854775807LL; /* signed 64 bit test value */
|
int64_t s64t = -9223372036854775807LL; /* signed 64 bit test value */
|
||||||
uint64_t u64t = 18446744073709551615ULL; /* unsigned 64 bit test value */
|
uint64_t u64t = 18446744073709551615ULL; /* unsigned 64 bit test value */
|
||||||
BOOST_CHECK(strprintf("%s %d %s", B, s64t, E) == B" -9223372036854775807 "E);
|
BOOST_CHECK(strprintf("%s %d %s", B, s64t, E) == B" -9223372036854775807 " E);
|
||||||
BOOST_CHECK(strprintf("%s %u %s", B, u64t, E) == B" 18446744073709551615 "E);
|
BOOST_CHECK(strprintf("%s %u %s", B, u64t, E) == B" 18446744073709551615 " E);
|
||||||
BOOST_CHECK(strprintf("%s %x %s", B, u64t, E) == B" ffffffffffffffff "E);
|
BOOST_CHECK(strprintf("%s %x %s", B, u64t, E) == B" ffffffffffffffff " E);
|
||||||
|
|
||||||
size_t st = 12345678; /* unsigned size_t test value */
|
size_t st = 12345678; /* unsigned size_t test value */
|
||||||
ssize_t sst = -12345678; /* signed size_t test value */
|
ssize_t sst = -12345678; /* signed size_t test value */
|
||||||
BOOST_CHECK(strprintf("%s %d %s", B, sst, E) == B" -12345678 "E);
|
BOOST_CHECK(strprintf("%s %d %s", B, sst, E) == B" -12345678 " E);
|
||||||
BOOST_CHECK(strprintf("%s %u %s", B, st, E) == B" 12345678 "E);
|
BOOST_CHECK(strprintf("%s %u %s", B, st, E) == B" 12345678 " E);
|
||||||
BOOST_CHECK(strprintf("%s %x %s", B, st, E) == B" bc614e "E);
|
BOOST_CHECK(strprintf("%s %x %s", B, st, E) == B" bc614e " E);
|
||||||
|
|
||||||
ptrdiff_t pt = 87654321; /* positive ptrdiff_t test value */
|
ptrdiff_t pt = 87654321; /* positive ptrdiff_t test value */
|
||||||
ptrdiff_t spt = -87654321; /* negative ptrdiff_t test value */
|
ptrdiff_t spt = -87654321; /* negative ptrdiff_t test value */
|
||||||
BOOST_CHECK(strprintf("%s %d %s", B, spt, E) == B" -87654321 "E);
|
BOOST_CHECK(strprintf("%s %d %s", B, spt, E) == B" -87654321 " E);
|
||||||
BOOST_CHECK(strprintf("%s %u %s", B, pt, E) == B" 87654321 "E);
|
BOOST_CHECK(strprintf("%s %u %s", B, pt, E) == B" 87654321 " E);
|
||||||
BOOST_CHECK(strprintf("%s %x %s", B, pt, E) == B" 5397fb1 "E);
|
BOOST_CHECK(strprintf("%s %x %s", B, pt, E) == B" 5397fb1 " E);
|
||||||
}
|
}
|
||||||
#undef B
|
#undef B
|
||||||
#undef E
|
#undef E
|
||||||
|
187
src/wallet.cpp
187
src/wallet.cpp
@ -1015,6 +1015,193 @@ set<uint256> CWalletTx::GetConflicts() const
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CAmount CWalletTx::GetDebit(const isminefilter& filter) const
|
||||||
|
{
|
||||||
|
if (vin.empty())
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
CAmount debit = 0;
|
||||||
|
if(filter & ISMINE_SPENDABLE)
|
||||||
|
{
|
||||||
|
if (fDebitCached)
|
||||||
|
debit += nDebitCached;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
nDebitCached = pwallet->GetDebit(*this, ISMINE_SPENDABLE);
|
||||||
|
fDebitCached = true;
|
||||||
|
debit += nDebitCached;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(filter & ISMINE_WATCH_ONLY)
|
||||||
|
{
|
||||||
|
if(fWatchDebitCached)
|
||||||
|
debit += nWatchDebitCached;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
nWatchDebitCached = pwallet->GetDebit(*this, ISMINE_WATCH_ONLY);
|
||||||
|
fWatchDebitCached = true;
|
||||||
|
debit += nWatchDebitCached;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return debit;
|
||||||
|
}
|
||||||
|
|
||||||
|
CAmount CWalletTx::GetCredit(const isminefilter& filter) const
|
||||||
|
{
|
||||||
|
// Must wait until coinbase is safely deep enough in the chain before valuing it
|
||||||
|
if (IsCoinBase() && GetBlocksToMaturity() > 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
int64_t credit = 0;
|
||||||
|
if (filter & ISMINE_SPENDABLE)
|
||||||
|
{
|
||||||
|
// GetBalance can assume transactions in mapWallet won't change
|
||||||
|
if (fCreditCached)
|
||||||
|
credit += nCreditCached;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
nCreditCached = pwallet->GetCredit(*this, ISMINE_SPENDABLE);
|
||||||
|
fCreditCached = true;
|
||||||
|
credit += nCreditCached;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (filter & ISMINE_WATCH_ONLY)
|
||||||
|
{
|
||||||
|
if (fWatchCreditCached)
|
||||||
|
credit += nWatchCreditCached;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
nWatchCreditCached = pwallet->GetCredit(*this, ISMINE_WATCH_ONLY);
|
||||||
|
fWatchCreditCached = true;
|
||||||
|
credit += nWatchCreditCached;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return credit;
|
||||||
|
}
|
||||||
|
|
||||||
|
CAmount CWalletTx::GetImmatureCredit(bool fUseCache) const
|
||||||
|
{
|
||||||
|
if (IsCoinBase() && GetBlocksToMaturity() > 0 && IsInMainChain())
|
||||||
|
{
|
||||||
|
if (fUseCache && fImmatureCreditCached)
|
||||||
|
return nImmatureCreditCached;
|
||||||
|
nImmatureCreditCached = pwallet->GetCredit(*this, ISMINE_SPENDABLE);
|
||||||
|
fImmatureCreditCached = true;
|
||||||
|
return nImmatureCreditCached;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
CAmount CWalletTx::GetAvailableCredit(bool fUseCache) const
|
||||||
|
{
|
||||||
|
if (pwallet == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
// Must wait until coinbase is safely deep enough in the chain before valuing it
|
||||||
|
if (IsCoinBase() && GetBlocksToMaturity() > 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (fUseCache && fAvailableCreditCached)
|
||||||
|
return nAvailableCreditCached;
|
||||||
|
|
||||||
|
CAmount nCredit = 0;
|
||||||
|
uint256 hashTx = GetHash();
|
||||||
|
for (unsigned int i = 0; i < vout.size(); i++)
|
||||||
|
{
|
||||||
|
if (!pwallet->IsSpent(hashTx, i))
|
||||||
|
{
|
||||||
|
const CTxOut &txout = vout[i];
|
||||||
|
nCredit += pwallet->GetCredit(txout, ISMINE_SPENDABLE);
|
||||||
|
if (!MoneyRange(nCredit))
|
||||||
|
throw std::runtime_error("CWalletTx::GetAvailableCredit() : value out of range");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
nAvailableCreditCached = nCredit;
|
||||||
|
fAvailableCreditCached = true;
|
||||||
|
return nCredit;
|
||||||
|
}
|
||||||
|
|
||||||
|
CAmount CWalletTx::GetImmatureWatchOnlyCredit(const bool& fUseCache) const
|
||||||
|
{
|
||||||
|
if (IsCoinBase() && GetBlocksToMaturity() > 0 && IsInMainChain())
|
||||||
|
{
|
||||||
|
if (fUseCache && fImmatureWatchCreditCached)
|
||||||
|
return nImmatureWatchCreditCached;
|
||||||
|
nImmatureWatchCreditCached = pwallet->GetCredit(*this, ISMINE_WATCH_ONLY);
|
||||||
|
fImmatureWatchCreditCached = true;
|
||||||
|
return nImmatureWatchCreditCached;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
CAmount CWalletTx::GetAvailableWatchOnlyCredit(const bool& fUseCache) const
|
||||||
|
{
|
||||||
|
if (pwallet == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
// Must wait until coinbase is safely deep enough in the chain before valuing it
|
||||||
|
if (IsCoinBase() && GetBlocksToMaturity() > 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (fUseCache && fAvailableWatchCreditCached)
|
||||||
|
return nAvailableWatchCreditCached;
|
||||||
|
|
||||||
|
CAmount nCredit = 0;
|
||||||
|
for (unsigned int i = 0; i < vout.size(); i++)
|
||||||
|
{
|
||||||
|
if (!pwallet->IsSpent(GetHash(), i))
|
||||||
|
{
|
||||||
|
const CTxOut &txout = vout[i];
|
||||||
|
nCredit += pwallet->GetCredit(txout, ISMINE_WATCH_ONLY);
|
||||||
|
if (!MoneyRange(nCredit))
|
||||||
|
throw std::runtime_error("CWalletTx::GetAvailableCredit() : value out of range");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
nAvailableWatchCreditCached = nCredit;
|
||||||
|
fAvailableWatchCreditCached = true;
|
||||||
|
return nCredit;
|
||||||
|
}
|
||||||
|
|
||||||
|
CAmount CWalletTx::GetChange() const
|
||||||
|
{
|
||||||
|
if (fChangeCached)
|
||||||
|
return nChangeCached;
|
||||||
|
nChangeCached = pwallet->GetChange(*this);
|
||||||
|
fChangeCached = true;
|
||||||
|
return nChangeCached;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CWalletTx::IsTrusted() const
|
||||||
|
{
|
||||||
|
// Quick answer in most cases
|
||||||
|
if (!IsFinalTx(*this))
|
||||||
|
return false;
|
||||||
|
int nDepth = GetDepthInMainChain();
|
||||||
|
if (nDepth >= 1)
|
||||||
|
return true;
|
||||||
|
if (nDepth < 0)
|
||||||
|
return false;
|
||||||
|
if (!bSpendZeroConfChange || !IsFromMe(ISMINE_ALL)) // using wtx's cached debit
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Trusted if all inputs are from us and are in the mempool:
|
||||||
|
BOOST_FOREACH(const CTxIn& txin, vin)
|
||||||
|
{
|
||||||
|
// Transactions not sent by us: not trusted
|
||||||
|
const CWalletTx* parent = pwallet->GetWalletTx(txin.prevout.hash);
|
||||||
|
if (parent == NULL)
|
||||||
|
return false;
|
||||||
|
const CTxOut& parentOut = parent->vout[txin.prevout.n];
|
||||||
|
if (pwallet->IsMine(parentOut) != ISMINE_SPENDABLE)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void CWallet::ResendWalletTransactions()
|
void CWallet::ResendWalletTransactions()
|
||||||
{
|
{
|
||||||
// Do this infrequently and randomly to avoid giving away
|
// Do this infrequently and randomly to avoid giving away
|
||||||
|
825
src/wallet.h
825
src/wallet.h
@ -103,6 +103,329 @@ public:
|
|||||||
StringMap destdata;
|
StringMap destdata;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
typedef std::map<std::string, std::string> mapValue_t;
|
||||||
|
|
||||||
|
|
||||||
|
static void ReadOrderPos(int64_t& nOrderPos, mapValue_t& mapValue)
|
||||||
|
{
|
||||||
|
if (!mapValue.count("n"))
|
||||||
|
{
|
||||||
|
nOrderPos = -1; // TODO: calculate elsewhere
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
nOrderPos = atoi64(mapValue["n"].c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void WriteOrderPos(const int64_t& nOrderPos, mapValue_t& mapValue)
|
||||||
|
{
|
||||||
|
if (nOrderPos == -1)
|
||||||
|
return;
|
||||||
|
mapValue["n"] = i64tostr(nOrderPos);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct COutputEntry
|
||||||
|
{
|
||||||
|
CTxDestination destination;
|
||||||
|
CAmount amount;
|
||||||
|
int vout;
|
||||||
|
};
|
||||||
|
|
||||||
|
/** A transaction with a merkle branch linking it to the block chain. */
|
||||||
|
class CMerkleTx : public CTransaction
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
int GetDepthInMainChainINTERNAL(const CBlockIndex* &pindexRet) const;
|
||||||
|
|
||||||
|
public:
|
||||||
|
uint256 hashBlock;
|
||||||
|
std::vector<uint256> vMerkleBranch;
|
||||||
|
int nIndex;
|
||||||
|
|
||||||
|
// memory only
|
||||||
|
mutable bool fMerkleVerified;
|
||||||
|
|
||||||
|
|
||||||
|
CMerkleTx()
|
||||||
|
{
|
||||||
|
Init();
|
||||||
|
}
|
||||||
|
|
||||||
|
CMerkleTx(const CTransaction& txIn) : CTransaction(txIn)
|
||||||
|
{
|
||||||
|
Init();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Init()
|
||||||
|
{
|
||||||
|
hashBlock = uint256();
|
||||||
|
nIndex = -1;
|
||||||
|
fMerkleVerified = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ADD_SERIALIZE_METHODS;
|
||||||
|
|
||||||
|
template <typename Stream, typename Operation>
|
||||||
|
inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
|
||||||
|
READWRITE(*(CTransaction*)this);
|
||||||
|
nVersion = this->nVersion;
|
||||||
|
READWRITE(hashBlock);
|
||||||
|
READWRITE(vMerkleBranch);
|
||||||
|
READWRITE(nIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
int SetMerkleBranch(const CBlock& block);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return depth of transaction in blockchain:
|
||||||
|
* -1 : not in blockchain, and not in memory pool (conflicted transaction)
|
||||||
|
* 0 : in memory pool, waiting to be included in a block
|
||||||
|
* >=1 : this many blocks deep in the main chain
|
||||||
|
*/
|
||||||
|
int GetDepthInMainChain(const CBlockIndex* &pindexRet) const;
|
||||||
|
int GetDepthInMainChain() const { const CBlockIndex *pindexRet; return GetDepthInMainChain(pindexRet); }
|
||||||
|
bool IsInMainChain() const { const CBlockIndex *pindexRet; return GetDepthInMainChainINTERNAL(pindexRet) > 0; }
|
||||||
|
int GetBlocksToMaturity() const;
|
||||||
|
bool AcceptToMemoryPool(bool fLimitFree=true, bool fRejectAbsurdFee=true);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A transaction with a bunch of additional info that only the owner cares about.
|
||||||
|
* It includes any unrecorded transactions needed to link it back to the block chain.
|
||||||
|
*/
|
||||||
|
class CWalletTx : public CMerkleTx
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
const CWallet* pwallet;
|
||||||
|
|
||||||
|
public:
|
||||||
|
mapValue_t mapValue;
|
||||||
|
std::vector<std::pair<std::string, std::string> > vOrderForm;
|
||||||
|
unsigned int fTimeReceivedIsTxTime;
|
||||||
|
unsigned int nTimeReceived; //! time received by this node
|
||||||
|
unsigned int nTimeSmart;
|
||||||
|
char fFromMe;
|
||||||
|
std::string strFromAccount;
|
||||||
|
int64_t nOrderPos; //! position in ordered transaction list
|
||||||
|
|
||||||
|
// memory only
|
||||||
|
mutable bool fDebitCached;
|
||||||
|
mutable bool fCreditCached;
|
||||||
|
mutable bool fImmatureCreditCached;
|
||||||
|
mutable bool fAvailableCreditCached;
|
||||||
|
mutable bool fWatchDebitCached;
|
||||||
|
mutable bool fWatchCreditCached;
|
||||||
|
mutable bool fImmatureWatchCreditCached;
|
||||||
|
mutable bool fAvailableWatchCreditCached;
|
||||||
|
mutable bool fChangeCached;
|
||||||
|
mutable CAmount nDebitCached;
|
||||||
|
mutable CAmount nCreditCached;
|
||||||
|
mutable CAmount nImmatureCreditCached;
|
||||||
|
mutable CAmount nAvailableCreditCached;
|
||||||
|
mutable CAmount nWatchDebitCached;
|
||||||
|
mutable CAmount nWatchCreditCached;
|
||||||
|
mutable CAmount nImmatureWatchCreditCached;
|
||||||
|
mutable CAmount nAvailableWatchCreditCached;
|
||||||
|
mutable CAmount nChangeCached;
|
||||||
|
|
||||||
|
CWalletTx()
|
||||||
|
{
|
||||||
|
Init(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
CWalletTx(const CWallet* pwalletIn)
|
||||||
|
{
|
||||||
|
Init(pwalletIn);
|
||||||
|
}
|
||||||
|
|
||||||
|
CWalletTx(const CWallet* pwalletIn, const CMerkleTx& txIn) : CMerkleTx(txIn)
|
||||||
|
{
|
||||||
|
Init(pwalletIn);
|
||||||
|
}
|
||||||
|
|
||||||
|
CWalletTx(const CWallet* pwalletIn, const CTransaction& txIn) : CMerkleTx(txIn)
|
||||||
|
{
|
||||||
|
Init(pwalletIn);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Init(const CWallet* pwalletIn)
|
||||||
|
{
|
||||||
|
pwallet = pwalletIn;
|
||||||
|
mapValue.clear();
|
||||||
|
vOrderForm.clear();
|
||||||
|
fTimeReceivedIsTxTime = false;
|
||||||
|
nTimeReceived = 0;
|
||||||
|
nTimeSmart = 0;
|
||||||
|
fFromMe = false;
|
||||||
|
strFromAccount.clear();
|
||||||
|
fDebitCached = false;
|
||||||
|
fCreditCached = false;
|
||||||
|
fImmatureCreditCached = false;
|
||||||
|
fAvailableCreditCached = false;
|
||||||
|
fWatchDebitCached = false;
|
||||||
|
fWatchCreditCached = false;
|
||||||
|
fImmatureWatchCreditCached = false;
|
||||||
|
fAvailableWatchCreditCached = false;
|
||||||
|
fChangeCached = false;
|
||||||
|
nDebitCached = 0;
|
||||||
|
nCreditCached = 0;
|
||||||
|
nImmatureCreditCached = 0;
|
||||||
|
nAvailableCreditCached = 0;
|
||||||
|
nWatchDebitCached = 0;
|
||||||
|
nWatchCreditCached = 0;
|
||||||
|
nAvailableWatchCreditCached = 0;
|
||||||
|
nImmatureWatchCreditCached = 0;
|
||||||
|
nChangeCached = 0;
|
||||||
|
nOrderPos = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ADD_SERIALIZE_METHODS;
|
||||||
|
|
||||||
|
template <typename Stream, typename Operation>
|
||||||
|
inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
|
||||||
|
if (ser_action.ForRead())
|
||||||
|
Init(NULL);
|
||||||
|
char fSpent = false;
|
||||||
|
|
||||||
|
if (!ser_action.ForRead())
|
||||||
|
{
|
||||||
|
mapValue["fromaccount"] = strFromAccount;
|
||||||
|
|
||||||
|
WriteOrderPos(nOrderPos, mapValue);
|
||||||
|
|
||||||
|
if (nTimeSmart)
|
||||||
|
mapValue["timesmart"] = strprintf("%u", nTimeSmart);
|
||||||
|
}
|
||||||
|
|
||||||
|
READWRITE(*(CMerkleTx*)this);
|
||||||
|
std::vector<CMerkleTx> vUnused; //! Used to be vtxPrev
|
||||||
|
READWRITE(vUnused);
|
||||||
|
READWRITE(mapValue);
|
||||||
|
READWRITE(vOrderForm);
|
||||||
|
READWRITE(fTimeReceivedIsTxTime);
|
||||||
|
READWRITE(nTimeReceived);
|
||||||
|
READWRITE(fFromMe);
|
||||||
|
READWRITE(fSpent);
|
||||||
|
|
||||||
|
if (ser_action.ForRead())
|
||||||
|
{
|
||||||
|
strFromAccount = mapValue["fromaccount"];
|
||||||
|
|
||||||
|
ReadOrderPos(nOrderPos, mapValue);
|
||||||
|
|
||||||
|
nTimeSmart = mapValue.count("timesmart") ? (unsigned int)atoi64(mapValue["timesmart"]) : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
mapValue.erase("fromaccount");
|
||||||
|
mapValue.erase("version");
|
||||||
|
mapValue.erase("spent");
|
||||||
|
mapValue.erase("n");
|
||||||
|
mapValue.erase("timesmart");
|
||||||
|
}
|
||||||
|
|
||||||
|
//! make sure balances are recalculated
|
||||||
|
void MarkDirty()
|
||||||
|
{
|
||||||
|
fCreditCached = false;
|
||||||
|
fAvailableCreditCached = false;
|
||||||
|
fWatchDebitCached = false;
|
||||||
|
fWatchCreditCached = false;
|
||||||
|
fAvailableWatchCreditCached = false;
|
||||||
|
fImmatureWatchCreditCached = false;
|
||||||
|
fDebitCached = false;
|
||||||
|
fChangeCached = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void BindWallet(CWallet *pwalletIn)
|
||||||
|
{
|
||||||
|
pwallet = pwalletIn;
|
||||||
|
MarkDirty();
|
||||||
|
}
|
||||||
|
|
||||||
|
//! filter decides which addresses will count towards the debit
|
||||||
|
CAmount GetDebit(const isminefilter& filter) const;
|
||||||
|
CAmount GetCredit(const isminefilter& filter) const;
|
||||||
|
CAmount GetImmatureCredit(bool fUseCache=true) const;
|
||||||
|
CAmount GetAvailableCredit(bool fUseCache=true) const;
|
||||||
|
CAmount GetImmatureWatchOnlyCredit(const bool& fUseCache=true) const;
|
||||||
|
CAmount GetAvailableWatchOnlyCredit(const bool& fUseCache=true) const;
|
||||||
|
CAmount GetChange() const;
|
||||||
|
|
||||||
|
void GetAmounts(std::list<COutputEntry>& listReceived,
|
||||||
|
std::list<COutputEntry>& listSent, CAmount& nFee, std::string& strSentAccount, const isminefilter& filter) const;
|
||||||
|
|
||||||
|
void GetAccountAmounts(const std::string& strAccount, CAmount& nReceived,
|
||||||
|
CAmount& nSent, CAmount& nFee, const isminefilter& filter) const;
|
||||||
|
|
||||||
|
bool IsFromMe(const isminefilter& filter) const
|
||||||
|
{
|
||||||
|
return (GetDebit(filter) > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsTrusted() const;
|
||||||
|
|
||||||
|
bool WriteToDisk(CWalletDB *pwalletdb);
|
||||||
|
|
||||||
|
int64_t GetTxTime() const;
|
||||||
|
int GetRequestCount() const;
|
||||||
|
|
||||||
|
void RelayWalletTransaction();
|
||||||
|
|
||||||
|
std::set<uint256> GetConflicts() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class COutput
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
const CWalletTx *tx;
|
||||||
|
int i;
|
||||||
|
int nDepth;
|
||||||
|
bool fSpendable;
|
||||||
|
|
||||||
|
COutput(const CWalletTx *txIn, int iIn, int nDepthIn, bool fSpendableIn)
|
||||||
|
{
|
||||||
|
tx = txIn; i = iIn; nDepth = nDepthIn; fSpendable = fSpendableIn;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string ToString() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/** Private key that includes an expiration date in case it never gets used. */
|
||||||
|
class CWalletKey
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CPrivKey vchPrivKey;
|
||||||
|
int64_t nTimeCreated;
|
||||||
|
int64_t nTimeExpires;
|
||||||
|
std::string strComment;
|
||||||
|
//! todo: add something to note what created it (user, getnewaddress, change)
|
||||||
|
//! maybe should have a map<string, string> property map
|
||||||
|
|
||||||
|
CWalletKey(int64_t nExpires=0);
|
||||||
|
|
||||||
|
ADD_SERIALIZE_METHODS;
|
||||||
|
|
||||||
|
template <typename Stream, typename Operation>
|
||||||
|
inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
|
||||||
|
if (!(nType & SER_GETHASH))
|
||||||
|
READWRITE(nVersion);
|
||||||
|
READWRITE(vchPrivKey);
|
||||||
|
READWRITE(nTimeCreated);
|
||||||
|
READWRITE(nTimeExpires);
|
||||||
|
READWRITE(LIMITED_STRING(strComment, 65536));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A CWallet is an extension of a keystore, which also maintains a set of transactions and balances,
|
* A CWallet is an extension of a keystore, which also maintains a set of transactions and balances,
|
||||||
* and provides the ability to create new transactions.
|
* and provides the ability to create new transactions.
|
||||||
@ -464,508 +787,6 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
typedef std::map<std::string, std::string> mapValue_t;
|
|
||||||
|
|
||||||
|
|
||||||
static void ReadOrderPos(int64_t& nOrderPos, mapValue_t& mapValue)
|
|
||||||
{
|
|
||||||
if (!mapValue.count("n"))
|
|
||||||
{
|
|
||||||
nOrderPos = -1; // TODO: calculate elsewhere
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
nOrderPos = atoi64(mapValue["n"].c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void WriteOrderPos(const int64_t& nOrderPos, mapValue_t& mapValue)
|
|
||||||
{
|
|
||||||
if (nOrderPos == -1)
|
|
||||||
return;
|
|
||||||
mapValue["n"] = i64tostr(nOrderPos);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct COutputEntry
|
|
||||||
{
|
|
||||||
CTxDestination destination;
|
|
||||||
CAmount amount;
|
|
||||||
int vout;
|
|
||||||
};
|
|
||||||
|
|
||||||
/** A transaction with a merkle branch linking it to the block chain. */
|
|
||||||
class CMerkleTx : public CTransaction
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
int GetDepthInMainChainINTERNAL(const CBlockIndex* &pindexRet) const;
|
|
||||||
|
|
||||||
public:
|
|
||||||
uint256 hashBlock;
|
|
||||||
std::vector<uint256> vMerkleBranch;
|
|
||||||
int nIndex;
|
|
||||||
|
|
||||||
// memory only
|
|
||||||
mutable bool fMerkleVerified;
|
|
||||||
|
|
||||||
|
|
||||||
CMerkleTx()
|
|
||||||
{
|
|
||||||
Init();
|
|
||||||
}
|
|
||||||
|
|
||||||
CMerkleTx(const CTransaction& txIn) : CTransaction(txIn)
|
|
||||||
{
|
|
||||||
Init();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Init()
|
|
||||||
{
|
|
||||||
hashBlock = uint256();
|
|
||||||
nIndex = -1;
|
|
||||||
fMerkleVerified = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
ADD_SERIALIZE_METHODS;
|
|
||||||
|
|
||||||
template <typename Stream, typename Operation>
|
|
||||||
inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
|
|
||||||
READWRITE(*(CTransaction*)this);
|
|
||||||
nVersion = this->nVersion;
|
|
||||||
READWRITE(hashBlock);
|
|
||||||
READWRITE(vMerkleBranch);
|
|
||||||
READWRITE(nIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
int SetMerkleBranch(const CBlock& block);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return depth of transaction in blockchain:
|
|
||||||
* -1 : not in blockchain, and not in memory pool (conflicted transaction)
|
|
||||||
* 0 : in memory pool, waiting to be included in a block
|
|
||||||
* >=1 : this many blocks deep in the main chain
|
|
||||||
*/
|
|
||||||
int GetDepthInMainChain(const CBlockIndex* &pindexRet) const;
|
|
||||||
int GetDepthInMainChain() const { const CBlockIndex *pindexRet; return GetDepthInMainChain(pindexRet); }
|
|
||||||
bool IsInMainChain() const { const CBlockIndex *pindexRet; return GetDepthInMainChainINTERNAL(pindexRet) > 0; }
|
|
||||||
int GetBlocksToMaturity() const;
|
|
||||||
bool AcceptToMemoryPool(bool fLimitFree=true, bool fRejectAbsurdFee=true);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A transaction with a bunch of additional info that only the owner cares about.
|
|
||||||
* It includes any unrecorded transactions needed to link it back to the block chain.
|
|
||||||
*/
|
|
||||||
class CWalletTx : public CMerkleTx
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
const CWallet* pwallet;
|
|
||||||
|
|
||||||
public:
|
|
||||||
mapValue_t mapValue;
|
|
||||||
std::vector<std::pair<std::string, std::string> > vOrderForm;
|
|
||||||
unsigned int fTimeReceivedIsTxTime;
|
|
||||||
unsigned int nTimeReceived; //! time received by this node
|
|
||||||
unsigned int nTimeSmart;
|
|
||||||
char fFromMe;
|
|
||||||
std::string strFromAccount;
|
|
||||||
int64_t nOrderPos; //! position in ordered transaction list
|
|
||||||
|
|
||||||
// memory only
|
|
||||||
mutable bool fDebitCached;
|
|
||||||
mutable bool fCreditCached;
|
|
||||||
mutable bool fImmatureCreditCached;
|
|
||||||
mutable bool fAvailableCreditCached;
|
|
||||||
mutable bool fWatchDebitCached;
|
|
||||||
mutable bool fWatchCreditCached;
|
|
||||||
mutable bool fImmatureWatchCreditCached;
|
|
||||||
mutable bool fAvailableWatchCreditCached;
|
|
||||||
mutable bool fChangeCached;
|
|
||||||
mutable CAmount nDebitCached;
|
|
||||||
mutable CAmount nCreditCached;
|
|
||||||
mutable CAmount nImmatureCreditCached;
|
|
||||||
mutable CAmount nAvailableCreditCached;
|
|
||||||
mutable CAmount nWatchDebitCached;
|
|
||||||
mutable CAmount nWatchCreditCached;
|
|
||||||
mutable CAmount nImmatureWatchCreditCached;
|
|
||||||
mutable CAmount nAvailableWatchCreditCached;
|
|
||||||
mutable CAmount nChangeCached;
|
|
||||||
|
|
||||||
CWalletTx()
|
|
||||||
{
|
|
||||||
Init(NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
CWalletTx(const CWallet* pwalletIn)
|
|
||||||
{
|
|
||||||
Init(pwalletIn);
|
|
||||||
}
|
|
||||||
|
|
||||||
CWalletTx(const CWallet* pwalletIn, const CMerkleTx& txIn) : CMerkleTx(txIn)
|
|
||||||
{
|
|
||||||
Init(pwalletIn);
|
|
||||||
}
|
|
||||||
|
|
||||||
CWalletTx(const CWallet* pwalletIn, const CTransaction& txIn) : CMerkleTx(txIn)
|
|
||||||
{
|
|
||||||
Init(pwalletIn);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Init(const CWallet* pwalletIn)
|
|
||||||
{
|
|
||||||
pwallet = pwalletIn;
|
|
||||||
mapValue.clear();
|
|
||||||
vOrderForm.clear();
|
|
||||||
fTimeReceivedIsTxTime = false;
|
|
||||||
nTimeReceived = 0;
|
|
||||||
nTimeSmart = 0;
|
|
||||||
fFromMe = false;
|
|
||||||
strFromAccount.clear();
|
|
||||||
fDebitCached = false;
|
|
||||||
fCreditCached = false;
|
|
||||||
fImmatureCreditCached = false;
|
|
||||||
fAvailableCreditCached = false;
|
|
||||||
fWatchDebitCached = false;
|
|
||||||
fWatchCreditCached = false;
|
|
||||||
fImmatureWatchCreditCached = false;
|
|
||||||
fAvailableWatchCreditCached = false;
|
|
||||||
fChangeCached = false;
|
|
||||||
nDebitCached = 0;
|
|
||||||
nCreditCached = 0;
|
|
||||||
nImmatureCreditCached = 0;
|
|
||||||
nAvailableCreditCached = 0;
|
|
||||||
nWatchDebitCached = 0;
|
|
||||||
nWatchCreditCached = 0;
|
|
||||||
nAvailableWatchCreditCached = 0;
|
|
||||||
nImmatureWatchCreditCached = 0;
|
|
||||||
nChangeCached = 0;
|
|
||||||
nOrderPos = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
ADD_SERIALIZE_METHODS;
|
|
||||||
|
|
||||||
template <typename Stream, typename Operation>
|
|
||||||
inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
|
|
||||||
if (ser_action.ForRead())
|
|
||||||
Init(NULL);
|
|
||||||
char fSpent = false;
|
|
||||||
|
|
||||||
if (!ser_action.ForRead())
|
|
||||||
{
|
|
||||||
mapValue["fromaccount"] = strFromAccount;
|
|
||||||
|
|
||||||
WriteOrderPos(nOrderPos, mapValue);
|
|
||||||
|
|
||||||
if (nTimeSmart)
|
|
||||||
mapValue["timesmart"] = strprintf("%u", nTimeSmart);
|
|
||||||
}
|
|
||||||
|
|
||||||
READWRITE(*(CMerkleTx*)this);
|
|
||||||
std::vector<CMerkleTx> vUnused; //! Used to be vtxPrev
|
|
||||||
READWRITE(vUnused);
|
|
||||||
READWRITE(mapValue);
|
|
||||||
READWRITE(vOrderForm);
|
|
||||||
READWRITE(fTimeReceivedIsTxTime);
|
|
||||||
READWRITE(nTimeReceived);
|
|
||||||
READWRITE(fFromMe);
|
|
||||||
READWRITE(fSpent);
|
|
||||||
|
|
||||||
if (ser_action.ForRead())
|
|
||||||
{
|
|
||||||
strFromAccount = mapValue["fromaccount"];
|
|
||||||
|
|
||||||
ReadOrderPos(nOrderPos, mapValue);
|
|
||||||
|
|
||||||
nTimeSmart = mapValue.count("timesmart") ? (unsigned int)atoi64(mapValue["timesmart"]) : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
mapValue.erase("fromaccount");
|
|
||||||
mapValue.erase("version");
|
|
||||||
mapValue.erase("spent");
|
|
||||||
mapValue.erase("n");
|
|
||||||
mapValue.erase("timesmart");
|
|
||||||
}
|
|
||||||
|
|
||||||
//! make sure balances are recalculated
|
|
||||||
void MarkDirty()
|
|
||||||
{
|
|
||||||
fCreditCached = false;
|
|
||||||
fAvailableCreditCached = false;
|
|
||||||
fWatchDebitCached = false;
|
|
||||||
fWatchCreditCached = false;
|
|
||||||
fAvailableWatchCreditCached = false;
|
|
||||||
fImmatureWatchCreditCached = false;
|
|
||||||
fDebitCached = false;
|
|
||||||
fChangeCached = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void BindWallet(CWallet *pwalletIn)
|
|
||||||
{
|
|
||||||
pwallet = pwalletIn;
|
|
||||||
MarkDirty();
|
|
||||||
}
|
|
||||||
|
|
||||||
//! filter decides which addresses will count towards the debit
|
|
||||||
CAmount GetDebit(const isminefilter& filter) const
|
|
||||||
{
|
|
||||||
if (vin.empty())
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
CAmount debit = 0;
|
|
||||||
if(filter & ISMINE_SPENDABLE)
|
|
||||||
{
|
|
||||||
if (fDebitCached)
|
|
||||||
debit += nDebitCached;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
nDebitCached = pwallet->GetDebit(*this, ISMINE_SPENDABLE);
|
|
||||||
fDebitCached = true;
|
|
||||||
debit += nDebitCached;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(filter & ISMINE_WATCH_ONLY)
|
|
||||||
{
|
|
||||||
if(fWatchDebitCached)
|
|
||||||
debit += nWatchDebitCached;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
nWatchDebitCached = pwallet->GetDebit(*this, ISMINE_WATCH_ONLY);
|
|
||||||
fWatchDebitCached = true;
|
|
||||||
debit += nWatchDebitCached;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return debit;
|
|
||||||
}
|
|
||||||
|
|
||||||
CAmount GetCredit(const isminefilter& filter) const
|
|
||||||
{
|
|
||||||
// Must wait until coinbase is safely deep enough in the chain before valuing it
|
|
||||||
if (IsCoinBase() && GetBlocksToMaturity() > 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
int64_t credit = 0;
|
|
||||||
if (filter & ISMINE_SPENDABLE)
|
|
||||||
{
|
|
||||||
// GetBalance can assume transactions in mapWallet won't change
|
|
||||||
if (fCreditCached)
|
|
||||||
credit += nCreditCached;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
nCreditCached = pwallet->GetCredit(*this, ISMINE_SPENDABLE);
|
|
||||||
fCreditCached = true;
|
|
||||||
credit += nCreditCached;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (filter & ISMINE_WATCH_ONLY)
|
|
||||||
{
|
|
||||||
if (fWatchCreditCached)
|
|
||||||
credit += nWatchCreditCached;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
nWatchCreditCached = pwallet->GetCredit(*this, ISMINE_WATCH_ONLY);
|
|
||||||
fWatchCreditCached = true;
|
|
||||||
credit += nWatchCreditCached;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return credit;
|
|
||||||
}
|
|
||||||
|
|
||||||
CAmount GetImmatureCredit(bool fUseCache=true) const
|
|
||||||
{
|
|
||||||
if (IsCoinBase() && GetBlocksToMaturity() > 0 && IsInMainChain())
|
|
||||||
{
|
|
||||||
if (fUseCache && fImmatureCreditCached)
|
|
||||||
return nImmatureCreditCached;
|
|
||||||
nImmatureCreditCached = pwallet->GetCredit(*this, ISMINE_SPENDABLE);
|
|
||||||
fImmatureCreditCached = true;
|
|
||||||
return nImmatureCreditCached;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
CAmount GetAvailableCredit(bool fUseCache=true) const
|
|
||||||
{
|
|
||||||
if (pwallet == 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
// Must wait until coinbase is safely deep enough in the chain before valuing it
|
|
||||||
if (IsCoinBase() && GetBlocksToMaturity() > 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (fUseCache && fAvailableCreditCached)
|
|
||||||
return nAvailableCreditCached;
|
|
||||||
|
|
||||||
CAmount nCredit = 0;
|
|
||||||
uint256 hashTx = GetHash();
|
|
||||||
for (unsigned int i = 0; i < vout.size(); i++)
|
|
||||||
{
|
|
||||||
if (!pwallet->IsSpent(hashTx, i))
|
|
||||||
{
|
|
||||||
const CTxOut &txout = vout[i];
|
|
||||||
nCredit += pwallet->GetCredit(txout, ISMINE_SPENDABLE);
|
|
||||||
if (!MoneyRange(nCredit))
|
|
||||||
throw std::runtime_error("CWalletTx::GetAvailableCredit(): value out of range");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
nAvailableCreditCached = nCredit;
|
|
||||||
fAvailableCreditCached = true;
|
|
||||||
return nCredit;
|
|
||||||
}
|
|
||||||
|
|
||||||
CAmount GetImmatureWatchOnlyCredit(const bool& fUseCache=true) const
|
|
||||||
{
|
|
||||||
if (IsCoinBase() && GetBlocksToMaturity() > 0 && IsInMainChain())
|
|
||||||
{
|
|
||||||
if (fUseCache && fImmatureWatchCreditCached)
|
|
||||||
return nImmatureWatchCreditCached;
|
|
||||||
nImmatureWatchCreditCached = pwallet->GetCredit(*this, ISMINE_WATCH_ONLY);
|
|
||||||
fImmatureWatchCreditCached = true;
|
|
||||||
return nImmatureWatchCreditCached;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
CAmount GetAvailableWatchOnlyCredit(const bool& fUseCache=true) const
|
|
||||||
{
|
|
||||||
if (pwallet == 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
// Must wait until coinbase is safely deep enough in the chain before valuing it
|
|
||||||
if (IsCoinBase() && GetBlocksToMaturity() > 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (fUseCache && fAvailableWatchCreditCached)
|
|
||||||
return nAvailableWatchCreditCached;
|
|
||||||
|
|
||||||
CAmount nCredit = 0;
|
|
||||||
for (unsigned int i = 0; i < vout.size(); i++)
|
|
||||||
{
|
|
||||||
if (!pwallet->IsSpent(GetHash(), i))
|
|
||||||
{
|
|
||||||
const CTxOut &txout = vout[i];
|
|
||||||
nCredit += pwallet->GetCredit(txout, ISMINE_WATCH_ONLY);
|
|
||||||
if (!MoneyRange(nCredit))
|
|
||||||
throw std::runtime_error("CWalletTx::GetAvailableCredit(): value out of range");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
nAvailableWatchCreditCached = nCredit;
|
|
||||||
fAvailableWatchCreditCached = true;
|
|
||||||
return nCredit;
|
|
||||||
}
|
|
||||||
|
|
||||||
CAmount GetChange() const
|
|
||||||
{
|
|
||||||
if (fChangeCached)
|
|
||||||
return nChangeCached;
|
|
||||||
nChangeCached = pwallet->GetChange(*this);
|
|
||||||
fChangeCached = true;
|
|
||||||
return nChangeCached;
|
|
||||||
}
|
|
||||||
|
|
||||||
void GetAmounts(std::list<COutputEntry>& listReceived,
|
|
||||||
std::list<COutputEntry>& listSent, CAmount& nFee, std::string& strSentAccount, const isminefilter& filter) const;
|
|
||||||
|
|
||||||
void GetAccountAmounts(const std::string& strAccount, CAmount& nReceived,
|
|
||||||
CAmount& nSent, CAmount& nFee, const isminefilter& filter) const;
|
|
||||||
|
|
||||||
bool IsFromMe(const isminefilter& filter) const
|
|
||||||
{
|
|
||||||
return (GetDebit(filter) > 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IsTrusted() const
|
|
||||||
{
|
|
||||||
// Quick answer in most cases
|
|
||||||
if (!IsFinalTx(*this))
|
|
||||||
return false;
|
|
||||||
int nDepth = GetDepthInMainChain();
|
|
||||||
if (nDepth >= 1)
|
|
||||||
return true;
|
|
||||||
if (nDepth < 0)
|
|
||||||
return false;
|
|
||||||
if (!bSpendZeroConfChange || !IsFromMe(ISMINE_ALL)) // using wtx's cached debit
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// Trusted if all inputs are from us and are in the mempool:
|
|
||||||
BOOST_FOREACH(const CTxIn& txin, vin)
|
|
||||||
{
|
|
||||||
// Transactions not sent by us: not trusted
|
|
||||||
const CWalletTx* parent = pwallet->GetWalletTx(txin.prevout.hash);
|
|
||||||
if (parent == NULL)
|
|
||||||
return false;
|
|
||||||
const CTxOut& parentOut = parent->vout[txin.prevout.n];
|
|
||||||
if (pwallet->IsMine(parentOut) != ISMINE_SPENDABLE)
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool WriteToDisk(CWalletDB *pwalletdb);
|
|
||||||
|
|
||||||
int64_t GetTxTime() const;
|
|
||||||
int GetRequestCount() const;
|
|
||||||
|
|
||||||
void RelayWalletTransaction();
|
|
||||||
|
|
||||||
std::set<uint256> GetConflicts() const;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class COutput
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
const CWalletTx *tx;
|
|
||||||
int i;
|
|
||||||
int nDepth;
|
|
||||||
bool fSpendable;
|
|
||||||
|
|
||||||
COutput(const CWalletTx *txIn, int iIn, int nDepthIn, bool fSpendableIn)
|
|
||||||
{
|
|
||||||
tx = txIn; i = iIn; nDepth = nDepthIn; fSpendable = fSpendableIn;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string ToString() const;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/** Private key that includes an expiration date in case it never gets used. */
|
|
||||||
class CWalletKey
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
CPrivKey vchPrivKey;
|
|
||||||
int64_t nTimeCreated;
|
|
||||||
int64_t nTimeExpires;
|
|
||||||
std::string strComment;
|
|
||||||
//! todo: add something to note what created it (user, getnewaddress, change)
|
|
||||||
//! maybe should have a map<string, string> property map
|
|
||||||
|
|
||||||
CWalletKey(int64_t nExpires=0);
|
|
||||||
|
|
||||||
ADD_SERIALIZE_METHODS;
|
|
||||||
|
|
||||||
template <typename Stream, typename Operation>
|
|
||||||
inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
|
|
||||||
if (!(nType & SER_GETHASH))
|
|
||||||
READWRITE(nVersion);
|
|
||||||
READWRITE(vchPrivKey);
|
|
||||||
READWRITE(nTimeCreated);
|
|
||||||
READWRITE(nTimeExpires);
|
|
||||||
READWRITE(LIMITED_STRING(strComment, 65536));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Account information.
|
* Account information.
|
||||||
* Stored in wallet with key "acc"+string account name.
|
* Stored in wallet with key "acc"+string account name.
|
||||||
|
Loading…
Reference in New Issue
Block a user