Bitcoin Core  22.99.0
P2P Digital Currency
addressbooktests.cpp
Go to the documentation of this file.
1 // Copyright (c) 2017-2020 The Bitcoin Core developers
2 // Distributed under the MIT software license, see the accompanying
3 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
4 
6 #include <qt/test/util.h>
8 
9 #include <interfaces/chain.h>
10 #include <interfaces/node.h>
11 #include <qt/clientmodel.h>
12 #include <qt/editaddressdialog.h>
13 #include <qt/optionsmodel.h>
14 #include <qt/platformstyle.h>
15 #include <qt/qvalidatedlineedit.h>
16 #include <qt/walletmodel.h>
17 
18 #include <key.h>
19 #include <key_io.h>
20 #include <wallet/wallet.h>
21 #include <walletinitinterface.h>
22 
23 #include <QApplication>
24 #include <QTimer>
25 #include <QMessageBox>
26 
27 namespace
28 {
29 
34 void EditAddressAndSubmit(
35  EditAddressDialog* dialog,
36  const QString& label, const QString& address, QString expected_msg)
37 {
38  QString warning_text;
39 
40  dialog->findChild<QLineEdit*>("labelEdit")->setText(label);
41  dialog->findChild<QValidatedLineEdit*>("addressEdit")->setText(address);
42 
43  ConfirmMessage(&warning_text, 5);
44  dialog->accept();
45  QCOMPARE(warning_text, expected_msg);
46 }
47 
60 void TestAddAddressesToSendBook(interfaces::Node& node)
61 {
62  TestChain100Setup test;
63  auto wallet_client = interfaces::MakeWalletClient(*test.m_node.chain, *Assert(test.m_node.args));
64  test.m_node.wallet_client = wallet_client.get();
65  node.setContext(&test.m_node);
66  std::shared_ptr<CWallet> wallet = std::make_shared<CWallet>(node.context()->chain.get(), "", CreateMockWalletDatabase());
67  wallet->SetupLegacyScriptPubKeyMan();
68  wallet->LoadWallet();
69 
70  auto build_address = [&wallet]() {
71  CKey key;
72  key.MakeNewKey(true);
74  key.GetPubKey(), wallet->m_default_address_type));
75 
76  return std::make_pair(dest, QString::fromStdString(EncodeDestination(dest)));
77  };
78 
79  CTxDestination r_key_dest, s_key_dest;
80 
81  // Add a preexisting "receive" entry in the address book.
82  QString preexisting_r_address;
83  QString r_label("already here (r)");
84 
85  // Add a preexisting "send" entry in the address book.
86  QString preexisting_s_address;
87  QString s_label("already here (s)");
88 
89  // Define a new address (which should add to the address book successfully).
90  QString new_address;
91 
92  std::tie(r_key_dest, preexisting_r_address) = build_address();
93  std::tie(s_key_dest, preexisting_s_address) = build_address();
94  std::tie(std::ignore, new_address) = build_address();
95 
96  {
97  LOCK(wallet->cs_wallet);
98  wallet->SetAddressBook(r_key_dest, r_label.toStdString(), "receive");
99  wallet->SetAddressBook(s_key_dest, s_label.toStdString(), "send");
100  }
101 
102  auto check_addbook_size = [&wallet](int expected_size) {
103  LOCK(wallet->cs_wallet);
104  QCOMPARE(static_cast<int>(wallet->m_address_book.size()), expected_size);
105  };
106 
107  // We should start with the two addresses we added earlier and nothing else.
108  check_addbook_size(2);
109 
110  // Initialize relevant QT models.
111  std::unique_ptr<const PlatformStyle> platformStyle(PlatformStyle::instantiate("other"));
112  OptionsModel optionsModel;
113  ClientModel clientModel(node, &optionsModel);
114  WalletContext& context = *node.walletClient().context();
115  AddWallet(context, wallet);
116  WalletModel walletModel(interfaces::MakeWallet(context, wallet), clientModel, platformStyle.get());
117  RemoveWallet(context, wallet, /* load_on_start= */ std::nullopt);
119  editAddressDialog.setModel(walletModel.getAddressTableModel());
120 
121  EditAddressAndSubmit(
122  &editAddressDialog, QString("uhoh"), preexisting_r_address,
123  QString(
124  "Address \"%1\" already exists as a receiving address with label "
125  "\"%2\" and so cannot be added as a sending address."
126  ).arg(preexisting_r_address).arg(r_label));
127 
128  check_addbook_size(2);
129 
130  EditAddressAndSubmit(
131  &editAddressDialog, QString("uhoh, different"), preexisting_s_address,
132  QString(
133  "The entered address \"%1\" is already in the address book with "
134  "label \"%2\"."
135  ).arg(preexisting_s_address).arg(s_label));
136 
137  check_addbook_size(2);
138 
139  // Submit a new address which should add successfully - we expect the
140  // warning message to be blank.
141  EditAddressAndSubmit(
142  &editAddressDialog, QString("new"), new_address, QString(""));
143 
144  check_addbook_size(3);
145 }
146 
147 } // namespace
148 
150 {
151 #ifdef Q_OS_MAC
152  if (QApplication::platformName() == "minimal") {
153  // Disable for mac on "minimal" platform to avoid crashes inside the Qt
154  // framework when it tries to look up unimplemented cocoa functions,
155  // and fails to handle returned nulls
156  // (https://bugreports.qt.io/browse/QTBUG-49686).
157  QWARN("Skipping AddressBookTests on mac build with 'minimal' platform set due to Qt bugs. To run AppTests, invoke "
158  "with 'QT_QPA_PLATFORM=cocoa test_bitcoin-qt' on mac, or else use a linux or windows build.");
159  return;
160  }
161 #endif
162  TestAddAddressesToSendBook(m_node);
163 }
RemoveWallet
bool RemoveWallet(WalletContext &context, const std::shared_ptr< CWallet > &wallet, std::optional< bool > load_on_start, std::vector< bilingual_str > &warnings)
Definition: wallet.cpp:116
wallet.h
CKey::MakeNewKey
void MakeNewKey(bool fCompressed)
Generate a new private key using a cryptographic PRNG.
Definition: key.cpp:160
WalletModel
Interface to Bitcoin wallet from Qt view code.
Definition: walletmodel.h:51
NodeContext::args
ArgsManager * args
Definition: context.h:49
key_io.h
setup_common.h
walletmodel.h
wallet
Definition: interfaces.cpp:50
GetDestinationForKey
CTxDestination GetDestinationForKey(const CPubKey &key, OutputType type)
Get a destination of the requested type (if possible) to the specified key.
Definition: outputtype.cpp:49
chain.h
interfaces::MakeWalletClient
std::unique_ptr< WalletClient > MakeWalletClient(Chain &chain, ArgsManager &args)
Return implementation of ChainClient interface for a wallet client.
Definition: dummywallet.cpp:69
NodeContext::chain
std::unique_ptr< interfaces::Chain > chain
Definition: context.h:50
Assert
#define Assert(val)
Identity function.
Definition: check.h:57
AddWallet
bool AddWallet(WalletContext &context, const std::shared_ptr< CWallet > &wallet)
Definition: wallet.cpp:104
OptionsModel
Interface from Qt to configuration data structure for Bitcoin client.
Definition: optionsmodel.h:39
EditAddressDialog
Dialog for editing an address and associated information.
Definition: editaddressdialog.h:22
CTxDestination
std::variant< CNoDestination, PKHash, ScriptHash, WitnessV0ScriptHash, WitnessV0KeyHash, WitnessV1Taproot, WitnessUnknown > CTxDestination
A txout script template with a specific destination.
Definition: standard.h:157
util.h
node.h
QValidatedLineEdit
Line edit that can be marked as "invalid" to show input validation feedback.
Definition: qvalidatedlineedit.h:13
ConfirmMessage
void ConfirmMessage(QString *text, int msec)
Press "Ok" button in message box dialog.
Definition: util.cpp:12
AddressBookTests::addressBookTests
void addressBookTests()
Definition: addressbooktests.cpp:149
TestChain100Setup
Testing fixture that pre-creates a 100-block REGTEST-mode block chain.
Definition: setup_common.h:116
walletinitinterface.h
CKey::GetPubKey
CPubKey GetPubKey() const
Compute the public key from a private key.
Definition: key.cpp:187
EditAddressDialog::NewSendingAddress
@ NewSendingAddress
Definition: editaddressdialog.h:28
interfaces::MakeWallet
std::unique_ptr< Wallet > MakeWallet(const std::shared_ptr< CWallet > &wallet)
Definition: dummywallet.cpp:64
PlatformStyle::instantiate
static const PlatformStyle * instantiate(const QString &platformId)
Get style associated with provided platform name, or 0 if not known.
Definition: platformstyle.cpp:124
editaddressdialog.h
interfaces::Node
Top-level interface for a bitcoin node (bitcoind process).
Definition: node.h:54
qvalidatedlineedit.h
NodeContext::wallet_client
interfaces::WalletClient * wallet_client
Reference to chain client that should used to load or create wallets opened by the gui.
Definition: context.h:55
platformstyle.h
EditAddressDialog::accept
void accept() override
Definition: editaddressdialog.cpp:96
key.h
ClientModel
Model for Bitcoin network client.
Definition: clientmodel.h:47
BasicTestingSetup::m_node
NodeContext m_node
Definition: setup_common.h:78
CKey
An encapsulated private key.
Definition: key.h:26
LOCK
#define LOCK(cs)
Definition: sync.h:226
CreateMockWalletDatabase
std::unique_ptr< WalletDatabase > CreateMockWalletDatabase()
Return object for accessing temporary in-memory database.
Definition: walletdb.cpp:1156
node
Definition: interfaces.cpp:68
AddressBookTests::m_node
interfaces::Node & m_node
Definition: addressbooktests.h:19
optionsmodel.h
WalletContext
WalletContext struct containing references to state shared between CWallet instances,...
Definition: context.h:34
addressbooktests.h
EncodeDestination
std::string EncodeDestination(const CTxDestination &dest)
Definition: key_io.cpp:256
clientmodel.h