Skip to content

Commit ec764fd

Browse files
committed
partial bitcoin#22154: Add OutputType::BECH32M and related wallet support for fetching bech32m addresses
includes: - 754f134
1 parent 690a1cd commit ec764fd

File tree

10 files changed

+26
-21
lines changed

10 files changed

+26
-21
lines changed

src/coinjoin/client.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1576,8 +1576,9 @@ bool CCoinJoinClientSession::CreateCollateralTransaction(CMutableTransaction& tx
15761576
// make our change address
15771577
CScript scriptChange;
15781578
CTxDestination dest;
1579+
bilingual_str error;
15791580
ReserveDestination reserveDest(m_wallet.get());
1580-
bool success = reserveDest.GetReservedDestination(dest, true);
1581+
bool success = reserveDest.GetReservedDestination(dest, true, error);
15811582
assert(success); // should never fail, as we just unlocked
15821583
scriptChange = GetScriptForDestination(dest);
15831584
reserveDest.KeepDestination();

src/coinjoin/util.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,8 @@ inline unsigned int GetSizeOfCompactSizeDiff(uint64_t nSizePrev, uint64_t nSizeN
2929
CKeyHolder::CKeyHolder(CWallet* pwallet) :
3030
reserveDestination(pwallet)
3131
{
32-
reserveDestination.GetReservedDestination(dest, false);
32+
bilingual_str error;
33+
reserveDestination.GetReservedDestination(dest, false, error);
3334
}
3435

3536
void CKeyHolder::KeepKey()
@@ -100,8 +101,9 @@ CTransactionBuilderOutput::CTransactionBuilderOutput(CTransactionBuilder* pTxBui
100101
{
101102
assert(pTxBuilder);
102103
CTxDestination txdest;
104+
bilingual_str error;
103105
LOCK(wallet.cs_wallet);
104-
dest.GetReservedDestination(txdest, false);
106+
dest.GetReservedDestination(txdest, false, error);
105107
script = ::GetScriptForDestination(txdest);
106108
}
107109

src/wallet/scriptpubkeyman.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -291,14 +291,16 @@ bool LegacyScriptPubKeyMan::Encrypt(const CKeyingMaterial& master_key, WalletBat
291291
return true;
292292
}
293293

294-
bool LegacyScriptPubKeyMan::GetReservedDestination(bool internal, CTxDestination& address, int64_t& index, CKeyPool& keypool)
294+
bool LegacyScriptPubKeyMan::GetReservedDestination(bool internal, CTxDestination& address, int64_t& index, CKeyPool& keypool, bilingual_str& error)
295295
{
296296
LOCK(cs_KeyStore);
297297
if (!CanGetAddresses(internal)) {
298+
error = _("Error: Keypool ran out, please call keypoolrefill first");
298299
return false;
299300
}
300301

301302
if (!ReserveKeyFromKeyPool(index, keypool, internal)) {
303+
error = _("Error: Keypool ran out, please call keypoolrefill first");
302304
return false;
303305
}
304306
// TODO: unify with bitcoin and use here GetDestinationForKey even if we have no type
@@ -1908,10 +1910,9 @@ bool DescriptorScriptPubKeyMan::Encrypt(const CKeyingMaterial& master_key, Walle
19081910
return true;
19091911
}
19101912

1911-
bool DescriptorScriptPubKeyMan::GetReservedDestination(bool internal, CTxDestination& address, int64_t& index, CKeyPool& keypool)
1913+
bool DescriptorScriptPubKeyMan::GetReservedDestination(bool internal, CTxDestination& address, int64_t& index, CKeyPool& keypool, bilingual_str& error)
19121914
{
19131915
LOCK(cs_desc_man);
1914-
bilingual_str error;
19151916
bool result = GetNewDestination(address, error);
19161917
index = m_wallet_descriptor.next_index - 1;
19171918
return result;

src/wallet/scriptpubkeyman.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ class ScriptPubKeyMan
170170
virtual bool CheckDecryptionKey(const CKeyingMaterial& master_key, bool accept_no_keys = false) { return false; }
171171
virtual bool Encrypt(const CKeyingMaterial& master_key, WalletBatch* batch) { return false; }
172172

173-
virtual bool GetReservedDestination(bool internal, CTxDestination& address, int64_t& index, CKeyPool& keypool) { return false; }
173+
virtual bool GetReservedDestination(bool internal, CTxDestination& address, int64_t& index, CKeyPool& keypool, bilingual_str& error) { return false; }
174174
virtual void KeepDestination(int64_t index) {}
175175
virtual void ReturnDestination(int64_t index, bool internal, const CTxDestination& addr) {}
176176

@@ -324,7 +324,7 @@ class LegacyScriptPubKeyMan : public ScriptPubKeyMan, public FillableSigningProv
324324
bool CheckDecryptionKey(const CKeyingMaterial& master_key, bool accept_no_keys = false) override;
325325
bool Encrypt(const CKeyingMaterial& master_key, WalletBatch* batch) override;
326326

327-
bool GetReservedDestination(bool internal, CTxDestination& address, int64_t& index, CKeyPool& keypool) override;
327+
bool GetReservedDestination(bool internal, CTxDestination& address, int64_t& index, CKeyPool& keypool, bilingual_str& error) override;
328328
void KeepDestination(int64_t index) override;
329329
void ReturnDestination(int64_t index, bool internal, const CTxDestination&) override;
330330

@@ -560,7 +560,7 @@ class DescriptorScriptPubKeyMan : public ScriptPubKeyMan
560560
bool CheckDecryptionKey(const CKeyingMaterial& master_key, bool accept_no_keys = false) override;
561561
bool Encrypt(const CKeyingMaterial& master_key, WalletBatch* batch) override;
562562

563-
bool GetReservedDestination(bool internal, CTxDestination& address, int64_t& index, CKeyPool& keypool) override;
563+
bool GetReservedDestination(bool internal, CTxDestination& address, int64_t& index, CKeyPool& keypool, bilingual_str& error) override;
564564
void ReturnDestination(int64_t index, bool internal, const CTxDestination& addr) override;
565565

566566
// Tops up the descriptor cache and m_map_script_pub_keys. The cache is stored in the wallet file

src/wallet/spend.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -742,8 +742,9 @@ static std::optional<CreatedTransactionResult> CreateTransactionInternal(
742742
// Reserve a new key pair from key pool. If it fails, provide a dummy
743743
// destination in case we don't need change.
744744
CTxDestination dest;
745-
if (!reservedest.GetReservedDestination(dest, true)) {
746-
error = _("Transaction needs a change address, but we can't generate it. Please call keypoolrefill first.");
745+
bilingual_str dest_err;
746+
if (!reservedest.GetReservedDestination(dest, true, dest_err)) {
747+
error = _("Transaction needs a change address, but we can't generate it.") + Untranslated(" ") + dest_err;
747748
}
748749
scriptChange = GetScriptForDestination(dest);
749750
// A valid destination implies a change script (and

src/wallet/test/coinjoin_tests.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ class CTransactionBuilderTestSetup : public TestChain100Setup
188188
coinControl.m_feerate = CFeeRate(1000);
189189
{
190190
LOCK(wallet->cs_wallet);
191-
BOOST_CHECK(reserveDest.GetReservedDestination(tallyItem.txdest, false));
191+
BOOST_CHECK(reserveDest.GetReservedDestination(tallyItem.txdest, false, strError));
192192
}
193193
for (CAmount nAmount : vecAmounts) {
194194
CTransactionRef tx;

src/wallet/wallet.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2356,7 +2356,7 @@ bool CWallet::GetNewDestination(const std::string label, CTxDestination& dest, b
23562356
spk_man->TopUp();
23572357
result = spk_man->GetNewDestination(dest, error);
23582358
} else {
2359-
error = strprintf(_("Error: No addresses available."));
2359+
error = _("Error: No addresses available.");
23602360
}
23612361
if (result) {
23622362
SetAddressBook(dest, label, "receive");
@@ -2365,14 +2365,13 @@ bool CWallet::GetNewDestination(const std::string label, CTxDestination& dest, b
23652365
return result;
23662366
}
23672367

2368-
bool CWallet::GetNewChangeDestination(CTxDestination& dest, bilingual_str& error)
2368+
bool CWallet::GetNewChangeDestination(CTxDestination& dest, bilingual_str& error)
23692369
{
23702370
LOCK(cs_wallet);
23712371
error.clear();
23722372

23732373
ReserveDestination reservedest(this);
2374-
if (!reservedest.GetReservedDestination(dest, true)) {
2375-
error = _("Error: Keypool ran out, please call keypoolrefill first");
2374+
if (!reservedest.GetReservedDestination(dest, true, error)) {
23762375
return false;
23772376
}
23782377

@@ -2446,10 +2445,11 @@ std::set<std::string> CWallet::ListAddrBookLabels(const std::string& purpose) co
24462445
return label_set;
24472446
}
24482447

2449-
bool ReserveDestination::GetReservedDestination(CTxDestination& dest, bool fInternalIn)
2448+
bool ReserveDestination::GetReservedDestination(CTxDestination& dest, bool fInternalIn, bilingual_str& error)
24502449
{
24512450
m_spk_man = pwallet->GetScriptPubKeyMan(fInternalIn);
24522451
if (!m_spk_man) {
2452+
error = _("Error: No addresses available.");
24532453
return false;
24542454
}
24552455

@@ -2459,7 +2459,7 @@ bool ReserveDestination::GetReservedDestination(CTxDestination& dest, bool fInte
24592459

24602460
CKeyPool keypool;
24612461
int64_t index;
2462-
if (!m_spk_man->GetReservedDestination(fInternalIn, address, index, keypool)) {
2462+
if (!m_spk_man->GetReservedDestination(fInternalIn, address, index, keypool, error)) {
24632463
return false;
24642464
}
24652465
nIndex = index;

src/wallet/wallet.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ class ReserveDestination
203203
}
204204

205205
//! Reserve an address
206-
bool GetReservedDestination(CTxDestination& pubkey, bool internal);
206+
bool GetReservedDestination(CTxDestination& pubkey, bool internal, bilingual_str& error);
207207
//! Return reserved address
208208
void ReturnDestination();
209209
//! Keep the address. Do not return its key to the keypool when this object goes out of scope

test/functional/rpc_fundrawtransaction.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -583,7 +583,7 @@ def test_locked_wallet(self):
583583
# creating the key must be impossible because the wallet is locked
584584
outputs = {self.nodes[0].getnewaddress():value - Decimal("0.1")}
585585
rawtx = self.nodes[1].createrawtransaction(inputs, outputs)
586-
assert_raises_rpc_error(-4, "Transaction needs a change address, but we can't generate it. Please call keypoolrefill first.", self.nodes[1].fundrawtransaction, rawtx)
586+
assert_raises_rpc_error(-4, "Transaction needs a change address, but we can't generate it.", self.nodes[1].fundrawtransaction, rawtx)
587587

588588
# Refill the keypool.
589589
self.nodes[1].walletpassphrase("test", 100)

test/functional/wallet_keypool_hd.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ def run_test(self):
197197

198198
# Using a fee rate (10 sat / byte) well above the minimum relay rate
199199
# creating a 5,000 sat transaction with change should not be possible
200-
assert_raises_rpc_error(-4, "Transaction needs a change address, but we can't generate it. Please call keypoolrefill first.", w2.walletcreatefundedpsbt, inputs=[], outputs=[{addr.pop(): 0.00005000}], options={"subtractFeeFromOutputs": [0], "feeRate": 0.000010})
200+
assert_raises_rpc_error(-4, "Transaction needs a change address, but we can't generate it.", w2.walletcreatefundedpsbt, inputs=[], outputs=[{addr.pop(): 0.00005000}], options={"subtractFeeFromOutputs": [0], "feeRate": 0.000010})
201201

202202
# creating a 10,000 sat transaction without change, with a manual input, should still be possible
203203
res = w2.walletcreatefundedpsbt(inputs=w2.listunspent(), outputs=[{destination: 0.00010000}], options={"subtractFeeFromOutputs": [0], "feeRate": 0.000010})

0 commit comments

Comments
 (0)