Remove Default impl from MemoBytes
Memo fields have two ways to encode an empty memo: - 0xF6 followed by all-zeroes, encoding "there is no memo". - All-zeroes, encoding the empty UTF-8 string. In almost all cases you want the former, but users thinking about byte slices may expect MemoBytes::default() to result in the latter. To ensure clarity, we now require calling either MemoBytes::default() or MemoBytes::from_bytes(&[]) to be explicit. No such confusion exists for the Memo enum, because the two types are visibly separated as different enum cases, and Memo::Empty makes sense as the default.
This commit is contained in:
parent
c7a3ef0e88
commit
8a84203685
|
@ -345,7 +345,7 @@ mod tests {
|
|||
Some(extfvk.fvk.ovk),
|
||||
note.clone(),
|
||||
to,
|
||||
MemoBytes::default(),
|
||||
MemoBytes::empty(),
|
||||
&mut rng,
|
||||
);
|
||||
let cmu = note.cmu().to_repr().as_ref().to_owned();
|
||||
|
|
|
@ -603,7 +603,7 @@ mod tests {
|
|||
Some(extfvk.fvk.ovk),
|
||||
note.clone(),
|
||||
to,
|
||||
MemoBytes::default(),
|
||||
MemoBytes::empty(),
|
||||
&mut rng,
|
||||
);
|
||||
let cmu = note.cmu().to_repr().as_ref().to_vec();
|
||||
|
@ -663,7 +663,7 @@ mod tests {
|
|||
Some(extfvk.fvk.ovk),
|
||||
note.clone(),
|
||||
to,
|
||||
MemoBytes::default(),
|
||||
MemoBytes::empty(),
|
||||
&mut rng,
|
||||
);
|
||||
let cmu = note.cmu().to_repr().as_ref().to_vec();
|
||||
|
@ -691,7 +691,7 @@ mod tests {
|
|||
Some(extfvk.fvk.ovk),
|
||||
note.clone(),
|
||||
change_addr,
|
||||
MemoBytes::default(),
|
||||
MemoBytes::empty(),
|
||||
&mut rng,
|
||||
);
|
||||
let cmu = note.cmu().to_repr().as_ref().to_vec();
|
||||
|
|
|
@ -36,7 +36,7 @@ fn bench_note_decryption(c: &mut Criterion) {
|
|||
let note = pa.create_note(value, rseed).unwrap();
|
||||
let cmu = note.cmu();
|
||||
|
||||
let mut ne = SaplingNoteEncryption::new(None, note, pa, MemoBytes::default(), &mut rng);
|
||||
let mut ne = SaplingNoteEncryption::new(None, note, pa, MemoBytes::empty(), &mut rng);
|
||||
let ephemeral_key = ne.epk().clone().into();
|
||||
let enc_ciphertext = ne.encrypt_note_plaintext();
|
||||
let out_ciphertext = ne.encrypt_outgoing_plaintext(&cv, &cmu);
|
||||
|
|
|
@ -58,14 +58,6 @@ impl fmt::Debug for MemoBytes {
|
|||
}
|
||||
}
|
||||
|
||||
impl Default for MemoBytes {
|
||||
fn default() -> Self {
|
||||
let mut bytes = [0u8; 512];
|
||||
bytes[0] = 0xF6;
|
||||
MemoBytes(Box::new(bytes))
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq for MemoBytes {
|
||||
fn eq(&self, rhs: &MemoBytes) -> bool {
|
||||
self.0[..] == rhs.0[..]
|
||||
|
@ -87,10 +79,22 @@ impl Ord for MemoBytes {
|
|||
}
|
||||
|
||||
impl MemoBytes {
|
||||
/// Creates a `MemoBytes` from a slice.
|
||||
/// Creates a `MemoBytes` indicating that no memo is present.
|
||||
pub fn empty() -> Self {
|
||||
let mut bytes = [0u8; 512];
|
||||
bytes[0] = 0xF6;
|
||||
MemoBytes(Box::new(bytes))
|
||||
}
|
||||
|
||||
/// Creates a `MemoBytes` from a slice, exactly as provided.
|
||||
///
|
||||
/// Returns an error if the provided slice is longer than 512 bytes. Slices shorter
|
||||
/// than 512 bytes are padded with null bytes.
|
||||
///
|
||||
/// Note that passing an empty slice to this API (or an all-zeroes slice) will result
|
||||
/// in a memo representing an empty string. What you almost certainly want in this
|
||||
/// case is [`MemoBytes::empty`], which uses a specific encoding to indicate that no
|
||||
/// memo is present.
|
||||
pub fn from_bytes(bytes: &[u8]) -> Result<Self, Error> {
|
||||
if bytes.len() > 512 {
|
||||
return Err(Error::TooLong(bytes.len()));
|
||||
|
@ -220,7 +224,7 @@ impl From<&Memo> for MemoBytes {
|
|||
/// Serializes the `Memo` per ZIP 302.
|
||||
fn from(memo: &Memo) -> Self {
|
||||
match memo {
|
||||
Memo::Empty => MemoBytes::default(),
|
||||
Memo::Empty => MemoBytes::empty(),
|
||||
Memo::Text(s) => {
|
||||
let mut bytes = [0u8; 512];
|
||||
let s_bytes = s.0.as_bytes();
|
||||
|
|
|
@ -135,7 +135,7 @@ pub fn prf_ock(
|
|||
/// let note = to.create_note(value, Rseed::BeforeZip212(rcm)).unwrap();
|
||||
/// let cmu = note.cmu();
|
||||
///
|
||||
/// let mut enc = SaplingNoteEncryption::new(ovk, note, to, MemoBytes::default(), &mut rng);
|
||||
/// let mut enc = SaplingNoteEncryption::new(ovk, note, to, MemoBytes::empty(), &mut rng);
|
||||
/// let encCiphertext = enc.encrypt_note_plaintext();
|
||||
/// let outCiphertext = enc.encrypt_outgoing_plaintext(&cv.commitment().into(), &cmu);
|
||||
/// ```
|
||||
|
@ -681,8 +681,7 @@ mod tests {
|
|||
let cmu = note.cmu();
|
||||
|
||||
let ovk = OutgoingViewingKey([0; 32]);
|
||||
let mut ne =
|
||||
SaplingNoteEncryption::new(Some(ovk), note, pa, MemoBytes::default(), &mut rng);
|
||||
let mut ne = SaplingNoteEncryption::new(Some(ovk), note, pa, MemoBytes::empty(), &mut rng);
|
||||
let epk = ne.epk().clone().into();
|
||||
let enc_ciphertext = ne.encrypt_note_plaintext();
|
||||
let out_ciphertext = ne.encrypt_outgoing_plaintext(&cv, &cmu);
|
||||
|
|
|
@ -142,7 +142,7 @@ impl SaplingOutput {
|
|||
ovk,
|
||||
to,
|
||||
note,
|
||||
memo: memo.unwrap_or_default(),
|
||||
memo: memo.unwrap_or_else(MemoBytes::empty),
|
||||
})
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue