From 152f45ba58b1548bba0788ca557fd66197063aa3 Mon Sep 17 00:00:00 2001 From: Peter Todd Date: Mon, 30 Nov 2015 13:11:18 +0800 Subject: [PATCH 1/3] Add option to opt into full-RBF when sending funds --- src/wallet/wallet.cpp | 9 ++++++--- src/wallet/wallet.h | 3 +++ 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 769322969d207..c804d79c28ba8 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -40,6 +40,7 @@ CFeeRate payTxFee(DEFAULT_TRANSACTION_FEE); unsigned int nTxConfirmTarget = DEFAULT_TX_CONFIRM_TARGET; bool bSpendZeroConfChange = DEFAULT_SPEND_ZEROCONF_CHANGE; bool fSendFreeTransactions = DEFAULT_SEND_FREE_TRANSACTIONS; +bool fOptIntoFullRbf = DEFAULT_OPT_INTO_FULL_RBF; const char * DEFAULT_WALLET_DAT = "wallet.dat"; const uint32_t BIP32_HARDENED_KEY_LIMIT = 0x80000000; @@ -2355,11 +2356,11 @@ bool CWallet::CreateTransaction(const vector& vecSend, CWalletTx& wt // Fill vin // - // Note how the sequence number is set to max()-1 so that the - // nLockTime set above actually works. + // Note how the sequence number is set to non-maxint so that + // the nLockTime set above actually works. BOOST_FOREACH(const PAIRTYPE(const CWalletTx*,unsigned int)& coin, setCoins) txNew.vin.push_back(CTxIn(coin.first->GetHash(),coin.second,CScript(), - std::numeric_limits::max()-1)); + std::numeric_limits::max() - (fOptIntoFullRbf ? 2 : 1))); // Sign int nIn = 0; @@ -3240,6 +3241,7 @@ std::string CWallet::GetWalletHelpString(bool showDebug) strUsage += HelpMessageOpt("-spendzeroconfchange", strprintf(_("Spend unconfirmed change when sending transactions (default: %u)"), DEFAULT_SPEND_ZEROCONF_CHANGE)); strUsage += HelpMessageOpt("-txconfirmtarget=", strprintf(_("If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)"), DEFAULT_TX_CONFIRM_TARGET)); strUsage += HelpMessageOpt("-usehd", _("Use hierarchical deterministic key generation (HD) after BIP32. Only has effect during wallet creation/first start") + " " + strprintf(_("(default: %u)"), DEFAULT_USE_HD_WALLET)); + strUsage += HelpMessageOpt("-optintofullrbf", strprintf(_("Send transactions with full-RBF opt-in enabled (default: %u)"), DEFAULT_OPT_INTO_FULL_RBF)); strUsage += HelpMessageOpt("-upgradewallet", _("Upgrade wallet to latest format on startup")); strUsage += HelpMessageOpt("-wallet=", _("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)); @@ -3480,6 +3482,7 @@ bool CWallet::ParameterInteraction() nTxConfirmTarget = GetArg("-txconfirmtarget", DEFAULT_TX_CONFIRM_TARGET); bSpendZeroConfChange = GetBoolArg("-spendzeroconfchange", DEFAULT_SPEND_ZEROCONF_CHANGE); fSendFreeTransactions = GetBoolArg("-sendfreetransactions", DEFAULT_SEND_FREE_TRANSACTIONS); + fOptIntoFullRbf = GetBoolArg("-optintofullrbf", DEFAULT_OPT_INTO_FULL_RBF); return true; } diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index c06513650c74a..5d93d2c4d96d8 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -37,6 +37,7 @@ extern CFeeRate payTxFee; extern unsigned int nTxConfirmTarget; extern bool bSpendZeroConfChange; extern bool fSendFreeTransactions; +extern bool fOptIntoFullRbf; static const unsigned int DEFAULT_KEYPOOL_SIZE = 100; //! -paytxfee default @@ -53,6 +54,8 @@ static const bool DEFAULT_SPEND_ZEROCONF_CHANGE = true; static const bool DEFAULT_SEND_FREE_TRANSACTIONS = false; //! -txconfirmtarget default static const unsigned int DEFAULT_TX_CONFIRM_TARGET = 2; +//! -optintofullrbf default +static const bool DEFAULT_OPT_INTO_FULL_RBF = false; //! Largest (in bytes) free transaction we're willing to create static const unsigned int MAX_FREE_TRANSACTION_CREATE_SIZE = 1000; static const bool DEFAULT_WALLETBROADCAST = true; From 05fa823bf60d21049caebc64dd5c5add8ba4ee10 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Fri, 26 Aug 2016 12:13:48 +0200 Subject: [PATCH 2/3] wallet: Add BIP125 comment for MAXINT-1/-2 behavior --- src/wallet/wallet.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index c804d79c28ba8..5542a536e1d39 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -2358,6 +2358,12 @@ bool CWallet::CreateTransaction(const vector& vecSend, CWalletTx& wt // // Note how the sequence number is set to non-maxint so that // the nLockTime set above actually works. + // + // BIP125 defines opt-in RBF as any nSequence < maxint-1, so + // we use the highest possible value in that range (maxint-2) + // to avoid conflicting with other possible uses of nSequence, + // and in the spirit of "smallest posible change from prior + // behavior." BOOST_FOREACH(const PAIRTYPE(const CWalletTx*,unsigned int)& coin, setCoins) txNew.vin.push_back(CTxIn(coin.first->GetHash(),coin.second,CScript(), std::numeric_limits::max() - (fOptIntoFullRbf ? 2 : 1))); From 86726d8680c3398c41e62924588c44f4a394367e Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Thu, 1 Sep 2016 15:24:45 +0200 Subject: [PATCH 3/3] Rename `-optintofullrbf` option to `-walletrbf` This makes it clear that this is a wallet option. --- src/wallet/wallet.cpp | 8 ++++---- src/wallet/wallet.h | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 5542a536e1d39..67a0174e1ba8e 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -40,7 +40,7 @@ CFeeRate payTxFee(DEFAULT_TRANSACTION_FEE); unsigned int nTxConfirmTarget = DEFAULT_TX_CONFIRM_TARGET; bool bSpendZeroConfChange = DEFAULT_SPEND_ZEROCONF_CHANGE; bool fSendFreeTransactions = DEFAULT_SEND_FREE_TRANSACTIONS; -bool fOptIntoFullRbf = DEFAULT_OPT_INTO_FULL_RBF; +bool fWalletRbf = DEFAULT_WALLET_RBF; const char * DEFAULT_WALLET_DAT = "wallet.dat"; const uint32_t BIP32_HARDENED_KEY_LIMIT = 0x80000000; @@ -2366,7 +2366,7 @@ bool CWallet::CreateTransaction(const vector& vecSend, CWalletTx& wt // behavior." BOOST_FOREACH(const PAIRTYPE(const CWalletTx*,unsigned int)& coin, setCoins) txNew.vin.push_back(CTxIn(coin.first->GetHash(),coin.second,CScript(), - std::numeric_limits::max() - (fOptIntoFullRbf ? 2 : 1))); + std::numeric_limits::max() - (fWalletRbf ? 2 : 1))); // Sign int nIn = 0; @@ -3247,7 +3247,7 @@ std::string CWallet::GetWalletHelpString(bool showDebug) strUsage += HelpMessageOpt("-spendzeroconfchange", strprintf(_("Spend unconfirmed change when sending transactions (default: %u)"), DEFAULT_SPEND_ZEROCONF_CHANGE)); strUsage += HelpMessageOpt("-txconfirmtarget=", strprintf(_("If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)"), DEFAULT_TX_CONFIRM_TARGET)); strUsage += HelpMessageOpt("-usehd", _("Use hierarchical deterministic key generation (HD) after BIP32. Only has effect during wallet creation/first start") + " " + strprintf(_("(default: %u)"), DEFAULT_USE_HD_WALLET)); - strUsage += HelpMessageOpt("-optintofullrbf", strprintf(_("Send transactions with full-RBF opt-in enabled (default: %u)"), DEFAULT_OPT_INTO_FULL_RBF)); + strUsage += HelpMessageOpt("-walletrbf", strprintf(_("Send transactions with full-RBF opt-in enabled (default: %u)"), DEFAULT_WALLET_RBF)); strUsage += HelpMessageOpt("-upgradewallet", _("Upgrade wallet to latest format on startup")); strUsage += HelpMessageOpt("-wallet=", _("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)); @@ -3488,7 +3488,7 @@ bool CWallet::ParameterInteraction() nTxConfirmTarget = GetArg("-txconfirmtarget", DEFAULT_TX_CONFIRM_TARGET); bSpendZeroConfChange = GetBoolArg("-spendzeroconfchange", DEFAULT_SPEND_ZEROCONF_CHANGE); fSendFreeTransactions = GetBoolArg("-sendfreetransactions", DEFAULT_SEND_FREE_TRANSACTIONS); - fOptIntoFullRbf = GetBoolArg("-optintofullrbf", DEFAULT_OPT_INTO_FULL_RBF); + fWalletRbf = GetBoolArg("-walletrbf", DEFAULT_WALLET_RBF); return true; } diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index 5d93d2c4d96d8..220b1e52b57e4 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -37,7 +37,7 @@ extern CFeeRate payTxFee; extern unsigned int nTxConfirmTarget; extern bool bSpendZeroConfChange; extern bool fSendFreeTransactions; -extern bool fOptIntoFullRbf; +extern bool fWalletRbf; static const unsigned int DEFAULT_KEYPOOL_SIZE = 100; //! -paytxfee default @@ -54,8 +54,8 @@ static const bool DEFAULT_SPEND_ZEROCONF_CHANGE = true; static const bool DEFAULT_SEND_FREE_TRANSACTIONS = false; //! -txconfirmtarget default static const unsigned int DEFAULT_TX_CONFIRM_TARGET = 2; -//! -optintofullrbf default -static const bool DEFAULT_OPT_INTO_FULL_RBF = false; +//! -walletrbf default +static const bool DEFAULT_WALLET_RBF = false; //! Largest (in bytes) free transaction we're willing to create static const unsigned int MAX_FREE_TRANSACTION_CREATE_SIZE = 1000; static const bool DEFAULT_WALLETBROADCAST = true;