Skip to content

Commit

Permalink
Made the ValueSum trait implementations more generic.
Browse files Browse the repository at this point in the history
  • Loading branch information
murisi committed May 21, 2024
1 parent 3f8d33b commit c62d4fe
Show file tree
Hide file tree
Showing 5 changed files with 87 additions and 97 deletions.
5 changes: 2 additions & 3 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 1 addition & 2 deletions masp_primitives/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,7 @@ sha2 = "0.10"
memuse = "0.2.1"

# - Checked arithmetic
num-traits = "0.2.14"
num-traits-decoupled = { package = "num-traits", version = "0.2.19", git = "https://github.com/heliaxdev/num-traits", rev = "e3e712fc4ecbf9d95399b0b98ee9f3d6b9973e38" }
num-traits = { version = "0.2.19", git = "https://github.com/heliaxdev/num-traits", rev = "3f3657caa34b8e116fdf3f8a3519c4ac29f012fe" }

# - Secret management
subtle = "2.2.3"
Expand Down
1 change: 1 addition & 0 deletions masp_primitives/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ pub use bls12_381;
pub use ff;
pub use group;
pub use jubjub;
pub use num_traits;

#[cfg(test)]
mod test_vectors;
171 changes: 81 additions & 90 deletions masp_primitives/src/transaction/components/amount.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use borsh::schema::Fields;
use borsh::schema::{Declaration, Definition};
use borsh::BorshSchema;
use borsh::{BorshDeserialize, BorshSerialize};
use num_traits_decoupled::{CheckedAdd, CheckedMul, CheckedNeg, CheckedSub, One};
use num_traits::{CheckedAdd, CheckedMul, CheckedNeg, CheckedSub, One};
use std::cmp::Ordering;
use std::collections::btree_map::Keys;
use std::collections::btree_map::{IntoIter, Iter};
Expand Down Expand Up @@ -412,177 +412,159 @@ impl_index!(i128);

impl_index!(u128);

