PSBT: Key pair serialization for new global keys

Conflicts:
	src/util/psbt/map/global.rs
This commit is contained in:
Dr Maxim Orlovsky 2020-11-28 14:41:52 +01:00
parent 2f838218a8
commit df8635c5fe
No known key found for this signature in database
GPG Key ID: FFC0250947E5C6F7
2 changed files with 35 additions and 7 deletions

View File

@ -20,7 +20,7 @@ use util::psbt::raw;
use hashes; use hashes;
#[derive(Debug)] #[derive(Copy, Clone, PartialEq, Eq, Debug)]
/// Enum for marking psbt hash error /// Enum for marking psbt hash error
pub enum PsbtHash { pub enum PsbtHash {
Ripemd, Ripemd,
@ -29,7 +29,7 @@ pub enum PsbtHash {
Hash256, Hash256,
} }
/// Ways that a Partially Signed Transaction might fail. /// Ways that a Partially Signed Transaction might fail.
#[derive(Debug)] #[derive(Clone, PartialEq, Eq, Debug)]
pub enum Error { pub enum Error {
/// Magic bytes for a PSBT must be the ASCII for "psbt" serialized in most /// Magic bytes for a PSBT must be the ASCII for "psbt" serialized in most
/// significant byte order. /// significant byte order.

View File

@ -23,11 +23,13 @@ use util::psbt::map::Map;
use util::psbt::raw; use util::psbt::raw;
use util::psbt; use util::psbt;
use util::psbt::Error; use util::psbt::Error;
use util::endian::u32_to_array_le;
use util::bip32::{ExtendedPubKey, KeySource, Fingerprint, DerivationPath, ChildNumber}; use util::bip32::{ExtendedPubKey, KeySource, Fingerprint, DerivationPath, ChildNumber};
/// Type: Unsigned Transaction PSBT_GLOBAL_UNSIGNED_TX = 0x00 /// Type: Unsigned Transaction PSBT_GLOBAL_UNSIGNED_TX = 0x00
const PSBT_GLOBAL_UNSIGNED_TX: u8 = 0x00; const PSBT_GLOBAL_UNSIGNED_TX: u8 = 0x00;
const PSBT_GLOBAL_XPUB: u8 = 0x01;
const PSBT_GLOBAL_VERSION: u8 = 0xFB;
/// A key-value map for global data. /// A key-value map for global data.
#[derive(Clone, Debug, PartialEq)] #[derive(Clone, Debug, PartialEq)]
pub struct Global { pub struct Global {
@ -104,6 +106,34 @@ impl Map for Global {
}, },
}); });
for (xpub, (fingerprint, derivation)) in &self.xpub {
rv.push(raw::Pair {
key: raw::Key {
type_value: PSBT_GLOBAL_XPUB,
key: xpub.encode().to_vec(),
},
value: {
let mut ret = Vec::with_capacity(4 + derivation.len() * 4);
ret.extend(fingerprint.as_bytes());
for no in 0..derivation.len() {
ret.extend(&u32_to_array_le(derivation[no].into())[..])
}
ret
}
});
}
// Serializing version only for non-default value; otherwise test vectors fail
if self.version > 0 {
rv.push(raw::Pair {
key: raw::Key {
type_value: PSBT_GLOBAL_VERSION,
key: vec![],
},
value: u32_to_array_le(self.version).to_vec()
});
}
for (key, value) in self.unknown.iter() { for (key, value) in self.unknown.iter() {
rv.push(raw::Pair { rv.push(raw::Pair {
key: key.clone(), key: key.clone(),
@ -219,8 +249,7 @@ impl Decodable for Global {
return Err(Error::InvalidKey(pair.key).into()) return Err(Error::InvalidKey(pair.key).into())
} }
} }
// Global Xpub PSBT_GLOBAL_XPUB => {
0x01 => {
if !pair.key.key.is_empty() { if !pair.key.key.is_empty() {
let xpub = ExtendedPubKey::decode(&pair.key.key) let xpub = ExtendedPubKey::decode(&pair.key.key)
.map_err(|_| { .map_err(|_| {
@ -248,8 +277,7 @@ impl Decodable for Global {
return Err(encode::Error::ParseFailed("Xpub global key must contain serialized Xpub data")) return Err(encode::Error::ParseFailed("Xpub global key must contain serialized Xpub data"))
} }
} }
// Version PSBT_GLOBAL_VERSION => {
0xFB => {
// key has to be empty // key has to be empty
if pair.key.key.is_empty() { if pair.key.key.is_empty() {
// there can only be one version // there can only be one version