diff --git a/ethcore/src/header.rs b/ethcore/src/header.rs index 1e1a54d57..0941c9ca6 100644 --- a/ethcore/src/header.rs +++ b/ethcore/src/header.rs @@ -61,7 +61,7 @@ pub struct Header { /// Block difficulty. pub difficulty: U256, - /// Block seal. + /// Vector of post-RLP-encoded fields. pub seal: Vec, /// The memoized hash of the RLP representation *including* the seal fields. @@ -201,7 +201,7 @@ impl Header { *self.bare_hash.borrow_mut() = None; } - // TODO: make these functions traity + // TODO: make these functions traity /// Place this header into an RLP stream `s`, optionally `with_seal`. pub fn stream_rlp(&self, s: &mut RlpStream, with_seal: Seal) { s.begin_list(13 + match with_seal { Seal::With => self.seal.len(), _ => 0 }); @@ -219,8 +219,8 @@ impl Header { s.append(&self.timestamp); s.append(&self.extra_data); if let Seal::With = with_seal { - for b in &self.seal { - s.append_raw(&b, 1); + for b in &self.seal { + s.append_raw(&b, 1); } } } @@ -275,4 +275,32 @@ impl Encodable for Header { #[cfg(test)] mod tests { + use rustc_serialize::hex::FromHex; + use util::rlp::{decode, encode}; + use super::Header; + + #[test] + fn test_header_seal_fields() { + // that's rlp of block header created with ethash engine. + let header_rlp = "f901f9a0d405da4e66f1445d455195229624e133f5baafe72b5cf7b3c36c12c8146e98b7a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a05fb2b4bfdef7b314451cb138a534d225c922fc0e5fbe25e451142732c3e25c25a088d2ec6b9860aae1a2c3b299f72b6a5d70d7f7ba4722c78f2c49ba96273c2158a007c6fdfa8eea7e86b81f5b0fc0f78f90cc19f4aa60d323151e0cac660199e9a1b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302008003832fefba82524d84568e932a80a0a0349d8c3df71f1a48a9df7d03fd5f14aeee7d91332c009ecaff0a71ead405bd88ab4e252a7e8c2a23".from_hex().unwrap(); + let mix_hash = "a0a0349d8c3df71f1a48a9df7d03fd5f14aeee7d91332c009ecaff0a71ead405bd".from_hex().unwrap(); + let nonce = "88ab4e252a7e8c2a23".from_hex().unwrap(); + + let header: Header = decode(&header_rlp); + let seal_fields = header.seal; + assert_eq!(seal_fields.len(), 2); + assert_eq!(seal_fields[0], mix_hash); + assert_eq!(seal_fields[1], nonce); + } + + #[test] + fn decode_and_encode_header() { + // that's rlp of block header created with ethash engine. + let header_rlp = "f901f9a0d405da4e66f1445d455195229624e133f5baafe72b5cf7b3c36c12c8146e98b7a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a05fb2b4bfdef7b314451cb138a534d225c922fc0e5fbe25e451142732c3e25c25a088d2ec6b9860aae1a2c3b299f72b6a5d70d7f7ba4722c78f2c49ba96273c2158a007c6fdfa8eea7e86b81f5b0fc0f78f90cc19f4aa60d323151e0cac660199e9a1b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302008003832fefba82524d84568e932a80a0a0349d8c3df71f1a48a9df7d03fd5f14aeee7d91332c009ecaff0a71ead405bd88ab4e252a7e8c2a23".from_hex().unwrap(); + + let header: Header = decode(&header_rlp); + let encoded_header = encode(&header).to_vec(); + + assert_eq!(header_rlp, encoded_header); + } } diff --git a/ethcore/src/views.rs b/ethcore/src/views.rs index 11e26eb5f..d47fec95a 100644 --- a/ethcore/src/views.rs +++ b/ethcore/src/views.rs @@ -301,11 +301,11 @@ impl<'a> HeaderView<'a> { /// Returns block extra data. pub fn extra_data(&self) -> Bytes { self.rlp.val_at(12) } - /// Returns block seal. + /// Returns a vector of post-RLP-encoded seal fields. pub fn seal(&self) -> Vec { let mut seal = vec![]; for i in 13..self.rlp.item_count() { - seal.push(self.rlp.val_at(i)); + seal.push(self.rlp.at(i).as_raw().to_vec()); } seal } @@ -316,3 +316,25 @@ impl<'a> Hashable for HeaderView<'a> { self.rlp.as_raw().sha3() } } + +#[cfg(test)] +mod tests { + use rustc_serialize::hex::FromHex; + use util::rlp::View; + use super::BlockView; + + #[test] + fn test_header_view_seal_fields() { + // that's rlp of block created with ethash engine. + let block_rlp = "f90261f901f9a0d405da4e66f1445d455195229624e133f5baafe72b5cf7b3c36c12c8146e98b7a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a05fb2b4bfdef7b314451cb138a534d225c922fc0e5fbe25e451142732c3e25c25a088d2ec6b9860aae1a2c3b299f72b6a5d70d7f7ba4722c78f2c49ba96273c2158a007c6fdfa8eea7e86b81f5b0fc0f78f90cc19f4aa60d323151e0cac660199e9a1b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302008003832fefba82524d84568e932a80a0a0349d8c3df71f1a48a9df7d03fd5f14aeee7d91332c009ecaff0a71ead405bd88ab4e252a7e8c2a23f862f86002018304cb2f94ec0e71ad0a90ffe1909d27dac207f7680abba42d01801ba03a347e72953c860f32b1eb2c78a680d8734b2ea08085d949d729479796f218d5a047ea6239d9e31ccac8af3366f5ca37184d26e7646e3191a3aeb81c4cf74de500c0".from_hex().unwrap(); + let mix_hash = "a0a0349d8c3df71f1a48a9df7d03fd5f14aeee7d91332c009ecaff0a71ead405bd".from_hex().unwrap(); + let nonce = "88ab4e252a7e8c2a23".from_hex().unwrap(); + + let block_view = BlockView::new(&block_rlp); + let header_view = block_view.header_view(); + let seal_fields = header_view.seal(); + assert_eq!(seal_fields.len(), 2); + assert_eq!(seal_fields[0], mix_hash); + assert_eq!(seal_fields[1], nonce); + } +}