use crate::chain;
use crate::core::core::{OutputFeatures, OutputIdentifier};
use crate::rest::*;
use crate::types::*;
use crate::util;
use crate::util::secp::pedersen::Commitment;
use std::sync::{Arc, Weak};
pub fn w<T>(weak: &Weak<T>) -> Result<Arc<T>, Error> {
weak.upgrade()
.ok_or_else(|| Error::Internal("failed to upgrade weak reference".to_owned()))
}
pub fn get_output(
chain: &Weak<chain::Chain>,
id: &str,
) -> Result<(Output, OutputIdentifier), Error> {
let c = util::from_hex(String::from(id))
.map_err(|_| Error::Argument(format!("Not a valid commitment: {}", id)))?;
let commit = Commitment::from_vec(c);
let outputs = [
OutputIdentifier::new(OutputFeatures::Plain, &commit),
OutputIdentifier::new(OutputFeatures::Coinbase, &commit),
];
let chain = w(chain)?;
for x in outputs.iter() {
let res = chain.is_unspent(x);
match res {
Ok(output_pos) => {
return Ok((
Output::new(&commit, output_pos.height, output_pos.pos),
x.clone(),
));
}
Err(e) => {
trace!(
"get_output: err: {} for commit: {:?} with feature: {:?}",
e.to_string(),
x.commit,
x.features
);
}
}
}
Err(Error::NotFound)
}
pub fn get_output_v2(
chain: &Weak<chain::Chain>,
id: &str,
include_proof: bool,
include_merkle_proof: bool,
) -> Result<(OutputPrintable, OutputIdentifier), Error> {
let c = util::from_hex(String::from(id))
.map_err(|_| Error::Argument(format!("Not a valid commitment, id: {}", id)))?;
let commit = Commitment::from_vec(c);
let outputs = [
OutputIdentifier::new(OutputFeatures::Plain, &commit),
OutputIdentifier::new(OutputFeatures::Coinbase, &commit),
];
let chain = w(chain)?;
for x in outputs.iter() {
let res = chain.is_unspent(x);
match res {
Ok(output_pos) => match chain.get_unspent_output_at(output_pos.pos) {
Ok(output) => {
let mut header = None;
if include_merkle_proof && output.is_coinbase() {
header = chain.get_header_by_height(output_pos.height).ok();
}
match OutputPrintable::from_output(
&output,
chain.clone(),
header.as_ref(),
include_proof,
include_merkle_proof,
) {
Ok(output_printable) => return Ok((output_printable, x.clone())),
Err(e) => {
trace!(
"get_output: err: {} for commit: {:?} with feature: {:?}",
e.to_string(),
x.commit,
x.features
);
}
}
}
Err(_) => return Err(Error::NotFound),
},
Err(e) => {
trace!(
"get_output: err: {} for commit: {:?} with feature: {:?}",
e.to_string(),
x.commit,
x.features
);
}
}
}
Err(Error::NotFound)
}