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

PSBT interface mockup #457

Closed

Conversation

sgeisler
Copy link
Contributor

@sgeisler sgeisler commented Aug 13, 2020

Alternative idea for #455

Currently it covers the following functionalities:

I wouldn't consider merging any of the PSBT interface PRs before every trait was implemented at least once and a working wallet could be built using these. But I consider this a good basis for discussion.

#[derive(Debug)]
pub enum PsbtSignError<E: Debug> {
/// The PSBT is not valid for signig according to BIP-174
ValidationError,
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This should be more fine-grained.

fn create_transaction(
&mut self,
outputs: &[TxOut],
change_output: Option<Script>,
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Maybe we want to have a different trait that allows this particular privacy optimization to avoid panics/useless error conditions.

Copy link
Collaborator

@dr-orlovsky dr-orlovsky left a comment

Choose a reason for hiding this comment

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

Not sure I understand core API differences with the other proposal (#456); and in parts where I see API diffs I left some questions

src/util/psbt/responsibilities.rs Outdated Show resolved Hide resolved
src/util/psbt/responsibilities.rs Outdated Show resolved Hide resolved
src/util/psbt/responsibilities.rs Outdated Show resolved Hide resolved
@sgeisler
Copy link
Contributor Author

@dr-orlovsky The main difference to #456 is that here the objects implementing responsibilities never hold the PSBT, but only the state they need to repeatedly perform their functionality and are thus reusable. As noted in the discussion in #456 enforcing a certain PSBT workflow seems futile, so there is no wrapping of PSBTs going on here. The notion of an abstract Responsibility is not present in this PR, but could be added if there's a use case for that. All defined traits only transform PSBTs.

@dr-orlovsky
Copy link
Collaborator

Oh, I see. My only objection that this leads, as a direct consequence, to the ability to change PSBT outside of normal flow, so we do not have a state machine of responsibilities chaining each other

@sgeisler
Copy link
Contributor Author

Such a state machine sounds nice in theory, but in practice we can't enforce that much without an overly complex representation of the PSBT in the type system. Looking at the example workflows in the BIP I'm pretty sure that PSBT is too general for this to be useful.

@sgeisler sgeisler force-pushed the 2020-08-psbt-interfaces branch 3 times, most recently from cecea5d to 649a166 Compare August 14, 2020 17:52
@dr-orlovsky
Copy link
Collaborator

I did an alternative implementation, pls see #456

Copy link
Collaborator

@stevenroose stevenroose left a comment

Choose a reason for hiding this comment

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

I don't really understand what the goal is of these kind of traits. Is it just a way to provide some basic signing code that a wallet can like "plug" into? I mean it seems to me that these traits would for almost all applications stay within the application, adding little value by making the traits "common".

The code that generalizes signing over a xpriv is useful though. But it seems to be a hassle to create all this framework just to provide that code?

I'd be curious though to experiment with this in rust-wallet!

fn create_transaction(
&mut self,
outputs: &[TxOut],
) -> Result<PartiallySignedTransaction, PsbtCreationError<Self::Error>>;
Copy link
Collaborator

Choose a reason for hiding this comment

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

Is this method supposed to create a transaction without inputs or is the implementor responsible for adding inputs to fulfill the tx?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, it's the implementor's responsibility to select UTXOs, that's an integral part of every wallet imo: tracking and selecting UTXOs.

#[derive(Debug)]
pub enum PsbtCreationError<E: Debug> {
/// The wallet doens't control a sufficient amount of Bitcoins to fund the transaction
InsufficientFunds,
Copy link
Collaborator

Choose a reason for hiding this comment

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

This probably answers my earlier question.

fn sign_psbt(
&mut self,
psbt: PartiallySignedTransaction,
) -> Result<PartiallySignedTransaction, PsbtSignError<Self::Error>>;
Copy link
Collaborator

Choose a reason for hiding this comment

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

Is it on purpose that this clones the entire PSBT instead of having a mutable reference? Perhaps 2 variants of this method could be provided? One could be provided by using the other.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It doesn't clone. It takes it by value, mutates it and either returns the altered version or an error. The problem with mut references is that it's much too easy to leave the PSBT in an invalid state in case of an early exit due to an error.

let key = match self.derive_priv(&ctx, &path) {
Ok(key) => key,
Err(crate::util::bip32::Error::Ecdsa(e)) => return Err(e),
_ => unreachable!(),
Copy link
Collaborator

Choose a reason for hiding this comment

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

This is dangerous.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oh, yeah, I mostly hacked that together to test the API.

@sgeisler
Copy link
Contributor Author

I'll leave some comments, but I consider this whole endeavor to be futile. rust-bitcoin probably won't be able to provide a sufficiently general interface without too much feature-creep (see this discussion). It might still be worthwhile for the signer trait, I really want to have a native HWI interface somehow, but it would need a lot of deliberation upfront. So I'll close this for now.

@sgeisler sgeisler closed this Oct 10, 2020
@dr-orlovsky
Copy link
Collaborator

Agree, closing my version as well

@dr-orlovsky dr-orlovsky added this to Done in PSBT Jan 30, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
PSBT
Done
Development

Successfully merging this pull request may close these issues.

None yet

3 participants