diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/consensus/validation.h | 4 | ||||
-rw-r--r-- | src/qt/forms/modaloverlay.ui | 10 | ||||
-rw-r--r-- | src/qt/forms/receivecoinsdialog.ui | 2 | ||||
-rw-r--r-- | src/qt/forms/sendcoinsdialog.ui | 2 | ||||
-rw-r--r-- | src/qt/guiutil.cpp | 84 | ||||
-rw-r--r-- | src/qt/optionsdialog.cpp | 4 | ||||
-rw-r--r-- | src/qt/sendcoinsdialog.cpp | 8 | ||||
-rw-r--r-- | src/qt/test/wallettests.cpp | 10 | ||||
-rw-r--r-- | src/randomenv.cpp | 25 | ||||
-rw-r--r-- | src/rpc/util.cpp | 6 | ||||
-rw-r--r-- | src/rpc/util.h | 2 | ||||
-rw-r--r-- | src/util/system.cpp | 8 | ||||
-rw-r--r-- | src/util/system.h | 4 | ||||
-rw-r--r-- | src/wallet/coincontrol.h | 6 | ||||
-rw-r--r-- | src/wallet/init.cpp | 2 | ||||
-rw-r--r-- | src/wallet/rpcwallet.cpp | 97 | ||||
-rw-r--r-- | src/wallet/wallet.h | 2 |
17 files changed, 115 insertions, 161 deletions
diff --git a/src/consensus/validation.h b/src/consensus/validation.h index e602b9d5f3..3401eb64ca 100644 --- a/src/consensus/validation.h +++ b/src/consensus/validation.h @@ -114,7 +114,7 @@ inline ValidationState::~ValidationState() {}; class TxValidationState : public ValidationState { private: - TxValidationResult m_result; + TxValidationResult m_result = TxValidationResult::TX_RESULT_UNSET; public: bool Invalid(TxValidationResult result, const std::string &reject_reason="", @@ -129,7 +129,7 @@ public: class BlockValidationState : public ValidationState { private: - BlockValidationResult m_result; + BlockValidationResult m_result = BlockValidationResult::BLOCK_RESULT_UNSET; public: bool Invalid(BlockValidationResult result, const std::string &reject_reason="", diff --git a/src/qt/forms/modaloverlay.ui b/src/qt/forms/modaloverlay.ui index b5a69c578d..da19a6fa2e 100644 --- a/src/qt/forms/modaloverlay.ui +++ b/src/qt/forms/modaloverlay.ui @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8"?> <ui version="4.0"> <class>ModalOverlay</class> - <widget class="ModalOverlay" name="ModalOverlay"> + <widget class="QWidget" name="ModalOverlay"> <property name="geometry"> <rect> <x>0</x> @@ -369,14 +369,6 @@ QLabel { color: rgb(40,40,40); }</string> </item> </layout> </widget> - <customwidgets> - <customwidget> - <class>ModalOverlay</class> - <extends>QWidget</extends> - <header>qt/modaloverlay.h</header> - <container>1</container> - </customwidget> - </customwidgets> <resources/> <connections/> </ui> diff --git a/src/qt/forms/receivecoinsdialog.ui b/src/qt/forms/receivecoinsdialog.ui index 64f52fcf45..7dbee6d689 100644 --- a/src/qt/forms/receivecoinsdialog.ui +++ b/src/qt/forms/receivecoinsdialog.ui @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8"?> <ui version="4.0"> <class>ReceiveCoinsDialog</class> - <widget class="QWidget" name="ReceiveCoinsDialog"> + <widget class="QDialog" name="ReceiveCoinsDialog"> <property name="geometry"> <rect> <x>0</x> diff --git a/src/qt/forms/sendcoinsdialog.ui b/src/qt/forms/sendcoinsdialog.ui index 7190d59240..cfd4bf33d4 100644 --- a/src/qt/forms/sendcoinsdialog.ui +++ b/src/qt/forms/sendcoinsdialog.ui @@ -1190,7 +1190,7 @@ Note: Since the fee is calculated on a per-byte basis, a fee of "100 satoshis p <number>3</number> </property> <item> - <widget class="QLabel" name="label"> + <widget class="QLabel" name="labelBalanceName"> <property name="sizePolicy"> <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> <horstretch>0</horstretch> diff --git a/src/qt/guiutil.cpp b/src/qt/guiutil.cpp index 31e62ab63d..2bb9535441 100644 --- a/src/qt/guiutil.cpp +++ b/src/qt/guiutil.cpp @@ -54,10 +54,7 @@ #include <QUrlQuery> #if defined(Q_OS_MAC) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wdeprecated-declarations" -#include <CoreServices/CoreServices.h> #include <QProcess> void ForceActivation(); @@ -691,87 +688,6 @@ bool SetStartOnSystemStartup(bool fAutoStart) return true; } - -#elif defined(Q_OS_MAC) && defined(MAC_OS_X_VERSION_MIN_REQUIRED) && MAC_OS_X_VERSION_MIN_REQUIRED <= 101100 -// based on: https://github.com/Mozketo/LaunchAtLoginController/blob/master/LaunchAtLoginController.m - -LSSharedFileListItemRef findStartupItemInList(CFArrayRef listSnapshot, LSSharedFileListRef list, CFURLRef findUrl) -{ - if (listSnapshot == nullptr) { - return nullptr; - } - - // loop through the list of startup items and try to find the bitcoin app - for(int i = 0; i < CFArrayGetCount(listSnapshot); i++) { - LSSharedFileListItemRef item = (LSSharedFileListItemRef)CFArrayGetValueAtIndex(listSnapshot, i); - UInt32 resolutionFlags = kLSSharedFileListNoUserInteraction | kLSSharedFileListDoNotMountVolumes; - CFURLRef currentItemURL = nullptr; - -#if defined(MAC_OS_X_VERSION_MAX_ALLOWED) && MAC_OS_X_VERSION_MAX_ALLOWED >= 10100 - if(&LSSharedFileListItemCopyResolvedURL) - currentItemURL = LSSharedFileListItemCopyResolvedURL(item, resolutionFlags, nullptr); -#if defined(MAC_OS_X_VERSION_MIN_REQUIRED) && MAC_OS_X_VERSION_MIN_REQUIRED < 10100 - else - LSSharedFileListItemResolve(item, resolutionFlags, ¤tItemURL, nullptr); -#endif -#else - LSSharedFileListItemResolve(item, resolutionFlags, ¤tItemURL, nullptr); -#endif - - if(currentItemURL) { - if (CFEqual(currentItemURL, findUrl)) { - // found - CFRelease(currentItemURL); - return item; - } - CFRelease(currentItemURL); - } - } - return nullptr; -} - -bool GetStartOnSystemStartup() -{ - CFURLRef bitcoinAppUrl = CFBundleCopyBundleURL(CFBundleGetMainBundle()); - if (bitcoinAppUrl == nullptr) { - return false; - } - - LSSharedFileListRef loginItems = LSSharedFileListCreate(nullptr, kLSSharedFileListSessionLoginItems, nullptr); - CFArrayRef listSnapshot = LSSharedFileListCopySnapshot(loginItems, nullptr); - bool res = (findStartupItemInList(listSnapshot, loginItems, bitcoinAppUrl) != nullptr); - CFRelease(bitcoinAppUrl); - CFRelease(loginItems); - CFRelease(listSnapshot); - return res; -} - -bool SetStartOnSystemStartup(bool fAutoStart) -{ - CFURLRef bitcoinAppUrl = CFBundleCopyBundleURL(CFBundleGetMainBundle()); - if (bitcoinAppUrl == nullptr) { - return false; - } - - LSSharedFileListRef loginItems = LSSharedFileListCreate(nullptr, kLSSharedFileListSessionLoginItems, nullptr); - CFArrayRef listSnapshot = LSSharedFileListCopySnapshot(loginItems, nullptr); - LSSharedFileListItemRef foundItem = findStartupItemInList(listSnapshot, loginItems, bitcoinAppUrl); - - if(fAutoStart && !foundItem) { - // add bitcoin app to startup item list - LSSharedFileListInsertItemURL(loginItems, kLSSharedFileListItemBeforeFirst, nullptr, nullptr, bitcoinAppUrl, nullptr, nullptr); - } - else if(!fAutoStart && foundItem) { - // remove item - LSSharedFileListItemRemove(loginItems, foundItem); - } - - CFRelease(bitcoinAppUrl); - CFRelease(loginItems); - CFRelease(listSnapshot); - return true; -} -#pragma GCC diagnostic pop #else bool GetStartOnSystemStartup() { return false; } diff --git a/src/qt/optionsdialog.cpp b/src/qt/optionsdialog.cpp index 57cafaaac0..d48c537c75 100644 --- a/src/qt/optionsdialog.cpp +++ b/src/qt/optionsdialog.cpp @@ -71,13 +71,11 @@ OptionsDialog::OptionsDialog(QWidget *parent, bool enableWallet) : #ifdef Q_OS_MAC /* remove Window tab on Mac */ ui->tabWidget->removeTab(ui->tabWidget->indexOf(ui->tabWindow)); -#if defined(MAC_OS_X_VERSION_MIN_REQUIRED) && MAC_OS_X_VERSION_MIN_REQUIRED > 101100 - /* hide launch at startup option if compiled against macOS > 10.11 (removed API) */ + /* hide launch at startup option on macOS */ ui->bitcoinAtStartup->setVisible(false); ui->verticalLayout_Main->removeWidget(ui->bitcoinAtStartup); ui->verticalLayout_Main->removeItem(ui->horizontalSpacer_0_Main); #endif -#endif /* remove Wallet tab in case of -disablewallet */ if (!enableWallet) { diff --git a/src/qt/sendcoinsdialog.cpp b/src/qt/sendcoinsdialog.cpp index c3d00fa38e..f1ea3e23e5 100644 --- a/src/qt/sendcoinsdialog.cpp +++ b/src/qt/sendcoinsdialog.cpp @@ -27,6 +27,7 @@ #include <wallet/coincontrol.h> #include <wallet/fees.h> #include <wallet/psbtwallet.h> +#include <wallet/wallet.h> #include <QFontMetrics> #include <QScrollBar> @@ -561,7 +562,12 @@ void SendCoinsDialog::setBalance(const interfaces::WalletBalances& balances) { if(model && model->getOptionsModel()) { - ui->labelBalance->setText(BitcoinUnits::formatWithUnit(model->getOptionsModel()->getDisplayUnit(), balances.balance)); + CAmount balance = balances.balance; + if (model->privateKeysDisabled()) { + balance = balances.watch_only_balance; + ui->labelBalanceName->setText(tr("Watch-only balance:")); + } + ui->labelBalance->setText(BitcoinUnits::formatWithUnit(model->getOptionsModel()->getDisplayUnit(), balance)); } } diff --git a/src/qt/test/wallettests.cpp b/src/qt/test/wallettests.cpp index 980de711db..dfd56511ea 100644 --- a/src/qt/test/wallettests.cpp +++ b/src/qt/test/wallettests.cpp @@ -170,6 +170,16 @@ void TestGUI(interfaces::Node& node) sendCoinsDialog.setModel(&walletModel); transactionView.setModel(&walletModel); + { + // Check balance in send dialog + QLabel* balanceLabel = sendCoinsDialog.findChild<QLabel*>("labelBalance"); + QString balanceText = balanceLabel->text(); + int unit = walletModel.getOptionsModel()->getDisplayUnit(); + CAmount balance = walletModel.wallet().getBalance(); + QString balanceComparison = BitcoinUnits::formatWithUnit(unit, balance, false, BitcoinUnits::separatorAlways); + QCOMPARE(balanceText, balanceComparison); + } + // Send two transactions, and verify they are added to transaction list. TransactionTableModel* transactionTableModel = walletModel.getTransactionTableModel(); QCOMPARE(transactionTableModel->rowCount({}), 105); diff --git a/src/randomenv.cpp b/src/randomenv.cpp index ec42ddabc3..6992c720ff 100644 --- a/src/randomenv.cpp +++ b/src/randomenv.cpp @@ -197,19 +197,30 @@ void AddAllCPUID(CSHA512& hasher) // Iterate over all standard leaves AddCPUID(hasher, 0, 0, ax, bx, cx, dx); // Returns max leaf in ax uint32_t max = ax; - for (uint32_t leaf = 1; leaf <= max; ++leaf) { - for (uint32_t subleaf = 0;; ++subleaf) { + for (uint32_t leaf = 1; leaf <= max && leaf <= 0xFF; ++leaf) { + uint32_t maxsub = 0; + for (uint32_t subleaf = 0; subleaf <= 0xFF; ++subleaf) { AddCPUID(hasher, leaf, subleaf, ax, bx, cx, dx); - // Iterate over subleaves for leaf 4, 11, 13 - if (leaf != 4 && leaf != 11 && leaf != 13) break; - if ((leaf == 4 || leaf == 13) && ax == 0) break; - if (leaf == 11 && (cx & 0xFF00) == 0) break; + // Iterate subleafs for leaf values 4, 7, 11, 13 + if (leaf == 4) { + if ((ax & 0x1f) == 0) break; + } else if (leaf == 7) { + if (subleaf == 0) maxsub = ax; + if (subleaf == maxsub) break; + } else if (leaf == 11) { + if ((cx & 0xff00) == 0) break; + } else if (leaf == 13) { + if (ax == 0 && bx == 0 && cx == 0 && dx == 0) break; + } else { + // For any other leaf, stop after subleaf 0. + break; + } } } // Iterate over all extended leaves AddCPUID(hasher, 0x80000000, 0, ax, bx, cx, dx); // Returns max extended leaf in ax uint32_t ext_max = ax; - for (uint32_t leaf = 0x80000001; leaf <= ext_max; ++leaf) { + for (uint32_t leaf = 0x80000001; leaf <= ext_max && leaf <= 0x800000FF; ++leaf) { AddCPUID(hasher, leaf, 0, ax, bx, cx, dx); } } diff --git a/src/rpc/util.cpp b/src/rpc/util.cpp index cfa3509c65..0791a365fe 100644 --- a/src/rpc/util.cpp +++ b/src/rpc/util.cpp @@ -131,18 +131,18 @@ CPubKey HexToPubKey(const std::string& hex_in) } // Retrieves a public key for an address from the given FillableSigningProvider -CPubKey AddrToPubKey(FillableSigningProvider* const keystore, const std::string& addr_in) +CPubKey AddrToPubKey(const FillableSigningProvider& keystore, const std::string& addr_in) { CTxDestination dest = DecodeDestination(addr_in); if (!IsValidDestination(dest)) { throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid address: " + addr_in); } - CKeyID key = GetKeyForDestination(*keystore, dest); + CKeyID key = GetKeyForDestination(keystore, dest); if (key.IsNull()) { throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, strprintf("%s does not refer to a key", addr_in)); } CPubKey vchPubKey; - if (!keystore->GetPubKey(key, vchPubKey)) { + if (!keystore.GetPubKey(key, vchPubKey)) { throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, strprintf("no full public key for address %s", addr_in)); } if (!vchPubKey.IsFullyValid()) { diff --git a/src/rpc/util.h b/src/rpc/util.h index 221638aa9e..9304e1fefb 100644 --- a/src/rpc/util.h +++ b/src/rpc/util.h @@ -69,7 +69,7 @@ extern std::string HelpExampleCli(const std::string& methodname, const std::stri extern std::string HelpExampleRpc(const std::string& methodname, const std::string& args); CPubKey HexToPubKey(const std::string& hex_in); -CPubKey AddrToPubKey(FillableSigningProvider* const keystore, const std::string& addr_in); +CPubKey AddrToPubKey(const FillableSigningProvider& keystore, const std::string& addr_in); CTxDestination AddAndGetMultisigDestination(const int required, const std::vector<CPubKey>& pubkeys, OutputType type, FillableSigningProvider& keystore, CScript& script_out); UniValue DescribeAddress(const CTxDestination& dest); diff --git a/src/util/system.cpp b/src/util/system.cpp index 2a2ae6fdf5..563ff6a54b 100644 --- a/src/util/system.cpp +++ b/src/util/system.cpp @@ -1126,17 +1126,13 @@ fs::path AbsPathForConfigVal(const fs::path& path, bool net_specific) return fs::absolute(path, GetDataDir(net_specific)); } -int ScheduleBatchPriority() +void ScheduleBatchPriority() { #ifdef SCHED_BATCH const static sched_param param{}; - if (int ret = pthread_setschedparam(pthread_self(), SCHED_BATCH, ¶m)) { + if (pthread_setschedparam(pthread_self(), SCHED_BATCH, ¶m) != 0) { LogPrintf("Failed to pthread_setschedparam: %s\n", strerror(errno)); - return ret; } - return 0; -#else - return 1; #endif } diff --git a/src/util/system.h b/src/util/system.h index e0b6371dc9..82903b5187 100644 --- a/src/util/system.h +++ b/src/util/system.h @@ -367,10 +367,8 @@ std::string CopyrightHolders(const std::string& strPrefix); * On platforms that support it, tell the kernel the calling thread is * CPU-intensive and non-interactive. See SCHED_BATCH in sched(7) for details. * - * @return The return value of sched_setschedule(), or 1 on systems without - * sched_setschedule(). */ -int ScheduleBatchPriority(); +void ScheduleBatchPriority(); namespace util { diff --git a/src/wallet/coincontrol.h b/src/wallet/coincontrol.h index fca4b75c45..2893d0ab3d 100644 --- a/src/wallet/coincontrol.h +++ b/src/wallet/coincontrol.h @@ -6,14 +6,18 @@ #define BITCOIN_WALLET_COINCONTROL_H #include <optional.h> +#include <outputtype.h> #include <policy/feerate.h> #include <policy/fees.h> #include <primitives/transaction.h> -#include <wallet/wallet.h> +#include <script/standard.h> const int DEFAULT_MIN_DEPTH = 0; const int DEFAULT_MAX_DEPTH = 9999999; +//! Default for -avoidpartialspends +static constexpr bool DEFAULT_AVOIDPARTIALSPENDS = false; + /** Coin Control Features. */ class CCoinControl { diff --git a/src/wallet/init.cpp b/src/wallet/init.cpp index 8b09dc9ad0..dd0d2ffbd7 100644 --- a/src/wallet/init.cpp +++ b/src/wallet/init.cpp @@ -8,9 +8,11 @@ #include <net.h> #include <node/context.h> #include <outputtype.h> +#include <ui_interface.h> #include <util/moneystr.h> #include <util/system.h> #include <util/translation.h> +#include <wallet/coincontrol.h> #include <wallet/wallet.h> #include <walletinitinterface.h> diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 3563b05c71..d906f6ddf0 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -951,7 +951,7 @@ static UniValue addmultisigaddress(const JSONRPCRequest& request) } RPCHelpMan{"addmultisigaddress", - "\nAdd a nrequired-to-sign multisignature address to the wallet. Requires a new wallet backup.\n" + "\nAdd an nrequired-to-sign multisignature address to the wallet. Requires a new wallet backup.\n" "Each key is a Bitcoin address or hex-encoded public key.\n" "This functionality is only intended for use with non-watchonly addresses.\n" "See `importaddress` for watchonly p2sh address support.\n" @@ -998,7 +998,7 @@ static UniValue addmultisigaddress(const JSONRPCRequest& request) if (IsHex(keys_or_addrs[i].get_str()) && (keys_or_addrs[i].get_str().length() == 66 || keys_or_addrs[i].get_str().length() == 130)) { pubkeys.push_back(HexToPubKey(keys_or_addrs[i].get_str())); } else { - pubkeys.push_back(AddrToPubKey(&spk_man, keys_or_addrs[i].get_str())); + pubkeys.push_back(AddrToPubKey(spk_man, keys_or_addrs[i].get_str())); } } @@ -3709,52 +3709,57 @@ UniValue getaddressinfo(const JSONRPCRequest& request) } RPCHelpMan{"getaddressinfo", - "\nReturn information about the given bitcoin address. Some information requires the address\n" - "to be in the wallet.\n", + "\nReturn information about the given bitcoin address.\n" + "Some of the information will only be present if the address is in the active wallet.\n", { - {"address", RPCArg::Type::STR, RPCArg::Optional::NO, "The bitcoin address to get the information of."}, + {"address", RPCArg::Type::STR, RPCArg::Optional::NO, "The bitcoin address for which to get information."}, }, RPCResult{ "{\n" - " \"address\" : \"address\", (string) The bitcoin address validated\n" - " \"scriptPubKey\" : \"hex\", (string) The hex-encoded scriptPubKey generated by the address\n" - " \"ismine\" : true|false, (boolean) If the address is yours or not\n" - " \"iswatchonly\" : true|false, (boolean) If the address is watchonly\n" - " \"solvable\" : true|false, (boolean) Whether we know how to spend coins sent to this address, ignoring the possible lack of private keys\n" - " \"desc\" : \"desc\", (string, optional) A descriptor for spending coins sent to this address (only when solvable)\n" - " \"isscript\" : true|false, (boolean) If the key is a script\n" - " \"ischange\" : true|false, (boolean) If the address was used for change output\n" - " \"iswitness\" : true|false, (boolean) If the address is a witness address\n" - " \"witness_version\" : version (numeric, optional) The version number of the witness program\n" - " \"witness_program\" : \"hex\" (string, optional) The hex value of the witness program\n" - " \"script\" : \"type\" (string, optional) The output script type. Only if \"isscript\" is true and the redeemscript is known. Possible types: nonstandard, pubkey, pubkeyhash, scripthash, multisig, nulldata, witness_v0_keyhash, witness_v0_scripthash, witness_unknown\n" - " \"hex\" : \"hex\", (string, optional) The redeemscript for the p2sh address\n" - " \"pubkeys\" (string, optional) Array of pubkeys associated with the known redeemscript (only if \"script\" is \"multisig\")\n" + " \"address\" : \"address\", (string) The bitcoin address validated.\n" + " \"scriptPubKey\" : \"hex\", (string) The hex-encoded scriptPubKey generated by the address.\n" + " \"ismine\" : true|false, (boolean) If the address is yours.\n" + " \"iswatchonly\" : true|false, (boolean) If the address is watchonly.\n" + " \"solvable\" : true|false, (boolean) If we know how to spend coins sent to this address, ignoring the possible lack of private keys.\n" + " \"desc\" : \"desc\", (string, optional) A descriptor for spending coins sent to this address (only when solvable).\n" + " \"isscript\" : true|false, (boolean) If the key is a script.\n" + " \"ischange\" : true|false, (boolean) If the address was used for change output.\n" + " \"iswitness\" : true|false, (boolean) If the address is a witness address.\n" + " \"witness_version\" : version (numeric, optional) The version number of the witness program.\n" + " \"witness_program\" : \"hex\" (string, optional) The hex value of the witness program.\n" + " \"script\" : \"type\" (string, optional) The output script type. Only if isscript is true and the redeemscript is known. Possible\n" + " types: nonstandard, pubkey, pubkeyhash, scripthash, multisig, nulldata, witness_v0_keyhash,\n" + " witness_v0_scripthash, witness_unknown.\n" + " \"hex\" : \"hex\", (string, optional) The redeemscript for the p2sh address.\n" + " \"pubkeys\" (array, optional) Array of pubkeys associated with the known redeemscript (only if script is multisig).\n" " [\n" - " \"pubkey\"\n" + " \"pubkey\" (string)\n" " ,...\n" " ]\n" - " \"sigsrequired\" : xxxxx (numeric, optional) Number of signatures required to spend multisig output (only if \"script\" is \"multisig\")\n" - " \"pubkey\" : \"publickeyhex\", (string, optional) The hex value of the raw public key, for single-key addresses (possibly embedded in P2SH or P2WSH)\n" - " \"embedded\" : {...}, (object, optional) Information about the address embedded in P2SH or P2WSH, if relevant and known. It includes all getaddressinfo output fields for the embedded address, excluding metadata (\"timestamp\", \"hdkeypath\", \"hdseedid\") and relation to the wallet (\"ismine\", \"iswatchonly\").\n" - " \"iscompressed\" : true|false, (boolean, optional) If the pubkey is compressed\n" - " \"label\" : \"label\" (string) The label associated with the address, \"\" is the default label\n" - " \"timestamp\" : timestamp, (number, optional) The creation time of the key if available in seconds since epoch (Jan 1 1970 GMT)\n" - " \"hdkeypath\" : \"keypath\" (string, optional) The HD keypath if the key is HD and available\n" - " \"hdseedid\" : \"<hash160>\" (string, optional) The Hash160 of the HD seed\n" - " \"hdmasterfingerprint\" : \"<hash160>\" (string, optional) The fingperint of the master key.\n" - " \"labels\" (object) Array of labels associated with the address.\n" + " \"sigsrequired\" : xxxxx (numeric, optional) The number of signatures required to spend multisig output (only if script is multisig).\n" + " \"pubkey\" : \"publickeyhex\", (string, optional) The hex value of the raw public key for single-key addresses (possibly embedded in P2SH or P2WSH).\n" + " \"embedded\" : {...}, (object, optional) Information about the address embedded in P2SH or P2WSH, if relevant and known. Includes all\n" + " getaddressinfo output fields for the embedded address, excluding metadata (timestamp, hdkeypath,\n" + " hdseedid) and relation to the wallet (ismine, iswatchonly).\n" + " \"iscompressed\" : true|false, (boolean, optional) If the pubkey is compressed.\n" + " \"label\" : \"label\" (string) The label associated with the address. Defaults to \"\". Equivalent to the name field in the labels array.\n" + " \"timestamp\" : timestamp, (number, optional) The creation time of the key if available, expressed in seconds since Epoch Time (Jan 1 1970 GMT).\n" + " \"hdkeypath\" : \"keypath\" (string, optional) The HD keypath, if the key is HD and available.\n" + " \"hdseedid\" : \"<hash160>\" (string, optional) The Hash160 of the HD seed.\n" + " \"hdmasterfingerprint\" : \"<hash160>\" (string, optional) The fingerprint of the master key.\n" + " \"labels\" (object) An array of labels associated with the address. Currently limited to one label but returned\n" + " as an array to keep the API stable if multiple labels are enabled in the future.\n" " [\n" " { (json object of label data)\n" - " \"name\": \"labelname\" (string) The label\n" - " \"purpose\": \"string\" (string) Purpose of address (\"send\" for sending address, \"receive\" for receiving address)\n" + " \"name\": \"label name\" (string) The label name. Defaults to \"\". Equivalent to the label field above.\n" + " \"purpose\": \"purpose\" (string) The purpose of the associated address (send or receive).\n" " },...\n" " ]\n" "}\n" }, RPCExamples{ - HelpExampleCli("getaddressinfo", "\"1PSSGeFHDnKNxiEyFrD1wcEaHr9hrQDDWc\"") - + HelpExampleRpc("getaddressinfo", "\"1PSSGeFHDnKNxiEyFrD1wcEaHr9hrQDDWc\"") + HelpExampleCli("getaddressinfo", "\"bc1q09vm5lfy0j5reeulh4x5752q25uqqvz34hufdl\"") + + HelpExampleRpc("getaddressinfo", "\"bc1q09vm5lfy0j5reeulh4x5752q25uqqvz34hufdl\"") }, }.Check(request); @@ -3773,23 +3778,39 @@ UniValue getaddressinfo(const JSONRPCRequest& request) CScript scriptPubKey = GetScriptForDestination(dest); ret.pushKV("scriptPubKey", HexStr(scriptPubKey.begin(), scriptPubKey.end())); + const SigningProvider* provider = pwallet->GetSigningProvider(scriptPubKey); isminetype mine = pwallet->IsMine(dest); ret.pushKV("ismine", bool(mine & ISMINE_SPENDABLE)); + bool solvable = provider && IsSolvable(*provider, scriptPubKey); ret.pushKV("solvable", solvable); + if (solvable) { ret.pushKV("desc", InferDescriptor(scriptPubKey, *provider)->ToString()); } + ret.pushKV("iswatchonly", bool(mine & ISMINE_WATCH_ONLY)); + + // Return DescribeWalletAddress fields. + // Always returned: isscript, ischange, iswitness. + // Optional: witness_version, witness_program, script, hex, pubkeys (array), + // sigsrequired, pubkey, embedded, iscompressed. UniValue detail = DescribeWalletAddress(pwallet, dest); ret.pushKVs(detail); + + // Return label field if existing. Currently only one label can be + // associated with an address, so the label should be equivalent to the + // value of the name key/value pair in the labels hash array below. if (pwallet->mapAddressBook.count(dest)) { ret.pushKV("label", pwallet->mapAddressBook[dest].name); } + ret.pushKV("ischange", pwallet->IsChange(scriptPubKey)); + // Fetch KeyMetadata, if present, for the timestamp, hdkeypath, hdseedid, + // and hdmasterfingerprint fields. ScriptPubKeyMan* spk_man = pwallet->GetScriptPubKeyMan(scriptPubKey); if (spk_man) { if (const CKeyMetadata* meta = spk_man->GetMetadata(dest)) { @@ -3802,9 +3823,11 @@ UniValue getaddressinfo(const JSONRPCRequest& request) } } - // Currently only one label can be associated with an address, return an array - // so the API remains stable if we allow multiple labels to be associated with - // an address. + // Return a labels array containing a hash of key/value pairs for the label + // name and address purpose. The name value is equivalent to the label field + // above. Currently only one label can be associated with an address, but we + // return an array so the API remains stable if we allow multiple labels to + // be associated with an address in the future. UniValue labels(UniValue::VARR); std::map<CTxDestination, CAddressBookData>::iterator mi = pwallet->mapAddressBook.find(dest); if (mi != pwallet->mapAddressBook.end()) { diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index fce49ec56c..51df4a9a8b 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -71,8 +71,6 @@ static const CAmount WALLET_INCREMENTAL_RELAY_FEE = 5000; static const bool DEFAULT_SPEND_ZEROCONF_CHANGE = true; //! Default for -walletrejectlongchains static const bool DEFAULT_WALLET_REJECT_LONG_CHAINS = false; -//! Default for -avoidpartialspends -static const bool DEFAULT_AVOIDPARTIALSPENDS = false; //! -txconfirmtarget default static const unsigned int DEFAULT_TX_CONFIRM_TARGET = 6; //! -walletrbf default |