Skip to content
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

Implement GetKey for KeyMap #765

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

tcharding
Copy link
Member

@tcharding tcharding commented Oct 29, 2024

Create a KeyMap type to replace the current BTreeMap alias and implement bitcoin::psbt::GetKey for it.

Close: #709

@tcharding tcharding force-pushed the 10-29-key-map branch 2 times, most recently from ba5b2bf to 4a3bd7e Compare October 29, 2024 01:31
@tcharding
Copy link
Member Author

cc @LLFourn

@tcharding tcharding force-pushed the 10-29-key-map branch 2 times, most recently from 81b4923 to 00342a1 Compare October 29, 2024 02:25
@apoelstra
Copy link
Member

Nice! Yeah, this is probably the right approach.

In 00342a1 you have a bunch of unreachables because you assume that public keys map consistently to secret keys. I think this is a reasonable assumption, but you need to enforce it in the insert method. Or perhaps you could change insert to just take a secret key, and do the pubkey computation itself.

Alternately, you could make insert be non-pub so that the type can only be constructed by calling Descriptor::parse_descriptor. This might be the better approach. (Though in this case I'd still add an assertion to insert checking consistency of the public and secret keys.)i

@LLFourn
Copy link
Contributor

LLFourn commented Oct 30, 2024

Thanks @tcharding. It might be nice to be able to append your key maps onto each other so you keep one big jumble of secret keys across all your descriptors in the application. This is possible now but would be harder to do if you make the field private (which does seem like the right thing in general). So maybe an .extend with another keymap. If you make it private you probably want to make a way to iterate it too.

@tcharding
Copy link
Member Author

Yes I threw the pub inner field so as not to have to implement the whole BTreeMap API but private inner is probably better as you say - I can do this now we a have loose concept ack.

@ValuedMammal
Copy link

Concept ACK

@sanket1729
Copy link
Member

It might be nice to be able to append your key maps onto each other so you keep one big jumble of secret keys across all your descriptors in the application.

Maybe in the longer term, a cleaner solution is to implement rust-bitcoin to implement GetKey for a tuple, vec, set of things that already implement GetKey.

impl_get_key_tuple!((T1, T2))
impl GetKey for Vec<T> where T: GetKey {
}
impl GetKey for BtreeSet<T>...

@sanket1729
Copy link
Member

Concept ACK.

@tcharding
Copy link
Member Author

Implemented iter::IntoIterator and iter::Extend, would love someone else to give a few minutes to thinking if this is all of the iterator traits we need please.

Also made new take only the secret key. I did not remove any unreachable calls, nor did I add an assertion on the pk/sk since pk in insertion is now controlled.

Create a `KeyMay` type to replace the current `BTreeMap` alias and
implement `bitcoin::psbt::GetKey` for it.

Close: rust-bitcoin#709
Copy link

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

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

Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.

Comments suppressed due to low confidence (2)

src/descriptor/key_map.rs:143

  • The use of the unreachable! macro can be problematic if assumptions change. Consider handling this case more gracefully.
unreachable!("XPrv maps to XPrv")

src/descriptor/key_map.rs:22

  • [nitpick] The name KeyMap is quite generic. Consider renaming it to something more descriptive like DescriptorKeyMap.
pub struct KeyMap {

if pk == request {
match v {
DescriptorSecretKey::Single(ref sk) => Some(sk.key),
_ => unreachable!("Single maps to Single"),
Copy link
Preview

Copilot AI Dec 16, 2024

Choose a reason for hiding this comment

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

The use of the unreachable! macro can be problematic if assumptions change. Consider handling this case more gracefully.

Suggested change
_ => unreachable!("Single maps to Single"),
_ => return Err(GetKeyError::InvalidKey),

Copilot is powered by AI, so mistakes are possible. Review output carefully before use.

Positive Feedback
Negative Feedback

Provide additional feedback

Please help us improve GitHub Copilot by sharing more details about this comment.

Please select one or more of the options
Copy link
Member

Choose a reason for hiding this comment

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

Lol, no

Copy link
Member Author

Choose a reason for hiding this comment

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

AI is so awesome I think we are all going to be out of a job soon.

Copy link
Contributor

Choose a reason for hiding this comment

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

Not if your job is to have fun :)

None
}
}
_ => unreachable!("XPrv maps to XPrv"),
Copy link
Preview

Copilot AI Dec 16, 2024

Choose a reason for hiding this comment

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

The use of the unreachable! macro can be problematic if assumptions change. Consider handling this case more gracefully.

Copilot is powered by AI, so mistakes are possible. Review output carefully before use.

Positive Feedback
Negative Feedback

Provide additional feedback

Please help us improve GitHub Copilot by sharing more details about this comment.

Please select one or more of the options
DescriptorSecretKey::MultiXPrv(xpriv) => {
Some(xpriv.xkey.to_priv())
}
_ => unreachable!("MultiXPrv maps to MultiXPrv"),
Copy link
Preview

Copilot AI Dec 16, 2024

Choose a reason for hiding this comment

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

The use of the unreachable! macro can be problematic if assumptions change. Consider handling this case more gracefully.

Copilot is powered by AI, so mistakes are possible. Review output carefully before use.

Positive Feedback
Negative Feedback

Provide additional feedback

Please help us improve GitHub Copilot by sharing more details about this comment.

Please select one or more of the options
@apoelstra
Copy link
Member

Too bad. copilot has been around long enough that you'd think it would work, but 100% of its suggestions are wrong and it's full of irritating woke language like "harmful" and "problematic".

Ok(self.map.iter().find_map(|(k, v)| {
match k {
DescriptorPublicKey::Single(ref pk) => match key_request {
KeyRequest::Pubkey(ref request) => match pk.key {
Copy link
Member

Choose a reason for hiding this comment

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

In d2c954a:

I think if you replace

match k {
    Thing => match key_request {
        Thing2 => ...

with

    match (k, key_request) {
        (Thing, Thing) => {

you can reduce the amount of indentation and should be able to reduce the number of branches.

@sanket1729
Copy link
Member

Too bad. copilot has been around long enough that you'd think it would work, but 100% of its suggestions are wrong and it's full of irritating woke language like "harmful" and "problematic".

:) . Still too far. Let's try it in another 6 months.

@sanket1729
Copy link
Member

@apoelstra @tcharding wdyt about #765 (comment)? I think that would solve future API requests like extend, merge etc

@apoelstra
Copy link
Member

Maybe in the longer term, a cleaner solution is to implement rust-bitcoin to implement GetKey for a tuple, vec, set of things that already implement GetKey.

concept ACK, though we haven't really looked at GetKey upstream with an eye to 1.0. Unsure what the trait will look like when we do.

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

Successfully merging this pull request may close these issues.

Implement GetKey for KeyMap
6 participants