diff --git a/src/block.rs b/src/block.rs index efde03c2d..3d882fd09 100644 --- a/src/block.rs +++ b/src/block.rs @@ -1,8 +1,53 @@ use util::hash::*; use util::hashdb::*; use util::overlaydb::*; +use util::rlp::*; +use util::sha3::*; use blockheader::*; 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 { + self.rlp.val_at(1) + } + + pub fn transaction_hashes(&self) -> Vec { + self.rlp.at(1).iter().map(|rlp| rlp.raw().sha3()).collect() + } + + pub fn uncles(&self) -> Vec
{ + self.rlp.val_at(2) + } + + pub fn uncle_hashes(&self) -> Vec { + self.rlp.at(2).iter().map(|rlp| rlp.raw().sha3()).collect() + } +} /// Active model of a block within the blockchain pub struct Block { diff --git a/src/blockchain.rs b/src/blockchain.rs index c5d74a6de..7c385018e 100644 --- a/src/blockchain.rs +++ b/src/blockchain.rs @@ -17,6 +17,7 @@ use importroute::*; use account::*; use genesis::*; use extras::*; +use transaction::*; pub struct BlockChain { // rlp list of 3 @@ -153,49 +154,62 @@ impl BlockChain { /// Returns true if the given block is known /// (though not necessarily a part of the canon chain). 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: first do lookup in blocks_db for given hash + // TODO: is comparing block numbers necessery? match self.query_extras(hash, &self.block_details) { None => false, 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 pub fn genesis_hash(&self) -> &H256 { &self.genesis_hash } - /// Get the hash of given block's number - pub fn number_hash(&self, hash: &U256) -> Option { - self.query_extras(hash, &self.block_hashes) - } - /// Get the partial-header of a block pub fn block_header(&self, hash: &H256) -> Option
{ - match self.block(hash) { - Some(bytes) => Some(BlockView::new(&bytes).header()), - None => None - } + self.block(hash).map(|bytes| BlockView::new(&bytes).header()) + } + + /// Get a list of transactions for a given block. + /// Returns None is block deos not exist. + pub fn transactions(&self, hash: &H256) -> Option> { + self.block(hash).map(|bytes| BlockView::new(&bytes).transactions()) } /// Get a list of transaction hashes for a given block. /// Returns None if block does not exist. pub fn transaction_hashes(&self, hash: &H256) -> Option> { - match self.block(hash) { - Some(bytes) => Some(BlockView::new(&bytes).transaction_hashes()), - None => None - } + self.block(hash).map(|bytes| BlockView::new(&bytes).transaction_hashes()) + } + + /// Get a list of uncles for a given block. + /// Returns None is block deos not exist. + pub fn uncles(&self, hash: &H256) -> Option> { + self.block(hash).map(|bytes| BlockView::new(&bytes).uncles()) } /// Get a list of uncle hashes for a given block. /// Returns None if block does not exist. pub fn uncle_hashes(&self, hash: &H256) -> Option> { - match self.block(hash) { - Some(bytes) => Some(BlockView::new(&bytes).uncle_hashes()), - None => None - } + self.block(hash).map(|bytes| BlockView::new(&bytes).uncle_hashes()) + } + + /// Get the familial details concerning a block. + pub fn block_details(&self, hash: &H256) -> Option { + self.query_extras(hash, &self.block_details) + } + + /// Get the hash of given block's number + pub fn number_hash(&self, hash: &U256) -> Option { + self.query_extras(hash, &self.block_hashes) } /// Get the transactions' log blooms of a block diff --git a/src/blockheader.rs b/src/blockheader.rs index baa79a15b..177d52ace 100644 --- a/src/blockheader.rs +++ b/src/blockheader.rs @@ -4,31 +4,6 @@ use util::uint::*; use util::rlp::*; 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 { self.rlp.val_at(1) } - pub fn uncle_hashes(&self) -> Vec { self.rlp.val_at(2) } -} - /// view onto block header rlp pub struct HeaderView<'a> { rlp: Rlp<'a> diff --git a/src/genesis.rs b/src/genesis.rs index 16cbab3e1..0c9640fe8 100644 --- a/src/genesis.rs +++ b/src/genesis.rs @@ -103,6 +103,7 @@ impl Genesis { #[test] fn test_genesis() { + use block::*; use blockheader::*; let g = Genesis::new_frontier();