Add block header handlers to grin api (#1248)

Support http://127.0.0.1:13413/v1/headers/{}
This commit is contained in:
yuntai 2018-07-12 06:43:08 +09:00 committed by Ignotus Peverell
parent 83be242fdf
commit 25ca2de487

View file

@ -510,6 +510,30 @@ impl Handler for ChainCompactHandler {
} }
} }
/// Gets block headers given either a hash or height.
/// GET /v1/headers/<hash>
/// GET /v1/headers/<height>
///
pub struct HeaderHandler {
pub chain: Weak<chain::Chain>,
}
impl HeaderHandler {
fn get_header(&self, input: String) -> Result<BlockHeaderPrintable, Error> {
if let Ok(height) = input.parse() {
match w(&self.chain).get_header_by_height(height) {
Ok(header) => return Ok(BlockHeaderPrintable::from_header(&header)),
Err(_) => return Err(ErrorKind::NotFound)?,
}
}
check_block_param(&input)?;
let vec = util::from_hex(input).unwrap();
let h = Hash::from_vec(&vec);
let header = w(&self.chain).get_block_header(&h).context(ErrorKind::NotFound)?;
Ok(BlockHeaderPrintable::from_header(&header))
}
}
/// Gets block details given either a hash or height. /// Gets block details given either a hash or height.
/// GET /v1/blocks/<hash> /// GET /v1/blocks/<hash>
/// GET /v1/blocks/<height> /// GET /v1/blocks/<height>
@ -542,6 +566,13 @@ impl BlockHandler {
Err(_) => return Err(ErrorKind::NotFound)?, Err(_) => return Err(ErrorKind::NotFound)?,
} }
} }
check_block_param(&input)?;
let vec = util::from_hex(input).unwrap();
Ok(Hash::from_vec(&vec))
}
}
fn check_block_param(input: &String) -> Result<(), Error> {
lazy_static! { lazy_static! {
static ref RE: Regex = Regex::new(r"[0-9a-fA-F]{64}").unwrap(); static ref RE: Regex = Regex::new(r"[0-9a-fA-F]{64}").unwrap();
} }
@ -550,9 +581,7 @@ impl BlockHandler {
"Not a valid hash or height.".to_owned(), "Not a valid hash or height.".to_owned(),
))?; ))?;
} }
let vec = util::from_hex(input).unwrap(); return Ok(())
Ok(Hash::from_vec(&vec))
}
} }
impl Handler for BlockHandler { impl Handler for BlockHandler {
@ -585,6 +614,20 @@ impl Handler for BlockHandler {
} }
} }
impl Handler for HeaderHandler {
fn handle(&self, req: &mut Request) -> IronResult<Response> {
let url = req.url.clone();
let mut path_elems = url.path();
if *path_elems.last().unwrap() == "" {
path_elems.pop();
}
let el = *path_elems.last().unwrap();
let h = self.get_header(el.to_string())
.map_err(|e| IronError::new(Fail::compat(e), status::InternalServerError))?;
json_response(&h)
}
}
// Get basic information about the transaction pool. // Get basic information about the transaction pool.
struct PoolInfoHandler<T> { struct PoolInfoHandler<T> {
tx_pool: Weak<RwLock<pool::TransactionPool<T>>>, tx_pool: Weak<RwLock<pool::TransactionPool<T>>>,
@ -712,6 +755,9 @@ pub fn start_rest_apis<T>(
let block_handler = BlockHandler { let block_handler = BlockHandler {
chain: chain.clone(), chain: chain.clone(),
}; };
let header_handler = HeaderHandler {
chain: chain.clone(),
};
let chain_tip_handler = ChainHandler { let chain_tip_handler = ChainHandler {
chain: chain.clone(), chain: chain.clone(),
}; };
@ -773,6 +819,7 @@ pub fn start_rest_apis<T>(
let router = router!( let router = router!(
index: get "/" => index_handler, index: get "/" => index_handler,
blocks: get "/blocks/*" => block_handler, blocks: get "/blocks/*" => block_handler,
headers: get "/headers/*" => header_handler,
chain_tip: get "/chain" => chain_tip_handler, chain_tip: get "/chain" => chain_tip_handler,
chain_compact: get "/chain/compact" => chain_compact_handler, chain_compact: get "/chain/compact" => chain_compact_handler,
chain_validate: get "/chain/validate" => chain_validation_handler, chain_validate: get "/chain/validate" => chain_validation_handler,