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

Add psbt BIP174 test vectors tests #935

Merged
merged 4 commits into from Oct 28, 2022

Conversation

DanGould
Copy link
Contributor

@DanGould DanGould commented Apr 3, 2022

resolves #892

@tcharding
Copy link
Member

tcharding commented Apr 3, 2022

what do you mean by "Clean up this error" on SignError?

I stole that error type, and a bunch of the code for signing PSBTs from the bdk project. By 'clean up' I meant remove all the variants that were not being used. Also, in general, all the error handling code is incomplete i.e., usage of expect throughout. I was planning on re-doing all that once everything worked.

One suggestion is to alias PartiallySignedTransaction as Psbt in rust-bitcoin

That's a PR you can do if you would like to. Conceptually simple but likely to get some argument/discussion if you like that sort of thing :) Otherwise I'll do it.

Cheers, will review.

EDIT: By the way, this should probably be a draft PR, its not ready for merge yet.

EDIT EDIT: So cool to wake up on Monday morning and find all your problems from last week solved! Thanks man.

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 going to push a commit to this branch @DanGould, want to take a look at it and squash it in if you agree with the changes?

examples/psbt.rs Outdated
Comment on lines 630 to 631
// OP_CHECKMULTISIG bug pops +1 value when evaluating. Need extra OP_0 byte in front
// Why is OP_0 called `OP_PUSHBYTES_0` in rust-bitcoin?
Copy link
Member

Choose a reason for hiding this comment

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

I did some digging, this is because in rust-bitcoin we map OP_1 - OP_16 to all::OP_PUSHNUM_0 - all::OP_PUSHNUM_16. Bitcoin Core does not define opcodes for the byte values 0x01 - 0x4b (at least not in enum opcodetype) but in rust-bitcoin we define all::OP_PUSHBYTES_1 - all::OP_PUSHBYTES_75, when these are serialized they are simply the byte values 0x01 - 0x4b. So, OP_0 could have been defined as OP_PUSHNUM_0 I guess but OP_PUSHBYTES_0 was chosen.

@apoelstra do you remember why this was done or why we did not explicitly have an OP_0 defined or aliased as we do for OP_FALSE?

This seem so obvious I feel like I'm missing something?

/// OP_0, the zero byte, the empty stack.
pub static OP_ZERO: All = all::OP_PUSHBYTES_0;

Copy link
Member

Choose a reason for hiding this comment

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

I think it just didn't occur to me. I have never needed to push a zero to the stack, only FALSE 🤷

I'd be happy to accept a new alias.

@tcharding
Copy link
Member

Nice work man! We have the seed passing issue to resolve still. Also, I'm starting to think that this should not be an example but rather should be an integration test. Then, the remaining TODOs are changes to rust-bitcoin. If you want to do them I'm happy to let you run with them :)

@tcharding
Copy link
Member

Locally this builds fine but CI is including recent changes to the sighash types, no idea what is going on with that. Its your branch @DanGould so I won't mess with it but my blunt guess would be update your local master branch then rebase this and change SigHash -> Sighash and force push.

@DanGould DanGould marked this pull request as draft April 4, 2022 04:25
tcharding added a commit to tcharding/rust-bitcoin that referenced this pull request Apr 5, 2022
Draft because I'm stuck.

We are currently working on PSBT workflow that uses the test vectors
from BIP174, issue rust-bitcoin#892 describes the problem.

PR rust-bitcoin#935 implements a solution using the test vectors but the code is
cluttered because of all the hex strings, also the code does not really
show how a user of `rust-bitcoin` would go about using the `psbt`
module.

I propose that rust-bitcoin#935 goes into `src/tests`, this PR  adds
`src/examples/psbt.rs`.

Add an example PSBT workflow based on a cold-storage signer and a
watch-only online wallet. The watch-only wallet is the Creator, Updater,
and Finalizer. The cold-storage wallet is the Signer.
tcharding added a commit to tcharding/rust-bitcoin that referenced this pull request Apr 5, 2022
Draft because I'm stuck.

We are currently working on PSBT workflow that uses the test vectors
from BIP174, issue rust-bitcoin#892 describes the problem.

PR rust-bitcoin#935 implements a solution using the test vectors but the code is
cluttered because of all the hex strings, also the code does not really
show how a user of `rust-bitcoin` would go about using the `psbt`
module.

I propose that rust-bitcoin#935 goes into `src/tests`, this PR  adds
`src/examples/psbt.rs`.

