|
|
|
@ -74,93 +74,52 @@ int64 nTransactionFee = 0;
@@ -74,93 +74,52 @@ int64 nTransactionFee = 0;
|
|
|
|
|
|
|
|
|
|
// These functions dispatch to one or all registered wallets
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void RegisterWallet(CWallet* pwalletIn) |
|
|
|
|
{ |
|
|
|
|
{ |
|
|
|
|
LOCK(cs_setpwalletRegistered); |
|
|
|
|
setpwalletRegistered.insert(pwalletIn); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void UnregisterWallet(CWallet* pwalletIn) |
|
|
|
|
{ |
|
|
|
|
{ |
|
|
|
|
LOCK(cs_setpwalletRegistered); |
|
|
|
|
setpwalletRegistered.erase(pwalletIn); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void UnregisterAllWallets() |
|
|
|
|
{ |
|
|
|
|
LOCK(cs_setpwalletRegistered); |
|
|
|
|
setpwalletRegistered.clear(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// get the wallet transaction with the given hash (if it exists)
|
|
|
|
|
bool static GetTransaction(const uint256& hashTx, CWalletTx& wtx) |
|
|
|
|
{ |
|
|
|
|
LOCK(cs_setpwalletRegistered); |
|
|
|
|
BOOST_FOREACH(CWallet* pwallet, setpwalletRegistered) |
|
|
|
|
if (pwallet->GetTransaction(hashTx,wtx)) |
|
|
|
|
return true; |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// erases transaction with the given hash from all wallets
|
|
|
|
|
void static EraseFromWallets(uint256 hash) |
|
|
|
|
{ |
|
|
|
|
LOCK(cs_setpwalletRegistered); |
|
|
|
|
BOOST_FOREACH(CWallet* pwallet, setpwalletRegistered) |
|
|
|
|
pwallet->EraseFromWallet(hash); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// make sure all wallets know about the given transaction, in the given block
|
|
|
|
|
void SyncWithWallets(const uint256 &hash, const CTransaction& tx, const CBlock* pblock, bool fUpdate) |
|
|
|
|
{ |
|
|
|
|
LOCK(cs_setpwalletRegistered); |
|
|
|
|
BOOST_FOREACH(CWallet* pwallet, setpwalletRegistered) |
|
|
|
|
pwallet->AddToWalletIfInvolvingMe(hash, tx, pblock, fUpdate); |
|
|
|
|
namespace { |
|
|
|
|
struct CMainSignals { |
|
|
|
|
// Notifies listeners of updated transaction data (passing hash, transaction, and optionally the block it is found in.
|
|
|
|
|
boost::signals2::signal<void (const uint256 &, const CTransaction &, const CBlock *)> SyncTransaction; |
|
|
|
|
// Notifies listeners of an erased transaction (currently disabled, requires transaction replacement).
|
|
|
|
|
boost::signals2::signal<void (const uint256 &)> EraseTransaction; |
|
|
|
|
// Notifies listeners of an updated transaction without new data (for now: a coinbase potentially becoming visible).
|
|
|
|
|
boost::signals2::signal<void (const uint256 &)> UpdatedTransaction; |
|
|
|
|
// Notifies listeners of a new active block chain.
|
|
|
|
|
boost::signals2::signal<void (const CBlockLocator &)> SetBestChain; |
|
|
|
|
// Notifies listeners about an inventory item being seen on the network.
|
|
|
|
|
boost::signals2::signal<void (const uint256 &)> Inventory; |
|
|
|
|
// Tells listeners to broadcast their data.
|
|
|
|
|
boost::signals2::signal<void ()> Broadcast; |
|
|
|
|
} g_signals; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// notify wallets about a new best chain
|
|
|
|
|
void static SetBestChain(const CBlockLocator& loc) |
|
|
|
|
{ |
|
|
|
|
LOCK(cs_setpwalletRegistered); |
|
|
|
|
BOOST_FOREACH(CWallet* pwallet, setpwalletRegistered) |
|
|
|
|
pwallet->SetBestChain(loc); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// notify wallets about an updated transaction
|
|
|
|
|
void static UpdatedTransaction(const uint256& hashTx) |
|
|
|
|
{ |
|
|
|
|
LOCK(cs_setpwalletRegistered); |
|
|
|
|
BOOST_FOREACH(CWallet* pwallet, setpwalletRegistered) |
|
|
|
|
pwallet->UpdatedTransaction(hashTx); |
|
|
|
|
void RegisterWallet(CWalletInterface* pwalletIn) { |
|
|
|
|
g_signals.SyncTransaction.connect(boost::bind(&CWalletInterface::SyncTransaction, pwalletIn, _1, _2, _3)); |
|
|
|
|
g_signals.EraseTransaction.connect(boost::bind(&CWalletInterface::EraseFromWallet, pwalletIn, _1)); |
|
|
|
|
g_signals.UpdatedTransaction.connect(boost::bind(&CWalletInterface::UpdatedTransaction, pwalletIn, _1)); |
|
|
|
|
g_signals.SetBestChain.connect(boost::bind(&CWalletInterface::SetBestChain, pwalletIn, _1)); |
|
|
|
|
g_signals.Inventory.connect(boost::bind(&CWalletInterface::Inventory, pwalletIn, _1)); |
|
|
|
|
g_signals.Broadcast.connect(boost::bind(&CWalletInterface::ResendWalletTransactions, pwalletIn)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// dump all wallets
|
|
|
|
|
void static PrintWallets(const CBlock& block) |
|
|
|
|
{ |
|
|
|
|
LOCK(cs_setpwalletRegistered); |
|
|
|
|
BOOST_FOREACH(CWallet* pwallet, setpwalletRegistered) |
|
|
|
|
pwallet->PrintWallet(block); |
|
|
|
|
void UnregisterWallet(CWalletInterface* pwalletIn) { |
|
|
|
|
g_signals.Broadcast.disconnect(boost::bind(&CWalletInterface::ResendWalletTransactions, pwalletIn)); |
|
|
|
|
g_signals.Inventory.disconnect(boost::bind(&CWalletInterface::Inventory, pwalletIn, _1)); |
|
|
|
|
g_signals.SetBestChain.disconnect(boost::bind(&CWalletInterface::SetBestChain, pwalletIn, _1)); |
|
|
|
|
g_signals.UpdatedTransaction.disconnect(boost::bind(&CWalletInterface::UpdatedTransaction, pwalletIn, _1)); |
|
|
|
|
g_signals.EraseTransaction.disconnect(boost::bind(&CWalletInterface::EraseFromWallet, pwalletIn, _1)); |
|
|
|
|
g_signals.SyncTransaction.disconnect(boost::bind(&CWalletInterface::SyncTransaction, pwalletIn, _1, _2, _3)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// notify wallets about an incoming inventory (for request counts)
|
|
|
|
|
void static Inventory(const uint256& hash) |
|
|
|
|
{ |
|
|
|
|
LOCK(cs_setpwalletRegistered); |
|
|
|
|
BOOST_FOREACH(CWallet* pwallet, setpwalletRegistered) |
|
|
|
|
pwallet->Inventory(hash); |
|
|
|
|
void UnregisterAllWallets() { |
|
|
|
|
g_signals.Broadcast.disconnect_all_slots(); |
|
|
|
|
g_signals.Inventory.disconnect_all_slots(); |
|
|
|
|
g_signals.SetBestChain.disconnect_all_slots(); |
|
|
|
|
g_signals.UpdatedTransaction.disconnect_all_slots(); |
|
|
|
|
g_signals.EraseTransaction.disconnect_all_slots(); |
|
|
|
|
g_signals.SyncTransaction.disconnect_all_slots(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// ask wallets to resend their transactions
|
|
|
|
|
void static ResendWalletTransactions() |
|
|
|
|
{ |
|
|
|
|
LOCK(cs_setpwalletRegistered); |
|
|
|
|
BOOST_FOREACH(CWallet* pwallet, setpwalletRegistered) |
|
|
|
|
pwallet->ResendWalletTransactions(); |
|
|
|
|
void SyncWithWallets(const uint256 &hash, const CTransaction &tx, const CBlock *pblock) { |
|
|
|
|
g_signals.SyncTransaction(hash, tx, pblock); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
@ -931,8 +890,8 @@ bool CTxMemPool::accept(CValidationState &state, const CTransaction &tx, bool fL
@@ -931,8 +890,8 @@ bool CTxMemPool::accept(CValidationState &state, const CTransaction &tx, bool fL
|
|
|
|
|
///// are we sure this is ok when loading transactions or restoring block txes
|
|
|
|
|
// If updated, erase old tx from wallet
|
|
|
|
|
if (ptxOld) |
|
|
|
|
EraseFromWallets(ptxOld->GetHash()); |
|
|
|
|
SyncWithWallets(hash, tx, NULL, true); |
|
|
|
|
g_signals.EraseTransaction(ptxOld->GetHash()); |
|
|
|
|
g_signals.SyncTransaction(hash, tx, NULL); |
|
|
|
|
|
|
|
|
|
LogPrint("mempool", "CTxMemPool::accept() : accepted %s (poolsz %"PRIszu")\n", |
|
|
|
|
hash.ToString().c_str(), |
|
|
|
@ -1095,27 +1054,6 @@ bool CMerkleTx::AcceptToMemoryPool(bool fLimitFree)
@@ -1095,27 +1054,6 @@ bool CMerkleTx::AcceptToMemoryPool(bool fLimitFree)
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool CWalletTx::AcceptWalletTransaction() |
|
|
|
|
{ |
|
|
|
|
{ |
|
|
|
|
LOCK(mempool.cs); |
|
|
|
|
// Add previous supporting transactions first
|
|
|
|
|
BOOST_FOREACH(CMerkleTx& tx, vtxPrev) |
|
|
|
|
{ |
|
|
|
|
if (!tx.IsCoinBase()) |
|
|
|
|
{ |
|
|
|
|
uint256 hash = tx.GetHash(); |
|
|
|
|
if (!mempool.exists(hash) && pcoinsTip->HaveCoins(hash)) |
|
|
|
|
tx.AcceptToMemoryPool(false); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
return AcceptToMemoryPool(false); |
|
|
|
|
} |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Return transaction in tx, and if it was found inside a block, its hash is placed in hashBlock
|
|
|
|
|
bool GetTransaction(const uint256 &hash, CTransaction &txOut, uint256 &hashBlock, bool fAllowSlow) |
|
|
|
|
{ |
|
|
|
@ -1992,7 +1930,7 @@ bool ConnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex, C
@@ -1992,7 +1930,7 @@ bool ConnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex, C
|
|
|
|
|
|
|
|
|
|
// Watch for transactions paying to me
|
|
|
|
|
for (unsigned int i = 0; i < block.vtx.size(); i++) |
|
|
|
|
SyncWithWallets(block.GetTxHash(i), block.vtx[i], &block, true); |
|
|
|
|
g_signals.SyncTransaction(block.GetTxHash(i), block.vtx[i], &block); |
|
|
|
|
|
|
|
|
|
return true; |
|
|
|
|
} |
|
|
|
@ -2126,7 +2064,7 @@ bool SetBestChain(CValidationState &state, CBlockIndex* pindexNew)
@@ -2126,7 +2064,7 @@ bool SetBestChain(CValidationState &state, CBlockIndex* pindexNew)
|
|
|
|
|
|
|
|
|
|
// Update best block in wallet (so we can detect restored wallets)
|
|
|
|
|
if ((pindexNew->nHeight % 20160) == 0 || (!fIsInitialDownload && (pindexNew->nHeight % 144) == 0)) |
|
|
|
|
::SetBestChain(chainActive.GetLocator(pindexNew)); |
|
|
|
|
g_signals.SetBestChain(chainActive.GetLocator(pindexNew)); |
|
|
|
|
|
|
|
|
|
// New best block
|
|
|
|
|
nTimeBestReceived = GetTime(); |
|
|
|
@ -2206,7 +2144,7 @@ bool AddToBlockIndex(CBlock& block, CValidationState& state, const CDiskBlockPos
@@ -2206,7 +2144,7 @@ bool AddToBlockIndex(CBlock& block, CValidationState& state, const CDiskBlockPos
|
|
|
|
|
CheckForkWarningConditions(); |
|
|
|
|
// Notify UI to display prev block's coinbase if it was ours
|
|
|
|
|
static uint256 hashPrevBestCoinBase; |
|
|
|
|
UpdatedTransaction(hashPrevBestCoinBase); |
|
|
|
|
g_signals.UpdatedTransaction(hashPrevBestCoinBase); |
|
|
|
|
hashPrevBestCoinBase = block.GetTxHash(0); |
|
|
|
|
} else |
|
|
|
|
CheckForkWarningConditionsOnNewFork(pindexNew); |
|
|
|
@ -3041,8 +2979,6 @@ void PrintBlockTree()
@@ -3041,8 +2979,6 @@ void PrintBlockTree()
|
|
|
|
|
DateTimeStrFormat("%Y-%m-%d %H:%M:%S", block.GetBlockTime()).c_str(), |
|
|
|
|
block.vtx.size()); |
|
|
|
|
|
|
|
|
|
PrintWallets(block); |
|
|
|
|
|
|
|
|
|
// put the main time-chain first
|
|
|
|
|
vector<CBlockIndex*>& vNext = mapNext[pindex]; |
|
|
|
|
for (unsigned int i = 0; i < vNext.size(); i++) |
|
|
|
@ -3331,7 +3267,7 @@ void static ProcessGetData(CNode* pfrom)
@@ -3331,7 +3267,7 @@ void static ProcessGetData(CNode* pfrom)
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Track requests for our stuff.
|
|
|
|
|
Inventory(inv.hash); |
|
|
|
|
g_signals.Inventory(inv.hash); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -3593,7 +3529,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
@@ -3593,7 +3529,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Track requests for our stuff
|
|
|
|
|
Inventory(inv.hash); |
|
|
|
|
g_signals.Inventory(inv.hash); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -4215,7 +4151,7 @@ bool SendMessages(CNode* pto, bool fSendTrickle)
@@ -4215,7 +4151,7 @@ bool SendMessages(CNode* pto, bool fSendTrickle)
|
|
|
|
|
// transactions become unconfirmed and spams other nodes.
|
|
|
|
|
if (!fReindex && !fImporting && !IsInitialBlockDownload()) |
|
|
|
|
{ |
|
|
|
|
ResendWalletTransactions(); |
|
|
|
|
g_signals.Broadcast(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
//
|
|
|
|
@ -4243,15 +4179,6 @@ bool SendMessages(CNode* pto, bool fSendTrickle)
@@ -4243,15 +4179,6 @@ bool SendMessages(CNode* pto, bool fSendTrickle)
|
|
|
|
|
hashRand = Hash(BEGIN(hashRand), END(hashRand)); |
|
|
|
|
bool fTrickleWait = ((hashRand & 3) != 0); |
|
|
|
|
|
|
|
|
|
// always trickle our own transactions
|
|
|
|
|
if (!fTrickleWait) |
|
|
|
|
{ |
|
|
|
|
CWalletTx wtx; |
|
|
|
|
if (GetTransaction(inv.hash, wtx)) |
|
|
|
|
if (wtx.fFromMe) |
|
|
|
|
fTrickleWait = true; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (fTrickleWait) |
|
|
|
|
{ |
|
|
|
|
vInvWait.push_back(inv); |
|
|
|
|