PSBT: Key pair serialization for new global keys
Conflicts: src/util/psbt/map/global.rs
This commit is contained in:
parent
2f838218a8
commit
df8635c5fe
|
@ -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.
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue