-
Notifications
You must be signed in to change notification settings - Fork 1.2k
backport: Merge bitcoin#29144, 28946, 28980, 28554, (partial) 28414 #7354
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
base: develop
Are you sure you want to change the base?
Changes from all commits
d04391b
2c82db6
921eef1
30d0347
2c6ca84
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 |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| RPC Wallet | ||
| ---------- | ||
|
|
||
| - RPC `walletprocesspsbt` return object now includes field `hex` (if the transaction | ||
| is complete) containing the serialized transaction suitable for RPC `sendrawtransaction`. (#28414) | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -5,6 +5,10 @@ | |
| #include <fs.h> | ||
| #include <util/settings.h> | ||
|
|
||
| #if defined(HAVE_CONFIG_H) | ||
| #include <config/bitcoin-config.h> | ||
| #endif | ||
|
|
||
| #include <tinyformat.h> | ||
| #include <univalue.h> | ||
|
|
||
|
|
@@ -90,7 +94,9 @@ bool ReadSettings(const fs::path& path, std::map<std::string, SettingsValue>& va | |
|
|
||
| SettingsValue in; | ||
| if (!in.read(std::string{std::istreambuf_iterator<char>(file), std::istreambuf_iterator<char>()})) { | ||
| errors.emplace_back(strprintf("Unable to parse settings file %s", fs::PathToString(path))); | ||
| errors.emplace_back(strprintf("Settings file %s does not contain valid JSON. This is probably caused by disk corruption or a crash, " | ||
| "and can be fixed by removing the file, which will reset settings to default values.", | ||
| fs::PathToString(path))); | ||
| return false; | ||
| } | ||
|
|
||
|
|
@@ -123,6 +129,13 @@ bool WriteSettings(const fs::path& path, | |
| std::vector<std::string>& errors) | ||
| { | ||
| SettingsValue out(SettingsValue::VOBJ); | ||
| // Add auto-generated warning comment only if it does not exist | ||
| if (!values.contains("_warning_")) { | ||
| out.pushKV("_warning_", strprintf("This file is automatically generated and updated by %s. Please do not edit this file while the node " | ||
| "is running, as any changes might be ignored or overwritten.", | ||
| PACKAGE_NAME)); | ||
|
Comment on lines
+133
to
+136
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.
After the first settings write, the next startup reads Useful? React with 👍 / 👎. |
||
| } | ||
| // Push settings values | ||
| for (const auto& value : values) { | ||
| out.__pushKV(value.first, value.second); | ||
| } | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -220,7 +220,6 @@ RPCHelpMan encryptwallet() | |||||||||||||
| "After this, any calls that interact with private keys such as sending or signing \n" | ||||||||||||||
| "will require the passphrase to be set prior the making these calls.\n" | ||||||||||||||
| "Use the walletpassphrase call for this, and then walletlock call.\n" | ||||||||||||||
| "If the wallet is already encrypted, use the walletpassphrasechange call.\n", | ||||||||||||||
| { | ||||||||||||||
|
Comment on lines
222
to
223
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. 🔴 Blocking: Incorrect bitcoin#28980 adaptation removes a required initializer separator The Dash parent and the upstream pre-PR code both ended the
Suggested change
source: ['codex']
Collaborator
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. yes, |
||||||||||||||
| {"passphrase", RPCArg::Type::STR, RPCArg::Optional::NO, "The pass phrase to encrypt the wallet with. It must be at least 1 character, but should be long."}, | ||||||||||||||
| }, | ||||||||||||||
|
|
@@ -266,7 +265,7 @@ RPCHelpMan encryptwallet() | |||||||||||||
| if (pwallet->IsHDEnabled()) { | ||||||||||||||
| return "wallet encrypted; If you forget the passphrase, you will lose access to your funds. Make sure that you have backup of your seed or mnemonic."; | ||||||||||||||
| } | ||||||||||||||
| return "wallet encrypted; The keypool has been flushed. You need to make a new backup."; | ||||||||||||||
| return "wallet encrypted; The keypool has been flushed. You need to make a new backup with the backupwallet RPC."; | ||||||||||||||
| }, | ||||||||||||||
| }; | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -77,12 +77,21 @@ def run_test(self): | |
|
|
||
| self.nodes[0].walletpassphrase(passphrase="password", timeout=1000000) | ||
|
|
||
| # Sign the transaction and send | ||
| signed_tx = self.nodes[0].walletprocesspsbt(psbt=psbtx, finalize=False)['psbt'] | ||
| finalized_tx = self.nodes[0].walletprocesspsbt(psbt=psbtx, finalize=True)['psbt'] | ||
| assert signed_tx != finalized_tx | ||
| final_tx = self.nodes[0].finalizepsbt(signed_tx)['hex'] | ||
| self.nodes[0].sendrawtransaction(final_tx) | ||
| # Sign the transaction but don't finalize | ||
| processed_psbt = self.nodes[0].walletprocesspsbt(psbt=psbtx, finalize=False) | ||
| assert "hex" not in processed_psbt | ||
| signed_psbt = processed_psbt['psbt'] | ||
|
|
||
| # Finalize and send | ||
| finalized_hex = self.nodes[0].finalizepsbt(signed_psbt)['hex'] | ||
| self.nodes[0].sendrawtransaction(finalized_hex) | ||
|
|
||
| # Alternative method: sign AND finalize in one command | ||
| processed_finalized_psbt = self.nodes[0].walletprocesspsbt(psbt=psbtx, finalize=True) | ||
| finalized_psbt = processed_finalized_psbt['psbt'] | ||
| finalized_psbt_hex = processed_finalized_psbt['hex'] | ||
| assert signed_psbt != finalized_psbt | ||
| assert finalized_psbt_hex == finalized_hex | ||
|
|
||
| # Manually selected inputs can be locked: | ||
| assert_equal(len(self.nodes[0].listlockunspent()), 0) | ||
|
|
@@ -139,7 +148,7 @@ def run_test(self): | |
| # Check decodepsbt fee calculation (input values shall only be counted once per UTXO) | ||
| assert_equal(decoded['fee'], created_psbt['fee']) | ||
| assert_equal(walletprocesspsbt_out['complete'], True) | ||
| self.nodes[1].sendrawtransaction(self.nodes[1].finalizepsbt(walletprocesspsbt_out['psbt'])['hex']) | ||
| self.nodes[1].sendrawtransaction(walletprocesspsbt_out['hex']) | ||
|
|
||
| self.log.info("Test walletcreatefundedpsbt fee rate of 10000 sat/vB and 0.1 BTC/kvB produces a total fee at or slightly below -maxtxfee (~0.05290000)") | ||
| res1 = self.nodes[1].walletcreatefundedpsbt(inputs, outputs, 0, {"fee_rate": 10000, "add_inputs": True}) | ||
|
|
@@ -230,7 +239,7 @@ def run_test(self): | |
| # partially sign with node 2. This should be complete and sendable | ||
| walletprocesspsbt_out = self.nodes[2].walletprocesspsbt(psbtx) | ||
| assert_equal(walletprocesspsbt_out['complete'], True) | ||
| self.nodes[2].sendrawtransaction(self.nodes[2].finalizepsbt(walletprocesspsbt_out['psbt'])['hex']) | ||
| self.nodes[2].sendrawtransaction(walletprocesspsbt_out['hex']) | ||
|
|
||
| # check that walletprocesspsbt fails to decode a non-psbt | ||
| rawtx = self.nodes[1].createrawtransaction([{"txid":txid,"vout":p2pkh_pos}], {self.nodes[1].getnewaddress():9.99}) | ||
|
|
@@ -514,14 +523,13 @@ def test_psbt_input_keys(psbt_input, keys): | |
| assert not signed['complete'] | ||
| signed = self.nodes[0].walletprocesspsbt(signed['psbt']) | ||
| assert signed['complete'] | ||
| self.nodes[0].finalizepsbt(signed['psbt']) | ||
|
|
||
| psbt = wallet.walletcreatefundedpsbt([ext_utxo], {self.nodes[0].getnewaddress(): 15}, 0, {"add_inputs": True, "solving_data":{"descriptors": [desc]}}) | ||
| signed = wallet.walletprocesspsbt(psbt['psbt']) | ||
| assert not signed['complete'] | ||
| signed = self.nodes[0].walletprocesspsbt(signed['psbt']) | ||
| assert signed['complete'] | ||
| final = self.nodes[0].finalizepsbt(signed['psbt'], False) | ||
| final = signed['hex'] | ||
|
|
||
| dec = self.nodes[0].decodepsbt(signed["psbt"]) | ||
| for i, txin in enumerate(dec["tx"]["vin"]): | ||
|
|
@@ -555,8 +563,8 @@ def test_psbt_input_keys(psbt_input, keys): | |
| ) | ||
| signed = wallet.walletprocesspsbt(psbt["psbt"]) | ||
| signed = self.nodes[0].walletprocesspsbt(signed["psbt"]) | ||
| final = self.nodes[0].finalizepsbt(signed["psbt"]) | ||
| assert self.nodes[0].testmempoolaccept([final["hex"]])[0]["allowed"] | ||
| final = signed["hex"] | ||
| assert self.nodes[0].testmempoolaccept([final])[0]["allowed"] | ||
|
Collaborator
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. 28414: mark as partial due to missing changes for taproot. |
||
| # Reducing the weight should have a lower fee | ||
| psbt2 = wallet.walletcreatefundedpsbt( | ||
| inputs=[{"txid": ext_utxo["txid"], "vout": ext_utxo["vout"], "size": low_input_weight}], | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.