Skip to content

Follow up to v21 TODO #293

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

Open
wants to merge 4 commits into
base: master
Choose a base branch
from

Conversation

jamillambert
Copy link
Collaborator

@jamillambert jamillambert commented Jul 14, 2025

There were a couple of points in the review of #289 that needed to be addressed.

Improve the tests as suggested, and add a comment to the rustdocs.

Redefine the create_wallet client macro so that for v21 and v22 where the default is a legacy wallet there is a separate function to create a descriptor wallet. Similarly for v23 and above where the default is a descriptor wallet there is a separate function to create a legacy wallet.

Closes #292

let request = ImportDescriptorsRequest {
desc: descriptor,
timestamp: serde_json::Value::String("now".to_string()),
timestamp: serde_json::Value::Number(serde_json::Number::from(start_time)),
};

let _: ImportDescriptors = node.client.import_descriptors(&[request]).expect("importdescriptors");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We want to check that the list isn't empty, right? Otherwise all the good work above is not validated.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

True. When I checked the list it turns out the RPC was returning an error message "Cannot import descriptor without private keys to a wallet with private keys enabled". So I have modified the test to create a descriptor with a private key.

@@ -314,17 +314,37 @@ fn wallet__import_address() {
#[cfg(not(feature = "v20_and_below"))]
fn wallet__import_descriptors() {
use node::{serde_json, ImportDescriptorsRequest};
use std::time::{SystemTime, UNIX_EPOCH};

let node = Node::with_wallet(Wallet::None, &[]);
let wallet_name = "desc_wallet";
node.client.create_wallet_with_descriptors(wallet_name).expect("create descriptor wallet");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps feature gate and then we only need to call the macro that defines this function in v21 and v22, making the default descriptor wallet thing explicit.

    #[cfg(feature = "v22_and_below")]
    node.client.create_wallet_with_descriptors(wallet_name).expect("create descriptor wallet");

    // v23 onwards uses descriptor wallets by default.
    #[cfg(not(feature = "v22_and_below"))]
    node.client.create_wallet(wallet_name).expect("create wallet"); 

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

@jamillambert
Copy link
Collaborator Author

jamillambert commented Jul 15, 2025

I added a new commit that addresses #292, I put it before the rewrite of the test, since the test uses the function. This also made one commit redundant, which has been dropped.

Comment on lines 72 to 73
let txindex_info = index_info.0.get("txindex").unwrap();
let _ = txindex_info.synced; // The synced field is a bool, accessing it validates the JSON deserialization
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It doesn't matter all that much but just for educational purposes this comment is incorrect. Its the unwrap that validates that we got a non-empty map. Which means that the let index_info: GetIndexInfo ... line that validates the deserialization. Accessing the field doesn't do anything.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I removed this line.

Comment on lines 17 to 20
/// Calls `createwallet` with `wallet` as the only argument.
/// In v23 and later this creates a descriptor wallet. Use `create_legacy_wallet` to create
/// a legacy wallet.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// Calls `createwallet` with `wallet` as the only argument.
/// In v23 and later this creates a descriptor wallet. Use `create_legacy_wallet` to create
/// a legacy wallet.
/// Calls `createwallet` with `wallet` as the only argument.
///
/// In v23 and later this creates a descriptor wallet. Use `create_legacy_wallet` to create
/// a legacy wallet.

Bit nit-picky and I wouldn't bother rebasing just for this.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

/// > 5. avoid_reuse (boolean, optional, default=false) Keep track of coin reuse, and treat dirty and clean coins differently with privacy considerations in mind.
/// > 6. descriptors (boolean, optional, default=true) Create a native descriptor wallet. The wallet will use descriptors internally to handle address creation
/// > 7. load_on_startup (boolean, optional) Save wallet name to persistent settings and load on startup. True to add wallet to startup list, false to remove, null to leave unchanged.
pub fn create_descriptor_wallet(&self, wallet: &str) -> Result<CreateWallet> {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is waaay better, nice one man.

let _txid = node.client.send_to_address(&address, amount).expect("sendtoaddress");

// 3. Get the descriptor from the private key.
let raw_descriptor = format!("wpkh({})", privkey.to_wif());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For my education, why does the descriptor use wpkh but the address above is a p2pkh address?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because one bit was copied from another test 😊. I have changed it now so both are native SegWit.

let request = ImportDescriptorsRequest {
desc: descriptor,
timestamp: serde_json::Value::String("now".to_string()),
timestamp: serde_json::Value::Number(serde_json::Number::from(start_time)),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: This whole thing is pretty ugly, would be nicer if the ImportDescriptorRequest had a constructor that took start_time and did the serde wrapping. Totally not required, just an observation.

Copy link
Collaborator Author

@jamillambert jamillambert Jul 16, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Created a constructor in a new commit, and also moved the imports to the top of the file.

Comment on lines +348 to +364
let info = node.client.get_descriptor_info(&raw_descriptor).expect("get_descriptor_info");
let descriptor = format!("{}#{}", raw_descriptor, info.checksum);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Clever!

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This took me a bit to figure out. It kept complaining that that the descriptor had no private key when it looked like it should.

Copy link
Member

@tcharding tcharding left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm ok to merge this as is if you want or if you want. I'll give you a chance to polish it if you feel like it.

@jamillambert jamillambert force-pushed the 0714-v21fixes branch 2 times, most recently from 2635d52 to 7defbf1 Compare July 16, 2025 08:45
@jamillambert
Copy link
Collaborator Author

I made changes to address all of your comments.

@jamillambert
Copy link
Collaborator Author

Rebased to remove merge conflict.

tcharding
tcharding previously approved these changes Jul 23, 2025
Copy link
Member

@tcharding tcharding left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACK a6ddd2e

@tcharding
Copy link
Member

Needs rebase.

The current test passes if the returned map is empty.

Update the test to access the values and ensure the deserialization
worked.
Change the client macro for v21 to match the style of the v23
definition. Only use this for v21 and v22 where the default wallet is a
legacy wallet.

Change the test to use the new function.

Add a comment to the v23 definition clarifying why the legacy wallet
function is needed.
The current test of the RPC always returns true due to scanning for the
timestamp `now`.

Move imports to the top of the file and allow unused.

Improve the test to be more thorough by creating a new address and then
scanning for the descriptor at a later time.
@jamillambert
Copy link
Collaborator Author

Rebased. It was the adding full stops patch that caused it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Clean up create wallet stuff
2 participants