-
Notifications
You must be signed in to change notification settings - Fork 1.2k
backport: merge bitcoin#25218, #25721, #25656, #25616, #26005, #24855, #18554, #17204, #20562, #21166, #25044, #25364, #25525, #25512, #24678, #26747, partial bitcoin#22154, #24584 (wallet backports: part 8) #6823
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
ec764fd
9e23b11
50ca8cf
03939f2
56accfe
bd897fa
240765e
f15a1b9
0fca914
c5e8bd6
c349dad
f883122
4e0725e
c6eabc1
a118fe1
c24c9ea
f405790
2a880d8
d63ca8a
c0f9225
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -29,7 +29,9 @@ inline unsigned int GetSizeOfCompactSizeDiff(uint64_t nSizePrev, uint64_t nSizeN | |||||||||||||||||||||||
| CKeyHolder::CKeyHolder(CWallet* pwallet) : | ||||||||||||||||||||||||
| reserveDestination(pwallet) | ||||||||||||||||||||||||
| { | ||||||||||||||||||||||||
| reserveDestination.GetReservedDestination(dest, false); | ||||||||||||||||||||||||
| auto dest_opt = reserveDestination.GetReservedDestination(false); | ||||||||||||||||||||||||
| assert(dest_opt); | ||||||||||||||||||||||||
| dest = *dest_opt; | ||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| void CKeyHolder::KeepKey() | ||||||||||||||||||||||||
|
|
@@ -99,10 +101,10 @@ CTransactionBuilderOutput::CTransactionBuilderOutput(CTransactionBuilder* pTxBui | |||||||||||||||||||||||
| nAmount(nAmountIn) | ||||||||||||||||||||||||
| { | ||||||||||||||||||||||||
| assert(pTxBuilder); | ||||||||||||||||||||||||
| CTxDestination txdest; | ||||||||||||||||||||||||
| LOCK(wallet.cs_wallet); | ||||||||||||||||||||||||
| dest.GetReservedDestination(txdest, false); | ||||||||||||||||||||||||
| script = ::GetScriptForDestination(txdest); | ||||||||||||||||||||||||
| auto dest_opt = dest.GetReservedDestination(false); | ||||||||||||||||||||||||
| assert(dest_opt); | ||||||||||||||||||||||||
| script = ::GetScriptForDestination(*dest_opt); | ||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
|
Comment on lines
+105
to
108
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Another assertion that should handle errors gracefully Similar to the CKeyHolder constructor, this assertion could fail if the wallet cannot provide addresses. The code should handle this error case properly. Consider proper error handling: - auto dest_opt = dest.GetReservedDestination(false);
- assert(dest_opt);
- script = ::GetScriptForDestination(*dest_opt);
+ auto dest_result = dest.GetReservedDestination(false);
+ if (!dest_result) {
+ throw std::runtime_error(strprintf("CTransactionBuilderOutput: %s", util::ErrorString(dest_result).original));
+ }
+ script = ::GetScriptForDestination(*dest_result);📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| bool CTransactionBuilderOutput::UpdateAmount(const CAmount nNewAmount) | ||||||||||||||||||||||||
|
|
@@ -280,12 +282,13 @@ bool CTransactionBuilder::Commit(bilingual_str& strResult) | |||||||||||||||||||||||
| CTransactionRef tx; | ||||||||||||||||||||||||
| { | ||||||||||||||||||||||||
| LOCK2(m_wallet.cs_wallet, ::cs_main); | ||||||||||||||||||||||||
| FeeCalculation fee_calc_out; | ||||||||||||||||||||||||
| if (auto txr = wallet::CreateTransaction(m_wallet, vecSend, nChangePosRet, strResult, coinControl, fee_calc_out)) { | ||||||||||||||||||||||||
| tx = txr->tx; | ||||||||||||||||||||||||
| nFeeRet = txr->fee; | ||||||||||||||||||||||||
| nChangePosRet = txr->change_pos; | ||||||||||||||||||||||||
| auto ret = wallet::CreateTransaction(m_wallet, vecSend, nChangePosRet, coinControl); | ||||||||||||||||||||||||
| if (ret) { | ||||||||||||||||||||||||
| tx = ret->tx; | ||||||||||||||||||||||||
| nFeeRet = ret->fee; | ||||||||||||||||||||||||
| nChangePosRet = ret->change_pos; | ||||||||||||||||||||||||
| } else { | ||||||||||||||||||||||||
| strResult = util::ErrorString(ret); | ||||||||||||||||||||||||
| return false; | ||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -112,7 +112,7 @@ class Wallet | |
| virtual std::string getWalletName() = 0; | ||
|
|
||
| // Get a new address. | ||
| virtual bool getNewDestination(const std::string label, CTxDestination& dest) = 0; | ||
| virtual util::Result<CTxDestination> getNewDestination(const std::string& label) = 0; | ||
|
|
||
| //! Get public key. | ||
| virtual bool getPubKey(const CScript& script, const CKeyID& address, CPubKey& pub_key) = 0; | ||
|
|
@@ -167,12 +167,11 @@ class Wallet | |
| virtual std::vector<COutPoint> listProTxCoins() = 0; | ||
|
|
||
| //! Create transaction. | ||
| virtual CTransactionRef createTransaction(const std::vector<wallet::CRecipient>& recipients, | ||
| virtual util::Result<CTransactionRef> createTransaction(const std::vector<wallet::CRecipient>& recipients, | ||
| const wallet::CCoinControl& coin_control, | ||
| bool sign, | ||
| int& change_pos, | ||
| CAmount& fee, | ||
| bilingual_str& fail_reason) = 0; | ||
| CAmount& fee) = 0; | ||
|
|
||
| //! Commit transaction. | ||
| virtual void commitTransaction(CTransactionRef tx, | ||
|
|
@@ -348,35 +347,35 @@ class Wallet | |
| class WalletLoader : public ChainClient | ||
| { | ||
| public: | ||
| //! Register non-core wallet RPCs | ||
| virtual void registerOtherRpcs(const Span<const CRPCCommand>& commands) = 0; | ||
| //! Register non-core wallet RPCs | ||
| virtual void registerOtherRpcs(const Span<const CRPCCommand>& commands) = 0; | ||
|
|
||
| //! Create new wallet. | ||
| virtual std::unique_ptr<Wallet> createWallet(const std::string& name, const SecureString& passphrase, uint64_t wallet_creation_flags, bilingual_str& error, std::vector<bilingual_str>& warnings) = 0; | ||
| //! Create new wallet. | ||
| virtual util::Result<std::unique_ptr<Wallet>> createWallet(const std::string& name, const SecureString& passphrase, uint64_t wallet_creation_flags, std::vector<bilingual_str>& warnings) = 0; | ||
|
|
||
| //! Load existing wallet. | ||
| virtual std::unique_ptr<Wallet> loadWallet(const std::string& name, bilingual_str& error, std::vector<bilingual_str>& warnings) = 0; | ||
| //! Load existing wallet. | ||
| virtual util::Result<std::unique_ptr<Wallet>> loadWallet(const std::string& name, std::vector<bilingual_str>& warnings) = 0; | ||
|
|
||
| //! Return default wallet directory. | ||
| virtual std::string getWalletDir() = 0; | ||
| //! Return default wallet directory. | ||
| virtual std::string getWalletDir() = 0; | ||
|
|
||
| //! Restore backup wallet | ||
| virtual BResult<std::unique_ptr<Wallet>> restoreWallet(const fs::path& backup_file, const std::string& wallet_name, std::vector<bilingual_str>& warnings) = 0; | ||
| //! Restore backup wallet | ||
| virtual util::Result<std::unique_ptr<Wallet>> restoreWallet(const fs::path& backup_file, const std::string& wallet_name, std::vector<bilingual_str>& warnings) = 0; | ||
|
|
||
| //! Return available wallets in wallet directory. | ||
| virtual std::vector<std::string> listWalletDir() = 0; | ||
| //! Return available wallets in wallet directory. | ||
| virtual std::vector<std::string> listWalletDir() = 0; | ||
|
|
||
| //! Return interfaces for accessing wallets (if any). | ||
| virtual std::vector<std::unique_ptr<Wallet>> getWallets() = 0; | ||
| //! Return interfaces for accessing wallets (if any). | ||
| virtual std::vector<std::unique_ptr<Wallet>> getWallets() = 0; | ||
|
|
||
| //! Register handler for load wallet messages. This callback is triggered by | ||
| //! createWallet and loadWallet above, and also triggered when wallets are | ||
| //! loaded at startup or by RPC. | ||
| using LoadWalletFn = std::function<void(std::unique_ptr<Wallet> wallet)>; | ||
| virtual std::unique_ptr<Handler> handleLoadWallet(LoadWalletFn fn) = 0; | ||
| //! Register handler for load wallet messages. This callback is triggered by | ||
| //! createWallet and loadWallet above, and also triggered when wallets are | ||
| //! loaded at startup or by RPC. | ||
| using LoadWalletFn = std::function<void(std::unique_ptr<Wallet> wallet)>; | ||
| virtual std::unique_ptr<Handler> handleLoadWallet(LoadWalletFn fn) = 0; | ||
|
|
||
| //! Return pointer to internal context, useful for testing. | ||
| virtual wallet::WalletContext* context() { return nullptr; } | ||
| //! Return pointer to internal context, useful for testing. | ||
| virtual wallet::WalletContext* context() { return nullptr; } | ||
| }; | ||
|
Comment on lines
+350
to
379
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 💡 Verification agent 🧩 Analysis chainWalletLoader methods migrated to util::Result — good, but verify call sites are updated The create/load/restore methods now return util::Result and drop the error out-param. This ripples through GUI/RPC. Please verify there are no remaining callers expecting the old signatures. Run this script to catch old-style usages (extra args/out-params): 🏁 Script executed: #!/bin/bash
set -euo pipefail
echo "Searching for old getNewDestination usages (with extra out-params)..."
rg -nP --type=cpp -C2 '\b(getNewDestination|GetNewDestination)\s*\(\s*[^,()]+\s*,\s*[^)]' || true
echo
echo "Searching for old createTransaction usages (fail_reason out-param or boolean return)..."
# Look for calls passing a bilingual_str or expecting bool
rg -nP --type=cpp -C3 '\bcreateTransaction\s*\(' || true
rg -nP --type=cpp -C2 'bilingual_str\s+\w+\s*;.*\bcreateTransaction\s*\(' || true
echo
echo "Searching for WalletLoader old create/load/restore signatures..."
rg -nP --type=cpp -C2 '\.createWallet\s*\([^)]{60,}\)' || true
rg -nP --type=cpp -C2 '\.loadWallet\s*\([^)]{60,}\)' || true
rg -nP --type=cpp -C2 '\.restoreWallet\s*\([^)]{60,}\)' || trueLength of output: 2428 Fix outdated createTransaction usage in Qt WalletModel We confirmed there are no remaining old-style calls to • src/qt/walletmodel.cpp:257 const auto& res = m_wallet->createTransaction(
vecSend, coinControl, !wallet().privateKeysDisabled(), nChangePosRet, nFeeRequired);with a call matching the interface’s new signature (e.g. passing only 🤖 Prompt for AI Agents |
||
|
|
||
| //! Information about one wallet address. | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Assert should be replaced with proper error handling
The constructor now uses
GetReservedDestination(false)which returns autil::Result. While asserting the result exists works, this could fail in production if the wallet cannot provide addresses (e.g., keypool exhausted). Consider proper error handling instead of assertions.Consider propagating the error instead of asserting:
📝 Committable suggestion
🤖 Prompt for AI Agents