Merge #12408: wallet: Change output type globals to members
fab8a6f60
wallet: Change output type globals to members (MarcoFalke)
Pull request description:
Output type is used by the wallet when generating addresses or transactions with change, thus it should be a member of `CWallet`.
Moreover, in light of multiwallet, it makes sense to prepare for per-wallet attributes instead of for-all-wallets globals.
Tree-SHA512: 4fa397cd82522e5bacf4870160a2a0f5e1f2dc046e4b9e2514dee18b187a0e1724d036315f77fa48e48f85533021d5e5525d798160a92d389d75512f3f9e1405
This commit is contained in:
commit
c39dd2ef59
16 changed files with 84 additions and 92 deletions
|
@ -441,6 +441,8 @@ int AddressTableModel::lookupAddress(const QString &address) const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
OutputType AddressTableModel::GetDefaultAddressType() const { return wallet->m_default_address_type; };
|
||||||
|
|
||||||
void AddressTableModel::emitDataChanged(int idx)
|
void AddressTableModel::emitDataChanged(int idx)
|
||||||
{
|
{
|
||||||
Q_EMIT dataChanged(index(idx, 0, QModelIndex()), index(idx, columns.length()-1, QModelIndex()));
|
Q_EMIT dataChanged(index(idx, 0, QModelIndex()), index(idx, columns.length()-1, QModelIndex()));
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
#include <QAbstractTableModel>
|
#include <QAbstractTableModel>
|
||||||
#include <QStringList>
|
#include <QStringList>
|
||||||
|
|
||||||
enum OutputType : int;
|
enum class OutputType;
|
||||||
|
|
||||||
class AddressTablePriv;
|
class AddressTablePriv;
|
||||||
class WalletModel;
|
class WalletModel;
|
||||||
|
@ -76,6 +76,8 @@ public:
|
||||||
|
|
||||||
EditStatus getEditStatus() const { return editStatus; }
|
EditStatus getEditStatus() const { return editStatus; }
|
||||||
|
|
||||||
|
OutputType GetDefaultAddressType() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
WalletModel *walletModel;
|
WalletModel *walletModel;
|
||||||
CWallet *wallet;
|
CWallet *wallet;
|
||||||
|
|
|
@ -11,7 +11,6 @@
|
||||||
#include <QDataWidgetMapper>
|
#include <QDataWidgetMapper>
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
|
|
||||||
extern OutputType g_address_type;
|
|
||||||
|
|
||||||
EditAddressDialog::EditAddressDialog(Mode _mode, QWidget *parent) :
|
EditAddressDialog::EditAddressDialog(Mode _mode, QWidget *parent) :
|
||||||
QDialog(parent),
|
QDialog(parent),
|
||||||
|
@ -80,7 +79,7 @@ bool EditAddressDialog::saveCurrentRow()
|
||||||
mode == NewSendingAddress ? AddressTableModel::Send : AddressTableModel::Receive,
|
mode == NewSendingAddress ? AddressTableModel::Send : AddressTableModel::Receive,
|
||||||
ui->labelEdit->text(),
|
ui->labelEdit->text(),
|
||||||
ui->addressEdit->text(),
|
ui->addressEdit->text(),
|
||||||
g_address_type);
|
model->GetDefaultAddressType());
|
||||||
break;
|
break;
|
||||||
case EditReceivingAddress:
|
case EditReceivingAddress:
|
||||||
case EditSendingAddress:
|
case EditSendingAddress:
|
||||||
|
|
|
@ -643,7 +643,7 @@ void PaymentServer::fetchPaymentACK(CWallet* wallet, const SendCoinsRecipient& r
|
||||||
// use for change. Despite an actual payment and not change, this is a close match:
|
// use for change. Despite an actual payment and not change, this is a close match:
|
||||||
// it's the output type we use subject to privacy issues, but not restricted by what
|
// it's the output type we use subject to privacy issues, but not restricted by what
|
||||||
// other software supports.
|
// other software supports.
|
||||||
const OutputType change_type = g_change_type != OUTPUT_TYPE_NONE ? g_change_type : g_address_type;
|
const OutputType change_type = wallet->m_default_change_type != OutputType::NONE ? wallet->m_default_change_type : wallet->m_default_address_type;
|
||||||
wallet->LearnRelatedScripts(newKey, change_type);
|
wallet->LearnRelatedScripts(newKey, change_type);
|
||||||
CTxDestination dest = GetDestinationForKey(newKey, change_type);
|
CTxDestination dest = GetDestinationForKey(newKey, change_type);
|
||||||
wallet->SetAddressBook(dest, strAccount, "refund");
|
wallet->SetAddressBook(dest, strAccount, "refund");
|
||||||
|
|
|
@ -95,13 +95,13 @@ void ReceiveCoinsDialog::setModel(WalletModel *_model)
|
||||||
columnResizingFixer = new GUIUtil::TableViewLastColumnResizingFixer(tableView, AMOUNT_MINIMUM_COLUMN_WIDTH, DATE_COLUMN_WIDTH, this);
|
columnResizingFixer = new GUIUtil::TableViewLastColumnResizingFixer(tableView, AMOUNT_MINIMUM_COLUMN_WIDTH, DATE_COLUMN_WIDTH, this);
|
||||||
|
|
||||||
// configure bech32 checkbox, disable if launched with legacy as default:
|
// configure bech32 checkbox, disable if launched with legacy as default:
|
||||||
if (model->getDefaultAddressType() == OUTPUT_TYPE_BECH32) {
|
if (model->getDefaultAddressType() == OutputType::BECH32) {
|
||||||
ui->useBech32->setCheckState(Qt::Checked);
|
ui->useBech32->setCheckState(Qt::Checked);
|
||||||
} else {
|
} else {
|
||||||
ui->useBech32->setCheckState(Qt::Unchecked);
|
ui->useBech32->setCheckState(Qt::Unchecked);
|
||||||
}
|
}
|
||||||
|
|
||||||
ui->useBech32->setVisible(model->getDefaultAddressType() != OUTPUT_TYPE_LEGACY);
|
ui->useBech32->setVisible(model->getDefaultAddressType() != OutputType::LEGACY);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -145,8 +145,8 @@ void ReceiveCoinsDialog::on_receiveButton_clicked()
|
||||||
QString label = ui->reqLabel->text();
|
QString label = ui->reqLabel->text();
|
||||||
/* Generate new receiving address */
|
/* Generate new receiving address */
|
||||||
OutputType address_type = model->getDefaultAddressType();
|
OutputType address_type = model->getDefaultAddressType();
|
||||||
if (address_type != OUTPUT_TYPE_LEGACY) {
|
if (address_type != OutputType::LEGACY) {
|
||||||
address_type = ui->useBech32->isChecked() ? OUTPUT_TYPE_BECH32 : OUTPUT_TYPE_P2SH_SEGWIT;
|
address_type = ui->useBech32->isChecked() ? OutputType::BECH32 : OutputType::P2SH_SEGWIT;
|
||||||
}
|
}
|
||||||
address = model->getAddressTableModel()->addRow(AddressTableModel::Receive, label, "", address_type);
|
address = model->getAddressTableModel()->addRow(AddressTableModel::Receive, label, "", address_type);
|
||||||
SendCoinsRecipient info(address, label,
|
SendCoinsRecipient info(address, label,
|
||||||
|
|
|
@ -150,9 +150,6 @@ void BumpFee(TransactionView& view, const uint256& txid, bool expectDisabled, st
|
||||||
// src/qt/test/test_bitcoin-qt -platform cocoa # macOS
|
// src/qt/test/test_bitcoin-qt -platform cocoa # macOS
|
||||||
void TestGUI()
|
void TestGUI()
|
||||||
{
|
{
|
||||||
g_address_type = OUTPUT_TYPE_P2SH_SEGWIT;
|
|
||||||
g_change_type = OUTPUT_TYPE_P2SH_SEGWIT;
|
|
||||||
|
|
||||||
// Set up wallet and chain with 105 blocks (5 mature blocks for spending).
|
// Set up wallet and chain with 105 blocks (5 mature blocks for spending).
|
||||||
TestChain100Setup test;
|
TestChain100Setup test;
|
||||||
for (int i = 0; i < 5; ++i) {
|
for (int i = 0; i < 5; ++i) {
|
||||||
|
@ -163,7 +160,7 @@ void TestGUI()
|
||||||
wallet.LoadWallet(firstRun);
|
wallet.LoadWallet(firstRun);
|
||||||
{
|
{
|
||||||
LOCK(wallet.cs_wallet);
|
LOCK(wallet.cs_wallet);
|
||||||
wallet.SetAddressBook(GetDestinationForKey(test.coinbaseKey.GetPubKey(), g_address_type), "", "receive");
|
wallet.SetAddressBook(GetDestinationForKey(test.coinbaseKey.GetPubKey(), wallet.m_default_address_type), "", "receive");
|
||||||
wallet.AddKeyPubKey(test.coinbaseKey, test.coinbaseKey.GetPubKey());
|
wallet.AddKeyPubKey(test.coinbaseKey, test.coinbaseKey.GetPubKey());
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
|
|
|
@ -736,7 +736,7 @@ bool WalletModel::hdEnabled() const
|
||||||
|
|
||||||
OutputType WalletModel::getDefaultAddressType() const
|
OutputType WalletModel::getDefaultAddressType() const
|
||||||
{
|
{
|
||||||
return g_address_type;
|
return wallet->m_default_address_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
int WalletModel::getDefaultConfirmTarget() const
|
int WalletModel::getDefaultConfirmTarget() const
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
|
|
||||||
enum OutputType : int;
|
enum class OutputType;
|
||||||
|
|
||||||
class AddressTableModel;
|
class AddressTableModel;
|
||||||
class OptionsModel;
|
class OptionsModel;
|
||||||
|
|
|
@ -18,8 +18,8 @@ class CCoinControl
|
||||||
public:
|
public:
|
||||||
//! Custom change destination, if not set an address is generated
|
//! Custom change destination, if not set an address is generated
|
||||||
CTxDestination destChange;
|
CTxDestination destChange;
|
||||||
//! Custom change type, ignored if destChange is set, defaults to g_change_type
|
//! Override the default change type if set, ignored if destChange is set
|
||||||
OutputType change_type;
|
boost::optional<OutputType> m_change_type;
|
||||||
//! If false, allows unselected inputs, but requires all selected inputs be used
|
//! If false, allows unselected inputs, but requires all selected inputs be used
|
||||||
bool fAllowOtherInputs;
|
bool fAllowOtherInputs;
|
||||||
//! Includes watch only addresses which match the ISMINE_WATCH_SOLVABLE criteria
|
//! Includes watch only addresses which match the ISMINE_WATCH_SOLVABLE criteria
|
||||||
|
@ -43,7 +43,7 @@ public:
|
||||||
void SetNull()
|
void SetNull()
|
||||||
{
|
{
|
||||||
destChange = CNoDestination();
|
destChange = CNoDestination();
|
||||||
change_type = g_change_type;
|
m_change_type.reset();
|
||||||
fAllowOtherInputs = false;
|
fAllowOtherInputs = false;
|
||||||
fAllowWatchOnly = false;
|
fAllowWatchOnly = false;
|
||||||
setSelected.clear();
|
setSelected.clear();
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
std::string GetWalletHelpString(bool showDebug)
|
std::string GetWalletHelpString(bool showDebug)
|
||||||
{
|
{
|
||||||
std::string strUsage = HelpMessageGroup(_("Wallet options:"));
|
std::string strUsage = HelpMessageGroup(_("Wallet options:"));
|
||||||
strUsage += HelpMessageOpt("-addresstype", strprintf("What type of addresses to use (\"legacy\", \"p2sh-segwit\", or \"bech32\", default: \"%s\")", FormatOutputType(OUTPUT_TYPE_DEFAULT)));
|
strUsage += HelpMessageOpt("-addresstype", strprintf("What type of addresses to use (\"legacy\", \"p2sh-segwit\", or \"bech32\", default: \"%s\")", FormatOutputType(DEFAULT_ADDRESS_TYPE)));
|
||||||
strUsage += HelpMessageOpt("-changetype", "What type of change to use (\"legacy\", \"p2sh-segwit\", or \"bech32\"). Default is same as -addresstype, except when -addresstype=p2sh-segwit a native segwit output is used when sending to a native segwit address)");
|
strUsage += HelpMessageOpt("-changetype", "What type of change to use (\"legacy\", \"p2sh-segwit\", or \"bech32\"). Default is same as -addresstype, except when -addresstype=p2sh-segwit a native segwit output is used when sending to a native segwit address)");
|
||||||
strUsage += HelpMessageOpt("-disablewallet", _("Do not load the wallet and disable wallet RPC calls"));
|
strUsage += HelpMessageOpt("-disablewallet", _("Do not load the wallet and disable wallet RPC calls"));
|
||||||
strUsage += HelpMessageOpt("-discardfee=<amt>", strprintf(_("The fee rate (in %s/kB) that indicates your tolerance for discarding change by adding it to the fee (default: %s). "
|
strUsage += HelpMessageOpt("-discardfee=<amt>", strprintf(_("The fee rate (in %s/kB) that indicates your tolerance for discarding change by adding it to the fee (default: %s). "
|
||||||
|
@ -181,18 +181,6 @@ bool WalletParameterInteraction()
|
||||||
bSpendZeroConfChange = gArgs.GetBoolArg("-spendzeroconfchange", DEFAULT_SPEND_ZEROCONF_CHANGE);
|
bSpendZeroConfChange = gArgs.GetBoolArg("-spendzeroconfchange", DEFAULT_SPEND_ZEROCONF_CHANGE);
|
||||||
fWalletRbf = gArgs.GetBoolArg("-walletrbf", DEFAULT_WALLET_RBF);
|
fWalletRbf = gArgs.GetBoolArg("-walletrbf", DEFAULT_WALLET_RBF);
|
||||||
|
|
||||||
g_address_type = ParseOutputType(gArgs.GetArg("-addresstype", ""));
|
|
||||||
if (g_address_type == OUTPUT_TYPE_NONE) {
|
|
||||||
return InitError(strprintf("Unknown address type '%s'", gArgs.GetArg("-addresstype", "")));
|
|
||||||
}
|
|
||||||
|
|
||||||
// If changetype is set in config file or parameter, check that it's valid.
|
|
||||||
// Default to OUTPUT_TYPE_NONE if not set.
|
|
||||||
g_change_type = ParseOutputType(gArgs.GetArg("-changetype", ""), OUTPUT_TYPE_NONE);
|
|
||||||
if (g_change_type == OUTPUT_TYPE_NONE && !gArgs.GetArg("-changetype", "").empty()) {
|
|
||||||
return InitError(strprintf("Unknown change type '%s'", gArgs.GetArg("-changetype", "")));
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -83,7 +83,7 @@ bool GetWalletAddressesForKey(CWallet * const pwallet, const CKeyID &keyid, std:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!fLabelFound) {
|
if (!fLabelFound) {
|
||||||
strAddr = EncodeDestination(GetDestinationForKey(key.GetPubKey(), g_address_type));
|
strAddr = EncodeDestination(GetDestinationForKey(key.GetPubKey(), pwallet->m_default_address_type));
|
||||||
}
|
}
|
||||||
return fLabelFound;
|
return fLabelFound;
|
||||||
}
|
}
|
||||||
|
|
|
@ -162,10 +162,10 @@ UniValue getnewaddress(const JSONRPCRequest& request)
|
||||||
if (!request.params[0].isNull())
|
if (!request.params[0].isNull())
|
||||||
strAccount = AccountFromValue(request.params[0]);
|
strAccount = AccountFromValue(request.params[0]);
|
||||||
|
|
||||||
OutputType output_type = g_address_type;
|
OutputType output_type = pwallet->m_default_address_type;
|
||||||
if (!request.params[1].isNull()) {
|
if (!request.params[1].isNull()) {
|
||||||
output_type = ParseOutputType(request.params[1].get_str(), g_address_type);
|
output_type = ParseOutputType(request.params[1].get_str(), pwallet->m_default_address_type);
|
||||||
if (output_type == OUTPUT_TYPE_NONE) {
|
if (output_type == OutputType::NONE) {
|
||||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, strprintf("Unknown address type '%s'", request.params[1].get_str()));
|
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, strprintf("Unknown address type '%s'", request.params[1].get_str()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -259,10 +259,10 @@ UniValue getrawchangeaddress(const JSONRPCRequest& request)
|
||||||
pwallet->TopUpKeyPool();
|
pwallet->TopUpKeyPool();
|
||||||
}
|
}
|
||||||
|
|
||||||
OutputType output_type = g_change_type != OUTPUT_TYPE_NONE ? g_change_type : g_address_type;
|
OutputType output_type = pwallet->m_default_change_type != OutputType::NONE ? pwallet->m_default_change_type : pwallet->m_default_address_type;
|
||||||
if (!request.params[0].isNull()) {
|
if (!request.params[0].isNull()) {
|
||||||
output_type = ParseOutputType(request.params[0].get_str(), output_type);
|
output_type = ParseOutputType(request.params[0].get_str(), output_type);
|
||||||
if (output_type == OUTPUT_TYPE_NONE) {
|
if (output_type == OutputType::NONE) {
|
||||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, strprintf("Unknown address type '%s'", request.params[0].get_str()));
|
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, strprintf("Unknown address type '%s'", request.params[0].get_str()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1221,10 +1221,10 @@ UniValue addmultisigaddress(const JSONRPCRequest& request)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
OutputType output_type = g_address_type;
|
OutputType output_type = pwallet->m_default_address_type;
|
||||||
if (!request.params[3].isNull()) {
|
if (!request.params[3].isNull()) {
|
||||||
output_type = ParseOutputType(request.params[3].get_str(), output_type);
|
output_type = ParseOutputType(request.params[3].get_str(), output_type);
|
||||||
if (output_type == OUTPUT_TYPE_NONE) {
|
if (output_type == OutputType::NONE) {
|
||||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, strprintf("Unknown address type '%s'", request.params[3].get_str()));
|
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, strprintf("Unknown address type '%s'", request.params[3].get_str()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3183,8 +3183,8 @@ UniValue fundrawtransaction(const JSONRPCRequest& request)
|
||||||
if (options.exists("changeAddress")) {
|
if (options.exists("changeAddress")) {
|
||||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Cannot specify both changeAddress and address_type options");
|
throw JSONRPCError(RPC_INVALID_PARAMETER, "Cannot specify both changeAddress and address_type options");
|
||||||
}
|
}
|
||||||
coinControl.change_type = ParseOutputType(options["change_type"].get_str(), coinControl.change_type);
|
coinControl.m_change_type = ParseOutputType(options["change_type"].get_str(), pwallet->m_default_change_type);
|
||||||
if (coinControl.change_type == OUTPUT_TYPE_NONE) {
|
if (coinControl.m_change_type == OutputType::NONE) {
|
||||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, strprintf("Unknown change type '%s'", options["change_type"].get_str()));
|
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, strprintf("Unknown change type '%s'", options["change_type"].get_str()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,8 +12,6 @@ WalletTestingSetup::WalletTestingSetup(const std::string& chainName):
|
||||||
TestingSetup(chainName), m_wallet("mock", CWalletDBWrapper::CreateMock())
|
TestingSetup(chainName), m_wallet("mock", CWalletDBWrapper::CreateMock())
|
||||||
{
|
{
|
||||||
bool fFirstRun;
|
bool fFirstRun;
|
||||||
g_address_type = OUTPUT_TYPE_DEFAULT;
|
|
||||||
g_change_type = OUTPUT_TYPE_DEFAULT;
|
|
||||||
m_wallet.LoadWallet(fFirstRun);
|
m_wallet.LoadWallet(fFirstRun);
|
||||||
RegisterValidationInterface(&m_wallet);
|
RegisterValidationInterface(&m_wallet);
|
||||||
|
|
||||||
|
|
|
@ -114,9 +114,6 @@ BOOST_FIXTURE_TEST_CASE(rescan, TestChain100Setup)
|
||||||
// than or equal to key birthday.
|
// than or equal to key birthday.
|
||||||
BOOST_FIXTURE_TEST_CASE(importwallet_rescan, TestChain100Setup)
|
BOOST_FIXTURE_TEST_CASE(importwallet_rescan, TestChain100Setup)
|
||||||
{
|
{
|
||||||
g_address_type = OUTPUT_TYPE_DEFAULT;
|
|
||||||
g_change_type = OUTPUT_TYPE_DEFAULT;
|
|
||||||
|
|
||||||
// Create two blocks with same timestamp to verify that importwallet rescan
|
// Create two blocks with same timestamp to verify that importwallet rescan
|
||||||
// will pick up both blocks, not just the first.
|
// will pick up both blocks, not just the first.
|
||||||
const int64_t BLOCK_TIME = chainActive.Tip()->GetBlockTimeMax() + 5;
|
const int64_t BLOCK_TIME = chainActive.Tip()->GetBlockTimeMax() + 5;
|
||||||
|
@ -272,8 +269,6 @@ public:
|
||||||
ListCoinsTestingSetup()
|
ListCoinsTestingSetup()
|
||||||
{
|
{
|
||||||
CreateAndProcessBlock({}, GetScriptForRawPubKey(coinbaseKey.GetPubKey()));
|
CreateAndProcessBlock({}, GetScriptForRawPubKey(coinbaseKey.GetPubKey()));
|
||||||
g_address_type = OUTPUT_TYPE_DEFAULT;
|
|
||||||
g_change_type = OUTPUT_TYPE_DEFAULT;
|
|
||||||
wallet = MakeUnique<CWallet>("mock", CWalletDBWrapper::CreateMock());
|
wallet = MakeUnique<CWallet>("mock", CWalletDBWrapper::CreateMock());
|
||||||
bool firstRun;
|
bool firstRun;
|
||||||
wallet->LoadWallet(firstRun);
|
wallet->LoadWallet(firstRun);
|
||||||
|
|
|
@ -42,8 +42,6 @@ CFeeRate payTxFee(DEFAULT_TRANSACTION_FEE);
|
||||||
unsigned int nTxConfirmTarget = DEFAULT_TX_CONFIRM_TARGET;
|
unsigned int nTxConfirmTarget = DEFAULT_TX_CONFIRM_TARGET;
|
||||||
bool bSpendZeroConfChange = DEFAULT_SPEND_ZEROCONF_CHANGE;
|
bool bSpendZeroConfChange = DEFAULT_SPEND_ZEROCONF_CHANGE;
|
||||||
bool fWalletRbf = DEFAULT_WALLET_RBF;
|
bool fWalletRbf = DEFAULT_WALLET_RBF;
|
||||||
OutputType g_address_type = OUTPUT_TYPE_NONE;
|
|
||||||
OutputType g_change_type = OUTPUT_TYPE_NONE;
|
|
||||||
bool g_wallet_allow_fallback_fee = true; //<! will be defined via chainparams
|
bool g_wallet_allow_fallback_fee = true; //<! will be defined via chainparams
|
||||||
|
|
||||||
const uint32_t BIP32_HARDENED_KEY_LIMIT = 0x80000000;
|
const uint32_t BIP32_HARDENED_KEY_LIMIT = 0x80000000;
|
||||||
|
@ -823,7 +821,7 @@ bool CWallet::GetAccountDestination(CTxDestination &dest, std::string strAccount
|
||||||
bForceNew = true;
|
bForceNew = true;
|
||||||
else {
|
else {
|
||||||
// Check if the current key has been used (TODO: check other addresses with the same key)
|
// Check if the current key has been used (TODO: check other addresses with the same key)
|
||||||
CScript scriptPubKey = GetScriptForDestination(GetDestinationForKey(account.vchPubKey, g_address_type));
|
CScript scriptPubKey = GetScriptForDestination(GetDestinationForKey(account.vchPubKey, m_default_address_type));
|
||||||
for (std::map<uint256, CWalletTx>::iterator it = mapWallet.begin();
|
for (std::map<uint256, CWalletTx>::iterator it = mapWallet.begin();
|
||||||
it != mapWallet.end() && account.vchPubKey.IsValid();
|
it != mapWallet.end() && account.vchPubKey.IsValid();
|
||||||
++it)
|
++it)
|
||||||
|
@ -840,12 +838,12 @@ bool CWallet::GetAccountDestination(CTxDestination &dest, std::string strAccount
|
||||||
if (!GetKeyFromPool(account.vchPubKey, false))
|
if (!GetKeyFromPool(account.vchPubKey, false))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
LearnRelatedScripts(account.vchPubKey, g_address_type);
|
LearnRelatedScripts(account.vchPubKey, m_default_address_type);
|
||||||
dest = GetDestinationForKey(account.vchPubKey, g_address_type);
|
dest = GetDestinationForKey(account.vchPubKey, m_default_address_type);
|
||||||
SetAddressBook(dest, strAccount, "receive");
|
SetAddressBook(dest, strAccount, "receive");
|
||||||
walletdb.WriteAccount(strAccount, account);
|
walletdb.WriteAccount(strAccount, account);
|
||||||
} else {
|
} else {
|
||||||
dest = GetDestinationForKey(account.vchPubKey, g_address_type);
|
dest = GetDestinationForKey(account.vchPubKey, m_default_address_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -2649,14 +2647,14 @@ bool CWallet::FundTransaction(CMutableTransaction& tx, CAmount& nFeeRet, int& nC
|
||||||
OutputType CWallet::TransactionChangeType(OutputType change_type, const std::vector<CRecipient>& vecSend)
|
OutputType CWallet::TransactionChangeType(OutputType change_type, const std::vector<CRecipient>& vecSend)
|
||||||
{
|
{
|
||||||
// If -changetype is specified, always use that change type.
|
// If -changetype is specified, always use that change type.
|
||||||
if (change_type != OUTPUT_TYPE_NONE) {
|
if (change_type != OutputType::NONE) {
|
||||||
return change_type;
|
return change_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
// if g_address_type is legacy, use legacy address as change (even
|
// if m_default_address_type is legacy, use legacy address as change (even
|
||||||
// if some of the outputs are P2WPKH or P2WSH).
|
// if some of the outputs are P2WPKH or P2WSH).
|
||||||
if (g_address_type == OUTPUT_TYPE_LEGACY) {
|
if (m_default_address_type == OutputType::LEGACY) {
|
||||||
return OUTPUT_TYPE_LEGACY;
|
return OutputType::LEGACY;
|
||||||
}
|
}
|
||||||
|
|
||||||
// if any destination is P2WPKH or P2WSH, use P2WPKH for the change
|
// if any destination is P2WPKH or P2WSH, use P2WPKH for the change
|
||||||
|
@ -2666,12 +2664,12 @@ OutputType CWallet::TransactionChangeType(OutputType change_type, const std::vec
|
||||||
int witnessversion = 0;
|
int witnessversion = 0;
|
||||||
std::vector<unsigned char> witnessprogram;
|
std::vector<unsigned char> witnessprogram;
|
||||||
if (recipient.scriptPubKey.IsWitnessProgram(witnessversion, witnessprogram)) {
|
if (recipient.scriptPubKey.IsWitnessProgram(witnessversion, witnessprogram)) {
|
||||||
return OUTPUT_TYPE_BECH32;
|
return OutputType::BECH32;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// else use g_address_type for change
|
// else use m_default_address_type for change
|
||||||
return g_address_type;
|
return m_default_address_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CWallet::CreateTransaction(const std::vector<CRecipient>& vecSend, CTransactionRef& tx, CReserveKey& reservekey, CAmount& nFeeRet,
|
bool CWallet::CreateTransaction(const std::vector<CRecipient>& vecSend, CTransactionRef& tx, CReserveKey& reservekey, CAmount& nFeeRet,
|
||||||
|
@ -2768,7 +2766,7 @@ bool CWallet::CreateTransaction(const std::vector<CRecipient>& vecSend, CTransac
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const OutputType change_type = TransactionChangeType(coin_control.change_type, vecSend);
|
const OutputType change_type = TransactionChangeType(coin_control.m_change_type ? *coin_control.m_change_type : m_default_change_type, vecSend);
|
||||||
|
|
||||||
LearnRelatedScripts(vchPubKey, change_type);
|
LearnRelatedScripts(vchPubKey, change_type);
|
||||||
scriptChange = GetScriptForDestination(GetDestinationForKey(vchPubKey, change_type));
|
scriptChange = GetScriptForDestination(GetDestinationForKey(vchPubKey, change_type));
|
||||||
|
@ -4002,8 +4000,7 @@ CWallet* CWallet::CreateWalletFromFile(const std::string& name, const fs::path&
|
||||||
}
|
}
|
||||||
|
|
||||||
walletInstance->SetBestChain(chainActive.GetLocator());
|
walletInstance->SetBestChain(chainActive.GetLocator());
|
||||||
}
|
} else if (gArgs.IsArgSet("-usehd")) {
|
||||||
else if (gArgs.IsArgSet("-usehd")) {
|
|
||||||
bool useHD = gArgs.GetBoolArg("-usehd", true);
|
bool useHD = gArgs.GetBoolArg("-usehd", true);
|
||||||
if (walletInstance->IsHDEnabled() && !useHD) {
|
if (walletInstance->IsHDEnabled() && !useHD) {
|
||||||
InitError(strprintf(_("Error loading %s: You can't disable HD on an already existing HD wallet"), walletFile));
|
InitError(strprintf(_("Error loading %s: You can't disable HD on an already existing HD wallet"), walletFile));
|
||||||
|
@ -4015,6 +4012,20 @@ CWallet* CWallet::CreateWalletFromFile(const std::string& name, const fs::path&
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
walletInstance->m_default_address_type = ParseOutputType(gArgs.GetArg("-addresstype", ""), DEFAULT_ADDRESS_TYPE);
|
||||||
|
if (walletInstance->m_default_address_type == OutputType::NONE) {
|
||||||
|
InitError(strprintf("Unknown address type '%s'", gArgs.GetArg("-addresstype", "")));
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If changetype is set in config file or parameter, check that it's valid.
|
||||||
|
// Default to OutputType::NONE if not set.
|
||||||
|
walletInstance->m_default_change_type = ParseOutputType(gArgs.GetArg("-changetype", ""), OutputType::NONE);
|
||||||
|
if (walletInstance->m_default_change_type == OutputType::NONE && !gArgs.GetArg("-changetype", "").empty()) {
|
||||||
|
InitError(strprintf("Unknown change type '%s'", gArgs.GetArg("-changetype", "")));
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
LogPrintf(" wallet %15dms\n", GetTimeMillis() - nStart);
|
LogPrintf(" wallet %15dms\n", GetTimeMillis() - nStart);
|
||||||
|
|
||||||
// Try to top up keypool. No-op if the wallet is locked.
|
// Try to top up keypool. No-op if the wallet is locked.
|
||||||
|
@ -4203,29 +4214,29 @@ OutputType ParseOutputType(const std::string& type, OutputType default_type)
|
||||||
if (type.empty()) {
|
if (type.empty()) {
|
||||||
return default_type;
|
return default_type;
|
||||||
} else if (type == OUTPUT_TYPE_STRING_LEGACY) {
|
} else if (type == OUTPUT_TYPE_STRING_LEGACY) {
|
||||||
return OUTPUT_TYPE_LEGACY;
|
return OutputType::LEGACY;
|
||||||
} else if (type == OUTPUT_TYPE_STRING_P2SH_SEGWIT) {
|
} else if (type == OUTPUT_TYPE_STRING_P2SH_SEGWIT) {
|
||||||
return OUTPUT_TYPE_P2SH_SEGWIT;
|
return OutputType::P2SH_SEGWIT;
|
||||||
} else if (type == OUTPUT_TYPE_STRING_BECH32) {
|
} else if (type == OUTPUT_TYPE_STRING_BECH32) {
|
||||||
return OUTPUT_TYPE_BECH32;
|
return OutputType::BECH32;
|
||||||
} else {
|
} else {
|
||||||
return OUTPUT_TYPE_NONE;
|
return OutputType::NONE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string& FormatOutputType(OutputType type)
|
const std::string& FormatOutputType(OutputType type)
|
||||||
{
|
{
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case OUTPUT_TYPE_LEGACY: return OUTPUT_TYPE_STRING_LEGACY;
|
case OutputType::LEGACY: return OUTPUT_TYPE_STRING_LEGACY;
|
||||||
case OUTPUT_TYPE_P2SH_SEGWIT: return OUTPUT_TYPE_STRING_P2SH_SEGWIT;
|
case OutputType::P2SH_SEGWIT: return OUTPUT_TYPE_STRING_P2SH_SEGWIT;
|
||||||
case OUTPUT_TYPE_BECH32: return OUTPUT_TYPE_STRING_BECH32;
|
case OutputType::BECH32: return OUTPUT_TYPE_STRING_BECH32;
|
||||||
default: assert(false);
|
default: assert(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CWallet::LearnRelatedScripts(const CPubKey& key, OutputType type)
|
void CWallet::LearnRelatedScripts(const CPubKey& key, OutputType type)
|
||||||
{
|
{
|
||||||
if (key.IsCompressed() && (type == OUTPUT_TYPE_P2SH_SEGWIT || type == OUTPUT_TYPE_BECH32)) {
|
if (key.IsCompressed() && (type == OutputType::P2SH_SEGWIT || type == OutputType::BECH32)) {
|
||||||
CTxDestination witdest = WitnessV0KeyHash(key.GetID());
|
CTxDestination witdest = WitnessV0KeyHash(key.GetID());
|
||||||
CScript witprog = GetScriptForDestination(witdest);
|
CScript witprog = GetScriptForDestination(witdest);
|
||||||
// Make sure the resulting program is solvable.
|
// Make sure the resulting program is solvable.
|
||||||
|
@ -4236,20 +4247,20 @@ void CWallet::LearnRelatedScripts(const CPubKey& key, OutputType type)
|
||||||
|
|
||||||
void CWallet::LearnAllRelatedScripts(const CPubKey& key)
|
void CWallet::LearnAllRelatedScripts(const CPubKey& key)
|
||||||
{
|
{
|
||||||
// OUTPUT_TYPE_P2SH_SEGWIT always adds all necessary scripts for all types.
|
// OutputType::P2SH_SEGWIT always adds all necessary scripts for all types.
|
||||||
LearnRelatedScripts(key, OUTPUT_TYPE_P2SH_SEGWIT);
|
LearnRelatedScripts(key, OutputType::P2SH_SEGWIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
CTxDestination GetDestinationForKey(const CPubKey& key, OutputType type)
|
CTxDestination GetDestinationForKey(const CPubKey& key, OutputType type)
|
||||||
{
|
{
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case OUTPUT_TYPE_LEGACY: return key.GetID();
|
case OutputType::LEGACY: return key.GetID();
|
||||||
case OUTPUT_TYPE_P2SH_SEGWIT:
|
case OutputType::P2SH_SEGWIT:
|
||||||
case OUTPUT_TYPE_BECH32: {
|
case OutputType::BECH32: {
|
||||||
if (!key.IsCompressed()) return key.GetID();
|
if (!key.IsCompressed()) return key.GetID();
|
||||||
CTxDestination witdest = WitnessV0KeyHash(key.GetID());
|
CTxDestination witdest = WitnessV0KeyHash(key.GetID());
|
||||||
CScript witprog = GetScriptForDestination(witdest);
|
CScript witprog = GetScriptForDestination(witdest);
|
||||||
if (type == OUTPUT_TYPE_P2SH_SEGWIT) {
|
if (type == OutputType::P2SH_SEGWIT) {
|
||||||
return CScriptID(witprog);
|
return CScriptID(witprog);
|
||||||
} else {
|
} else {
|
||||||
return witdest;
|
return witdest;
|
||||||
|
@ -4275,10 +4286,10 @@ CTxDestination CWallet::AddAndGetDestinationForScript(const CScript& script, Out
|
||||||
{
|
{
|
||||||
// Note that scripts over 520 bytes are not yet supported.
|
// Note that scripts over 520 bytes are not yet supported.
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case OUTPUT_TYPE_LEGACY:
|
case OutputType::LEGACY:
|
||||||
return CScriptID(script);
|
return CScriptID(script);
|
||||||
case OUTPUT_TYPE_P2SH_SEGWIT:
|
case OutputType::P2SH_SEGWIT:
|
||||||
case OUTPUT_TYPE_BECH32: {
|
case OutputType::BECH32: {
|
||||||
WitnessV0ScriptHash hash;
|
WitnessV0ScriptHash hash;
|
||||||
CSHA256().Write(script.data(), script.size()).Finalize(hash.begin());
|
CSHA256().Write(script.data(), script.size()).Finalize(hash.begin());
|
||||||
CTxDestination witdest = hash;
|
CTxDestination witdest = hash;
|
||||||
|
@ -4287,7 +4298,7 @@ CTxDestination CWallet::AddAndGetDestinationForScript(const CScript& script, Out
|
||||||
if (!IsSolvable(*this, witprog)) return CScriptID(script);
|
if (!IsSolvable(*this, witprog)) return CScriptID(script);
|
||||||
// Add the redeemscript, so that P2WSH and P2SH-P2WSH outputs are recognized as ours.
|
// Add the redeemscript, so that P2WSH and P2SH-P2WSH outputs are recognized as ours.
|
||||||
AddCScript(witprog);
|
AddCScript(witprog);
|
||||||
if (type == OUTPUT_TYPE_BECH32) {
|
if (type == OutputType::BECH32) {
|
||||||
return witdest;
|
return witdest;
|
||||||
} else {
|
} else {
|
||||||
return CScriptID(witprog);
|
return CScriptID(witprog);
|
||||||
|
|
|
@ -43,6 +43,7 @@ extern bool bSpendZeroConfChange;
|
||||||
extern bool fWalletRbf;
|
extern bool fWalletRbf;
|
||||||
extern bool g_wallet_allow_fallback_fee;
|
extern bool g_wallet_allow_fallback_fee;
|
||||||
|
|
||||||
|
//! Default for -keypool
|
||||||
static const unsigned int DEFAULT_KEYPOOL_SIZE = 1000;
|
static const unsigned int DEFAULT_KEYPOOL_SIZE = 1000;
|
||||||
//! -paytxfee default
|
//! -paytxfee default
|
||||||
static const CAmount DEFAULT_TRANSACTION_FEE = 0;
|
static const CAmount DEFAULT_TRANSACTION_FEE = 0;
|
||||||
|
@ -96,18 +97,15 @@ enum WalletFeature
|
||||||
FEATURE_LATEST = FEATURE_COMPRPUBKEY // HD is optional, use FEATURE_COMPRPUBKEY as latest version
|
FEATURE_LATEST = FEATURE_COMPRPUBKEY // HD is optional, use FEATURE_COMPRPUBKEY as latest version
|
||||||
};
|
};
|
||||||
|
|
||||||
enum OutputType : int
|
enum class OutputType {
|
||||||
{
|
NONE,
|
||||||
OUTPUT_TYPE_NONE,
|
LEGACY,
|
||||||
OUTPUT_TYPE_LEGACY,
|
P2SH_SEGWIT,
|
||||||
OUTPUT_TYPE_P2SH_SEGWIT,
|
BECH32,
|
||||||
OUTPUT_TYPE_BECH32,
|
|
||||||
|
|
||||||
OUTPUT_TYPE_DEFAULT = OUTPUT_TYPE_P2SH_SEGWIT
|
|
||||||
};
|
};
|
||||||
|
|
||||||
extern OutputType g_address_type;
|
//! Default for -addresstype
|
||||||
extern OutputType g_change_type;
|
constexpr OutputType DEFAULT_ADDRESS_TYPE{OutputType::P2SH_SEGWIT};
|
||||||
|
|
||||||
|
|
||||||
/** A key pool entry */
|
/** A key pool entry */
|
||||||
|
@ -989,6 +987,8 @@ public:
|
||||||
static CFeeRate minTxFee;
|
static CFeeRate minTxFee;
|
||||||
static CFeeRate fallbackFee;
|
static CFeeRate fallbackFee;
|
||||||
static CFeeRate m_discard_rate;
|
static CFeeRate m_discard_rate;
|
||||||
|
OutputType m_default_address_type{DEFAULT_ADDRESS_TYPE};
|
||||||
|
OutputType m_default_change_type{OutputType::NONE}; // Default to OutputType::NONE if not set by -changetype
|
||||||
|
|
||||||
bool NewKeyPool();
|
bool NewKeyPool();
|
||||||
size_t KeypoolCountExternalKeys();
|
size_t KeypoolCountExternalKeys();
|
||||||
|
@ -1232,7 +1232,7 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
OutputType ParseOutputType(const std::string& str, OutputType default_type = OUTPUT_TYPE_DEFAULT);
|
OutputType ParseOutputType(const std::string& str, OutputType default_type);
|
||||||
const std::string& FormatOutputType(OutputType type);
|
const std::string& FormatOutputType(OutputType type);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in a new issue