diff --git a/sdk/src/types/block/address/multi.rs b/sdk/src/types/block/address/multi.rs index 36fdc297a0..591d71d092 100644 --- a/sdk/src/types/block/address/multi.rs +++ b/sdk/src/types/block/address/multi.rs @@ -6,14 +6,7 @@ use core::{fmt, ops::RangeInclusive}; use derive_more::{AsRef, Deref, Display, From}; use iterator_sorted::is_unique_sorted; -use packable::{ - bounded::BoundedU8, - error::{UnpackError, UnpackErrorExt}, - packer::Packer, - prefix::BoxedSlicePrefix, - unpacker::Unpacker, - Packable, -}; +use packable::{bounded::BoundedU8, prefix::BoxedSlicePrefix, Packable}; use crate::types::block::{address::Address, Error}; @@ -77,12 +70,17 @@ fn verify_weight(weight: &u8, _visitor: &()) -> Result<(), E /// An address that consists of addresses with weights and a threshold value. /// The Multi Address can be unlocked if the cumulative weight of all unlocked addresses is equal to or exceeds the /// threshold. -#[derive(Clone, Debug, Deref, Eq, PartialEq, Ord, PartialOrd, Hash)] +#[derive(Clone, Debug, Deref, Eq, PartialEq, Ord, PartialOrd, Hash, Packable)] +#[packable(unpack_error = Error)] +#[packable(verify_with = verify_multi_address)] pub struct MultiAddress { /// The weighted unlocked addresses. #[deref] + #[packable(verify_with = verify_addresses)] + #[packable(unpack_error_with = |e| e.unwrap_item_err_or_else(|p| Error::InvalidWeightedAddressCount(p.into())))] addresses: BoxedSlicePrefix, /// The threshold that needs to be reached by the unlocked addresses in order to unlock the multi address. + #[packable(verify_with = verify_threshold)] threshold: u16, } @@ -103,9 +101,11 @@ impl MultiAddress { let addresses = BoxedSlicePrefix::::try_from(addresses) .map_err(Error::InvalidWeightedAddressCount)?; - verify_cumulative_weight::(&addresses, &threshold, &())?; + let multi_address = Self { addresses, threshold }; - Ok(Self { addresses, threshold }) + verify_multi_address::(&multi_address, &())?; + + Ok(multi_address) } /// Returns the addresses of a [`MultiAddress`]. @@ -121,38 +121,6 @@ impl MultiAddress { } } -impl Packable for MultiAddress { - type UnpackError = Error; - type UnpackVisitor = (); - - #[inline] - fn pack(&self, packer: &mut P) -> Result<(), P::Error> { - self.addresses.pack(packer)?; - self.threshold.pack(packer)?; - - Ok(()) - } - - #[inline] - fn unpack( - unpacker: &mut U, - visitor: &Self::UnpackVisitor, - ) -> Result> { - let addresses = - BoxedSlicePrefix::::unpack::<_, VERIFY>(unpacker, visitor) - .map_packable_err(|e| e.unwrap_item_err_or_else(|e| Error::InvalidWeightedAddressCount(e.into())))?; - - verify_addresses::(&addresses, &()).map_err(UnpackError::Packable)?; - - let threshold = u16::unpack::<_, VERIFY>(unpacker, visitor).coerce()?; - - verify_threshold::(&threshold, &()).map_err(UnpackError::Packable)?; - verify_cumulative_weight::(&addresses, &threshold, &()).map_err(UnpackError::Packable)?; - - Ok(Self { addresses, threshold }) - } -} - fn verify_addresses(addresses: &[WeightedAddress], _visitor: &()) -> Result<(), Error> { if VERIFY && !is_unique_sorted(addresses.iter().map(WeightedAddress::address)) { return Err(Error::WeightedAddressesNotUniqueSorted); @@ -169,18 +137,14 @@ fn verify_threshold(threshold: &u16, _visitor: &()) -> Resul } } -fn verify_cumulative_weight( - addresses: &[WeightedAddress], - threshold: &u16, - _visitor: &(), -) -> Result<(), Error> { +fn verify_multi_address(address: &MultiAddress, _visitor: &()) -> Result<(), Error> { if VERIFY { - let cumulative_weight = addresses.iter().map(|address| address.weight as u16).sum::(); + let cumulative_weight = address.iter().map(|address| address.weight as u16).sum::(); - if cumulative_weight < *threshold { + if cumulative_weight < address.threshold { return Err(Error::InvalidMultiAddressCumulativeWeight { cumulative_weight, - threshold: *threshold, + threshold: address.threshold, }); } }