Bitcoin Core  24.99.0
P2P Digital Currency
availablecoins_tests.cpp
Go to the documentation of this file.
1 // Copyright (c) 2022 The Bitcoin Core developers
2 // Distributed under the MIT software license, see the accompanying
3 // file COPYING or https://www.opensource.org/licenses/mit-license.php.
4 
5 #include <validation.h>
6 #include <wallet/coincontrol.h>
7 #include <wallet/spend.h>
8 #include <wallet/test/util.h>
10 
11 #include <boost/test/unit_test.hpp>
12 
13 namespace wallet {
14 BOOST_FIXTURE_TEST_SUITE(availablecoins_tests, WalletTestingSetup)
16 {
17 public:
19  {
20  CreateAndProcessBlock({}, {});
21  wallet = CreateSyncedWallet(*m_node.chain, m_node.chainman->ActiveChain(), m_args, coinbaseKey);
22  }
23 
25  {
26  wallet.reset();
27  }
29  {
30  CTransactionRef tx;
31  CCoinControl dummy;
32  {
33  constexpr int RANDOM_CHANGE_POSITION = -1;
34  auto res = CreateTransaction(*wallet, {recipient}, RANDOM_CHANGE_POSITION, dummy);
35  BOOST_CHECK(res);
36  tx = res->tx;
37  }
38  wallet->CommitTransaction(tx, {}, {});
39  CMutableTransaction blocktx;
40  {
41  LOCK(wallet->cs_wallet);
42  blocktx = CMutableTransaction(*wallet->mapWallet.at(tx->GetHash()).tx);
43  }
44  CreateAndProcessBlock({CMutableTransaction(blocktx)}, GetScriptForRawPubKey(coinbaseKey.GetPubKey()));
45 
46  LOCK(wallet->cs_wallet);
47  LOCK(m_node.chainman->GetMutex());
48  wallet->SetLastBlockProcessed(wallet->GetLastBlockHeight() + 1, m_node.chainman->ActiveChain().Tip()->GetBlockHash());
49  auto it = wallet->mapWallet.find(tx->GetHash());
50  BOOST_CHECK(it != wallet->mapWallet.end());
51  it->second.m_state = TxStateConfirmed{m_node.chainman->ActiveChain().Tip()->GetBlockHash(), m_node.chainman->ActiveChain().Height(), /*index=*/1};
52  return it->second;
53  }
54 
55  std::unique_ptr<CWallet> wallet;
56 };
57 
59 {
60  CoinsResult available_coins;
62  LOCK(wallet->cs_wallet);
63 
64  // Verify our wallet has one usable coinbase UTXO before starting
65  // This UTXO is a P2PK, so it should show up in the Other bucket
66  available_coins = AvailableCoins(*wallet);
67  BOOST_CHECK_EQUAL(available_coins.Size(), 1U);
68  BOOST_CHECK_EQUAL(available_coins.coins[OutputType::UNKNOWN].size(), 1U);
69 
70  // We will create a self transfer for each of the OutputTypes and
71  // verify it is put in the correct bucket after running GetAvailablecoins
72  //
73  // For each OutputType, We expect 2 UTXOs in our wallet following the self transfer:
74  // 1. One UTXO as the recipient
75  // 2. One UTXO from the change, due to payment address matching logic
76 
77  // Bech32m
78  dest = wallet->GetNewDestination(OutputType::BECH32M, "");
79  BOOST_ASSERT(dest);
80  AddTx(CRecipient{{GetScriptForDestination(*dest)}, 1 * COIN, /*fSubtractFeeFromAmount=*/true});
81  available_coins = AvailableCoins(*wallet);
82  BOOST_CHECK_EQUAL(available_coins.coins[OutputType::BECH32M].size(), 2U);
83 
84  // Bech32
85  dest = wallet->GetNewDestination(OutputType::BECH32, "");
86  BOOST_ASSERT(dest);
87  AddTx(CRecipient{{GetScriptForDestination(*dest)}, 2 * COIN, /*fSubtractFeeFromAmount=*/true});
88  available_coins = AvailableCoins(*wallet);
89  BOOST_CHECK_EQUAL(available_coins.coins[OutputType::BECH32].size(), 2U);
90 
91  // P2SH-SEGWIT
92  dest = wallet->GetNewDestination(OutputType::P2SH_SEGWIT, "");
93  BOOST_ASSERT(dest);
94  AddTx(CRecipient{{GetScriptForDestination(*dest)}, 3 * COIN, /*fSubtractFeeFromAmount=*/true});
95  available_coins = AvailableCoins(*wallet);
96  BOOST_CHECK_EQUAL(available_coins.coins[OutputType::P2SH_SEGWIT].size(), 2U);
97 
98  // Legacy (P2PKH)
99  dest = wallet->GetNewDestination(OutputType::LEGACY, "");
100  BOOST_ASSERT(dest);
101  AddTx(CRecipient{{GetScriptForDestination(*dest)}, 4 * COIN, /*fSubtractFeeFromAmount=*/true});
102  available_coins = AvailableCoins(*wallet);
103  BOOST_CHECK_EQUAL(available_coins.coins[OutputType::LEGACY].size(), 2U);
104 }
105 
107 } // namespace wallet
static constexpr CAmount COIN
The amount of satoshis in one BTC.
Definition: amount.h:15
node::NodeContext m_node
Definition: bitcoin-gui.cpp:37
CWalletTx & AddTx(CRecipient recipient)
Coin Control Features.
Definition: coincontrol.h:30
A transaction with a bunch of additional info that only the owner cares about.
Definition: transaction.h:138
BOOST_AUTO_TEST_SUITE_END()
Definition: node.h:39
std::unique_ptr< CWallet > CreateSyncedWallet(interfaces::Chain &chain, CChain &cchain, ArgsManager &args, const CKey &key)
Definition: util.cpp:19
CoinsResult AvailableCoins(const CWallet &wallet, const CCoinControl *coinControl, std::optional< CFeeRate > feerate, const CAmount &nMinimumAmount, const CAmount &nMaximumAmount, const CAmount &nMinimumSumAmount, const uint64_t nMaximumCount, bool only_spendable)
Populate the CoinsResult struct with vectors of available COutputs, organized by OutputType.
Definition: spend.cpp:146
util::Result< CreatedTransactionResult > CreateTransaction(CWallet &wallet, const std::vector< CRecipient > &vecSend, int change_pos, const CCoinControl &coin_control, bool sign)
Create a new transaction paying the recipients with a set of coins selected by SelectCoins(); Also cr...
Definition: spend.cpp:1038
static int64_t AddTx(ChainstateManager &chainman, CWallet &wallet, uint32_t lockTime, int64_t mockTime, int64_t blockTime)
BOOST_FIXTURE_TEST_CASE(BasicOutputTypesTest, AvailableCoinsTestingSetup)
#define BOOST_CHECK_EQUAL(v1, v2)
Definition: object.cpp:17
#define BOOST_CHECK(expr)
Definition: object.cpp:16
std::shared_ptr< const CTransaction > CTransactionRef
Definition: transaction.h:414
CScript GetScriptForRawPubKey(const CPubKey &pubKey)
Generate a P2PK script for the given pubkey.
Definition: standard.cpp:339
CScript GetScriptForDestination(const CTxDestination &dest)
Generate a Bitcoin scriptPubKey for the given CTxDestination.
Definition: standard.cpp:334
A mutable version of CTransaction.
Definition: transaction.h:373
Testing fixture that pre-creates a 100-block REGTEST-mode block chain.
Definition: setup_common.h:126
std::unique_ptr< ChainstateManager > chainman
Definition: context.h:54
std::unique_ptr< interfaces::Chain > chain
Definition: context.h:57
COutputs available for spending, stored by OutputType.
Definition: spend.h:40
size_t Size() const
The following methods are provided so that CoinsResult can mimic a vector, i.e., methods can work wit...
Definition: spend.cpp:82
std::map< OutputType, std::vector< COutput > > coins
Definition: spend.h:41
State of transaction confirmed in a block.
Definition: transaction.h:24
#define LOCK(cs)
Definition: sync.h:261