New PSBT global keys#499
New PSBT global keys#499apoelstra merged 8 commits intorust-bitcoin:masterfrom BP-WG:pending/psbt-global
Conversation
stevenroose
left a comment
There was a problem hiding this comment.
You also forgot to implement Map::get_pairs to do the serialization part.
Some unit tests that add some roundtrips of some PSBTs with the new keys would also be appreciated.
|
needs rebase |
|
Rebased and addressed @stevenroose comments. NB: this is based on #470, which also had review comments (they are addressed now, but #470 needs to be merged first) |
src/util/bip32.rs
Outdated
src/util/bip32.rs
Outdated
There was a problem hiding this comment.
The BIP only specifies versions for Testnet, is it safe to use the same for Signet and Regtest
There was a problem hiding this comment.
I think it's reasonable for now. Regtest copies a lot of values from testnet.
src/util/bip32.rs
Outdated
There was a problem hiding this comment.
Can the from_slice() only fail if size is incorrect?
It looks like https://github.com/bitcoin-core/secp256k1/blob/9e5939d2848df5508e3a6eb038273b28d255248c/src/secp256k1.c#L550-L559 can fail if there is overflow or if secret key is zero.
There was a problem hiding this comment.
Fixed in the other branch and now fine after the rebase
|
Can you squash these commits together? It's not too long to read, and it's a bit harder to review because you make changes that are later modified. |
src/util/psbt/map/global.rs
Outdated
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
|
I think this breaks PSBT serialization. The Otherwise it looks great! |
|
@justinmoon you are right, and even more: we need to do a proper merge according to BIP174 rules and resolve conflicts. Working on the change |
|
@apoelstra squashed old commits; new commits are on top and they do not change previous code but splits added functionality into logical blocks for review simplification In general, it was not that trivial to do the merge procedure and key pair export; there were two questions which I do not know the right answer for, but proposing what I think will work the best:
My current implementation:
|
|
src/util/psbt/map/global.rs
Outdated
There was a problem hiding this comment.
This will cause runtime error. ret is a vec with length 0, so you can't use vec[0..4]
There was a problem hiding this comment.
Very good point, thank you. Fixed
|
You seem to have some Rust v1.29 compilation error in the ordering algorithm. |
|
@stevenroose @apoelstra 1.29 fixed for all commit history. It's extremely stupid with borrow checks and making it compiling required an unnecessary clone; I have tried everything else and it simply was not working with 1.29 :( |
src/util/psbt/map/global.rs
Outdated
There was a problem hiding this comment.
nit: the correct term is "commutative"
apoelstra
left a comment
There was a problem hiding this comment.
ack 794c5196a0eb4ec635a35cf09708ff8da6a00d28
apoelstra
left a comment
There was a problem hiding this comment.
ack 794c5196a0eb4ec635a35cf09708ff8da6a00d28
stevenroose
left a comment
There was a problem hiding this comment.
utACK d1ace733e0de532707df7140ee5be1eb3faedbe0
src/util/psbt/map/global.rs
Outdated
There was a problem hiding this comment.
Largest here means just by ordering the bytes, right? So 0xdeadbeef wins from 0xbeadbeef? This is a bit arbitrary. But I suppose I can agree that it's better to do something then to error.
There was a problem hiding this comment.
Correct. Actually since fingerprint is [u8; 4] and not u32 I assume it uses little-endian comparison. And yes, this is arbitrary
There was a problem hiding this comment.
nit: I'd perhaps rephrase "choose largest pingerprint using binary ordering" because this suggests that the fingerprint "size" might have real meaning :p
|
@apoelstra you "approved" a different commit than the hash you mention inside the approve message. Can you confirm you meant to ack d1ace73? |
stevenroose
left a comment
There was a problem hiding this comment.
Left a bunch of nits. I didn't want to make them to not hold up the MR, but since your CI fails and you need to push changes anyway, I thought I'd leave them anyway.
src/util/bip32.rs
Outdated
There was a problem hiding this comment.
nit: There's no need to do this. It's probably microscopically more efficient to leave it self.
There was a problem hiding this comment.
This is not about efficiency, this is required by compiler, otherwise we get
error[E0631]: type mismatch in function arguments
--> src/util/psbt/map/global.rs:182:71
|
182 | (fp, deriv.len(), deriv.into_iter().rposition(ChildNumber::is_normal))
| ^^^^^^^^^^^^^^^^^^^^^^ expected signature of `fn(&ChildNumber) -> _`
|
::: src/util/bip32.rs:129:5
|
129 | pub fn is_normal(self) -> bool {
| ------------------------------ found signature of `fn(ChildNumber) -> _`
basically you need &self in order to be able to use the functions inside the iterators
There was a problem hiding this comment.
you can just add .cloned() on the iterator before .rposition. Or .copied() in Rust 1.36. But what you did here is fine.
src/util/bip32.rs
Outdated
There was a problem hiding this comment.
nit: There's no need to do this. It's probably microscopically more efficient to leave it self.
src/util/psbt/map/global.rs
Outdated
There was a problem hiding this comment.
this can be for n in &derivation without the index. Or even
derivation.for_each(|n| ret.extend(&u32_to_array_le(n.into())));There was a problem hiding this comment.
No, it can't be: there is no iter() for Derivation. You can only use derivation.into_iter()
src/util/psbt/map/global.rs
Outdated
There was a problem hiding this comment.
nit: I think cmp::max(self.version, other.version) reads better; but very much a nit :)
src/util/psbt/map/global.rs
Outdated
There was a problem hiding this comment.
nit: I'd perhaps rephrase "choose largest pingerprint using binary ordering" because this suggests that the fingerprint "size" might have real meaning :p
src/util/psbt/map/global.rs
Outdated
There was a problem hiding this comment.
nit: Put on same line as string as long as it doesn't exceed 100 width :)
src/util/psbt/map/global.rs
Outdated
There was a problem hiding this comment.
nit: This exceeds 100 characters, right? how about putting the encode::Error::ParseFailed on the same line as .map_err?
src/util/psbt/map/global.rs
Outdated
There was a problem hiding this comment.
nit: I think you can actually do
let mut fingerprint = Fingerprint::default();
decoder.read_exact(&mut fingerprint[..])?;but I'm not 100% sure
There was a problem hiding this comment.
You can't: there is no IndexMut impl for Fingerprint
Plus necessary changes to BIP 32 implementations and error type
Conflicts: src/util/psbt/map/global.rs
8b16662
|
Had to rebase since it had conflicts with merged #530 and had a failed fuzz tests. Also used this opportunity to address @stevenroose nits. Will need a re-ACK from you guys, @apoelstra, @stevenroose |
sgeisler
left a comment
There was a problem hiding this comment.
I think by and large this PR is in a good state. I'm still not super happy with the merge logic, it seems way too convoluted, reasoning about it was somewhat hard and I'm not sure it's entirely consistent. But since many reviewed so far and didn't take issue with it I'd be fine with it since the BIP didn't specify to detect such inconsistencies afaik. @apoelstra, what do you think, keep polishing or merge?
sgeisler
left a comment
There was a problem hiding this comment.
I found some logic bugs which is probably a good indicator to add some tests for the newly added logic.
Based/depends on #470
Part of epic #473