Add an example PSBT workflow based on a cold-storage signer and a
watch-only online wallet. The watch-only wallet is the Creator, Updater,
and Finalizer. The cold-storage wallet is the Signer.
@tcharding tcharding changed the title add psbt example Add psbt test vectors example Apr 5, 2022
examples/psbt.rs Outdated Show resolved Hide resolved
@DanGould
Copy link
Contributor Author

DanGould commented Apr 5, 2022

I'm starting to think that this should not be an example but rather should be an integration test —@tcharding

concept ack to that and your psbt watch-only example as an example. I'll turn these TODOs into PRs.

examples/psbt.rs Outdated Show resolved Hide resolved
examples/psbt.rs Outdated Show resolved Hide resolved
examples/psbt.rs Outdated Show resolved Hide resolved
examples/psbt.rs Outdated Show resolved Hide resolved
examples/psbt.rs Outdated Show resolved Hide resolved
@tcharding
Copy link
Member

For your CI fixes you can check out #940 or

  • Use BTreeMap:new() and then call insert instead of using BTreeMap::from
  • Add an explicit scope around the immutable/mutable borrow issue (if you hit it)

@DanGould DanGould force-pushed the psbt-example branch 2 times, most recently from dea0872 to 4bde605 Compare April 7, 2022 04:28
@DanGould
Copy link
Contributor Author

DanGould commented Apr 7, 2022

Why the heck aren't I seeing these errors when running act locally? I feel like a pleb pushing CI failing builds

@tcharding
Copy link
Member

Don't beat yourself up about it, it took me months on this project to work out how to see the Rust 1.29 errors. I don't use act, in case it helps I can get these errors locally using

RUST_LOG=warn cargo-gen-lockfile-rust-1.29-bitcoin; RUST_LOG=warn cargo +1.29 run --example psbt

And the shell function

function cargo-gen-lockfile-rust-1.29-bitcoin {
    RUST_LOG=warn cargo clean
    rm Cargo.lock

    cargo +1.29 generate-lockfile --verbose && \
        cargo +1.29 update -p cc --precise "1.0.41" --verbose && \
        cargo +1.29 update --package "serde" --precise "1.0.98" --verbose && \
        cargo +1.29 update -p "serde_derive" --precise "1.0.98" --verbose

    export RUST_LOG=$saved_log
}

@DanGould
Copy link
Contributor Author

DanGould commented Apr 7, 2022

@tcharding would it make sense to add this script to contributing.md? I wonder why this doesn't show up with act on its own. I get that this will change when we upgrade rust. this would have saved me 3 pushes at this point

@tcharding
Copy link
Member

Yeah go for it.

@tcharding
Copy link
Member

All green! I rekon this is pretty close to ready-for-review. I still rekon we should be asserting against PSBTs not against hex, do you have an opinion on that?

@DanGould DanGould force-pushed the psbt-example branch 2 times, most recently from 31da281 to eff0d9a Compare April 7, 2022 07:50
@DanGould
Copy link
Contributor Author

DanGould commented Apr 7, 2022

We're asserting against PSBTs now 👍

Sincere thanks for all the guidance. I'm thrilled to be able to contribute :D

edit: if this is going to be an integration test it looks like we'll need a home for them.

@DanGould DanGould marked this pull request as ready for review April 7, 2022 07:53
@tcharding
Copy link
Member

We're asserting against PSBTs now

There were a few missed, I pushed a wip patch, you can squash if you like it.

I also pushed a commit that moves the example to tests/ as is customary for Rust integration tests, run it with cargo test bip174_psbt_workflow.

@tcharding
Copy link
Member

I'm thrilled to be able to contribute

I'm glad you are enjoying it, this is a mad project with good people working on it. I'm learning heaps hacking on this repo.

@tcharding
Copy link
Member

Oh and incase you want to know why its in tests/: https://doc.rust-lang.org/rust-by-example/testing/integration_testing.html

@DanGould
Copy link
Contributor Author

DanGould commented Aug 28, 2022

Now this uses the same signer as #940, is rebased on master, and satisfies the clippy gods.

I pair programmed the latest with @0xBEEFCAF3 and added him as a co-author.

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.

This looks good, a few trivial whitespace issues to fix.

With the whitespace fixes: ACK 210f5ec

src/blockdata/opcodes.rs Outdated Show resolved Hide resolved
tests/psbt.rs Outdated Show resolved Hide resolved
tests/psbt.rs Outdated Show resolved Hide resolved
tests/psbt.rs Outdated
psbt
}

/// Finalizes a PSBT accord to the Input Finalizer role described in BIP 174.
Copy link
Member

Choose a reason for hiding this comment

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

Perhaps we should comment here that finalizing can better be done with miniscript?

