diff --git a/Cargo.lock b/Cargo.lock index eb6072d4..6fab48aa 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -436,7 +436,7 @@ dependencies = [ "criterion-plot", "itertools 0.10.5", "lazy_static", - "num-traits", + "num-traits 0.2.19 (registry+https://github.com/rust-lang/crates.io-index)", "oorandom", "plotters", "rayon", @@ -617,7 +617,7 @@ dependencies = [ "libm", "num-bigint", "num-integer", - "num-traits", + "num-traits 0.2.19 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -920,7 +920,7 @@ dependencies = [ "masp_note_encryption", "memuse", "nonempty", - "num-traits", + "num-traits 0.2.19 (git+https://github.com/heliaxdev/num-traits?rev=3f3657caa34b8e116fdf3f8a3519c4ac29f012fe)", "proptest", "rand", "rand_core", @@ -1021,7 +1021,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c165a9ab64cf766f73521c0dd2cfdff64f488b8f0b3e621face3462d3db536d7" dependencies = [ "num-integer", - "num-traits", + "num-traits 0.2.19 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1040,7 +1040,7 @@ version = "0.1.46" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" dependencies = [ - "num-traits", + "num-traits 0.2.19 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1053,6 +1053,14 @@ dependencies = [ "libm", ] +[[package]] +name = "num-traits" +version = "0.2.19" +source = "git+https://github.com/heliaxdev/num-traits?rev=3f3657caa34b8e116fdf3f8a3519c4ac29f012fe#3f3657caa34b8e116fdf3f8a3519c4ac29f012fe" +dependencies = [ + "autocfg", +] + [[package]] name = "num_cpus" version = "1.16.0" @@ -1174,7 +1182,7 @@ version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d2c224ba00d7cadd4d5c660deaf2098e5e80e07846537c51f9cfa4be50c1fd45" dependencies = [ - "num-traits", + "num-traits 0.2.19 (registry+https://github.com/rust-lang/crates.io-index)", "plotters-backend", "plotters-svg", "wasm-bindgen", @@ -1286,7 +1294,7 @@ dependencies = [ "bit-vec", "bitflags 2.5.0", "lazy_static", - "num-traits", + "num-traits 0.2.19 (registry+https://github.com/rust-lang/crates.io-index)", "rand", "rand_chacha", "rand_xorshift", diff --git a/masp_primitives/Cargo.toml b/masp_primitives/Cargo.toml index e78dbf41..1c696803 100644 --- a/masp_primitives/Cargo.toml +++ b/masp_primitives/Cargo.toml @@ -37,7 +37,7 @@ sha2 = "0.10" memuse = "0.2.1" # - Checked arithmetic -num-traits = "0.2.14" +num-traits = { version = "0.2.19", git = "https://github.com/heliaxdev/num-traits", rev = "3f3657caa34b8e116fdf3f8a3519c4ac29f012fe" } # - Secret management subtle = "2.2.3" diff --git a/masp_primitives/src/lib.rs b/masp_primitives/src/lib.rs index 308e9323..07765909 100644 --- a/masp_primitives/src/lib.rs +++ b/masp_primitives/src/lib.rs @@ -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; diff --git a/masp_primitives/src/transaction/components/amount.rs b/masp_primitives/src/transaction/components/amount.rs index cf9888ae..3ed1141d 100644 --- a/masp_primitives/src/transaction/components/amount.rs +++ b/masp_primitives/src/transaction/components/amount.rs @@ -412,174 +412,159 @@ impl_index!(i128); impl_index!(u128); -impl MulAssign for ValueSum +impl MulAssign for ValueSum where Unit: Hash + Ord + BorshSerialize + BorshDeserialize + Clone, - Value: BorshSerialize + Lhs: BorshSerialize + BorshDeserialize + PartialEq + Eq + Copy + Default - + PartialOrd - + CheckedMul, + + CheckedMul, + Rhs: Copy, { - fn mul_assign(&mut self, rhs: Value) { + fn mul_assign(&mut self, rhs: Rhs) { *self = self.clone() * rhs; } } -impl Mul for ValueSum +impl Mul for ValueSum where Unit: Hash + Ord + BorshSerialize + BorshDeserialize + Clone, - Value: BorshSerialize - + BorshDeserialize - + PartialEq - + Eq - + Copy - + Default - + PartialOrd - + CheckedMul, + Lhs: BorshSerialize + BorshDeserialize + PartialEq + Eq + Copy + Default + CheckedMul, + Rhs: Copy, + >::Output: Default + BorshSerialize + BorshDeserialize + Eq, { - type Output = ValueSum; + type Output = ValueSum>::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"), + amount.checked_mul(rhs).expect("overflow detected"), ); } - comps.retain(|_, v| *v != Value::default()); + comps.retain(|_, v| *v != >::Output::default()); ValueSum(comps) } } -impl AddAssign<&ValueSum> for ValueSum +impl AddAssign<&ValueSum> for ValueSum where Unit: Hash + Ord + BorshSerialize + BorshDeserialize + Clone, - Value: BorshSerialize + Lhs: BorshSerialize + BorshDeserialize + PartialEq + Eq + Copy + Default - + PartialOrd - + CheckedAdd, + + CheckedAdd, + Rhs: BorshSerialize + BorshDeserialize + PartialEq + Eq + Copy + Default, { - fn add_assign(&mut self, rhs: &ValueSum) { + fn add_assign(&mut self, rhs: &ValueSum) { *self = self.clone() + rhs; } } -impl AddAssign> for ValueSum +impl AddAssign> for ValueSum where Unit: Hash + Ord + BorshSerialize + BorshDeserialize + Clone, - Value: BorshSerialize + Lhs: BorshSerialize + BorshDeserialize + PartialEq + Eq + Copy + Default - + PartialOrd - + CheckedAdd, + + CheckedAdd, + Rhs: BorshSerialize + BorshDeserialize + PartialEq + Eq + Copy + Default, { - fn add_assign(&mut self, rhs: ValueSum) { + fn add_assign(&mut self, rhs: ValueSum) { *self += &rhs } } -impl Add<&ValueSum> for ValueSum +impl Add<&ValueSum> for ValueSum where Unit: Hash + Ord + BorshSerialize + BorshDeserialize + Clone, - Value: BorshSerialize - + BorshDeserialize - + PartialEq - + Eq - + Copy - + Default - + PartialOrd - + CheckedAdd, + Lhs: BorshSerialize + BorshDeserialize + PartialEq + Eq + Copy + Default + CheckedAdd, + Rhs: BorshSerialize + BorshDeserialize + PartialEq + Eq + Copy + Default, + >::Output: BorshSerialize + BorshDeserialize + Eq + Default, { - type Output = ValueSum; + type Output = ValueSum>::Output>; - fn add(self, rhs: &ValueSum) -> Self::Output { + fn add(self, rhs: &ValueSum) -> Self::Output { self.checked_add(rhs).expect("overflow detected") } } -impl Add> for ValueSum +impl Add> for ValueSum where Unit: Hash + Ord + BorshSerialize + BorshDeserialize + Clone, - Value: BorshSerialize - + BorshDeserialize - + PartialEq - + Eq - + Copy - + Default - + PartialOrd - + CheckedAdd, + Lhs: BorshSerialize + BorshDeserialize + PartialEq + Eq + Copy + Default + CheckedAdd, + Rhs: BorshSerialize + BorshDeserialize + PartialEq + Eq + Copy + Default, + >::Output: BorshSerialize + BorshDeserialize + Eq + Default, { - type Output = ValueSum; + type Output = ValueSum>::Output>; - fn add(self, rhs: ValueSum) -> Self::Output { + fn add(self, rhs: ValueSum) -> Self::Output { self + &rhs } } -impl CheckedAdd for ValueSum +impl CheckedAdd<&ValueSum> for &ValueSum where Unit: Hash + Ord + BorshSerialize + BorshDeserialize + Clone, - Value: BorshSerialize - + BorshDeserialize - + PartialEq - + Eq - + Copy - + Default - + PartialOrd - + CheckedAdd, + Lhs: BorshSerialize + BorshDeserialize + PartialEq + Eq + Copy + Default + CheckedAdd, + Rhs: BorshSerialize + BorshDeserialize + PartialEq + Eq + Copy + Default, + >::Output: BorshSerialize + BorshDeserialize + Eq + Default, { - fn checked_add(&self, v: &Self) -> Option { - let mut comps = self.0.clone(); + type Output = ValueSum>::Output>; + + fn checked_add(self, v: &ValueSum) -> Option { + 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.insert(atype.clone(), self.get(atype).checked_add(*amount)?); } - comps.retain(|_, v| *v != Value::default()); + comps.retain(|_, v| *v != >::Output::default()); Some(ValueSum(comps)) } } -impl SubAssign<&ValueSum> for ValueSum +impl SubAssign<&ValueSum> for ValueSum where Unit: Hash + Ord + BorshSerialize + BorshDeserialize + Clone, - Value: BorshSerialize + Lhs: BorshSerialize + BorshDeserialize + PartialEq + Eq + Copy + Default - + PartialOrd - + CheckedSub, + + CheckedSub, + Rhs: BorshSerialize + BorshDeserialize + PartialEq + Eq + Copy + Default, { - fn sub_assign(&mut self, rhs: &ValueSum) { + fn sub_assign(&mut self, rhs: &ValueSum) { *self = self.clone() - rhs } } -impl SubAssign> for ValueSum +impl SubAssign> for ValueSum where Unit: Hash + Ord + BorshSerialize + BorshDeserialize + Clone, - Value: BorshSerialize + Lhs: BorshSerialize + BorshDeserialize + PartialEq + Eq + Copy + Default - + PartialOrd - + CheckedSub, + + CheckedSub, + Rhs: BorshSerialize + BorshDeserialize + PartialEq + Eq + Copy + Default, { - fn sub_assign(&mut self, rhs: ValueSum) { + fn sub_assign(&mut self, rhs: ValueSum) { *self -= &rhs } } @@ -595,8 +580,9 @@ where + Default + PartialOrd + CheckedNeg, + ::Output: BorshSerialize + BorshDeserialize + Eq + Default, { - type Output = ValueSum; + type Output = ValueSum::Output>; fn neg(mut self) -> Self::Output { let mut comps = BTreeMap::new(); @@ -606,46 +592,57 @@ where amount.checked_neg().expect("overflow detected"), ); } - comps.retain(|_, v| *v != Value::default()); + comps.retain(|_, v| *v != ::Output::default()); ValueSum(comps) } } -impl Sub<&ValueSum> for ValueSum +impl Sub<&ValueSum> for ValueSum where Unit: Hash + Ord + BorshSerialize + BorshDeserialize + Clone, - Value: BorshSerialize + BorshDeserialize + PartialEq + Eq + Copy + Default + CheckedSub, + Lhs: BorshSerialize + BorshDeserialize + PartialEq + Eq + Copy + Default + CheckedSub, + Rhs: BorshSerialize + BorshDeserialize + PartialEq + Eq + Copy + Default, + >::Output: BorshSerialize + BorshDeserialize + Eq + Default, { - type Output = ValueSum; + type Output = ValueSum>::Output>; - fn sub(self, rhs: &ValueSum) -> Self::Output { + fn sub(self, rhs: &ValueSum) -> Self::Output { self.checked_sub(rhs).expect("underflow detected") } } -impl Sub> for ValueSum +impl Sub> for ValueSum where Unit: Hash + Ord + BorshSerialize + BorshDeserialize + Clone, - Value: BorshSerialize + BorshDeserialize + PartialEq + Eq + Copy + Default + CheckedSub, + Lhs: BorshSerialize + BorshDeserialize + PartialEq + Eq + Copy + Default + CheckedSub, + Rhs: BorshSerialize + BorshDeserialize + PartialEq + Eq + Copy + Default, + >::Output: BorshSerialize + BorshDeserialize + Eq + Default, { - type Output = ValueSum; + type Output = ValueSum>::Output>; - fn sub(self, rhs: ValueSum) -> Self::Output { + fn sub(self, rhs: ValueSum) -> Self::Output { self - &rhs } } -impl CheckedSub for ValueSum +impl CheckedSub<&ValueSum> for &ValueSum where Unit: Hash + Ord + BorshSerialize + BorshDeserialize + Clone, - Value: BorshSerialize + BorshDeserialize + PartialEq + Eq + Copy + Default + CheckedSub, + Lhs: BorshSerialize + BorshDeserialize + PartialEq + Eq + Copy + Default + CheckedSub, + Rhs: BorshSerialize + BorshDeserialize + PartialEq + Eq + Copy + Default, + >::Output: BorshSerialize + BorshDeserialize + Eq + Default, { - fn checked_sub(&self, v: &Self) -> Option { - let mut comps = self.0.clone(); + type Output = ValueSum>::Output>; + + fn checked_sub(self, v: &ValueSum) -> Option { + 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.insert(atype.clone(), self.get(atype).checked_sub(*amount)?); } - comps.retain(|_, v| *v != Value::default()); + comps.retain(|_, v| *v != >::Output::default()); Some(ValueSum(comps)) } } diff --git a/masp_primitives/src/transaction/components/sapling/builder.rs b/masp_primitives/src/transaction/components/sapling/builder.rs index df4a2b03..eb150197 100644 --- a/masp_primitives/src/transaction/components/sapling/builder.rs +++ b/masp_primitives/src/transaction/components/sapling/builder.rs @@ -652,7 +652,7 @@ impl SaplingBuilder

{ 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, @@ -710,7 +710,7 @@ impl SaplingBuilder

{ ) -> 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);