8 remove all unwrap (#9)
* Remove all unwraps from sending * Remove unwraps from receiving * Move Result type to utils
This commit is contained in:
parent
a7001e4a3d
commit
ad2c5b0e72
|
@ -1,4 +1,4 @@
|
|||
#![allow(non_snake_case, dead_code)]
|
||||
#![allow(non_snake_case)]
|
||||
pub mod receiving;
|
||||
pub mod sending;
|
||||
pub mod structs;
|
||||
|
|
111
src/receiving.rs
111
src/receiving.rs
|
@ -5,40 +5,31 @@ use std::{collections::HashMap, str::FromStr};
|
|||
|
||||
use crate::{
|
||||
structs::{OutputWithSignature, ScannedOutput},
|
||||
utils::ser_uint32,
|
||||
utils::{ser_uint32, Result},
|
||||
};
|
||||
|
||||
pub fn get_receiving_addresses(
|
||||
B_scan: PublicKey,
|
||||
B_spend: PublicKey,
|
||||
labels: &HashMap<String, String>,
|
||||
) -> Vec<String> {
|
||||
) -> Result<Vec<String>> {
|
||||
let mut receiving_addresses: Vec<String> = vec![];
|
||||
receiving_addresses.push(encode_silent_payment_address(B_scan, B_spend, None, None));
|
||||
receiving_addresses.push(encode_silent_payment_address(B_scan, B_spend, None, None)?);
|
||||
for (_, label) in labels {
|
||||
receiving_addresses.push(create_labeled_silent_payment_address(
|
||||
B_scan, B_spend, label, None, None,
|
||||
));
|
||||
)?);
|
||||
}
|
||||
|
||||
receiving_addresses
|
||||
Ok(receiving_addresses)
|
||||
}
|
||||
|
||||
pub fn get_A_sum_public_keys(input: &Vec<String>) -> PublicKey {
|
||||
let keys: Vec<PublicKey> = input
|
||||
.iter()
|
||||
.map(|x| match PublicKey::from_str(&x) {
|
||||
Ok(key) => key,
|
||||
Err(_) => {
|
||||
// we always assume even pairing for input public keys if they are omitted
|
||||
let x_only_public_key = XOnlyPublicKey::from_str(&x).unwrap();
|
||||
PublicKey::from_x_only_public_key(x_only_public_key, secp256k1::Parity::Even)
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
let keys_refs: Vec<&PublicKey> = keys.iter().collect();
|
||||
pub fn get_A_sum_public_keys(
|
||||
input: &Vec<PublicKey>,
|
||||
) -> std::result::Result<PublicKey, secp256k1::Error> {
|
||||
let keys_refs: &Vec<&PublicKey> = &input.iter().collect();
|
||||
|
||||
PublicKey::combine_keys(&keys_refs).unwrap()
|
||||
PublicKey::combine_keys(keys_refs)
|
||||
}
|
||||
|
||||
fn encode_silent_payment_address(
|
||||
|
@ -46,9 +37,9 @@ fn encode_silent_payment_address(
|
|||
B_m: PublicKey,
|
||||
hrp: Option<&str>,
|
||||
version: Option<u8>,
|
||||
) -> String {
|
||||
) -> Result<String> {
|
||||
let hrp = hrp.unwrap_or("sp");
|
||||
let version = bech32::u5::try_from_u8(version.unwrap_or(0)).unwrap();
|
||||
let version = bech32::u5::try_from_u8(version.unwrap_or(0))?;
|
||||
|
||||
let B_scan_bytes = B_scan.serialize();
|
||||
let B_m_bytes = B_m.serialize();
|
||||
|
@ -57,7 +48,7 @@ fn encode_silent_payment_address(
|
|||
|
||||
data.insert(0, version);
|
||||
|
||||
bech32::encode(hrp, data, bech32::Variant::Bech32m).unwrap()
|
||||
Ok(bech32::encode(hrp, data, bech32::Variant::Bech32m)?)
|
||||
}
|
||||
|
||||
fn create_labeled_silent_payment_address(
|
||||
|
@ -66,32 +57,26 @@ fn create_labeled_silent_payment_address(
|
|||
m: &String,
|
||||
hrp: Option<&str>,
|
||||
version: Option<u8>,
|
||||
) -> String {
|
||||
let bytes = hex::decode(m).unwrap().try_into().unwrap();
|
||||
) -> Result<String> {
|
||||
let bytes: [u8; 32] = hex::decode(m)?.as_slice().try_into()?;
|
||||
|
||||
let scalar = Scalar::from_be_bytes(bytes).unwrap();
|
||||
let scalar = Scalar::from_be_bytes(bytes)?;
|
||||
let secp = Secp256k1::new();
|
||||
let G: PublicKey = SecretKey::from_slice(&Scalar::ONE.to_be_bytes())
|
||||
.unwrap()
|
||||
.public_key(&secp);
|
||||
let intermediate = G.mul_tweak(&secp, &scalar).unwrap();
|
||||
let B_m = intermediate.combine(&B_spend).unwrap();
|
||||
let G: PublicKey = SecretKey::from_slice(&Scalar::ONE.to_be_bytes())?.public_key(&secp);
|
||||
let intermediate = G.mul_tweak(&secp, &scalar)?;
|
||||
let B_m = intermediate.combine(&B_spend)?;
|
||||
|
||||
encode_silent_payment_address(B_scan, B_m, hrp, version)
|
||||
}
|
||||
|
||||
fn calculate_P_n(B_spend: &PublicKey, t_n: [u8; 32]) -> PublicKey {
|
||||
fn calculate_P_n(B_spend: &PublicKey, t_n: [u8; 32]) -> Result<PublicKey> {
|
||||
let secp = Secp256k1::new();
|
||||
|
||||
let G: PublicKey = SecretKey::from_slice(&Scalar::ONE.to_be_bytes())
|
||||
.unwrap()
|
||||
.public_key(&secp);
|
||||
let intermediate = G
|
||||
.mul_tweak(&secp, &Scalar::from_be_bytes(t_n).unwrap())
|
||||
.unwrap();
|
||||
let P_n = intermediate.combine(&B_spend).unwrap();
|
||||
let G: PublicKey = SecretKey::from_slice(&Scalar::ONE.to_be_bytes())?.public_key(&secp);
|
||||
let intermediate = G.mul_tweak(&secp, &Scalar::from_be_bytes(t_n)?)?;
|
||||
let P_n = intermediate.combine(&B_spend)?;
|
||||
|
||||
P_n
|
||||
Ok(P_n)
|
||||
}
|
||||
|
||||
fn calculate_t_n(ecdh_shared_secret: &[u8; 33], n: u32) -> [u8; 32] {
|
||||
|
@ -105,14 +90,14 @@ fn calculate_ecdh_secret(
|
|||
A_sum: &PublicKey,
|
||||
b_scan: SecretKey,
|
||||
outpoints_hash: [u8; 32],
|
||||
) -> [u8; 33] {
|
||||
) -> Result<[u8; 33]> {
|
||||
let secp = Secp256k1::new();
|
||||
|
||||
let intermediate = A_sum.mul_tweak(&secp, &b_scan.into()).unwrap();
|
||||
let scalar = Scalar::from_be_bytes(outpoints_hash).unwrap();
|
||||
let ecdh_shared_secret = intermediate.mul_tweak(&secp, &scalar).unwrap().serialize();
|
||||
let intermediate = A_sum.mul_tweak(&secp, &b_scan.into())?;
|
||||
let scalar = Scalar::from_be_bytes(outpoints_hash)?;
|
||||
let ecdh_shared_secret = intermediate.mul_tweak(&secp, &scalar)?.serialize();
|
||||
|
||||
ecdh_shared_secret
|
||||
Ok(ecdh_shared_secret)
|
||||
}
|
||||
|
||||
pub fn scanning(
|
||||
|
@ -122,9 +107,9 @@ pub fn scanning(
|
|||
outpoints_hash: [u8; 32],
|
||||
outputs_to_check: Vec<XOnlyPublicKey>,
|
||||
labels: Option<&HashMap<String, String>>,
|
||||
) -> Vec<ScannedOutput> {
|
||||
) -> Result<Vec<ScannedOutput>> {
|
||||
let secp = secp256k1::Secp256k1::new();
|
||||
let ecdh_shared_secret = calculate_ecdh_secret(&A_sum, b_scan, outpoints_hash);
|
||||
let ecdh_shared_secret = calculate_ecdh_secret(&A_sum, b_scan, outpoints_hash)?;
|
||||
let mut n = 0;
|
||||
let mut wallet: Vec<ScannedOutput> = vec![];
|
||||
|
||||
|
@ -132,7 +117,7 @@ pub fn scanning(
|
|||
while found {
|
||||
found = false;
|
||||
let t_n = calculate_t_n(&ecdh_shared_secret, n);
|
||||
let P_n = calculate_P_n(&B_spend, t_n);
|
||||
let P_n = calculate_P_n(&B_spend, t_n)?;
|
||||
let (P_n_xonly, _) = P_n.x_only_public_key();
|
||||
if outputs_to_check.iter().any(|&output| output.eq(&P_n_xonly)) {
|
||||
let pub_key = hex::encode(P_n_xonly.serialize());
|
||||
|
@ -149,23 +134,19 @@ pub fn scanning(
|
|||
let output_even = output.public_key(secp256k1::Parity::Even);
|
||||
let output_odd = output.public_key(secp256k1::Parity::Odd);
|
||||
|
||||
let m_G_sub_even = output_even.combine(&P_n_negated).unwrap();
|
||||
let m_G_sub_odd = output_odd.combine(&P_n_negated).unwrap();
|
||||
let m_G_sub_even = output_even.combine(&P_n_negated)?;
|
||||
let m_G_sub_odd = output_odd.combine(&P_n_negated)?;
|
||||
let keys: Vec<PublicKey> = vec![m_G_sub_even, m_G_sub_odd];
|
||||
for labelkeystr in labels.keys() {
|
||||
let labelkey = PublicKey::from_str(labelkeystr).unwrap();
|
||||
let labelkey = PublicKey::from_str(labelkeystr)?;
|
||||
if keys.iter().any(|x| x.eq(&labelkey)) {
|
||||
let P_nm = hex::encode(output.serialize());
|
||||
let label = labels.get(labelkeystr).unwrap();
|
||||
let label_bytes = hex::decode(label).unwrap().try_into().unwrap();
|
||||
let label_scalar = Scalar::from_be_bytes(label_bytes).unwrap();
|
||||
let t_n_as_secret_key = SecretKey::from_slice(&t_n).unwrap();
|
||||
let priv_key_tweak = hex::encode(
|
||||
t_n_as_secret_key
|
||||
.add_tweak(&label_scalar)
|
||||
.unwrap()
|
||||
.secret_bytes(),
|
||||
);
|
||||
let label_bytes = hex::decode(label)?.as_slice().try_into()?;
|
||||
let label_scalar = Scalar::from_be_bytes(label_bytes)?;
|
||||
let t_n_as_secret_key = SecretKey::from_slice(&t_n)?;
|
||||
let priv_key_tweak =
|
||||
hex::encode(t_n_as_secret_key.add_tweak(&label_scalar)?.secret_bytes());
|
||||
wallet.push(ScannedOutput {
|
||||
pub_key: P_nm,
|
||||
priv_key_tweak,
|
||||
|
@ -177,23 +158,23 @@ pub fn scanning(
|
|||
}
|
||||
}
|
||||
}
|
||||
wallet
|
||||
Ok(wallet)
|
||||
}
|
||||
|
||||
pub fn verify_and_calculate_signatures(
|
||||
add_to_wallet: &mut Vec<ScannedOutput>,
|
||||
b_spend: SecretKey,
|
||||
) -> Result<Vec<OutputWithSignature>, secp256k1::Error> {
|
||||
) -> Result<Vec<OutputWithSignature>> {
|
||||
let secp = secp256k1::Secp256k1::new();
|
||||
let msg = Message::from_hashed_data::<secp256k1::hashes::sha256::Hash>(b"message");
|
||||
let aux = secp256k1::hashes::sha256::Hash::hash(b"random auxiliary data").to_byte_array();
|
||||
|
||||
let mut res: Vec<OutputWithSignature> = vec![];
|
||||
for output in add_to_wallet {
|
||||
let pubkey = XOnlyPublicKey::from_str(&output.pub_key).unwrap();
|
||||
let tweak = hex::decode(&output.priv_key_tweak).unwrap();
|
||||
let scalar = Scalar::from_be_bytes(tweak.try_into().unwrap()).unwrap();
|
||||
let mut full_priv_key = b_spend.add_tweak(&scalar).unwrap();
|
||||
let pubkey = XOnlyPublicKey::from_str(&output.pub_key)?;
|
||||
let tweak: [u8; 32] = hex::decode(&output.priv_key_tweak)?.as_slice().try_into()?;
|
||||
let scalar = Scalar::from_be_bytes(tweak)?;
|
||||
let mut full_priv_key = b_spend.add_tweak(&scalar)?;
|
||||
|
||||
let (_, parity) = full_priv_key.x_only_public_key(&secp);
|
||||
|
||||
|
|
|
@ -1,66 +1,64 @@
|
|||
use bech32::FromBase32;
|
||||
|
||||
use secp256k1::{Parity, PublicKey, Scalar, Secp256k1, SecretKey};
|
||||
use std::{collections::HashMap, str::FromStr};
|
||||
use std::collections::HashMap;
|
||||
|
||||
use crate::utils::{hash_outpoints, ser_uint32, sha256};
|
||||
use crate::utils::{hash_outpoints, ser_uint32, sha256, Result};
|
||||
|
||||
fn get_a_sum_secret_keys(input: &Vec<(String, bool)>) -> SecretKey {
|
||||
fn get_a_sum_secret_keys(input: &Vec<(SecretKey, bool)>) -> Result<SecretKey> {
|
||||
let secp = Secp256k1::new();
|
||||
|
||||
let mut negated_keys: Vec<SecretKey> = vec![];
|
||||
|
||||
for (keystr, is_xonly) in input {
|
||||
let key = SecretKey::from_str(&keystr).unwrap();
|
||||
for (key, x_only) in input {
|
||||
let (_, parity) = key.x_only_public_key(&secp);
|
||||
|
||||
if *is_xonly && parity == Parity::Odd {
|
||||
if *x_only && parity == Parity::Odd {
|
||||
negated_keys.push(key.negate());
|
||||
} else {
|
||||
negated_keys.push(key);
|
||||
negated_keys.push(*key);
|
||||
}
|
||||
}
|
||||
|
||||
let (head, tail) = negated_keys.split_first().unwrap();
|
||||
let (head, tail) = negated_keys.split_first().ok_or("Empty input list")?;
|
||||
|
||||
let result: SecretKey = tail
|
||||
let result: Result<SecretKey> = tail
|
||||
.iter()
|
||||
.fold(*head, |acc, &item| acc.add_tweak(&item.into()).unwrap());
|
||||
.fold(Ok(*head), |acc: Result<SecretKey>, &item| {
|
||||
Ok(acc?.add_tweak(&item.into())?)
|
||||
});
|
||||
|
||||
result
|
||||
}
|
||||
|
||||
fn decode_silent_payment_address(addr: &str) -> (PublicKey, PublicKey) {
|
||||
let (_hrp, data, _variant) = bech32::decode(&addr).unwrap();
|
||||
fn decode_silent_payment_address(addr: &str) -> Result<(PublicKey, PublicKey)> {
|
||||
let (_hrp, data, _variant) = bech32::decode(&addr)?;
|
||||
|
||||
let data = Vec::<u8>::from_base32(&data[1..]).unwrap();
|
||||
let data = Vec::<u8>::from_base32(&data[1..])?;
|
||||
|
||||
let B_scan = PublicKey::from_slice(&data[..33]).unwrap();
|
||||
let B_spend = PublicKey::from_slice(&data[33..]).unwrap();
|
||||
let B_scan = PublicKey::from_slice(&data[..33])?;
|
||||
let B_spend = PublicKey::from_slice(&data[33..])?;
|
||||
|
||||
(B_scan, B_spend)
|
||||
Ok((B_scan, B_spend))
|
||||
}
|
||||
|
||||
pub fn create_outputs(
|
||||
outpoints: &Vec<(String, u32)>,
|
||||
input_priv_keys: &Vec<(String, bool)>,
|
||||
input_priv_keys: &Vec<(SecretKey, bool)>,
|
||||
recipients: &Vec<(String, f32)>,
|
||||
) -> Vec<HashMap<String, f32>> {
|
||||
) -> Result<Vec<HashMap<String, f32>>> {
|
||||
let secp = Secp256k1::new();
|
||||
|
||||
let outpoints_hash = hash_outpoints(outpoints);
|
||||
let outpoints_hash = hash_outpoints(outpoints)?;
|
||||
|
||||
let a_sum = get_a_sum_secret_keys(input_priv_keys);
|
||||
let a_sum = get_a_sum_secret_keys(input_priv_keys)?;
|
||||
|
||||
let mut silent_payment_groups: HashMap<PublicKey, Vec<(PublicKey, f32)>> = HashMap::new();
|
||||
for (payment_address, amount) in recipients {
|
||||
let (B_scan, B_m) = decode_silent_payment_address(&payment_address);
|
||||
let (B_scan, B_m) = decode_silent_payment_address(&payment_address)?;
|
||||
|
||||
if silent_payment_groups.contains_key(&B_scan) {
|
||||
silent_payment_groups
|
||||
.get_mut(&B_scan)
|
||||
.unwrap()
|
||||
.push((B_m, *amount));
|
||||
if let Some(payments) = silent_payment_groups.get_mut(&B_scan) {
|
||||
payments.push((B_m, *amount));
|
||||
} else {
|
||||
silent_payment_groups.insert(B_scan, vec![(B_m, *amount)]);
|
||||
}
|
||||
|
@ -71,9 +69,9 @@ pub fn create_outputs(
|
|||
let mut n = 0;
|
||||
|
||||
//calculate shared secret
|
||||
let intermediate = B_scan.mul_tweak(&secp, &a_sum.into()).unwrap();
|
||||
let scalar = Scalar::from_be_bytes(outpoints_hash).unwrap();
|
||||
let ecdh_shared_secret = intermediate.mul_tweak(&secp, &scalar).unwrap().serialize();
|
||||
let intermediate = B_scan.mul_tweak(&secp, &a_sum.into())?;
|
||||
let scalar = Scalar::from_be_bytes(outpoints_hash)?;
|
||||
let ecdh_shared_secret = intermediate.mul_tweak(&secp, &scalar)?.serialize();
|
||||
|
||||
for (B_m, amount) in B_m_values {
|
||||
let mut bytes: Vec<u8> = Vec::new();
|
||||
|
@ -81,15 +79,10 @@ pub fn create_outputs(
|
|||
bytes.extend_from_slice(&ser_uint32(n));
|
||||
|
||||
let t_n = sha256(&bytes);
|
||||
// eprintln!("t_n = {:?}", hex::encode(t_n));
|
||||
|
||||
let G: PublicKey = SecretKey::from_slice(&Scalar::ONE.to_be_bytes())
|
||||
.unwrap()
|
||||
.public_key(&secp);
|
||||
let res = G
|
||||
.mul_tweak(&secp, &Scalar::from_be_bytes(t_n).unwrap())
|
||||
.unwrap();
|
||||
let reskey = res.combine(&B_m).unwrap();
|
||||
let G: PublicKey = SecretKey::from_slice(&Scalar::ONE.to_be_bytes())?.public_key(&secp);
|
||||
let res = G.mul_tweak(&secp, &Scalar::from_be_bytes(t_n)?)?;
|
||||
let reskey = res.combine(&B_m)?;
|
||||
let (reskey_xonly, _) = reskey.x_only_public_key();
|
||||
|
||||
let mut toAdd: HashMap<String, f32> = HashMap::new();
|
||||
|
@ -100,5 +93,5 @@ pub fn create_outputs(
|
|||
n += 1;
|
||||
}
|
||||
}
|
||||
result
|
||||
Ok(result)
|
||||
}
|
||||
|
|
10
src/utils.rs
10
src/utils.rs
|
@ -3,6 +3,8 @@ use std::io::Write;
|
|||
use hex::FromHex;
|
||||
use secp256k1::hashes::{sha256, Hash};
|
||||
|
||||
pub type Result<T> = std::result::Result<T, Box<dyn std::error::Error>>;
|
||||
|
||||
pub fn sha256(message: &[u8]) -> [u8; 32] {
|
||||
sha256::Hash::hash(message).to_byte_array()
|
||||
}
|
||||
|
@ -11,11 +13,11 @@ pub fn ser_uint32(u: u32) -> Vec<u8> {
|
|||
u.to_be_bytes().into()
|
||||
}
|
||||
|
||||
pub fn hash_outpoints(sending_data: &Vec<(String, u32)>) -> [u8; 32] {
|
||||
pub fn hash_outpoints(sending_data: &Vec<(String, u32)>) -> Result<[u8; 32]> {
|
||||
let mut outpoints: Vec<Vec<u8>> = vec![];
|
||||
|
||||
for (txid_str, vout) in sending_data {
|
||||
let mut txid = Vec::from_hex(txid_str).unwrap();
|
||||
let mut txid = Vec::from_hex(txid_str)?;
|
||||
txid.reverse();
|
||||
let mut vout_bytes = vout.to_le_bytes().to_vec();
|
||||
txid.append(&mut vout_bytes);
|
||||
|
@ -26,8 +28,8 @@ pub fn hash_outpoints(sending_data: &Vec<(String, u32)>) -> [u8; 32] {
|
|||
let mut engine = sha256::HashEngine::default();
|
||||
|
||||
for v in outpoints {
|
||||
engine.write_all(&v).unwrap();
|
||||
engine.write_all(&v)?;
|
||||
}
|
||||
|
||||
sha256::Hash::from_engine(engine).to_byte_array()
|
||||
Ok(sha256::Hash::from_engine(engine).to_byte_array())
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ use silentpayments::utils;
|
|||
mod tests {
|
||||
use std::{collections::HashSet, str::FromStr};
|
||||
|
||||
use secp256k1::XOnlyPublicKey;
|
||||
use secp256k1::{PublicKey, SecretKey, XOnlyPublicKey};
|
||||
|
||||
use crate::{
|
||||
common::input::{self, get_testing_silent_payment_key_pair, ComparableHashMap, TestData},
|
||||
|
@ -40,8 +40,14 @@ mod tests {
|
|||
let expected_comparable: HashSet<ComparableHashMap> =
|
||||
expected.outputs.into_iter().map(|x| x.into()).collect();
|
||||
|
||||
let input_priv_keys: Vec<(SecretKey, bool)> = given
|
||||
.input_priv_keys
|
||||
.iter()
|
||||
.map(|(keystr, x_only)| (SecretKey::from_str(&keystr).unwrap(), *x_only))
|
||||
.collect();
|
||||
|
||||
let outputs =
|
||||
create_outputs(&given.outpoints, &given.input_priv_keys, &given.recipients);
|
||||
create_outputs(&given.outpoints, &input_priv_keys, &given.recipients).unwrap();
|
||||
|
||||
for map in &outputs {
|
||||
for key in map.keys() {
|
||||
|
@ -68,7 +74,8 @@ mod tests {
|
|||
let (b_scan, b_spend, B_scan, B_spend) =
|
||||
get_testing_silent_payment_key_pair(&given.bip32_seed);
|
||||
|
||||
let receiving_addresses = get_receiving_addresses(B_scan, B_spend, &given.labels);
|
||||
let receiving_addresses =
|
||||
get_receiving_addresses(B_scan, B_spend, &given.labels).unwrap();
|
||||
|
||||
let set1: HashSet<_> = receiving_addresses.iter().collect();
|
||||
let set2: HashSet<_> = expected.addresses.iter().collect();
|
||||
|
@ -82,8 +89,26 @@ mod tests {
|
|||
.map(|x| XOnlyPublicKey::from_str(x).unwrap())
|
||||
.collect();
|
||||
|
||||
let outpoints_hash = hash_outpoints(&given.outpoints);
|
||||
let A_sum = get_A_sum_public_keys(&given.input_pub_keys);
|
||||
let outpoints_hash = hash_outpoints(&given.outpoints).unwrap();
|
||||
|
||||
let input_pub_keys: Vec<PublicKey> = given
|
||||
.input_pub_keys
|
||||
.iter()
|
||||
.map(|x| match PublicKey::from_str(&x) {
|
||||
Ok(key) => key,
|
||||
Err(_) => {
|
||||
// we always assume even pairing for input public keys if they are omitted
|
||||
let x_only_public_key = XOnlyPublicKey::from_str(&x).unwrap();
|
||||
PublicKey::from_x_only_public_key(
|
||||
x_only_public_key,
|
||||
secp256k1::Parity::Even,
|
||||
)
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
|
||||
let A_sum = get_A_sum_public_keys(&input_pub_keys).unwrap();
|
||||
|
||||
let labels = match &given.labels.len() {
|
||||
0 => None,
|
||||
_ => Some(&given.labels),
|
||||
|
@ -96,7 +121,8 @@ mod tests {
|
|||
outpoints_hash,
|
||||
outputs_to_check,
|
||||
labels,
|
||||
);
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let res = verify_and_calculate_signatures(&mut add_to_wallet, b_spend).unwrap();
|
||||
assert_eq!(res, expected.outputs);
|
||||
|
|
Loading…
Reference in New Issue