Merge remote-tracking branch 'janko33bd/Blackcoin-Lore' into build-fixes-0.13
This commit is contained in:
@@ -94,6 +94,10 @@ void WalletTxToJSON(const CWalletTx& wtx, UniValue& entry)
|
||||
BOOST_FOREACH(const uint256& conflict, wtx.GetConflicts())
|
||||
conflicts.push_back(conflict.GetHex());
|
||||
entry.push_back(Pair("walletconflicts", conflicts));
|
||||
UniValue respends;
|
||||
BOOST_FOREACH(const uint256& respend, wtx.GetConflicts(false))
|
||||
respends.push_back(respend.GetHex());
|
||||
entry.push_back(Pair("respendsobserved", respends));
|
||||
entry.push_back(Pair("time", wtx.GetTxTime()));
|
||||
entry.push_back(Pair("timereceived", (int64_t)wtx.nTimeReceived));
|
||||
|
||||
@@ -1394,6 +1398,12 @@ UniValue listtransactions(const UniValue& params, bool fHelp)
|
||||
" category of transactions.\n"
|
||||
" \"blocktime\": xxx, (numeric) The block time in seconds since epoch (1 Jan 1970 GMT).\n"
|
||||
" \"txid\": \"transactionid\", (string) The transaction id. Available for 'send' and 'receive' category of transactions.\n"
|
||||
" \"walletconflicts\" : [\n"
|
||||
" \"conflictid\", (string) Ids of transactions, including equivalent clones, that re-spend a txid input.\n"
|
||||
" ],\n"
|
||||
" \"respendsobserved\" : [\n"
|
||||
" \"respendid\", (string) Ids of transactions, NOT equivalent clones, that re-spend a txid input. \"Double-spends.\"\n"
|
||||
" ],\n"
|
||||
" \"time\": xxx, (numeric) The transaction time in seconds since epoch (midnight Jan 1 1970 GMT).\n"
|
||||
" \"timereceived\": xxx, (numeric) The time received in seconds since epoch (midnight Jan 1 1970 GMT). Available \n"
|
||||
" for 'send' and 'receive' category of transactions.\n"
|
||||
@@ -1588,6 +1598,12 @@ UniValue listsinceblock(const UniValue& params, bool fHelp)
|
||||
" \"blockindex\": n, (numeric) The block index containing the transaction. Available for 'send' and 'receive' category of transactions.\n"
|
||||
" \"blocktime\": xxx, (numeric) The block time in seconds since epoch (1 Jan 1970 GMT).\n"
|
||||
" \"txid\": \"transactionid\", (string) The transaction id. Available for 'send' and 'receive' category of transactions.\n"
|
||||
" \"walletconflicts\" : [\n"
|
||||
" \"conflictid\", (string) Ids of transactions, including equivalent clones, that re-spend a txid input.\n"
|
||||
" ],\n"
|
||||
" \"respendsobserved\" : [\n"
|
||||
" \"respendid\", (string) Ids of transactions, NOT equivalent clones, that re-spend a txid input. \"Double-spends.\"\n"
|
||||
" ],\n"
|
||||
" \"time\": xxx, (numeric) The transaction time in seconds since epoch (Jan 1 1970 GMT).\n"
|
||||
" \"timereceived\": xxx, (numeric) The time received in seconds since epoch (Jan 1 1970 GMT). Available for 'send' and 'receive' category of transactions.\n"
|
||||
" \"comment\": \"...\", (string) If a comment is associated with the transaction.\n"
|
||||
@@ -1672,6 +1688,12 @@ UniValue gettransaction(const UniValue& params, bool fHelp)
|
||||
" \"blockindex\" : xx, (numeric) The block index\n"
|
||||
" \"blocktime\" : ttt, (numeric) The time in seconds since epoch (1 Jan 1970 GMT)\n"
|
||||
" \"txid\" : \"transactionid\", (string) The transaction id.\n"
|
||||
" \"walletconflicts\" : [\n"
|
||||
" \"conflictid\", (string) Ids of transactions, including equivalent clones, that re-spend a txid input.\n"
|
||||
" ],\n"
|
||||
" \"respendsobserved\" : [\n"
|
||||
" \"respendid\", (string) Ids of transactions, NOT equivalent clones, that re-spend a txid input. \"Double-spends.\"\n"
|
||||
" ],\n"
|
||||
" \"time\" : ttt, (numeric) The transaction time in seconds since epoch (1 Jan 1970 GMT)\n"
|
||||
" \"timereceived\" : ttt, (numeric) The time received in seconds since epoch (1 Jan 1970 GMT)\n"
|
||||
" \"bip125-replaceable\": \"yes|no|unknown\" (string) Whether this transaction could be replaced due to BIP125 (replace-by-fee);\n"
|
||||
|
||||
@@ -391,7 +391,7 @@ bool CWallet::SetMaxVersion(int nVersion)
|
||||
return true;
|
||||
}
|
||||
|
||||
set<uint256> CWallet::GetConflicts(const uint256& txid) const
|
||||
set<uint256> CWallet::GetConflicts(const uint256& txid, bool includeEquivalent) const
|
||||
{
|
||||
set<uint256> result;
|
||||
AssertLockHeld(cs_wallet);
|
||||
@@ -409,7 +409,8 @@ set<uint256> CWallet::GetConflicts(const uint256& txid) const
|
||||
continue; // No conflict if zero or one spends
|
||||
range = mapTxSpends.equal_range(txin.prevout);
|
||||
for (TxSpends::const_iterator it = range.first; it != range.second; ++it)
|
||||
result.insert(it->second);
|
||||
if (includeEquivalent || !wtx.IsEquivalentTo(mapWallet.at(it->second)))
|
||||
result.insert(it->second);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -1196,6 +1197,20 @@ bool CWallet::AddToWallet(const CWalletTx& wtxIn, bool fFromLoadWallet, CWalletD
|
||||
// Notify UI of new or updated transaction
|
||||
NotifyTransactionChanged(this, hash, fInsertedNew ? CT_NEW : CT_UPDATED);
|
||||
|
||||
// Notifications for existing transactions that now have conflicts with this one
|
||||
if (fInsertedNew)
|
||||
{
|
||||
BOOST_FOREACH(const uint256& conflictHash, wtxIn.GetConflicts())
|
||||
{
|
||||
CWalletTx& txConflict = mapWallet[conflictHash];
|
||||
NotifyTransactionChanged(this, conflictHash, CT_UPDATED); //Updates UI table
|
||||
if (IsFromMe(txConflict) || IsMine(txConflict))
|
||||
{
|
||||
NotifyTransactionChanged(this, conflictHash, CT_GOT_CONFLICT); //Throws dialog
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// notify an external script when a wallet transaction comes in or is updated
|
||||
std::string strCmd = GetArg("-walletnotify", "");
|
||||
|
||||
@@ -1205,6 +1220,15 @@ bool CWallet::AddToWallet(const CWalletTx& wtxIn, bool fFromLoadWallet, CWalletD
|
||||
boost::thread t(runCommand, strCmd); // thread runs free
|
||||
}
|
||||
|
||||
// external respend notify
|
||||
std::string strCmdRespend = GetArg("-respendnotify", "");
|
||||
if (!strCmdRespend.empty())
|
||||
{
|
||||
boost::replace_all(strCmd, "%s", wtxIn.GetHash().GetHex());
|
||||
boost::replace_all(strCmd, "%t", hash.GetHex());
|
||||
boost::thread t(runCommand, strCmd); // thread runs free
|
||||
}
|
||||
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -1214,7 +1238,7 @@ bool CWallet::AddToWallet(const CWalletTx& wtxIn, bool fFromLoadWallet, CWalletD
|
||||
* pblock is optional, but should be provided if the transaction is known to be in a block.
|
||||
* If fUpdate is true, existing transactions will be updated.
|
||||
*/
|
||||
bool CWallet::AddToWalletIfInvolvingMe(const CTransaction& tx, const CBlock* pblock, bool fUpdate)
|
||||
bool CWallet::AddToWalletIfInvolvingMe(const CTransaction& tx, const CBlock* pblock, bool fUpdate, bool fRespend)
|
||||
{
|
||||
{
|
||||
AssertLockHeld(cs_wallet);
|
||||
@@ -1234,7 +1258,15 @@ bool CWallet::AddToWalletIfInvolvingMe(const CTransaction& tx, const CBlock* pbl
|
||||
|
||||
bool fExisted = mapWallet.count(tx.GetHash()) != 0;
|
||||
if (fExisted && !fUpdate) return false;
|
||||
if (fExisted || IsMine(tx) || IsFromMe(tx))
|
||||
|
||||
bool fIsConflicting = IsConflicting(tx);
|
||||
// Don't add respends that pay us, unless they conflict with us. Prevents resource exhaustion.
|
||||
if (!fIsConflicting && fRespend) return false;
|
||||
|
||||
if (fIsConflicting)
|
||||
nConflictsReceived++;
|
||||
|
||||
if (fExisted || IsMine(tx) || IsFromMe(tx) || fIsConflicting)
|
||||
{
|
||||
CWalletTx wtx(this,tx);
|
||||
|
||||
@@ -1369,24 +1401,21 @@ void CWallet::MarkConflicted(const uint256& hashBlock, const uint256& hashTx)
|
||||
}
|
||||
}
|
||||
|
||||
void CWallet::SyncTransaction(const CTransaction& tx, const CBlock* pblock)
|
||||
void CWallet::SyncTransaction(const CTransaction& tx, const CBlock* pblock, bool fRespend)
|
||||
{
|
||||
LOCK2(cs_main, cs_wallet);
|
||||
|
||||
if (!pblock) {
|
||||
// wallets need to refund inputs when disconnecting coinstake
|
||||
if (tx.IsCoinStake()) {
|
||||
if (IsFromMe(tx)) {
|
||||
DisableTransaction(tx);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
LOCK2(cs_main, cs_wallet);
|
||||
|
||||
if (!pblock) {
|
||||
// wallets need to refund inputs when disconnecting coinstake
|
||||
if (tx.IsCoinStake()) {
|
||||
if (IsFromMe(tx)) {
|
||||
DisableTransaction(tx);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!AddToWalletIfInvolvingMe(tx, pblock, true))
|
||||
if (!AddToWalletIfInvolvingMe(tx, pblock, true, fRespend))
|
||||
return; // Not one of ours
|
||||
|
||||
// If a transaction changes 'conflicted' state, that changes the balance
|
||||
@@ -1415,6 +1444,14 @@ isminetype CWallet::IsMine(const CTxIn &txin) const
|
||||
return ISMINE_NO;
|
||||
}
|
||||
|
||||
bool CWallet::IsConflicting(const CTransaction& tx) const
|
||||
{
|
||||
BOOST_FOREACH(const CTxIn& txin, tx.vin)
|
||||
if (mapTxSpends.count(txin.prevout))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
CAmount CWallet::GetDebit(const CTxIn &txin, const isminefilter& filter) const
|
||||
{
|
||||
{
|
||||
@@ -1751,7 +1788,7 @@ int CWallet::ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate)
|
||||
ReadBlockFromDisk(block, pindex, Params().GetConsensus());
|
||||
BOOST_FOREACH(CTransaction& tx, block.vtx)
|
||||
{
|
||||
if (AddToWalletIfInvolvingMe(tx, &block, fUpdate))
|
||||
if (AddToWalletIfInvolvingMe(tx, &block, fUpdate, false))
|
||||
ret++;
|
||||
}
|
||||
pindex = chainActive.Next(pindex);
|
||||
@@ -1782,7 +1819,7 @@ void CWallet::ReacceptWalletTransactions()
|
||||
|
||||
int nDepth = wtx.GetDepthInMainChain();
|
||||
|
||||
if (!wtx.IsCoinBase() && !wtx.IsCoinStake() && (nDepth == 0 && !wtx.isAbandoned())) {
|
||||
if (!wtx.IsCoinBase() && !wtx.IsCoinStake() && (nDepth == 0 && !wtx.isAbandoned() && (IsMine(wtx) || IsFromMe(wtx)))) {
|
||||
mapSorted.insert(std::make_pair(wtx.nOrderPos, &wtx));
|
||||
}
|
||||
}
|
||||
@@ -1811,13 +1848,13 @@ bool CWalletTx::RelayWalletTransaction()
|
||||
return false;
|
||||
}
|
||||
|
||||
set<uint256> CWalletTx::GetConflicts() const
|
||||
set<uint256> CWalletTx::GetConflicts(bool includeEquivalent) const
|
||||
{
|
||||
set<uint256> result;
|
||||
if (pwallet != NULL)
|
||||
{
|
||||
uint256 myHash = GetHash();
|
||||
result = pwallet->GetConflicts(myHash);
|
||||
result = pwallet->GetConflicts(myHash, includeEquivalent);
|
||||
result.erase(myHash);
|
||||
}
|
||||
return result;
|
||||
@@ -3436,9 +3473,9 @@ void CWallet::UpdatedTransaction(const uint256 &hashTx)
|
||||
}
|
||||
}
|
||||
|
||||
void CWallet::GetScriptForMining(boost::shared_ptr<CReserveScript> &script)
|
||||
void CWallet::GetScriptForMining(std::shared_ptr<CReserveScript> &script)
|
||||
{
|
||||
boost::shared_ptr<CReserveKey> rKey(new CReserveKey(this));
|
||||
std::shared_ptr<CReserveKey> rKey = std::make_shared<CReserveKey>(this);
|
||||
CPubKey pubkey;
|
||||
if (!rKey->GetReservedKey(pubkey))
|
||||
return;
|
||||
@@ -3667,6 +3704,7 @@ std::string CWallet::GetWalletHelpString(bool showDebug)
|
||||
strUsage += HelpMessageOpt("-wallet=<file>", _("Specify wallet file (within data directory)") + " " + strprintf(_("(default: %s)"), DEFAULT_WALLET_DAT));
|
||||
strUsage += HelpMessageOpt("-walletbroadcast", _("Make the wallet broadcast transactions") + " " + strprintf(_("(default: %u)"), DEFAULT_WALLETBROADCAST));
|
||||
strUsage += HelpMessageOpt("-walletnotify=<cmd>", _("Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)"));
|
||||
strUsage += HelpMessageOpt("-respendnotify=<cmd>", _("Execute command when a network tx respends wallet tx input (%s=respend TxID, %t=wallet TxID)"));
|
||||
strUsage += HelpMessageOpt("-zapwallettxes=<mode>", _("Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup") +
|
||||
" " + _("(1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data)"));
|
||||
|
||||
|
||||
@@ -26,8 +26,6 @@
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
extern CWallet* pwalletMain;
|
||||
|
||||
/**
|
||||
@@ -413,7 +411,7 @@ public:
|
||||
|
||||
bool RelayWalletTransaction();
|
||||
|
||||
std::set<uint256> GetConflicts() const;
|
||||
std::set<uint256> GetConflicts(bool includeEquivalent=true) const;
|
||||
};
|
||||
|
||||
|
||||
@@ -614,6 +612,9 @@ public:
|
||||
MasterKeyMap mapMasterKeys;
|
||||
unsigned int nMasterKeyMaxID;
|
||||
|
||||
// Increment to cause UI refresh, similar to new block
|
||||
int64_t nConflictsReceived;
|
||||
|
||||
CWallet()
|
||||
{
|
||||
SetNull();
|
||||
@@ -645,6 +646,7 @@ public:
|
||||
nLastResend = 0;
|
||||
nTimeFirstKey = 0;
|
||||
fBroadcastTransactions = false;
|
||||
nConflictsReceived = 0;
|
||||
}
|
||||
|
||||
std::map<uint256, CWalletTx> mapWallet;
|
||||
@@ -743,8 +745,8 @@ public:
|
||||
|
||||
void MarkDirty();
|
||||
bool AddToWallet(const CWalletTx& wtxIn, bool fFromLoadWallet, CWalletDB* pwalletdb);
|
||||
void SyncTransaction(const CTransaction& tx, const CBlock* pblock);
|
||||
bool AddToWalletIfInvolvingMe(const CTransaction& tx, const CBlock* pblock, bool fUpdate);
|
||||
void SyncTransaction(const CTransaction& tx, const CBlock* pblock, bool fRespend);
|
||||
bool AddToWalletIfInvolvingMe(const CTransaction& tx, const CBlock* pblock, bool fUpdate, bool fRespend);
|
||||
int ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate = false);
|
||||
void ReacceptWalletTransactions();
|
||||
void ResendWalletTransactions(int64_t nBestBlockTime);
|
||||
@@ -812,6 +814,7 @@ public:
|
||||
bool IsMine(const CTransaction& tx) const;
|
||||
/** should probably be renamed to IsRelevantToMe */
|
||||
bool IsFromMe(const CTransaction& tx) const;
|
||||
bool IsConflicting(const CTransaction& tx) const;
|
||||
CAmount GetDebit(const CTransaction& tx, const isminefilter& filter) const;
|
||||
CAmount GetCredit(const CTransaction& tx, const isminefilter& filter) const;
|
||||
CAmount GetChange(const CTransaction& tx) const;
|
||||
@@ -837,7 +840,7 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void GetScriptForMining(boost::shared_ptr<CReserveScript> &script);
|
||||
void GetScriptForMining(std::shared_ptr<CReserveScript> &script);
|
||||
void ResetRequestCount(const uint256 &hash)
|
||||
{
|
||||
LOCK(cs_wallet);
|
||||
@@ -864,7 +867,7 @@ public:
|
||||
void DisableTransaction(const CTransaction &tx);
|
||||
|
||||
//! Get wallet transactions that conflict with given transaction (spend same outputs)
|
||||
std::set<uint256> GetConflicts(const uint256& txid) const;
|
||||
std::set<uint256> GetConflicts(const uint256& txid, bool includeEquivalent) const;
|
||||
|
||||
//! Flush wallet (bitdb flush)
|
||||
void Flush(bool shutdown=false);
|
||||
|
||||
Reference in New Issue
Block a user