Skip to content

Commit 65d3e92

Browse files
committed
Provide an ordering for PseudoExtendedKeys.
1 parent c81406e commit 65d3e92

File tree

2 files changed

+62
-4
lines changed

2 files changed

+62
-4
lines changed

masp_primitives/src/transaction/components/sapling/builder.rs

+1-4
Original file line numberDiff line numberDiff line change
@@ -116,10 +116,7 @@ impl BorshDeserialize for SpendBuildParams {
116116
std::io::Error::new(std::io::ErrorKind::InvalidData, "alpha not in field")
117117
})?;
118118
// Finally, aggregate the spend parameters
119-
Ok(SpendBuildParams {
120-
rcv,
121-
alpha,
122-
})
119+
Ok(SpendBuildParams { rcv, alpha })
123120
}
124121
}
125122

masp_primitives/src/zip32/sapling.rs

+61
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ use borsh::schema::Fields;
2323
use borsh::BorshSchema;
2424
use borsh::{BorshDeserialize, BorshSerialize};
2525
use byteorder::{ByteOrder, LittleEndian, ReadBytesExt, WriteBytesExt};
26+
use ff::PrimeField;
2627
use fpe::ff1::{BinaryNumeralString, FF1};
2728
use std::collections::BTreeMap;
2829
use std::{
@@ -1095,6 +1096,66 @@ impl From<ExtendedFullViewingKey> for PseudoExtendedKey {
10951096
}
10961097
}
10971098

1099+
impl BorshDeserialize for PseudoExtendedKey {
1100+
fn deserialize_reader<R: Read>(reader: &mut R) -> io::Result<Self> {
1101+
let xfvk = ExtendedFullViewingKey::deserialize_reader(reader)?;
1102+
let ask = Option::<[u8; 32]>::deserialize_reader(reader)?
1103+
.map(|x| {
1104+
Option::from(jubjub::Fr::from_repr(x))
1105+
.ok_or_else(|| io::Error::new(io::ErrorKind::InvalidData, "ask not in field"))
1106+
})
1107+
.transpose()?;
1108+
let nsk = Option::<[u8; 32]>::deserialize_reader(reader)?
1109+
.map(|x| {
1110+
Option::from(jubjub::Fr::from_repr(x))
1111+
.ok_or_else(|| io::Error::new(io::ErrorKind::InvalidData, "nsk not in field"))
1112+
})
1113+
.transpose()?;
1114+
Ok(Self { xfvk, ask, nsk })
1115+
}
1116+
}
1117+
1118+
impl BorshSerialize for PseudoExtendedKey {
1119+
fn serialize<W: Write>(&self, writer: &mut W) -> io::Result<()> {
1120+
self.xfvk.serialize(writer)?;
1121+
self.ask.map(|x| x.to_bytes()).serialize(writer)?;
1122+
self.nsk.map(|x| x.to_bytes()).serialize(writer)
1123+
}
1124+
}
1125+
1126+
impl BorshSchema for PseudoExtendedKey {
1127+
fn add_definitions_recursively(definitions: &mut BTreeMap<Declaration, Definition>) {
1128+
let definition = Definition::Struct {
1129+
fields: Fields::NamedFields(vec![
1130+
("xfvk".into(), ExtendedFullViewingKey::declaration()),
1131+
("ask".into(), Option::<[u8; 32]>::declaration()),
1132+
("nsk".into(), Option::<[u8; 32]>::declaration()),
1133+
]),
1134+
};
1135+
add_definition(Self::declaration(), definition, definitions);
1136+
ExtendedFullViewingKey::add_definitions_recursively(definitions);
1137+
Option::<[u8; 32]>::add_definitions_recursively(definitions);
1138+
}
1139+
1140+
fn declaration() -> Declaration {
1141+
"PseudoExtendedKey".into()
1142+
}
1143+
}
1144+
1145+
impl PartialOrd for PseudoExtendedKey {
1146+
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
1147+
Some(self.cmp(other))
1148+
}
1149+
}
1150+
1151+
impl Ord for PseudoExtendedKey {
1152+
fn cmp(&self, other: &Self) -> Ordering {
1153+
let a = borsh::to_vec(self).expect("unable to canonicalize PseudoExtendedKey");
1154+
let b = borsh::to_vec(other).expect("unable to canonicalize PseudoExtendedKey");
1155+
a.cmp(&b)
1156+
}
1157+
}
1158+
10981159
#[cfg(test)]
10991160
mod tests {
11001161
use super::*;

0 commit comments

Comments
 (0)