ShortId implementation (and CompactBlock) (#637)

* [wip] short_id implementation (first attempt)
todo - make this more reusable (a trait?) so we can use it for inputs/outputs/kernels easily

* factor short_id support out into ShortIdentifiable trait

* block can now be converted to compact_block
rename existing block.compact() -> block.cut_through()

* expose compact block representation via block api endpoint
optional with ?compact query param
This commit is contained in:
AntiochP
2018-01-19 17:43:02 -05:00
committed by GitHub
parent f9726e8154
commit 9085e548f7
9 changed files with 418 additions and 25 deletions
+27 -5
View File
@@ -385,9 +385,13 @@ impl Handler for ChainHandler {
}
}
// Gets block details given either a hash or height.
// GET /v1/block/<hash>
// GET /v1/block/<height>
/// Gets block details given either a hash or height.
/// GET /v1/blocks/<hash>
/// GET /v1/blocks/<height>
///
/// Optionally return results as "compact blocks" by passing "?compact" query param
/// GET /v1/blocks/<hash>?compact
///
pub struct BlockHandler {
pub chain: Arc<chain::Chain>,
}
@@ -398,6 +402,11 @@ impl BlockHandler {
Ok(BlockPrintable::from_block(&block, self.chain.clone(), false))
}
fn get_compact_block(&self, h: &Hash) -> Result<CompactBlockPrintable, Error> {
let block = self.chain.clone().get_block(h).map_err(|_| Error::NotFound)?;
Ok(CompactBlockPrintable::from_compact_block(&block.as_compact_block()))
}
// Try to decode the string as a height or a hash.
fn parse_input(&self, input: String) -> Result<Hash, Error> {
if let Ok(height) = input.parse() {
@@ -426,8 +435,21 @@ impl Handler for BlockHandler {
}
let el = *path_elems.last().unwrap();
let h = try!(self.parse_input(el.to_string()));
let b = try!(self.get_block(&h));
json_response(&b)
let mut compact = false;
if let Ok(params) = req.get_ref::<UrlEncodedQuery>() {
if let Some(_) = params.get("compact") {
compact = true;
}
}
if compact {
let b = try!(self.get_compact_block(&h));
json_response(&b)
} else {
let b = try!(self.get_block(&h));
json_response(&b)
}
}
}
+24
View File
@@ -367,6 +367,30 @@ impl BlockPrintable {
}
}
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct CompactBlockPrintable {
/// The block header
pub header: BlockHeaderPrintable,
/// Inputs (hex short_ids)
pub inputs: Vec<String>,
/// Outputs (hex short_ids)
pub outputs: Vec<String>,
/// Kernels (hex short_ids)
pub kernels: Vec<String>,
}
impl CompactBlockPrintable {
/// Convert a compact block into a printable representation suitable for api response
pub fn from_compact_block(cb: &core::CompactBlock) -> CompactBlockPrintable {
CompactBlockPrintable {
header: BlockHeaderPrintable::from_header(&cb.header),
inputs: cb.inputs.iter().map(|x| x.to_hex()).collect(),
outputs: cb.outputs.iter().map(|x| x.to_hex()).collect(),
kernels: cb.kernels.iter().map(|x| x.to_hex()).collect(),
}
}
}
// For wallet reconstruction, include the header info along with the
// transactions in the block
#[derive(Debug, Serialize, Deserialize, Clone)]