diff --git a/api/src/auth.rs b/api/src/auth.rs
index 3b00fa701..073c9374c 100644
--- a/api/src/auth.rs
+++ b/api/src/auth.rs
@@ -13,19 +13,25 @@
// limitations under the License.
use crate::router::{Handler, HandlerObj, ResponseFuture};
+use crate::web::response;
use futures::future::ok;
use hyper::header::{HeaderValue, AUTHORIZATION, WWW_AUTHENTICATE};
use hyper::{Body, Request, Response, StatusCode};
use ring::constant_time::verify_slices_are_equal;
+lazy_static! {
+ pub static ref GRIN_BASIC_REALM: HeaderValue =
+ HeaderValue::from_str("Basic realm=GrinAPI").unwrap();
+}
+
// Basic Authentication Middleware
pub struct BasicAuthMiddleware {
api_basic_auth: String,
- basic_realm: String,
+ basic_realm: &'static HeaderValue,
}
impl BasicAuthMiddleware {
- pub fn new(api_basic_auth: String, basic_realm: String) -> BasicAuthMiddleware {
+ pub fn new(api_basic_auth: String, basic_realm: &'static HeaderValue) -> BasicAuthMiddleware {
BasicAuthMiddleware {
api_basic_auth,
basic_realm,
@@ -39,8 +45,12 @@ impl Handler for BasicAuthMiddleware {
req: Request
,
mut handlers: Box>,
) -> ResponseFuture {
+ let next_handler = match handlers.next() {
+ Some(h) => h,
+ None => return response(StatusCode::INTERNAL_SERVER_ERROR, "no handler found"),
+ };
if req.method().as_str() == "OPTIONS" {
- return handlers.next().unwrap().call(req, handlers);
+ return next_handler.call(req, handlers);
}
if req.headers().contains_key(AUTHORIZATION)
&& verify_slices_are_equal(
@@ -49,7 +59,7 @@ impl Handler for BasicAuthMiddleware {
)
.is_ok()
{
- handlers.next().unwrap().call(req, handlers)
+ next_handler.call(req, handlers)
} else {
// Unauthorized 401
unauthorized_response(&self.basic_realm)
@@ -57,13 +67,10 @@ impl Handler for BasicAuthMiddleware {
}
}
-fn unauthorized_response(basic_realm: &str) -> ResponseFuture {
+fn unauthorized_response(basic_realm: &HeaderValue) -> ResponseFuture {
let response = Response::builder()
.status(StatusCode::UNAUTHORIZED)
- .header(
- WWW_AUTHENTICATE,
- HeaderValue::from_str(basic_realm).unwrap(),
- )
+ .header(WWW_AUTHENTICATE, basic_realm)
.body(Body::empty())
.unwrap();
Box::new(ok(response))
diff --git a/api/src/client.rs b/api/src/client.rs
index dd279c2f6..6415b31bd 100644
--- a/api/src/client.rs
+++ b/api/src/client.rs
@@ -136,9 +136,8 @@ fn build_request<'a>(
.into()
})?;
let mut builder = Request::builder();
- if api_secret.is_some() {
- let basic_auth =
- "Basic ".to_string() + &to_base64(&("grin:".to_string() + &api_secret.unwrap()));
+ if let Some(api_secret) = api_secret {
+ let basic_auth = format!("Basic {}", to_base64(&format!("grin:{}", api_secret)));
builder.header(AUTHORIZATION, basic_auth);
}
@@ -224,6 +223,7 @@ fn send_request_async(req: Request) -> Box) -> Result {
let task = send_request_async(req);
- let mut rt = Runtime::new().unwrap();
+ let mut rt =
+ Runtime::new().context(ErrorKind::Internal("can't create Tokio runtime".to_owned()))?;
Ok(rt.block_on(task)?)
}
diff --git a/api/src/handlers.rs b/api/src/handlers.rs
index 3c4fc6088..feb65e343 100644
--- a/api/src/handlers.rs
+++ b/api/src/handlers.rs
@@ -20,39 +20,26 @@ mod server_api;
mod transactions_api;
mod utils;
-use crate::router::{Router, RouterError};
-
-// Server
-use self::server_api::IndexHandler;
-use self::server_api::StatusHandler;
-
-// Blocks
use self::blocks_api::BlockHandler;
use self::blocks_api::HeaderHandler;
-
-// TX Set
-use self::transactions_api::TxHashSetHandler;
-
-// Chain
use self::chain_api::ChainCompactHandler;
use self::chain_api::ChainHandler;
use self::chain_api::ChainValidationHandler;
use self::chain_api::OutputHandler;
-
-// Pool Handlers
-use self::pool_api::PoolInfoHandler;
-use self::pool_api::PoolPushHandler;
-
-// Peers
use self::peers_api::PeerHandler;
use self::peers_api::PeersAllHandler;
use self::peers_api::PeersConnectedHandler;
-
-use crate::auth::BasicAuthMiddleware;
+use self::pool_api::PoolInfoHandler;
+use self::pool_api::PoolPushHandler;
+use self::server_api::IndexHandler;
+use self::server_api::StatusHandler;
+use self::transactions_api::TxHashSetHandler;
+use crate::auth::{BasicAuthMiddleware, GRIN_BASIC_REALM};
use crate::chain;
use crate::p2p;
use crate::pool;
use crate::rest::*;
+use crate::router::{Router, RouterError};
use crate::util;
use crate::util::RwLock;
use std::net::SocketAddr;
@@ -76,11 +63,10 @@ pub fn start_rest_apis(
) -> bool {
let mut apis = ApiServer::new();
let mut router = build_router(chain, tx_pool, peers).expect("unable to build API router");
- if api_secret.is_some() {
- let api_basic_auth =
- "Basic ".to_string() + &util::to_base64(&("grin:".to_string() + &api_secret.unwrap()));
- let basic_realm = "Basic realm=GrinAPI".to_string();
- let basic_auth_middleware = Arc::new(BasicAuthMiddleware::new(api_basic_auth, basic_realm));
+ if let Some(api_secret) = api_secret {
+ let api_basic_auth = format!("Basic {}", util::to_base64(&format!("grin:{}", api_secret)));
+ let basic_auth_middleware =
+ Arc::new(BasicAuthMiddleware::new(api_basic_auth, &GRIN_BASIC_REALM));
router.add_middleware(basic_auth_middleware);
}
diff --git a/api/src/handlers/blocks_api.rs b/api/src/handlers/blocks_api.rs
index 9da0a1c87..4cea007a5 100644
--- a/api/src/handlers/blocks_api.rs
+++ b/api/src/handlers/blocks_api.rs
@@ -41,7 +41,7 @@ impl HeaderHandler {
return Ok(h);
}
if let Ok(height) = input.parse() {
- match w(&self.chain).get_header_by_height(height) {
+ match w(&self.chain)?.get_header_by_height(height) {
Ok(header) => return Ok(BlockHeaderPrintable::from_header(&header)),
Err(_) => return Err(ErrorKind::NotFound)?,
}
@@ -50,7 +50,7 @@ impl HeaderHandler {
let vec = util::from_hex(input)
.map_err(|e| ErrorKind::Argument(format!("invalid input: {}", e)))?;
let h = Hash::from_vec(&vec);
- let header = w(&self.chain)
+ let header = w(&self.chain)?
.get_block_header(&h)
.context(ErrorKind::NotFound)?;
Ok(BlockHeaderPrintable::from_header(&header))
@@ -58,7 +58,7 @@ impl HeaderHandler {
fn get_header_for_output(&self, commit_id: String) -> Result {
let oid = get_output(&self.chain, &commit_id)?.1;
- match w(&self.chain).get_header_for_output(&oid) {
+ match w(&self.chain)?.get_header_for_output(&oid) {
Ok(header) => Ok(BlockHeaderPrintable::from_header(&header)),
Err(_) => Err(ErrorKind::NotFound)?,
}
@@ -85,22 +85,23 @@ pub struct BlockHandler {
impl BlockHandler {
fn get_block(&self, h: &Hash) -> Result {
- let block = w(&self.chain).get_block(h).context(ErrorKind::NotFound)?;
- Ok(BlockPrintable::from_block(&block, w(&self.chain), false))
+ let chain = w(&self.chain)?;
+ let block = chain.get_block(h).context(ErrorKind::NotFound)?;
+ BlockPrintable::from_block(&block, chain, false)
+ .map_err(|_| ErrorKind::Internal("chain error".to_owned()).into())
}
fn get_compact_block(&self, h: &Hash) -> Result {
- let block = w(&self.chain).get_block(h).context(ErrorKind::NotFound)?;
- Ok(CompactBlockPrintable::from_compact_block(
- &block.into(),
- w(&self.chain),
- ))
+ let chain = w(&self.chain)?;
+ let block = chain.get_block(h).context(ErrorKind::NotFound)?;
+ CompactBlockPrintable::from_compact_block(&block.into(), chain)
+ .map_err(|_| ErrorKind::Internal("chain error".to_owned()).into())
}
// Try to decode the string as a height or a hash.
fn parse_input(&self, input: String) -> Result {
if let Ok(height) = input.parse() {
- match w(&self.chain).get_header_by_height(height) {
+ match w(&self.chain)?.get_header_by_height(height) {
Ok(header) => return Ok(header.hash()),
Err(_) => return Err(ErrorKind::NotFound)?,
}
diff --git a/api/src/handlers/chain_api.rs b/api/src/handlers/chain_api.rs
index d0df2aa4f..1badea37d 100644
--- a/api/src/handlers/chain_api.rs
+++ b/api/src/handlers/chain_api.rs
@@ -21,6 +21,7 @@ use crate::types::*;
use crate::util;
use crate::util::secp::pedersen::Commitment;
use crate::web::*;
+use failure::ResultExt;
use hyper::{Body, Request, StatusCode};
use std::sync::Weak;
@@ -32,7 +33,7 @@ pub struct ChainHandler {
impl ChainHandler {
fn get_tip(&self) -> Result {
- let head = w(&self.chain)
+ let head = w(&self.chain)?
.head()
.map_err(|e| ErrorKind::Internal(format!("can't get head: {}", e)))?;
Ok(Tip::from_tip(head))
@@ -53,7 +54,7 @@ pub struct ChainValidationHandler {
impl Handler for ChainValidationHandler {
fn get(&self, _req: Request) -> ResponseFuture {
- match w(&self.chain).validate(true) {
+ match w_fut!(&self.chain).validate(true) {
Ok(_) => response(StatusCode::OK, "{}"),
Err(e) => response(
StatusCode::INTERNAL_SERVER_ERROR,
@@ -72,7 +73,7 @@ pub struct ChainCompactHandler {
impl Handler for ChainCompactHandler {
fn post(&self, _req: Request) -> ResponseFuture {
- match w(&self.chain).compact() {
+ match w_fut!(&self.chain).compact() {
Ok(_) => response(StatusCode::OK, "{}"),
Err(e) => response(
StatusCode::INTERNAL_SERVER_ERROR,
@@ -118,13 +119,14 @@ impl OutputHandler {
commitments: Vec,
include_proof: bool,
) -> Result {
- let header = w(&self.chain)
+ let header = w(&self.chain)?
.get_header_by_height(block_height)
.map_err(|_| ErrorKind::NotFound)?;
// TODO - possible to compact away blocks we care about
// in the period between accepting the block and refreshing the wallet
- let block = w(&self.chain)
+ let chain = w(&self.chain)?;
+ let block = chain
.get_block(&header.hash())
.map_err(|_| ErrorKind::NotFound)?;
let outputs = block
@@ -132,9 +134,10 @@ impl OutputHandler {
.iter()
.filter(|output| commitments.is_empty() || commitments.contains(&output.commit))
.map(|output| {
- OutputPrintable::from_output(output, w(&self.chain), Some(&header), include_proof)
+ OutputPrintable::from_output(output, chain.clone(), Some(&header), include_proof)
})
- .collect();
+ .collect::, _>>()
+ .context(ErrorKind::Internal("cain error".to_owned()))?;
Ok(BlockOutputs {
header: BlockHeaderInfo::from_header(&header),
diff --git a/api/src/handlers/peers_api.rs b/api/src/handlers/peers_api.rs
index 639b2927e..a36813cb1 100644
--- a/api/src/handlers/peers_api.rs
+++ b/api/src/handlers/peers_api.rs
@@ -26,7 +26,7 @@ pub struct PeersAllHandler {
impl Handler for PeersAllHandler {
fn get(&self, _req: Request) -> ResponseFuture {
- let peers = &w(&self.peers).all_peers();
+ let peers = &w_fut!(&self.peers).all_peers();
json_response_pretty(&peers)
}
}
@@ -37,7 +37,7 @@ pub struct PeersConnectedHandler {
impl Handler for PeersConnectedHandler {
fn get(&self, _req: Request) -> ResponseFuture {
- let peers: Vec = w(&self.peers)
+ let peers: Vec = w_fut!(&self.peers)
.connected_peers()
.iter()
.map(|p| p.info.clone().into())
@@ -73,7 +73,7 @@ impl Handler for PeerHandler {
);
}
- match w(&self.peers).get_peer(peer_addr) {
+ match w_fut!(&self.peers).get_peer(peer_addr) {
Ok(peer) => json_response(&peer),
Err(_) => response(StatusCode::NOT_FOUND, "peer not found"),
}
@@ -101,8 +101,8 @@ impl Handler for PeerHandler {
};
match command {
- "ban" => w(&self.peers).ban_peer(addr, ReasonForBan::ManualBan),
- "unban" => w(&self.peers).unban_peer(addr),
+ "ban" => w_fut!(&self.peers).ban_peer(addr, ReasonForBan::ManualBan),
+ "unban" => w_fut!(&self.peers).unban_peer(addr),
_ => return response(StatusCode::BAD_REQUEST, "invalid command"),
};
diff --git a/api/src/handlers/pool_api.rs b/api/src/handlers/pool_api.rs
index 299b79a28..cf9278cef 100644
--- a/api/src/handlers/pool_api.rs
+++ b/api/src/handlers/pool_api.rs
@@ -24,7 +24,7 @@ use crate::util;
use crate::util::RwLock;
use crate::web::*;
use failure::ResultExt;
-use futures::future::ok;
+use futures::future::{err, ok};
use futures::Future;
use hyper::{Body, Request, StatusCode};
use std::sync::Weak;
@@ -37,7 +37,7 @@ pub struct PoolInfoHandler {
impl Handler for PoolInfoHandler {
fn get(&self, _req: Request) -> ResponseFuture {
- let pool_arc = w(&self.tx_pool);
+ let pool_arc = w_fut!(&self.tx_pool);
let pool = pool_arc.read();
json_response(&PoolInfo {
@@ -63,7 +63,11 @@ impl PoolPushHandler {
let params = QueryParams::from(req.uri().query());
let fluff = params.get("fluff").is_some();
- let pool_arc = w(&self.tx_pool).clone();
+ let pool_arc = match w(&self.tx_pool) {
+ //w(&self.tx_pool).clone();
+ Ok(p) => p,
+ Err(e) => return Box::new(err(e)),
+ };
Box::new(
parse_body(req)
diff --git a/api/src/handlers/server_api.rs b/api/src/handlers/server_api.rs
index 42a829a65..d5092b054 100644
--- a/api/src/handlers/server_api.rs
+++ b/api/src/handlers/server_api.rs
@@ -45,12 +45,12 @@ pub struct StatusHandler {
impl StatusHandler {
fn get_status(&self) -> Result {
- let head = w(&self.chain)
+ let head = w(&self.chain)?
.head()
.map_err(|e| ErrorKind::Internal(format!("can't get head: {}", e)))?;
Ok(Status::from_tip_and_peers(
head,
- w(&self.peers).peer_count(),
+ w(&self.peers)?.peer_count(),
))
}
}
diff --git a/api/src/handlers/transactions_api.rs b/api/src/handlers/transactions_api.rs
index 42723e71d..a65047624 100644
--- a/api/src/handlers/transactions_api.rs
+++ b/api/src/handlers/transactions_api.rs
@@ -45,23 +45,26 @@ pub struct TxHashSetHandler {
impl TxHashSetHandler {
// gets roots
- fn get_roots(&self) -> TxHashSet {
- TxHashSet::from_head(w(&self.chain))
+ fn get_roots(&self) -> Result {
+ Ok(TxHashSet::from_head(w(&self.chain)?))
}
// gets last n outputs inserted in to the tree
- fn get_last_n_output(&self, distance: u64) -> Vec {
- TxHashSetNode::get_last_n_output(w(&self.chain), distance)
+ fn get_last_n_output(&self, distance: u64) -> Result, Error> {
+ Ok(TxHashSetNode::get_last_n_output(w(&self.chain)?, distance))
}
// gets last n outputs inserted in to the tree
- fn get_last_n_rangeproof(&self, distance: u64) -> Vec {
- TxHashSetNode::get_last_n_rangeproof(w(&self.chain), distance)
+ fn get_last_n_rangeproof(&self, distance: u64) -> Result, Error> {
+ Ok(TxHashSetNode::get_last_n_rangeproof(
+ w(&self.chain)?,
+ distance,
+ ))
}
// gets last n outputs inserted in to the tree
- fn get_last_n_kernel(&self, distance: u64) -> Vec {
- TxHashSetNode::get_last_n_kernel(w(&self.chain), distance)
+ fn get_last_n_kernel(&self, distance: u64) -> Result, Error> {
+ Ok(TxHashSetNode::get_last_n_kernel(w(&self.chain)?, distance))
}
// allows traversal of utxo set
@@ -70,18 +73,21 @@ impl TxHashSetHandler {
if max > 1000 {
max = 1000;
}
- let outputs = w(&self.chain)
+ let chain = w(&self.chain)?;
+ let outputs = chain
.unspent_outputs_by_insertion_index(start_index, max)
.context(ErrorKind::NotFound)?;
- Ok(OutputListing {
+ let out = OutputListing {
last_retrieved_index: outputs.0,
highest_index: outputs.1,
outputs: outputs
.2
.iter()
- .map(|x| OutputPrintable::from_output(x, w(&self.chain), None, true))
- .collect(),
- })
+ .map(|x| OutputPrintable::from_output(x, chain.clone(), None, true))
+ .collect::, _>>()
+ .context(ErrorKind::Internal("cain error".to_owned()))?,
+ };
+ Ok(out)
}
// return a dummy output with merkle proof for position filled out
@@ -92,10 +98,9 @@ impl TxHashSetHandler {
id
)))?;
let commit = Commitment::from_vec(c);
- let output_pos = w(&self.chain)
- .get_output_pos(&commit)
- .context(ErrorKind::NotFound)?;
- let merkle_proof = chain::Chain::get_merkle_proof_for_pos(&w(&self.chain), commit)
+ let chain = w(&self.chain)?;
+ let output_pos = chain.get_output_pos(&commit).context(ErrorKind::NotFound)?;
+ let merkle_proof = chain::Chain::get_merkle_proof_for_pos(&chain, commit)
.map_err(|_| ErrorKind::NotFound)?;
Ok(OutputPrintable {
output_type: OutputType::Coinbase,
@@ -120,10 +125,10 @@ impl Handler for TxHashSetHandler {
let id = parse_param_no_err!(params, "id", "".to_owned());
match right_path_element!(req) {
- "roots" => json_response_pretty(&self.get_roots()),
- "lastoutputs" => json_response_pretty(&self.get_last_n_output(last_n)),
- "lastrangeproofs" => json_response_pretty(&self.get_last_n_rangeproof(last_n)),
- "lastkernels" => json_response_pretty(&self.get_last_n_kernel(last_n)),
+ "roots" => result_to_response(self.get_roots()),
+ "lastoutputs" => result_to_response(self.get_last_n_output(last_n)),
+ "lastrangeproofs" => result_to_response(self.get_last_n_rangeproof(last_n)),
+ "lastkernels" => result_to_response(self.get_last_n_kernel(last_n)),
"outputs" => result_to_response(self.outputs(start_index, max)),
"merkleproof" => result_to_response(self.get_merkle_proof_for_output(&id)),
_ => response(StatusCode::BAD_REQUEST, ""),
diff --git a/api/src/handlers/utils.rs b/api/src/handlers/utils.rs
index bedaf0904..1aa309e98 100644
--- a/api/src/handlers/utils.rs
+++ b/api/src/handlers/utils.rs
@@ -24,8 +24,9 @@ use std::sync::{Arc, Weak};
// 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(weak: &Weak) -> Arc {
- weak.upgrade().unwrap()
+pub fn w(weak: &Weak) -> Result, Error> {
+ weak.upgrade()
+ .ok_or_else(|| ErrorKind::Internal("failed to upgrade weak refernce".to_owned()).into())
}
/// Retrieves an output from the chain given a commit id (a tiny bit iteratively)
@@ -48,14 +49,16 @@ pub fn get_output(
OutputIdentifier::new(OutputFeatures::Coinbase, &commit),
];
- for x in outputs.iter().filter(|x| w(chain).is_unspent(x).is_ok()) {
- let block_height = w(chain)
+ let chain = w(chain)?;
+
+ for x in outputs.iter().filter(|x| chain.is_unspent(x).is_ok()) {
+ let block_height = chain
.get_header_for_output(&x)
.context(ErrorKind::Internal(
"Can't get header for output".to_owned(),
))?
.height;
- let output_pos = w(chain).get_output_pos(&x.commit).unwrap_or(0);
+ let output_pos = chain.get_output_pos(&x.commit).unwrap_or(0);
return Ok((Output::new(&commit, block_height, output_pos), x.clone()));
}
Err(ErrorKind::NotFound)?
diff --git a/api/src/lib.rs b/api/src/lib.rs
index 282a29009..d9a566e19 100644
--- a/api/src/lib.rs
+++ b/api/src/lib.rs
@@ -39,7 +39,7 @@ mod rest;
mod router;
mod types;
-pub use crate::auth::BasicAuthMiddleware;
+pub use crate::auth::{BasicAuthMiddleware, GRIN_BASIC_REALM};
pub use crate::handlers::start_rest_apis;
pub use crate::rest::*;
pub use crate::router::*;
diff --git a/api/src/rest.rs b/api/src/rest.rs
index fa26ef64a..98c1b1314 100644
--- a/api/src/rest.rs
+++ b/api/src/rest.rs
@@ -19,11 +19,12 @@
//! register them on a ApiServer.
use crate::router::{Handler, HandlerObj, ResponseFuture, Router};
+use crate::web::response;
use failure::{Backtrace, Context, Fail, ResultExt};
use futures::sync::oneshot;
use futures::Stream;
use hyper::rt::Future;
-use hyper::{rt, Body, Request, Server};
+use hyper::{rt, Body, Request, Server, StatusCode};
use rustls;
use rustls::internal::pemfile;
use std::fmt::{self, Display};
@@ -264,6 +265,9 @@ impl Handler for LoggingMiddleware {
mut handlers: Box>,
) -> ResponseFuture {
debug!("REST call: {} {}", req.method(), req.uri().path());
- handlers.next().unwrap().call(req, handlers)
+ match handlers.next() {
+ Some(handler) => handler.call(req, handlers),
+ None => response(StatusCode::INTERNAL_SERVER_ERROR, "no handler found"),
+ }
}
}
diff --git a/api/src/types.rs b/api/src/types.rs
index c069ac014..4ae837177 100644
--- a/api/src/types.rs
+++ b/api/src/types.rs
@@ -222,7 +222,9 @@ impl<'de> serde::de::Visitor<'de> for PrintableCommitmentVisitor {
E: serde::de::Error,
{
Ok(PrintableCommitment {
- commit: pedersen::Commitment::from_vec(util::from_hex(String::from(v)).unwrap()),
+ commit: pedersen::Commitment::from_vec(
+ util::from_hex(String::from(v)).map_err(serde::de::Error::custom)?,
+ ),
})
}
}
@@ -255,7 +257,7 @@ impl OutputPrintable {
chain: Arc,
block_header: Option<&core::BlockHeader>,
include_proof: bool,
- ) -> OutputPrintable {
+ ) -> Result {
let output_type = if output.is_coinbase() {
OutputType::Coinbase
} else {
@@ -266,7 +268,7 @@ impl OutputPrintable {
let spent = chain.is_unspent(&out_id).is_err();
let block_height = match spent {
true => None,
- false => Some(chain.get_header_for_output(&out_id).unwrap().height),
+ false => Some(chain.get_header_for_output(&out_id)?.height),
};
let proof = if include_proof {
@@ -280,13 +282,15 @@ impl OutputPrintable {
// We require the rewind() to be stable even after the PMMR is pruned and
// compacted so we can still recreate the necessary proof.
let mut merkle_proof = None;
- if output.is_coinbase() && !spent && block_header.is_some() {
- merkle_proof = chain.get_merkle_proof(&out_id, &block_header.unwrap()).ok()
+ if output.is_coinbase() && !spent {
+ if let Some(block_header) = block_header {
+ merkle_proof = chain.get_merkle_proof(&out_id, &block_header).ok();
+ }
};
let output_pos = chain.get_output_pos(&output.commit).unwrap_or(0);
- OutputPrintable {
+ Ok(OutputPrintable {
output_type,
commit: output.commit,
spent,
@@ -295,7 +299,7 @@ impl OutputPrintable {
block_height,
merkle_proof,
mmr_index: output_pos,
- }
+ })
}
pub fn commit(&self) -> Result {
@@ -303,12 +307,13 @@ impl OutputPrintable {
}
pub fn range_proof(&self) -> Result {
- let proof_str = self
- .proof
- .clone()
- .ok_or_else(|| ser::Error::HexError(format!("output range_proof missing")))
- .unwrap();
- let p_vec = util::from_hex(proof_str).unwrap();
+ let proof_str = match self.proof.clone() {
+ Some(p) => p,
+ None => return Err(ser::Error::HexError(format!("output range_proof missing"))),
+ };
+
+ let p_vec = util::from_hex(proof_str)
+ .map_err(|_| ser::Error::HexError(format!("invalud output range_proof")))?;
let mut p_bytes = [0; util::secp::constants::MAX_PROOF_SIZE];
for i in 0..p_bytes.len() {
p_bytes[i] = p_vec[i];
@@ -428,6 +433,15 @@ impl<'de> serde::de::Deserialize<'de> for OutputPrintable {
}
}
+ if output_type.is_none()
+ || commit.is_none()
+ || spent.is_none()
+ || proof_hash.is_none()
+ || mmr_index.is_none()
+ {
+ return Err(serde::de::Error::custom("invalid output"));
+ }
+
Ok(OutputPrintable {
output_type: output_type.unwrap(),
commit: commit.unwrap(),
@@ -570,7 +584,7 @@ impl BlockPrintable {
block: &core::Block,
chain: Arc,
include_proof: bool,
- ) -> BlockPrintable {
+ ) -> Result {
let inputs = block
.inputs()
.iter()
@@ -587,18 +601,19 @@ impl BlockPrintable {
include_proof,
)
})
- .collect();
+ .collect::, _>>()?;
+
let kernels = block
.kernels()
.iter()
.map(|kernel| TxKernelPrintable::from_txkernel(kernel))
.collect();
- BlockPrintable {
+ Ok(BlockPrintable {
header: BlockHeaderPrintable::from_header(&block.header),
inputs: inputs,
outputs: outputs,
kernels: kernels,
- }
+ })
}
}
@@ -620,24 +635,24 @@ impl CompactBlockPrintable {
pub fn from_compact_block(
cb: &core::CompactBlock,
chain: Arc,
- ) -> CompactBlockPrintable {
- let block = chain.get_block(&cb.hash()).unwrap();
+ ) -> Result {
+ let block = chain.get_block(&cb.hash())?;
let out_full = cb
.out_full()
.iter()
.map(|x| OutputPrintable::from_output(x, chain.clone(), Some(&block.header), false))
- .collect();
+ .collect::, _>>()?;
let kern_full = cb
.kern_full()
.iter()
.map(|x| TxKernelPrintable::from_txkernel(x))
.collect();
- CompactBlockPrintable {
+ Ok(CompactBlockPrintable {
header: BlockHeaderPrintable::from_header(&cb.header),
out_full,
kern_full,
kern_ids: cb.kern_ids().iter().map(|x| x.to_hex()).collect(),
- }
+ })
}
}
diff --git a/api/src/web.rs b/api/src/web.rs
index 1bd296237..eb525bb8e 100644
--- a/api/src/web.rs
+++ b/api/src/web.rs
@@ -180,3 +180,12 @@ macro_rules! parse_param_no_err(
}
}
));
+
+#[macro_export]
+macro_rules! w_fut(
+ ($p: expr) =>(
+ match w($p) {
+ Ok(p) => p,
+ Err(_) => return response(StatusCode::INTERNAL_SERVER_ERROR, "weak reference upgrade failed" ),
+ }
+ ));
diff --git a/api/tests/rest.rs b/api/tests/rest.rs
index 641ce3d2e..3651bf717 100644
--- a/api/tests/rest.rs
+++ b/api/tests/rest.rs
@@ -2,7 +2,7 @@ use grin_api as api;
use grin_util as util;
use crate::api::*;
-use hyper::{Body, Request};
+use hyper::{Body, Request, StatusCode};
use std::net::SocketAddr;
use std::sync::atomic::{AtomicUsize, Ordering, ATOMIC_USIZE_INIT};
use std::sync::Arc;
@@ -43,7 +43,10 @@ impl Handler for CounterMiddleware {
mut handlers: Box>,
) -> ResponseFuture {
self.counter.fetch_add(1, Ordering::SeqCst);
- handlers.next().unwrap().call(req, handlers)
+ match handlers.next() {
+ Some(h) => h.call(req, handlers),
+ None => return response(StatusCode::INTERNAL_SERVER_ERROR, "no handler found"),
+ }
}
}
diff --git a/wallet/src/controller.rs b/wallet/src/controller.rs
index f69a02dd1..996fa04e4 100644
--- a/wallet/src/controller.rs
+++ b/wallet/src/controller.rs
@@ -16,7 +16,9 @@
//! invocations) as needed.
//! Still experimental
use crate::adapters::{FileWalletCommAdapter, HTTPWalletCommAdapter, KeybaseWalletCommAdapter};
-use crate::api::{ApiServer, BasicAuthMiddleware, Handler, ResponseFuture, Router, TLSConfig};
+use crate::api::{
+ ApiServer, BasicAuthMiddleware, Handler, ResponseFuture, Router, TLSConfig, GRIN_BASIC_REALM,
+};
use crate::core::core;
use crate::core::core::Transaction;
use crate::keychain::Keychain;
@@ -89,8 +91,8 @@ where
if api_secret.is_some() {
let api_basic_auth =
"Basic ".to_string() + &to_base64(&("grin:".to_string() + &api_secret.unwrap()));
- let basic_realm = "Basic realm=GrinOwnerAPI".to_string();
- let basic_auth_middleware = Arc::new(BasicAuthMiddleware::new(api_basic_auth, basic_realm));
+ let basic_auth_middleware =
+ Arc::new(BasicAuthMiddleware::new(api_basic_auth, &GRIN_BASIC_REALM));
router.add_middleware(basic_auth_middleware);
}
router
diff --git a/wallet/src/test_framework/mod.rs b/wallet/src/test_framework/mod.rs
index 3d5d7fddb..b66bd350f 100644
--- a/wallet/src/test_framework/mod.rs
+++ b/wallet/src/test_framework/mod.rs
@@ -75,7 +75,7 @@ fn get_outputs_by_pmmr_index_local(
outputs: outputs
.2
.iter()
- .map(|x| api::OutputPrintable::from_output(x, chain.clone(), None, true))
+ .map(|x| api::OutputPrintable::from_output(x, chain.clone(), None, true).unwrap())
.collect(),
}
}