common improvements in querying

This commit is contained in:
debris 2015-12-14 17:12:47 +01:00
parent ee65595a76
commit b7ed6144db
4 changed files with 79 additions and 44 deletions

View File

@ -1,8 +1,53 @@
use util::hash::*; use util::hash::*;
use util::hashdb::*; use util::hashdb::*;
use util::overlaydb::*; use util::overlaydb::*;
use util::rlp::*;
use util::sha3::*;
use blockheader::*; use blockheader::*;
use state::*; use state::*;
use transaction::*;
/// view onto block rlp
pub struct BlockView<'a> {
rlp: Rlp<'a>
}
impl<'a> BlockView<'a> {
pub fn new(bytes: &'a [u8]) -> BlockView<'a> {
BlockView {
rlp: Rlp::new(bytes)
}
}
pub fn new_from_rlp(rlp: Rlp<'a>) -> BlockView<'a> {
BlockView {
rlp: rlp
}
}
pub fn rlp(&self) -> &Rlp<'a> { &self.rlp }
pub fn header(&self) -> Header { self.rlp.val_at(0) }
pub fn header_view(&self) -> HeaderView<'a> {
HeaderView::new_from_rlp(self.rlp.at(0))
}
pub fn transactions(&self) -> Vec<Transaction> {
self.rlp.val_at(1)
}
pub fn transaction_hashes(&self) -> Vec<H256> {
self.rlp.at(1).iter().map(|rlp| rlp.raw().sha3()).collect()
}
pub fn uncles(&self) -> Vec<Header> {
self.rlp.val_at(2)
}
pub fn uncle_hashes(&self) -> Vec<H256> {
self.rlp.at(2).iter().map(|rlp| rlp.raw().sha3()).collect()
}
}
/// Active model of a block within the blockchain /// Active model of a block within the blockchain
pub struct Block { pub struct Block {

View File

@ -17,6 +17,7 @@ use importroute::*;
use account::*; use account::*;
use genesis::*; use genesis::*;
use extras::*; use extras::*;
use transaction::*;
pub struct BlockChain { pub struct BlockChain {
// rlp list of 3 // rlp list of 3
@ -153,49 +154,62 @@ impl BlockChain {
/// Returns true if the given block is known /// Returns true if the given block is known
/// (though not necessarily a part of the canon chain). /// (though not necessarily a part of the canon chain).
pub fn is_known(&self, hash: &H256) -> bool { pub fn is_known(&self, hash: &H256) -> bool {
// TODO: first do lookup in blocks_db for given hash
// TODO: consider taking into account current block // TODO: consider taking into account current block
// TODO: first do lookup in blocks_db for given hash
// TODO: is comparing block numbers necessery?
match self.query_extras(hash, &self.block_details) { match self.query_extras(hash, &self.block_details) {
None => false, None => false,
Some(details) => details.number <= self.last_block_number Some(details) => details.number <= self.last_block_number
} }
} }
/// Returns true if transaction is known.
pub fn is_known_transaction(&self, hash: &H256) -> bool {
self.query_extras_exist(hash, &self.transaction_addresses)
}
/// Returns reference to genesis hash /// Returns reference to genesis hash
pub fn genesis_hash(&self) -> &H256 { pub fn genesis_hash(&self) -> &H256 {
&self.genesis_hash &self.genesis_hash
} }
/// Get the hash of given block's number
pub fn number_hash(&self, hash: &U256) -> Option<H256> {
self.query_extras(hash, &self.block_hashes)
}
/// Get the partial-header of a block /// Get the partial-header of a block
pub fn block_header(&self, hash: &H256) -> Option<Header> { pub fn block_header(&self, hash: &H256) -> Option<Header> {
match self.block(hash) { self.block(hash).map(|bytes| BlockView::new(&bytes).header())
Some(bytes) => Some(BlockView::new(&bytes).header()),
None => None
} }
/// Get a list of transactions for a given block.
/// Returns None is block deos not exist.
pub fn transactions(&self, hash: &H256) -> Option<Vec<Transaction>> {
self.block(hash).map(|bytes| BlockView::new(&bytes).transactions())
} }
/// Get a list of transaction hashes for a given block. /// Get a list of transaction hashes for a given block.
/// Returns None if block does not exist. /// Returns None if block does not exist.
pub fn transaction_hashes(&self, hash: &H256) -> Option<Vec<H256>> { pub fn transaction_hashes(&self, hash: &H256) -> Option<Vec<H256>> {
match self.block(hash) { self.block(hash).map(|bytes| BlockView::new(&bytes).transaction_hashes())
Some(bytes) => Some(BlockView::new(&bytes).transaction_hashes()),
None => None
} }
/// Get a list of uncles for a given block.
/// Returns None is block deos not exist.
pub fn uncles(&self, hash: &H256) -> Option<Vec<Header>> {
self.block(hash).map(|bytes| BlockView::new(&bytes).uncles())
} }
/// Get a list of uncle hashes for a given block. /// Get a list of uncle hashes for a given block.
/// Returns None if block does not exist. /// Returns None if block does not exist.
pub fn uncle_hashes(&self, hash: &H256) -> Option<Vec<H256>> { pub fn uncle_hashes(&self, hash: &H256) -> Option<Vec<H256>> {
match self.block(hash) { self.block(hash).map(|bytes| BlockView::new(&bytes).uncle_hashes())
Some(bytes) => Some(BlockView::new(&bytes).uncle_hashes()),
None => None
} }
/// Get the familial details concerning a block.
pub fn block_details(&self, hash: &H256) -> Option<BlockDetails> {
self.query_extras(hash, &self.block_details)
}
/// Get the hash of given block's number
pub fn number_hash(&self, hash: &U256) -> Option<H256> {
self.query_extras(hash, &self.block_hashes)
} }
/// Get the transactions' log blooms of a block /// Get the transactions' log blooms of a block

View File

@ -4,31 +4,6 @@ use util::uint::*;
use util::rlp::*; use util::rlp::*;
use util::sha3; use util::sha3;
/// view onto block rlp
pub struct BlockView<'a> {
rlp: Rlp<'a>
}
impl<'a> BlockView<'a> {
pub fn new(bytes: &'a [u8]) -> BlockView<'a> {
BlockView {
rlp: Rlp::new(bytes)
}
}
pub fn new_from_rlp(rlp: Rlp<'a>) -> BlockView<'a> {
BlockView {
rlp: rlp
}
}
pub fn rlp(&self) -> &Rlp<'a> { &self.rlp }
pub fn header(&self) -> Header { self.rlp.val_at(0) }
pub fn header_view(&self) -> HeaderView<'a> { HeaderView::new_from_rlp(self.rlp.at(0)) }
pub fn transaction_hashes(&self) -> Vec<H256> { self.rlp.val_at(1) }
pub fn uncle_hashes(&self) -> Vec<H256> { self.rlp.val_at(2) }
}
/// view onto block header rlp /// view onto block header rlp
pub struct HeaderView<'a> { pub struct HeaderView<'a> {
rlp: Rlp<'a> rlp: Rlp<'a>

View File

@ -103,6 +103,7 @@ impl Genesis {
#[test] #[test]
fn test_genesis() { fn test_genesis() {
use block::*;
use blockheader::*; use blockheader::*;
let g = Genesis::new_frontier(); let g = Genesis::new_frontier();