parity-zcash/rpc/src/v1/impls/blockchain.rs

129 lines
3.9 KiB
Rust
Raw Normal View History

2016-12-10 02:50:07 -08:00
use v1::traits::BlockChain;
use v1::types::{GetBlockResponse, VerboseBlock};
use v1::types::GetTransactionResponse;
use v1::types::GetTxOutResponse;
use v1::types::GetTxOutSetInfoResponse;
use v1::types::RawBlock;
use v1::types::H256;
use v1::types::U256;
2016-12-10 03:38:51 -08:00
use v1::helpers::errors::block_not_found;
2016-12-10 02:50:07 -08:00
use jsonrpc_core::Error;
use db;
use verification;
use ser::serialize;
use primitives::hash::H256 as GlobalH256;
pub struct BlockChainClient<T: BlockChainClientCoreApi> {
2016-12-10 03:38:51 -08:00
core: T,
2016-12-10 02:50:07 -08:00
}
pub trait BlockChainClientCoreApi: Send + Sync + 'static {
fn get_raw_block(&self, hash: GlobalH256) -> Option<RawBlock>;
fn get_verbose_block(&self, hash: GlobalH256) -> Option<VerboseBlock>;
}
pub struct BlockChainClientCore {
storage: db::SharedStore,
}
impl BlockChainClientCore {
pub fn new(storage: db::SharedStore) -> Self {
BlockChainClientCore {
storage: storage,
}
}
}
impl BlockChainClientCoreApi for BlockChainClientCore {
fn get_raw_block(&self, hash: GlobalH256) -> Option<RawBlock> {
self.storage.block(hash.into())
.map(|block| {
serialize(&block).into()
})
}
fn get_verbose_block(&self, hash: GlobalH256) -> Option<VerboseBlock> {
self.storage.block(hash.into())
.map(|block| {
let block: db::IndexedBlock = block.into();
let height = self.storage.block_number(block.hash());
let confirmations = match height {
Some(block_number) => (self.storage.best_block().expect("genesis block is required").number - block_number + 1) as i64,
None => -1,
};
let block_size = block.size();
let median_time = verification::ChainVerifier::median_timestamp(self.storage.as_block_header_provider(), block.header());
VerboseBlock {
confirmations: confirmations,
size: block_size as u32,
strippedsize: block_size as u32, // TODO: segwit
weight: block_size as u32, // TODO: segwit
height: height,
mediantime: median_time,
difficulty: 0f64, // TODO: https://en.bitcoin.it/wiki/Difficulty + https://www.bitcoinmining.com/what-is-bitcoin-mining-difficulty/
chainwork: U256::default(), // TODO: read from storage
previousblockhash: Some(block.header().previous_header_hash.clone().into()),
nextblockhash: height.and_then(|h| self.storage.block_hash(h + 1).map(|h| h.into())),
bits: block.header().bits.into(),
hash: block.hash().clone().reversed().into(),
merkleroot: block.header().merkle_root_hash.clone().into(),
nonce: block.header().nonce,
time: block.header().time,
tx: vec![], // TODO
version: block.header().version,
version_hex: format!("{:x}", block.header().version),
}
})
}
}
impl<T> BlockChainClient<T> where T: BlockChainClientCoreApi {
pub fn new(core: T) -> Self {
BlockChainClient {
2016-12-10 03:38:51 -08:00
core: core,
2016-12-10 02:50:07 -08:00
}
}
}
impl<T> BlockChain for BlockChainClient<T> where T: BlockChainClientCoreApi {
fn best_block_hash(&self) -> Result<H256, Error> {
rpc_unimplemented!()
}
fn block_hash(&self, _height: u32) -> Result<H256, Error> {
rpc_unimplemented!()
}
fn difficulty(&self) -> Result<f64, Error> {
rpc_unimplemented!()
}
2016-12-10 03:38:51 -08:00
fn block(&self, hash: H256, verbose: Option<bool>) -> Result<GetBlockResponse, Error> {
let global_hash: GlobalH256 = hash.clone().into();
if verbose.unwrap_or_default() {
self.core.get_verbose_block(global_hash.reversed())
.map(|block| GetBlockResponse::Verbose(block))
} else {
self.core.get_raw_block(global_hash.reversed())
.map(|block| GetBlockResponse::Raw(block))
}
.ok_or(block_not_found(hash))
2016-12-10 02:50:07 -08:00
}
fn transaction(&self, _hash: H256, _watch_only: Option<bool>) -> Result<GetTransactionResponse, Error> {
rpc_unimplemented!()
}
fn transaction_out(&self, _transaction_hash: H256, _out_index: u32, _include_mempool: Option<bool>) -> Result<GetTxOutResponse, Error> {
rpc_unimplemented!()
}
fn transaction_out_set_info(&self) -> Result<GetTxOutSetInfoResponse, Error> {
rpc_unimplemented!()
}
}
#[cfg(test)]
pub mod tests {
}