Copy link
Member

Choose a reason for hiding this comment

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

If we do we should add the same comment in examples/ecdsa-psbt.rs.

tests/psbt.rs Outdated
Comment on lines 392 to 402
let mut inputs = psbt.inputs.clone();

for (i, input) in inputs.iter_mut().enumerate() {
for sk in keys {
let mut required_pks = input.bip32_derivation.keys();
let pk = sk.public_key(secp);
if required_pks.any(|required| (*required) == pk.inner) {
psbt_sign::sign(&mut psbt, sk, i, secp).expect("failed to sign input with key");
}
}
}
Copy link
Member

@tcharding tcharding Aug 30, 2022

Choose a reason for hiding this comment

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

I applied the patches from this PR to the sign PSBT (#957) PR and was able to implement GetKey for &[PriavateKey] based on this code. If/when both this PR and #957 merges this function can become

/// Signs `psbt` with `keys` if required.
fn sign(mut psbt: Psbt, keys: &[PrivateKey]) -> Psbt {
    let secp = SECP256K1;
    psbt.sign(&keys, &secp);
    psbt
}

which smells like success :)

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 took a little massaging since &keys needs to be GetKeys. I think it works now

@tcharding
Copy link
Member

Thanks for sticking at this one @DanGould!

@tcharding
Copy link
Member

Hey @DanGould, now that the ecdsa-psbt module merged and the PSBT signing API improvements, this one should be able to merge. Have you time to check it over and rebase?

@tcharding tcharding changed the title Add psbt test vectors example Add psbt BIP174 test vectors tests Oct 24, 2022
@tcharding
Copy link
Member

I re-named the PR to remove the word "example" because this adds tests not example.

@DanGould DanGould force-pushed the psbt-example branch 2 times, most recently from 62259a2 to 421fe92 Compare October 25, 2022 22:35
tcharding
tcharding previously approved these changes Oct 26, 2022
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've said it before but this test is hot. All my suggestions are just nits though I'd like to see util removed from the import paths if that's ok.

ACK 421fe92

vout: input_0.index,
},
script_sig: Script::new(),
sequence: bitcoin::Sequence(0xFFFFFFFF), // Disable nSequence.
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
sequence: bitcoin::Sequence(0xFFFFFFFF), // Disable nSequence.
sequence: Sequence::MAX, // Disable nSequence.


Transaction {
version: 2,
lock_time: bitcoin::absolute::PackedLockTime::ZERO,
Copy link
Member

@tcharding tcharding Oct 26, 2022

Choose a reason for hiding this comment

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

nit: With the addition of use bitcoin::locktime::absolute;

Suggested change
lock_time: bitcoin::absolute::PackedLockTime::ZERO,
lock_time: absolute::PackedLockTime::ZERO,

Comment on lines 13 to 14
use bitcoin::util::bip32::{ExtendedPrivKey, ExtendedPubKey, Fingerprint, IntoDerivationPath, KeySource};
use bitcoin::util::psbt::{Psbt, PsbtSighashType};
Copy link
Member

Choose a reason for hiding this comment

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

nit: We are in the process of flattening util, would be better if the import path did not use util (both psbt and bip32 are in scope at the crate root).

@tcharding
Copy link
Member

Will need to be rebased once #1345 goes in.

@DanGould
Copy link
Contributor Author

added nits & rustfmt +nightly to use our fancy rustfmt.toml

tcharding
tcharding previously approved these changes Oct 26, 2022
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.

formatted, awesome. Thanks man.

ACK 5459c4f

(Rebase after we merge fix to master still to come.)

tcharding and others added 4 commits October 27, 2022 10:40
In preparation for adding integration tests in the standard Rust
`tests/` directroy; move the contents of `test_data` to `tests/data`.
Implement Test Vectors from BIP 174

Co-authored-by: Tobin Harding <me@tobin.cc>
Co-authored-by: Armin Sabouri <armins88@gmail.com>
@DanGould
Copy link
Contributor Author

cherry-picked #1347 so we have a clean history and pass CI before @tcharding wakes up

@tcharding
Copy link
Member

ACK b8bd31d

Thanks man!

Copy link
Member

@sanket1729 sanket1729 left a comment

Choose a reason for hiding this comment

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

ACK b8bd31d. Thanks for sticking with this PR. This looks awesome after #957

@sanket1729 sanket1729 merged commit 21ae79b into rust-bitcoin:master Oct 28, 2022
@DanGould DanGould deleted the psbt-example branch October 28, 2022 13:57
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.

Write an example psbt workflow
5 participants