mirror of
https://github.com/jwinterm/grin-wallet.git
synced 2026-10-17 07:11:36 +02:00
De-panic output_amounts(): fallible make-outputs parsing
OutputSelectionArgs::output_amounts() unwrap()'d the float parse of each make-outputs value, panicking on bad input via the API path (the CLI now validates earlier). Return Result instead; sum_output_amounts() propagates. num_custom_outputs() now counts CSV entries without parsing, so it stays infallible and the debug! macros that use it are unaffected.
This commit is contained in:
@@ -137,7 +137,7 @@ fn contract_self_spend_custom_tx_impl(test_dir: &'static str) -> Result<(), libw
|
||||
assert_eq!(
|
||||
commits[15].output.value,
|
||||
3 * consensus::REWARD
|
||||
- selection_args.sum_output_amounts()
|
||||
- selection_args.sum_output_amounts()?
|
||||
- my_fee_contribution(3, 6, 1, 1)?.fee()
|
||||
);
|
||||
Ok(())
|
||||
|
||||
@@ -92,7 +92,7 @@ where
|
||||
// Σmy_inputs >= Σmy_outputs + my_fee_cost
|
||||
// Each party later balances the equation by adding an additional output (change output or receiver output)
|
||||
let net_change = setup_args.net_change.unwrap();
|
||||
let custom_outputs_amount_sum = setup_args.selection_args.sum_output_amounts();
|
||||
let custom_outputs_amount_sum = setup_args.selection_args.sum_output_amounts()?;
|
||||
let pay_amount = if net_change < 0 {
|
||||
net_change.abs() as u64
|
||||
} else {
|
||||
@@ -260,7 +260,7 @@ fn build_output_amount_list(
|
||||
setup_args: &ContractSetupArgsAPI,
|
||||
) -> Result<Vec<u64>, Error> {
|
||||
let expected_net_change = setup_args.net_change.unwrap();
|
||||
let mut my_output_amounts = setup_args.selection_args.output_amounts();
|
||||
let mut my_output_amounts = setup_args.selection_args.output_amounts()?;
|
||||
let custom_outputs_sum = my_output_amounts.iter().sum::<u64>();
|
||||
// We know that `Σmy_inputs >= Σmy_outputs + my_fee_cost` holds so we balance the equation by adding
|
||||
// an additional output holding the missing amount (change output or receiver output)
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
|
||||
//! Types related to a contract
|
||||
|
||||
use crate::error::Error;
|
||||
use crate::grin_core::consensus;
|
||||
use crate::slate_versions::ser as dalek_ser;
|
||||
use ed25519_dalek::PublicKey as DalekPublicKey;
|
||||
@@ -49,25 +50,32 @@ impl OutputSelectionArgs {
|
||||
}
|
||||
}
|
||||
/// Returns the outputs we have to create
|
||||
pub fn output_amounts(&self) -> Vec<u64> {
|
||||
if self.make_outputs.is_some() {
|
||||
let output_amounts: Vec<u64> = self.make_outputs.as_ref().unwrap()[..]
|
||||
// TODO: move consensus code outside of here. Consider turning make_outputs to Vec<u64>
|
||||
pub fn output_amounts(&self) -> Result<Vec<u64>, Error> {
|
||||
match self.make_outputs.as_ref() {
|
||||
Some(s) => s
|
||||
.split(",")
|
||||
// TODO: move consensus code outside of here. Consider turning make_outputs to Vec<u64>
|
||||
.map(|amt| (amt.parse::<f64>().unwrap() * consensus::GRIN_BASE as f64) as u64)
|
||||
.collect();
|
||||
output_amounts
|
||||
} else {
|
||||
vec![]
|
||||
.map(|amt| {
|
||||
amt.parse::<f64>()
|
||||
.map(|g| (g * consensus::GRIN_BASE as f64) as u64)
|
||||
.map_err(|e| {
|
||||
Error::GenericError(format!("Invalid output amount '{}': {}", amt, e))
|
||||
})
|
||||
})
|
||||
.collect(),
|
||||
None => Ok(vec![]),
|
||||
}
|
||||
}
|
||||
/// Returns the sum of our output amounts
|
||||
pub fn sum_output_amounts(&self) -> u64 {
|
||||
self.output_amounts().iter().sum()
|
||||
pub fn sum_output_amounts(&self) -> Result<u64, Error> {
|
||||
Ok(self.output_amounts()?.iter().sum())
|
||||
}
|
||||
/// Returns the number of custom outputs
|
||||
/// Returns the number of custom outputs (count only; does not parse the amounts)
|
||||
pub fn num_custom_outputs(&self) -> usize {
|
||||
self.output_amounts().len()
|
||||
self.make_outputs
|
||||
.as_ref()
|
||||
.map(|s| s.split(",").count())
|
||||
.unwrap_or(0)
|
||||
}
|
||||
|
||||
// TODO: make sure to validate this: if custom outputs are specified, it has to be a payjoin.
|
||||
|
||||
Reference in New Issue
Block a user