Add `zcash_encoding::{CompactSize, Vector}::serialized_size` and

`zcash_primitives::legacy::Script::serialized_size`. Use the latter in
`zcash_primitives::transaction::fees::transparent::OutputView::serialized_size`.

Signed-off-by: Daira-Emma Hopwood <daira@jacaranda.org>
This commit is contained in:
Daira-Emma Hopwood 2024-06-18 21:06:39 +01:00
parent 17af8e32e8
commit 9881861228
5 changed files with 40 additions and 7 deletions

View File

@ -6,6 +6,9 @@ and this library adheres to Rust's notion of
[Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [Unreleased]
### Added
- `zcash_encoding::CompactSize::serialized_size`
- `zcash_encoding::Vector::serialized_size`
## [0.2.0] - 2022-10-19
### Changed

View File

@ -93,6 +93,16 @@ impl CompactSize {
}
}
}
/// Returns the number of bytes needed to encode the given size in compact form.
pub fn serialized_size(size: usize) -> usize {
match size {
s if s < 253 => 1,
s if s <= 0xFFFF => 3,
s if s <= 0xFFFFFFFF => 5,
_ => 9,
}
}
}
/// Namespace for functions that perform encoding of vectors.
@ -171,6 +181,12 @@ impl Vector {
CompactSize::write(&mut writer, items.len())?;
items.try_for_each(|e| func(&mut writer, e))
}
/// Returns the serialized size of a vector of `u8` as written by `[Vector::write]`.
pub fn serialized_size(vec: &[u8]) -> usize {
let length = vec.len();
CompactSize::serialized_size(length) + length
}
}
/// Namespace for functions that perform encoding of array contents.
@ -279,8 +295,11 @@ mod tests {
<T as TryInto<usize>>::Error: Debug,
{
let mut data = vec![];
CompactSize::write(&mut data, value.try_into().unwrap()).unwrap();
let value_usize: usize = value.try_into().unwrap();
CompactSize::write(&mut data, value_usize).unwrap();
assert_eq!(&data[..], expected);
let serialized_size = CompactSize::serialized_size(value_usize);
assert_eq!(serialized_size, expected.len());
let result: io::Result<T> = CompactSize::read_t(&data[..]);
match result {
Ok(n) => assert_eq!(n, value),
@ -308,6 +327,8 @@ mod tests {
let mut data = vec![];
CompactSize::write(&mut data, value).unwrap();
assert_eq!(&data[..], encoded);
let serialized_size = CompactSize::serialized_size(value);
assert_eq!(serialized_size, encoded.len());
assert!(CompactSize::read(encoded).is_err());
}
}
@ -320,6 +341,8 @@ mod tests {
let mut data = vec![];
Vector::write(&mut data, &$value, |w, e| w.write_u8(*e)).unwrap();
assert_eq!(&data[..], &$expected[..]);
let serialized_size = Vector::serialized_size(&$value);
assert_eq!(serialized_size, $expected.len());
match Vector::read(&data[..], |r| r.read_u8()) {
Ok(v) => assert_eq!(v, $value),
Err(e) => panic!("Unexpected error: {:?}", e),

View File

@ -11,6 +11,11 @@ and this library adheres to Rust's notion of
- `impl From<TransparentKeyScope> for bip32::ChildNumber`
- `impl From<NonHardenedChildIndex> for bip32::ChildNumber`
- `impl TryFrom<bip32::ChildNumber> for NonHardenedChildIndex`
- `zcash_primitives::legacy::Script::serialized_size`
- `zcash_primitives::transaction::fees::transparent`:
- `InputSize`
- `InputView::serialized_size`
- `OutputView::serialized_size`
### Changed
- MSRV is now 1.70.0.

View File

@ -322,6 +322,11 @@ impl Script {
Vector::write(&mut writer, &self.0, |w, e| w.write_u8(*e))
}
/// Returns the length of this script as encoded (including the initial CompactSize).
pub fn serialized_size(&self) -> usize {
Vector::serialized_size(&self.0)
}
/// Returns the address that this Script contains, if any.
pub(crate) fn address(&self) -> Option<TransparentAddress> {
if self.0.len() == 25

View File

@ -77,12 +77,9 @@ pub trait OutputView: std::fmt::Debug {
/// Returns the serialized size of the txout.
fn serialized_size(&self) -> usize {
let mut buf: Vec<u8> = vec![];
self.script_pubkey()
.write(&mut buf)
.expect("script does not exceed available memory");
// The length of a transparent TxOut is the length of an amount plus the length of the serialized script pubkey.
8 + buf.len()
// The serialized size of a transparent `TxOut` is the serialized size of an amount
// plus the serialized size of the script pubkey.
8 + self.script_pubkey().serialized_size()
}
}