wallet: make it possible to disable transaction broadcast

This is an advanced feature which will disable any kind of automatic
transaction broadcasting in the wallet. This gives the user full control
of how the transaction is sent.

For example they can broadcast new transactions through some other
mechanism themselves, after getting the transaction hex through `gettransaction`.

This just adds the option `-walletbroadcast=<0,1>`. Right now these
transactions will get the status

    Status: conflicted, has not been successfully broadcast yet

They shouldn't be shown as conflicted at all (`walletconflicts` is empty). This status
will go away when the transaction is received through the network.
This commit is contained in:
Wladimir J. van der Laan 2015-03-27 10:34:48 +01:00
parent 41113e33ad
commit 6f252627b2
3 changed files with 23 additions and 7 deletions

View file

@ -337,6 +337,7 @@ std::string HelpMessage(HelpMessageMode mode)
FormatMoney(maxTxFee))); FormatMoney(maxTxFee)));
strUsage += HelpMessageOpt("-upgradewallet", _("Upgrade wallet to latest format") + " " + _("on startup")); strUsage += HelpMessageOpt("-upgradewallet", _("Upgrade wallet to latest format") + " " + _("on startup"));
strUsage += HelpMessageOpt("-wallet=<file>", _("Specify wallet file (within data directory)") + " " + strprintf(_("(default: %s)"), "wallet.dat")); strUsage += HelpMessageOpt("-wallet=<file>", _("Specify wallet file (within data directory)") + " " + strprintf(_("(default: %s)"), "wallet.dat"));
strUsage += HelpMessageOpt("-walletbroadcast", _("Make the wallet broadcast transactions") + " " + strprintf(_("(default: %u)"), true));
strUsage += HelpMessageOpt("-walletnotify=<cmd>", _("Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)")); strUsage += HelpMessageOpt("-walletnotify=<cmd>", _("Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)"));
strUsage += HelpMessageOpt("-zapwallettxes=<mode>", _("Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup") + 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)")); " " + _("(1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data)"));
@ -1242,6 +1243,7 @@ bool AppInit2(boost::thread_group& threadGroup)
} }
} }
} }
pwalletMain->SetBroadcastTransactions(GetBoolArg("-walletbroadcast", true));
} // (!fDisableWallet) } // (!fDisableWallet)
#else // ENABLE_WALLET #else // ENABLE_WALLET
LogPrintf("No wallet compiled in!\n"); LogPrintf("No wallet compiled in!\n");

View file

@ -1096,6 +1096,9 @@ int CWallet::ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate)
void CWallet::ReacceptWalletTransactions() void CWallet::ReacceptWalletTransactions()
{ {
// If transcations aren't broadcasted, don't let them into local mempool either
if (!fBroadcastTransactions)
return;
LOCK2(cs_main, cs_wallet); LOCK2(cs_main, cs_wallet);
BOOST_FOREACH(PAIRTYPE(const uint256, CWalletTx)& item, mapWallet) BOOST_FOREACH(PAIRTYPE(const uint256, CWalletTx)& item, mapWallet)
{ {
@ -1116,6 +1119,7 @@ void CWallet::ReacceptWalletTransactions()
bool CWalletTx::RelayWalletTransaction() bool CWalletTx::RelayWalletTransaction()
{ {
assert(pwallet->GetBroadcastTransactions());
if (!IsCoinBase()) if (!IsCoinBase())
{ {
if (GetDepthInMainChain() == 0) { if (GetDepthInMainChain() == 0) {
@ -1354,7 +1358,7 @@ void CWallet::ResendWalletTransactions(int64_t nBestBlockTime)
{ {
// Do this infrequently and randomly to avoid giving away // Do this infrequently and randomly to avoid giving away
// that these are our transactions. // that these are our transactions.
if (GetTime() < nNextResend) if (GetTime() < nNextResend || !fBroadcastTransactions)
return; return;
bool fFirst = (nNextResend == 0); bool fFirst = (nNextResend == 0);
nNextResend = GetTime() + GetRand(30 * 60); nNextResend = GetTime() + GetRand(30 * 60);
@ -1979,14 +1983,17 @@ bool CWallet::CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey)
// Track how many getdata requests our transaction gets // Track how many getdata requests our transaction gets
mapRequestCount[wtxNew.GetHash()] = 0; mapRequestCount[wtxNew.GetHash()] = 0;
// Broadcast if (fBroadcastTransactions)
if (!wtxNew.AcceptToMemoryPool(false))
{ {
// This must not fail. The transaction has already been signed and recorded. // Broadcast
LogPrintf("CommitTransaction(): Error: Transaction not valid"); if (!wtxNew.AcceptToMemoryPool(false))
return false; {
// This must not fail. The transaction has already been signed and recorded.
LogPrintf("CommitTransaction(): Error: Transaction not valid");
return false;
}
wtxNew.RelayWalletTransaction();
} }
wtxNew.RelayWalletTransaction();
} }
return true; return true;
} }

View file

@ -455,6 +455,7 @@ private:
int64_t nNextResend; int64_t nNextResend;
int64_t nLastResend; int64_t nLastResend;
bool fBroadcastTransactions;
/** /**
* Used to keep track of spent outpoints, and * Used to keep track of spent outpoints, and
@ -518,6 +519,7 @@ public:
nNextResend = 0; nNextResend = 0;
nLastResend = 0; nLastResend = 0;
nTimeFirstKey = 0; nTimeFirstKey = 0;
fBroadcastTransactions = false;
} }
std::map<uint256, CWalletTx> mapWallet; std::map<uint256, CWalletTx> mapWallet;
@ -723,6 +725,11 @@ public:
/** Watch-only address added */ /** Watch-only address added */
boost::signals2::signal<void (bool fHaveWatchOnly)> NotifyWatchonlyChanged; boost::signals2::signal<void (bool fHaveWatchOnly)> NotifyWatchonlyChanged;
/** Inquire whether this wallet broadcasts transactions. */
bool GetBroadcastTransactions() const { return fBroadcastTransactions; }
/** Set whether this wallet broadcasts transactions. */
void SetBroadcastTransactions(bool broadcast) { fBroadcastTransactions = broadcast; }
}; };
/** A key allocated from the key pool. */ /** A key allocated from the key pool. */