openethereum/ethcore/src/header.rs

256 lines
7.4 KiB
Rust
Raw Normal View History

2016-02-05 13:40:41 +01:00
// Copyright 2015, 2016 Ethcore (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
2016-02-02 15:29:53 +01:00
//! Block header.
use util::*;
use basic_types::*;
use time::now_utc;
2016-01-20 20:45:31 +01:00
/// Type for Block number
pub type BlockNumber = u64;
/// A block header.
///
/// Reflects the specific RLP fields of a block in the chain with additional room for the seal
/// which is non-specific.
///
/// Doesn't do all that much on its own.
2016-02-02 18:21:31 +01:00
#[derive(Debug, Clone)]
pub struct Header {
2016-01-10 14:05:39 +01:00
// TODO: make all private.
2016-02-02 18:21:31 +01:00
/// Parent hash.
2015-12-17 19:26:21 +01:00
pub parent_hash: H256,
2016-02-02 18:21:31 +01:00
/// Block timestamp.
pub timestamp: u64,
2016-02-02 18:21:31 +01:00
/// Block number.
pub number: BlockNumber,
2016-02-02 18:21:31 +01:00
/// Block author.
2015-12-17 19:26:21 +01:00
pub author: Address,
2016-02-02 18:21:31 +01:00
/// Transactions root.
2015-12-17 19:26:21 +01:00
pub transactions_root: H256,
2016-02-02 18:21:31 +01:00
/// Block uncles hash.
2015-12-17 19:26:21 +01:00
pub uncles_hash: H256,
2016-02-02 18:21:31 +01:00
/// Block extra data.
2015-12-17 19:26:21 +01:00
pub extra_data: Bytes,
2016-02-02 18:21:31 +01:00
/// State root.
2015-12-17 19:26:21 +01:00
pub state_root: H256,
2016-02-02 18:21:31 +01:00
/// Block receipts root.
2015-12-17 19:26:21 +01:00
pub receipts_root: H256,
2016-02-02 18:21:31 +01:00
/// Block bloom.
2015-12-17 19:26:21 +01:00
pub log_bloom: LogBloom,
2016-02-02 18:21:31 +01:00
/// Gas used for contracts execution.
2015-12-17 19:26:21 +01:00
pub gas_used: U256,
2016-02-02 18:21:31 +01:00
/// Block gas limit.
2015-12-17 19:26:21 +01:00
pub gas_limit: U256,
2016-02-02 18:21:31 +01:00
/// Block difficulty.
2015-12-17 19:26:21 +01:00
pub difficulty: U256,
2016-02-02 18:21:31 +01:00
/// Block seal.
2015-12-17 19:26:21 +01:00
pub seal: Vec<Bytes>,
2015-12-26 15:47:07 +01:00
2016-02-03 13:20:32 +01:00
/// The memoized hash of the RLP representation *including* the seal fields.
pub hash: RefCell<Option<H256>>,
2016-02-03 13:20:32 +01:00
/// The memoized hash of the RLP representation *without* the seal fields.
2016-01-17 12:00:34 +01:00
pub bare_hash: RefCell<Option<H256>>,
}
2016-02-02 18:21:31 +01:00
impl Default for Header {
fn default() -> Self {
Header {
2016-01-04 13:25:32 +01:00
parent_hash: ZERO_H256.clone(),
timestamp: 0,
number: 0,
2016-01-04 13:25:32 +01:00
author: ZERO_ADDRESS.clone(),
2015-12-27 00:48:03 +01:00
transactions_root: SHA3_NULL_RLP,
uncles_hash: SHA3_EMPTY_LIST_RLP,
extra_data: vec![],
2015-12-27 00:48:03 +01:00
state_root: SHA3_NULL_RLP,
receipts_root: SHA3_NULL_RLP,
2016-01-04 13:25:32 +01:00
log_bloom: ZERO_LOGBLOOM.clone(),
2015-12-27 00:48:03 +01:00
gas_used: ZERO_U256,
gas_limit: ZERO_U256,
2015-12-27 00:48:03 +01:00
difficulty: ZERO_U256,
seal: vec![],
2016-01-04 13:25:32 +01:00
hash: RefCell::new(None),
2016-01-17 12:00:34 +01:00
bare_hash: RefCell::new(None),
}
}
2016-02-02 18:21:31 +01:00
}
impl Header {
/// Create a new, default-valued, header.
pub fn new() -> Self {
Self::default()
}
2015-12-24 17:18:47 +01:00
2016-02-03 13:20:32 +01:00
/// Get the number field of the header.
pub fn number(&self) -> BlockNumber { self.number }
2016-02-03 13:20:32 +01:00
/// Get the timestamp field of the header.
pub fn timestamp(&self) -> u64 { self.timestamp }
2016-02-03 13:20:32 +01:00
/// Get the author field of the header.
2016-01-10 14:05:39 +01:00
pub fn author(&self) -> &Address { &self.author }
2016-02-03 13:20:32 +01:00
/// Get the extra data field of the header.
2016-01-10 14:05:39 +01:00
pub fn extra_data(&self) -> &Bytes { &self.extra_data }
2016-02-03 13:20:32 +01:00
/// Get the state root field of the header.
pub fn state_root(&self) -> &H256 { &self.state_root }
2016-02-03 13:20:32 +01:00
/// Get the receipts root field of the header.
pub fn receipts_root(&self) -> &H256 { &self.receipts_root }
2016-02-03 13:20:32 +01:00
/// Get the gas limit field of the header.
2016-01-15 23:32:17 +01:00
pub fn gas_limit(&self) -> &U256 { &self.gas_limit }
2016-02-03 13:20:32 +01:00
/// Get the difficulty field of the header.
2016-01-15 23:32:17 +01:00
pub fn difficulty(&self) -> &U256 { &self.difficulty }
2016-02-03 13:20:32 +01:00
/// Get the seal field of the header.
2016-01-10 14:05:39 +01:00
pub fn seal(&self) -> &Vec<Bytes> { &self.seal }
// TODO: seal_at, set_seal_at &c.
2016-02-03 13:20:32 +01:00
/// Set the number field of the header.
pub fn set_number(&mut self, a: BlockNumber) { self.number = a; self.note_dirty(); }
2016-02-03 13:20:32 +01:00
/// Set the timestamp field of the header.
pub fn set_timestamp(&mut self, a: u64) { self.timestamp = a; self.note_dirty(); }
2016-02-03 13:20:32 +01:00
/// Set the timestamp field of the header to the current time.
pub fn set_timestamp_now(&mut self) { self.timestamp = now_utc().to_timespec().sec as u64; self.note_dirty(); }
2016-02-03 13:20:32 +01:00
/// Set the author field of the header.
2016-01-10 14:05:39 +01:00
pub fn set_author(&mut self, a: Address) { if a != self.author { self.author = a; self.note_dirty(); } }
2016-02-03 13:20:32 +01:00
/// Set the extra data field of the header.
2016-01-10 14:05:39 +01:00
pub fn set_extra_data(&mut self, a: Bytes) { if a != self.extra_data { self.extra_data = a; self.note_dirty(); } }
2016-02-03 13:20:32 +01:00
/// Set the gas used field of the header.
2016-01-15 23:32:17 +01:00
pub fn set_gas_used(&mut self, a: U256) { self.gas_used = a; self.note_dirty(); }
2016-02-03 13:20:32 +01:00
/// Set the gas limit field of the header.
2016-01-15 23:32:17 +01:00
pub fn set_gas_limit(&mut self, a: U256) { self.gas_limit = a; self.note_dirty(); }
2016-02-03 13:20:32 +01:00
/// Set the difficulty field of the header.
2016-01-15 23:32:17 +01:00
pub fn set_difficulty(&mut self, a: U256) { self.difficulty = a; self.note_dirty(); }
2016-02-03 13:20:32 +01:00
/// Set the seal field of the header.
2016-01-10 14:05:39 +01:00
pub fn set_seal(&mut self, a: Vec<Bytes>) { self.seal = a; self.note_dirty(); }
/// Get the hash of this header (sha3 of the RLP).
2015-12-24 17:18:47 +01:00
pub fn hash(&self) -> H256 {
let mut hash = self.hash.borrow_mut();
match &mut *hash {
&mut Some(ref h) => h.clone(),
hash @ &mut None => {
*hash = Some(self.rlp_sha3(Seal::With));
hash.as_ref().unwrap().clone()
}
2015-12-26 15:47:07 +01:00
}
2015-12-24 17:18:47 +01:00
}
2016-01-17 12:00:34 +01:00
/// Get the hash of the header excluding the seal
pub fn bare_hash(&self) -> H256 {
let mut hash = self.bare_hash.borrow_mut();
match &mut *hash {
&mut Some(ref h) => h.clone(),
hash @ &mut None => {
*hash = Some(self.rlp_sha3(Seal::Without));
hash.as_ref().unwrap().clone()
}
}
}
/// Note that some fields have changed. Resets the memoised hash.
pub fn note_dirty(&self) {
*self.hash.borrow_mut() = None;
2016-01-17 12:00:34 +01:00
*self.bare_hash.borrow_mut() = None;
}
// TODO: make these functions traity
2016-02-03 13:20:32 +01:00
/// Place this header into an RLP stream `s`, optionally `with_seal`.
pub fn stream_rlp(&self, s: &mut RlpStream, with_seal: Seal) {
2016-01-27 17:22:01 +01:00
s.begin_list(13 + match with_seal { Seal::With => self.seal.len(), _ => 0 });
s.append(&self.parent_hash);
s.append(&self.uncles_hash);
s.append(&self.author);
s.append(&self.state_root);
s.append(&self.transactions_root);
s.append(&self.receipts_root);
s.append(&self.log_bloom);
s.append(&self.difficulty);
s.append(&self.number);
s.append(&self.gas_limit);
s.append(&self.gas_used);
s.append(&self.timestamp);
s.append(&self.extra_data);
2016-01-17 15:56:09 +01:00
if let Seal::With = with_seal {
for b in &self.seal {
s.append_raw(&b, 1);
}
}
}
2016-02-03 13:20:32 +01:00
/// Get the RLP of this header, optionally `with_seal`.
pub fn rlp(&self, with_seal: Seal) -> Bytes {
let mut s = RlpStream::new();
self.stream_rlp(&mut s, with_seal);
s.out()
}
2016-02-03 13:20:32 +01:00
/// Get the SHA3 (Keccak) of this header, optionally `with_seal`.
pub fn rlp_sha3(&self, with_seal: Seal) -> H256 { self.rlp(with_seal).sha3() }
2015-12-08 16:31:36 +01:00
}
impl Decodable for Header {
fn decode<D>(decoder: &D) -> Result<Self, DecoderError> where D: Decoder {
2015-12-26 15:47:07 +01:00
let r = decoder.as_rlp();
2015-12-14 12:09:32 +01:00
2015-12-14 15:22:41 +01:00
let mut blockheader = Header {
2015-12-26 15:47:07 +01:00
parent_hash: try!(r.val_at(0)),
uncles_hash: try!(r.val_at(1)),
author: try!(r.val_at(2)),
state_root: try!(r.val_at(3)),
transactions_root: try!(r.val_at(4)),
receipts_root: try!(r.val_at(5)),
log_bloom: try!(r.val_at(6)),
difficulty: try!(r.val_at(7)),
number: try!(r.val_at(8)),
gas_limit: try!(r.val_at(9)),
gas_used: try!(r.val_at(10)),
timestamp: try!(r.val_at(11)),
extra_data: try!(r.val_at(12)),
2015-12-14 12:09:32 +01:00
seal: vec![],
2016-01-17 12:00:34 +01:00
hash: RefCell::new(Some(r.as_raw().sha3())),
bare_hash: RefCell::new(None),
2015-12-14 12:09:32 +01:00
};
2015-12-14 15:22:41 +01:00
2015-12-26 15:47:07 +01:00
for i in 13..r.item_count() {
2016-01-08 16:00:32 +01:00
blockheader.seal.push(try!(r.at(i)).as_raw().to_vec())
2015-12-14 15:22:41 +01:00
}
2015-12-14 12:09:32 +01:00
Ok(blockheader)
2015-12-08 16:31:36 +01:00
}
}
impl Encodable for Header {
2016-01-27 17:22:01 +01:00
fn rlp_append(&self, s: &mut RlpStream) {
self.stream_rlp(s, Seal::With);
2015-12-08 16:31:36 +01:00
}
}
2015-12-09 00:45:33 +01:00
#[cfg(test)]
mod tests {
}