grin/api/src/handlers/utils.rs

58 lines
2 KiB
Rust

// Copyright 2018 The Grin Developers
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
use chain;
use core::core::{OutputFeatures, OutputIdentifier};
use failure::ResultExt;
use rest::*;
use std::sync::{Arc, Weak};
use types::*;
use util;
use util::secp::pedersen::Commitment;
// All handlers use `Weak` references instead of `Arc` to avoid cycles that
// can never be destroyed. These 2 functions are simple helpers to reduce the
// boilerplate of dealing with `Weak`.
pub fn w<T>(weak: &Weak<T>) -> Arc<T> {
weak.upgrade().unwrap()
}
/// Retrieves an output from the chain given a commit id (a tiny bit iteratively)
pub fn get_output(
chain: &Weak<chain::Chain>,
id: &str,
) -> Result<(Output, OutputIdentifier), Error> {
let c = util::from_hex(String::from(id)).context(ErrorKind::Argument(format!(
"Not a valid commitment: {}",
id
)))?;
let commit = Commitment::from_vec(c);
// We need the features here to be able to generate the necessary hash
// to compare against the hash in the output MMR.
// For now we can just try both (but this probably needs to be part of the api
// params)
let outputs = [
OutputIdentifier::new(OutputFeatures::DEFAULT_OUTPUT, &commit),
OutputIdentifier::new(OutputFeatures::COINBASE_OUTPUT, &commit),
];
for x in outputs.iter() {
if let Ok(_) = w(chain).is_unspent(&x) {
let block_height = w(chain).get_header_for_output(&x).unwrap().height;
return Ok((Output::new(&commit, block_height), x.clone()));
}
}
Err(ErrorKind::NotFound)?
}