BSPT: Improving global xpub merging algorithm

This commit is contained in:
Dr Maxim Orlovsky 2020-12-16 16:39:46 +01:00
parent 8b1666295c
commit 21c11e3315
No known key found for this signature in database
GPG Key ID: FFC0250947E5C6F7
1 changed files with 19 additions and 13 deletions

View File

@ -172,30 +172,36 @@ impl Map for Global {
// 1) if fingerprints are equal but derivations are not, we report an error; otherwise // 1) if fingerprints are equal but derivations are not, we report an error; otherwise
// 2) choose longest unhardened derivation; if equal // 2) choose longest unhardened derivation; if equal
// 3) choose longest derivation; if equal // 3) choose longest derivation; if equal
// 4) choose largest fingerprint using binary ordering; if equal // 4) choose the largest derivation using binary ordering; if equal
// 5) do nothing // 5) check that fingerprints are equal, otherwise fail;
let (fingerprint2, len2, normal_len2) = { // 6) if fingerprints are also equal we do nothing
let (fingerprint2, len2, normal_len2, deriv_cmp) = {
// weird scope needed for rustc 1.29 borrow checker // weird scope needed for rustc 1.29 borrow checker
let (fp, deriv) = entry.get().clone(); let (fp, deriv) = entry.get().clone();
(fp, deriv.len(), deriv.into_iter().rposition(ChildNumber::is_normal)) (
fp,
deriv.len(),
deriv.into_iter().rposition(ChildNumber::is_normal),
derivation1.cmp(&deriv)
)
}; };
let len1 = derivation1.len(); let len1 = derivation1.len();
let normal_len1 = derivation1.into_iter().rposition(ChildNumber::is_normal); let normal_len1 = derivation1.into_iter().rposition(ChildNumber::is_normal);
match (normal_len1.cmp(&normal_len2), len1.cmp(&len2), fingerprint1.cmp(&fingerprint2)) { match (normal_len1.cmp(&normal_len2), len1.cmp(&len2), deriv_cmp, fingerprint1.cmp(&fingerprint2)) {
(Ordering::Equal, Ordering::Equal, Ordering::Equal) => {}, (Ordering::Equal, Ordering::Equal, Ordering::Equal, Ordering::Equal) => {},
(Ordering::Equal, _, Ordering::Equal) => { (Ordering::Equal, Ordering::Equal, Ordering::Equal, _) => {
return Err(psbt::Error::MergeConflict(format!( return Err(psbt::Error::MergeConflict(format!(
"global xpub {} has inconsistent key sources", xpub "global xpub {} has inconsistent key sources", xpub
).to_owned())); ).to_owned()));
} }
(Ordering::Greater, _, _) (Ordering::Greater, ..)
| (Ordering::Equal, Ordering::Greater, _) | (Ordering::Equal, Ordering::Greater, ..)
| (Ordering::Equal, Ordering::Equal, Ordering::Greater) => { | (Ordering::Equal, Ordering::Equal, Ordering::Greater, _) => {
entry.insert((fingerprint1, derivation1)); entry.insert((fingerprint1, derivation1));
}, },
(Ordering::Less, _, _) (Ordering::Less, ..)
| (Ordering::Equal, Ordering::Less, _) | (Ordering::Equal, Ordering::Less, ..)
| (Ordering::Equal, Ordering::Equal, Ordering::Less) => { | (Ordering::Equal, Ordering::Equal, Ordering::Less, _) => {
// do nothing here: we already own the proper data // do nothing here: we already own the proper data
} }
} }