impl<Unit, Value> MulAssign<Value> for ValueSum<Unit, Value>
impl<Unit, Lhs, Rhs> MulAssign<Rhs> for ValueSum<Unit, Lhs>
where
Unit: Hash + Ord + BorshSerialize + BorshDeserialize + Clone,
Value: BorshSerialize
Lhs: BorshSerialize
+ BorshDeserialize
+ PartialEq
+ Eq
+ Copy
+ Default
+ PartialOrd
+ CheckedMul<Output = Value>,
+ CheckedMul<Rhs, Output = Lhs>,
Rhs: Copy,
{
fn mul_assign(&mut self, rhs: Value) {
fn mul_assign(&mut self, rhs: Rhs) {
*self = self.clone() * rhs;
}
}

impl<Unit, Value> Mul<Value> for ValueSum<Unit, Value>
impl<Unit, Lhs, Rhs> Mul<Rhs> for ValueSum<Unit, Lhs>
where
Unit: Hash + Ord + BorshSerialize + BorshDeserialize + Clone,
Value: BorshSerialize
+ BorshDeserialize
+ PartialEq
+ Eq
+ Copy
+ Default
+ PartialOrd
+ CheckedMul,
<Value as CheckedMul>::Output : Default + BorshSerialize + BorshDeserialize + Eq,
Lhs: BorshSerialize + BorshDeserialize + PartialEq + Eq + Copy + Default + CheckedMul<Rhs>,
Rhs: Copy,
<Lhs as CheckedMul<Rhs>>::Output: Default + BorshSerialize + BorshDeserialize + Eq,
{
type Output = ValueSum<Unit, <Value as CheckedMul>::Output>;
type Output = ValueSum<Unit, <Lhs as CheckedMul<Rhs>>::Output>;

fn mul(self, rhs: Value) -> Self::Output {
fn mul(self, rhs: Rhs) -> Self::Output {
let mut comps = BTreeMap::new();
for (atype, amount) in self.0.iter() {
comps.insert(
atype.clone(),
amount.checked_mul(rhs).expect("overflow detected"),
);
}
comps.retain(|_, v| *v != <Value as CheckedMul>::Output::default());
comps.retain(|_, v| *v != <Lhs as CheckedMul<Rhs>>::Output::default());
ValueSum(comps)
}
}

impl<Unit, Value> AddAssign<&ValueSum<Unit, Value>> for ValueSum<Unit, Value>
impl<Unit, Lhs, Rhs> AddAssign<&ValueSum<Unit, Rhs>> for ValueSum<Unit, Lhs>
where
Unit: Hash + Ord + BorshSerialize + BorshDeserialize + Clone,
Value: BorshSerialize
Lhs: BorshSerialize
+ BorshDeserialize
+ PartialEq
+ Eq
+ Copy
+ Default
+ PartialOrd
+ CheckedAdd<Output = Value>,
+ CheckedAdd<Rhs, Output = Lhs>,
Rhs: BorshSerialize + BorshDeserialize + PartialEq + Eq + Copy + Default,
{
fn add_assign(&mut self, rhs: &ValueSum<Unit, Value>) {
fn add_assign(&mut self, rhs: &ValueSum<Unit, Rhs>) {
*self = self.clone() + rhs;
}
}

impl<Unit, Value> AddAssign<ValueSum<Unit, Value>> for ValueSum<Unit, Value>
impl<Unit, Lhs, Rhs> AddAssign<ValueSum<Unit, Rhs>> for ValueSum<Unit, Lhs>
where
Unit: Hash + Ord + BorshSerialize + BorshDeserialize + Clone,
Value: BorshSerialize
Lhs: BorshSerialize
+ BorshDeserialize
+ PartialEq
+ Eq
+ Copy
+ Default
+ PartialOrd
+ CheckedAdd<Output = Value>,
+ CheckedAdd<Rhs, Output = Lhs>,
Rhs: BorshSerialize + BorshDeserialize + PartialEq + Eq + Copy + Default,
{
fn add_assign(&mut self, rhs: ValueSum<Unit, Value>) {
fn add_assign(&mut self, rhs: ValueSum<Unit, Rhs>) {
*self += &rhs
}
}

impl<Unit, Value> Add<&ValueSum<Unit, Value>> for ValueSum<Unit, Value>
impl<Unit, Lhs, Rhs> Add<&ValueSum<Unit, Rhs>> for ValueSum<Unit, Lhs>
where
Unit: Hash + Ord + BorshSerialize + BorshDeserialize + Clone,
Value: BorshSerialize
+ BorshDeserialize
+ PartialEq
+ Eq
+ Copy
+ Default
+ PartialOrd
+ CheckedAdd<Output = Value>,
Lhs: BorshSerialize + BorshDeserialize + PartialEq + Eq + Copy + Default + CheckedAdd<Rhs>,
Rhs: BorshSerialize + BorshDeserialize + PartialEq + Eq + Copy + Default,
<Lhs as CheckedAdd<Rhs>>::Output: BorshSerialize + BorshDeserialize + Eq + Default,
{
type Output = ValueSum<Unit, Value>;
type Output = ValueSum<Unit, <Lhs as CheckedAdd<Rhs>>::Output>;

fn add(self, rhs: &ValueSum<Unit, Value>) -> Self::Output {
fn add(self, rhs: &ValueSum<Unit, Rhs>) -> Self::Output {
self.checked_add(rhs).expect("overflow detected")
}
}

impl<Unit, Value> Add<ValueSum<Unit, Value>> for ValueSum<Unit, Value>
impl<Unit, Lhs, Rhs> Add<ValueSum<Unit, Rhs>> for ValueSum<Unit, Lhs>
where
Unit: Hash + Ord + BorshSerialize + BorshDeserialize + Clone,
Value: BorshSerialize
+ BorshDeserialize
+ PartialEq
+ Eq
+ Copy
+ Default
+ PartialOrd
+ CheckedAdd<Output = Value>,
Lhs: BorshSerialize + BorshDeserialize + PartialEq + Eq + Copy + Default + CheckedAdd<Rhs>,
Rhs: BorshSerialize + BorshDeserialize + PartialEq + Eq + Copy + Default,
<Lhs as CheckedAdd<Rhs>>::Output: BorshSerialize + BorshDeserialize + Eq + Default,
{
type Output = ValueSum<Unit, Value>;
type Output = ValueSum<Unit, <Lhs as CheckedAdd<Rhs>>::Output>;

fn add(self, rhs: ValueSum<Unit, Value>) -> Self::Output {
fn add(self, rhs: ValueSum<Unit, Rhs>) -> Self::Output {
self + &rhs
}
}

impl<Unit, Value> CheckedAdd for &ValueSum<Unit, Value>
impl<Unit, Lhs, Rhs> CheckedAdd<&ValueSum<Unit, Rhs>> for &ValueSum<Unit, Lhs>
where
Unit: Hash + Ord + BorshSerialize + BorshDeserialize + Clone,
Value: BorshSerialize
+ BorshDeserialize
+ PartialEq
+ Eq
+ Copy
+ Default
+ PartialOrd
+ CheckedAdd<Output = Value>,
Lhs: BorshSerialize + BorshDeserialize + PartialEq + Eq + Copy + Default + CheckedAdd<Rhs>,
Rhs: BorshSerialize + BorshDeserialize + PartialEq + Eq + Copy + Default,
<Lhs as CheckedAdd<Rhs>>::Output: BorshSerialize + BorshDeserialize + Eq + Default,
{
type Output = ValueSum<Unit, Value>;

fn checked_add(self, v: Self) -> Option<Self::Output> {
let mut comps = self.0.clone();
type Output = ValueSum<Unit, <Lhs as CheckedAdd<Rhs>>::Output>;

fn checked_add(self, v: &ValueSum<Unit, Rhs>) -> Option<Self::Output> {
let mut comps = BTreeMap::new();
for (atype, amount) in self.components() {
comps.insert(atype.clone(), amount.checked_add(Rhs::default())?);
}
for (atype, amount) in v.components() {
comps.insert(atype.clone(), self.get(atype).checked_add(*amount)?);
}
comps.retain(|_, v| *v != Value::default());
comps.retain(|_, v| *v != <Lhs as CheckedAdd<Rhs>>::Output::default());
Some(ValueSum(comps))
}
}

impl<Unit, Value> SubAssign<&ValueSum<Unit, Value>> for ValueSum<Unit, Value>
impl<Unit, Lhs, Rhs> SubAssign<&ValueSum<Unit, Rhs>> for ValueSum<Unit, Lhs>
where
Unit: Hash + Ord + BorshSerialize + BorshDeserialize + Clone,
Value: BorshSerialize
Lhs: BorshSerialize
+ BorshDeserialize
+ PartialEq
+ Eq
+ Copy
+ Default
+ PartialOrd
+ CheckedSub<Output = Value>,
+ CheckedSub<Rhs, Output = Lhs>,
Rhs: BorshSerialize + BorshDeserialize + PartialEq + Eq + Copy + Default,
{
fn sub_assign(&mut self, rhs: &ValueSum<Unit, Value>) {
fn sub_assign(&mut self, rhs: &ValueSum<Unit, Rhs>) {
*self = self.clone() - rhs
}
}

impl<Unit, Value> SubAssign<ValueSum<Unit, Value>> for ValueSum<Unit, Value>
impl<Unit, Lhs, Rhs> SubAssign<ValueSum<Unit, Rhs>> for ValueSum<Unit, Lhs>
where
Unit: Hash + Ord + BorshSerialize + BorshDeserialize + Clone,
Value: BorshSerialize
Lhs: BorshSerialize
+ BorshDeserialize
+ PartialEq
+ Eq
+ Copy
+ Default
+ PartialOrd
+ CheckedSub<Output = Value>,
+ CheckedSub<Rhs, Output = Lhs>,
Rhs: BorshSerialize + BorshDeserialize + PartialEq + Eq + Copy + Default,
{
fn sub_assign(&mut self, rhs: ValueSum<Unit, Value>) {
fn sub_assign(&mut self, rhs: ValueSum<Unit, Rhs>) {
*self -= &rhs
}
}
Expand Down Expand Up @@ -615,43 +597,52 @@ where
}
}

impl<Unit, Value> Sub<&ValueSum<Unit, Value>> for ValueSum<Unit, Value>
impl<Unit, Lhs, Rhs> Sub<&ValueSum<Unit, Rhs>> for ValueSum<Unit, Lhs>
where
Unit: Hash + Ord + BorshSerialize + BorshDeserialize + Clone,
Value: BorshSerialize + BorshDeserialize + PartialEq + Eq + Copy + Default + CheckedSub<Output = Value>,
Lhs: BorshSerialize + BorshDeserialize + PartialEq + Eq + Copy + Default + CheckedSub<Rhs>,
Rhs: BorshSerialize + BorshDeserialize + PartialEq + Eq + Copy + Default,
<Lhs as CheckedSub<Rhs>>::Output: BorshSerialize + BorshDeserialize + Eq + Default,
{
type Output = ValueSum<Unit, Value>;
type Output = ValueSum<Unit, <Lhs as CheckedSub<Rhs>>::Output>;

fn sub(self, rhs: &ValueSum<Unit, Value>) -> Self::Output {
fn sub(self, rhs: &ValueSum<Unit, Rhs>) -> Self::Output {
self.checked_sub(rhs).expect("underflow detected")
}
}

impl<Unit, Value> Sub<ValueSum<Unit, Value>> for ValueSum<Unit, Value>
impl<Unit, Lhs, Rhs> Sub<ValueSum<Unit, Rhs>> for ValueSum<Unit, Lhs>
where
Unit: Hash + Ord + BorshSerialize + BorshDeserialize + Clone,
Value: BorshSerialize + BorshDeserialize + PartialEq + Eq + Copy + Default + CheckedSub<Output = Value>,
Lhs: BorshSerialize + BorshDeserialize + PartialEq + Eq + Copy + Default + CheckedSub<Rhs>,
Rhs: BorshSerialize + BorshDeserialize + PartialEq + Eq + Copy + Default,
<Lhs as CheckedSub<Rhs>>::Output: BorshSerialize + BorshDeserialize + Eq + Default,
{
type Output = ValueSum<Unit, Value>;
type Output = ValueSum<Unit, <Lhs as CheckedSub<Rhs>>::Output>;

fn sub(self, rhs: ValueSum<Unit, Value>) -> Self::Output {
fn sub(self, rhs: ValueSum<Unit, Rhs>) -> Self::Output {
self - &rhs
}
}

impl<Unit, Value> CheckedSub for &ValueSum<Unit, Value>
impl<Unit, Lhs, Rhs> CheckedSub<&ValueSum<Unit, Rhs>> for &ValueSum<Unit, Lhs>
where
Unit: Hash + Ord + BorshSerialize + BorshDeserialize + Clone,
Value: BorshSerialize + BorshDeserialize + PartialEq + Eq + Copy + Default + CheckedSub<Output = Value>,
Lhs: BorshSerialize + BorshDeserialize + PartialEq + Eq + Copy + Default + CheckedSub<Rhs>,
Rhs: BorshSerialize + BorshDeserialize + PartialEq + Eq + Copy + Default,
<Lhs as CheckedSub<Rhs>>::Output: BorshSerialize + BorshDeserialize + Eq + Default,
{
type Output = ValueSum<Unit, Value>;

fn checked_sub(self, v: Self) -> Option<Self::Output> {
let mut comps = self.0.clone();
type Output = ValueSum<Unit, <Lhs as CheckedSub<Rhs>>::Output>;

fn checked_sub(self, v: &ValueSum<Unit, Rhs>) -> Option<Self::Output> {
let mut comps = BTreeMap::new();
for (atype, amount) in self.components() {
comps.insert(atype.clone(), amount.checked_sub(Rhs::default())?);
}
for (atype, amount) in v.components() {
comps.insert(atype.clone(), self.get(atype).checked_sub(*amount)?);
}
comps.retain(|_, v| *v != Value::default());
comps.retain(|_, v| *v != <Lhs as CheckedSub<Rhs>>::Output::default());
Some(ValueSum(comps))
}
}
Expand Down
4 changes: 2 additions & 2 deletions masp_primitives/src/transaction/components/sapling/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -652,7 +652,7 @@ impl<P: consensus::Parameters> SaplingBuilder<P> {
self.spend_anchor = Some(merkle_path.root(node).into())
}

self.value_balance += ValueSum::from_pair(note.asset_type, note.value.into());
self.value_balance += ValueSum::from_pair(note.asset_type, i128::from(note.value));

self.spends.push(SpendDescriptionInfo {
extsk,
Expand Down Expand Up @@ -710,7 +710,7 @@ impl<P: consensus::Parameters> SaplingBuilder<P> {
) -> Result<(), Error> {
let output = SaplingOutputInfo::new_internal(ovk, to, asset_type, value, memo)?;

self.value_balance -= ValueSum::from_pair(asset_type, value.into());
self.value_balance -= ValueSum::from_pair(asset_type, i128::from(value));

self.outputs.push(output);

Expand Down

0 comments on commit c62d4fe

Please sign in to comment.