few client methods use BlockId instead of hash and BlockNumber
This commit is contained in:
@@ -23,24 +23,6 @@ use extras::*;
|
||||
use transaction::*;
|
||||
use views::*;
|
||||
|
||||
/// Uniquely identifies block.
|
||||
pub enum BlockId {
|
||||
/// Block's sha3.
|
||||
/// Querying by hash is always faster.
|
||||
Hash(H256),
|
||||
/// Block number within canon blockchain.
|
||||
Number(BlockNumber)
|
||||
}
|
||||
|
||||
/// Uniquely identifies transaction.
|
||||
pub enum TransactionId {
|
||||
/// Transaction's sha3.
|
||||
Hash(H256),
|
||||
/// Block id and transaction index within this block.
|
||||
/// Querying by block position is always faster.
|
||||
Location(BlockId, usize)
|
||||
}
|
||||
|
||||
/// Represents a tree route between `from` block and `to` block:
|
||||
pub struct TreeRoute {
|
||||
/// A vector of hashes of all blocks, ordered from `from` to `to`.
|
||||
@@ -129,18 +111,8 @@ pub trait BlockProvider {
|
||||
}
|
||||
|
||||
/// Get transaction with given transaction hash.
|
||||
fn transaction(&self, id: TransactionId) -> Option<LocalizedTransaction> {
|
||||
match id {
|
||||
TransactionId::Hash(ref hash) => self.transaction_address(hash),
|
||||
TransactionId::Location(BlockId::Hash(hash), index) => Some(TransactionAddress {
|
||||
block_hash: hash,
|
||||
index: index
|
||||
}),
|
||||
TransactionId::Location(BlockId::Number(number), index) => self.block_hash(number).map(|hash| TransactionAddress {
|
||||
block_hash: hash,
|
||||
index: index
|
||||
})
|
||||
}.and_then(|address| self.block(&address.block_hash).and_then(|bytes| BlockView::new(&bytes).localized_transaction_at(address.index)))
|
||||
fn transaction(&self, address: &TransactionAddress) -> Option<LocalizedTransaction> {
|
||||
self.block(&address.block_hash).and_then(|bytes| BlockView::new(&bytes).localized_transaction_at(address.index))
|
||||
}
|
||||
|
||||
/// Get a list of transactions for a given block.
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
|
||||
use util::*;
|
||||
use rocksdb::{Options, DB, DBCompactionStyle};
|
||||
use blockchain::{BlockChain, BlockProvider, CacheSize, TransactionId};
|
||||
use blockchain::{BlockChain, BlockProvider, CacheSize};
|
||||
use views::BlockView;
|
||||
use error::*;
|
||||
use header::BlockNumber;
|
||||
@@ -32,8 +32,27 @@ use env_info::LastHashes;
|
||||
use verification::*;
|
||||
use block::*;
|
||||
use transaction::LocalizedTransaction;
|
||||
use extras::TransactionAddress;
|
||||
pub use blockchain::TreeRoute;
|
||||
|
||||
/// Uniquely identifies block.
|
||||
pub enum BlockId {
|
||||
/// Block's sha3.
|
||||
/// Querying by hash is always faster.
|
||||
Hash(H256),
|
||||
/// Block number within canon blockchain.
|
||||
Number(BlockNumber)
|
||||
}
|
||||
|
||||
/// Uniquely identifies transaction.
|
||||
pub enum TransactionId {
|
||||
/// Transaction's sha3.
|
||||
Hash(H256),
|
||||
/// Block id and transaction index within this block.
|
||||
/// Querying by block position is always faster.
|
||||
Location(BlockId, usize)
|
||||
}
|
||||
|
||||
/// General block status
|
||||
#[derive(Debug, Eq, PartialEq)]
|
||||
pub enum BlockStatus {
|
||||
@@ -70,41 +89,25 @@ impl fmt::Display for BlockChainInfo {
|
||||
|
||||
/// Blockchain database client. Owns and manages a blockchain and a block queue.
|
||||
pub trait BlockChainClient : Sync + Send {
|
||||
/// Get raw block header data by block header hash.
|
||||
fn block_header(&self, hash: &H256) -> Option<Bytes>;
|
||||
/// Get raw block header data by block id.
|
||||
fn block_header(&self, id: BlockId) -> Option<Bytes>;
|
||||
|
||||
/// Get raw block body data by block header hash.
|
||||
/// Get raw block body data by block id.
|
||||
/// Block body is an RLP list of two items: uncles and transactions.
|
||||
fn block_body(&self, hash: &H256) -> Option<Bytes>;
|
||||
fn block_body(&self, id: BlockId) -> Option<Bytes>;
|
||||
|
||||
/// Get raw block data by block header hash.
|
||||
fn block(&self, hash: &H256) -> Option<Bytes>;
|
||||
fn block(&self, id: BlockId) -> Option<Bytes>;
|
||||
|
||||
/// Get block status by block header hash.
|
||||
fn block_status(&self, hash: &H256) -> BlockStatus;
|
||||
fn block_status(&self, id: BlockId) -> BlockStatus;
|
||||
|
||||
/// Get block total difficulty.
|
||||
fn block_total_difficulty(&self, hash: &H256) -> Option<U256>;
|
||||
fn block_total_difficulty(&self, id: BlockId) -> Option<U256>;
|
||||
|
||||
/// Get address code.
|
||||
fn code(&self, address: &Address) -> Option<Bytes>;
|
||||
|
||||
/// Get raw block header data by block number.
|
||||
fn block_header_at(&self, n: BlockNumber) -> Option<Bytes>;
|
||||
|
||||
/// Get raw block body data by block number.
|
||||
/// Block body is an RLP list of two items: uncles and transactions.
|
||||
fn block_body_at(&self, n: BlockNumber) -> Option<Bytes>;
|
||||
|
||||
/// Get raw block data by block number.
|
||||
fn block_at(&self, n: BlockNumber) -> Option<Bytes>;
|
||||
|
||||
/// Get block status by block number.
|
||||
fn block_status_at(&self, n: BlockNumber) -> BlockStatus;
|
||||
|
||||
/// Get block total difficulty.
|
||||
fn block_total_difficulty_at(&self, n: BlockNumber) -> Option<U256>;
|
||||
|
||||
/// Get transaction with given hash.
|
||||
fn transaction(&self, id: TransactionId) -> Option<LocalizedTransaction>;
|
||||
|
||||
@@ -132,7 +135,7 @@ pub trait BlockChainClient : Sync + Send {
|
||||
|
||||
/// Get the best block header.
|
||||
fn best_block_header(&self) -> Bytes {
|
||||
self.block_header(&self.chain_info().best_block_hash).unwrap()
|
||||
self.block_header(BlockId::Hash(self.chain_info().best_block_hash)).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -332,68 +335,62 @@ impl Client {
|
||||
pub fn configure_cache(&self, pref_cache_size: usize, max_cache_size: usize) {
|
||||
self.chain.write().unwrap().configure_cache(pref_cache_size, max_cache_size);
|
||||
}
|
||||
|
||||
fn block_hash(&self, id: BlockId) -> Option<H256> {
|
||||
match id {
|
||||
BlockId::Hash(hash) => Some(hash),
|
||||
BlockId::Number(number) => self.chain.read().unwrap().block_hash(number)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl BlockChainClient for Client {
|
||||
fn block_header(&self, hash: &H256) -> Option<Bytes> {
|
||||
self.chain.read().unwrap().block(hash).map(|bytes| BlockView::new(&bytes).rlp().at(0).as_raw().to_vec())
|
||||
fn block_header(&self, id: BlockId) -> Option<Bytes> {
|
||||
self.block_hash(id).and_then(|hash| self.chain.read().unwrap().block(&hash).map(|bytes| BlockView::new(&bytes).rlp().at(0).as_raw().to_vec()))
|
||||
}
|
||||
|
||||
fn block_body(&self, hash: &H256) -> Option<Bytes> {
|
||||
self.chain.read().unwrap().block(hash).map(|bytes| {
|
||||
let rlp = Rlp::new(&bytes);
|
||||
let mut body = RlpStream::new();
|
||||
body.append_raw(rlp.at(1).as_raw(), 1);
|
||||
body.append_raw(rlp.at(2).as_raw(), 1);
|
||||
body.out()
|
||||
fn block_body(&self, id: BlockId) -> Option<Bytes> {
|
||||
self.block_hash(id).and_then(|hash| {
|
||||
self.chain.read().unwrap().block(&hash).map(|bytes| {
|
||||
let rlp = Rlp::new(&bytes);
|
||||
let mut body = RlpStream::new();
|
||||
body.append_raw(rlp.at(1).as_raw(), 1);
|
||||
body.append_raw(rlp.at(2).as_raw(), 1);
|
||||
body.out()
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
fn block(&self, hash: &H256) -> Option<Bytes> {
|
||||
self.chain.read().unwrap().block(hash)
|
||||
fn block(&self, id: BlockId) -> Option<Bytes> {
|
||||
self.block_hash(id).and_then(|hash| {
|
||||
self.chain.read().unwrap().block(&hash)
|
||||
})
|
||||
}
|
||||
|
||||
fn block_status(&self, hash: &H256) -> BlockStatus {
|
||||
if self.chain.read().unwrap().is_known(&hash) {
|
||||
BlockStatus::InChain
|
||||
} else {
|
||||
self.block_queue.read().unwrap().block_status(hash)
|
||||
fn block_status(&self, id: BlockId) -> BlockStatus {
|
||||
match self.block_hash(id) {
|
||||
Some(ref hash) if self.chain.read().unwrap().is_known(hash) => BlockStatus::InChain,
|
||||
Some(hash) => self.block_queue.read().unwrap().block_status(&hash),
|
||||
None => BlockStatus::Unknown
|
||||
}
|
||||
}
|
||||
|
||||
fn block_total_difficulty(&self, hash: &H256) -> Option<U256> {
|
||||
self.chain.read().unwrap().block_details(hash).map(|d| d.total_difficulty)
|
||||
fn block_total_difficulty(&self, id: BlockId) -> Option<U256> {
|
||||
self.block_hash(id).and_then(|hash| self.chain.read().unwrap().block_details(&hash)).map(|d| d.total_difficulty)
|
||||
}
|
||||
|
||||
fn code(&self, address: &Address) -> Option<Bytes> {
|
||||
self.state().code(address)
|
||||
}
|
||||
|
||||
fn block_header_at(&self, n: BlockNumber) -> Option<Bytes> {
|
||||
self.chain.read().unwrap().block_hash(n).and_then(|h| self.block_header(&h))
|
||||
}
|
||||
|
||||
fn block_body_at(&self, n: BlockNumber) -> Option<Bytes> {
|
||||
self.chain.read().unwrap().block_hash(n).and_then(|h| self.block_body(&h))
|
||||
}
|
||||
|
||||
fn block_at(&self, n: BlockNumber) -> Option<Bytes> {
|
||||
self.chain.read().unwrap().block_hash(n).and_then(|h| self.block(&h))
|
||||
}
|
||||
|
||||
fn block_status_at(&self, n: BlockNumber) -> BlockStatus {
|
||||
match self.chain.read().unwrap().block_hash(n) {
|
||||
Some(h) => self.block_status(&h),
|
||||
None => BlockStatus::Unknown
|
||||
}
|
||||
}
|
||||
|
||||
fn block_total_difficulty_at(&self, n: BlockNumber) -> Option<U256> {
|
||||
self.chain.read().unwrap().block_hash(n).and_then(|h| self.block_total_difficulty(&h))
|
||||
}
|
||||
|
||||
fn transaction(&self, id: TransactionId) -> Option<LocalizedTransaction> {
|
||||
self.chain.read().unwrap().transaction(id)
|
||||
match id {
|
||||
TransactionId::Hash(ref hash) => self.chain.read().unwrap().transaction_address(hash),
|
||||
TransactionId::Location(id, index) => self.block_hash(id).map(|hash| TransactionAddress {
|
||||
block_hash: hash,
|
||||
index: index
|
||||
})
|
||||
}.and_then(|address| self.chain.read().unwrap().transaction(&address))
|
||||
}
|
||||
|
||||
fn tree_route(&self, from: &H256, to: &H256) -> Option<TreeRoute> {
|
||||
@@ -413,7 +410,7 @@ impl BlockChainClient for Client {
|
||||
if self.chain.read().unwrap().is_known(&header.hash()) {
|
||||
return Err(ImportError::AlreadyInChain);
|
||||
}
|
||||
if self.block_status(&header.parent_hash) == BlockStatus::Unknown {
|
||||
if self.block_status(BlockId::Hash(header.parent_hash)) == BlockStatus::Unknown {
|
||||
return Err(ImportError::UnknownParent);
|
||||
}
|
||||
self.block_queue.write().unwrap().import_block(bytes)
|
||||
|
||||
Reference in New Issue
Block a user