openethereum/crates/ethcore/types/src/block.rs

78 lines
2.8 KiB
Rust

// Copyright 2015-2020 Parity Technologies (UK) Ltd.
// This file is part of OpenEthereum.
// OpenEthereum 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.
// OpenEthereum 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 OpenEthereum. If not, see <http://www.gnu.org/licenses/>.
//! Base data structure of this module is `Block`.
//!
//! Blocks can be produced by a local node or they may be received from the network.
//!
//! To create a block locally, we start with an `OpenBlock`. This block is mutable
//! and can be appended to with transactions and uncles.
//!
//! When ready, `OpenBlock` can be closed and turned into a `ClosedBlock`. A `ClosedBlock` can
//! be reopend again by a miner under certain circumstances. On block close, state commit is
//! performed.
//!
//! `LockedBlock` is a version of a `ClosedBlock` that cannot be reopened. It can be sealed
//! using an engine.
//!
//! `ExecutedBlock` is an underlaying data structure used by all structs above to store block
//! related info.
use crate::bytes::Bytes;
use crate::{
header::Header,
transaction::{TypedTransaction, UnverifiedTransaction},
BlockNumber,
};
use rlp::{DecoderError, Rlp, RlpStream};
/// A block, encoded as it is on the block chain.
#[derive(Default, Debug, Clone, PartialEq)]
pub struct Block {
/// The header of this block.
pub header: Header,
/// The transactions in this block.
pub transactions: Vec<UnverifiedTransaction>,
/// The uncles of this block.
pub uncles: Vec<Header>,
}
impl Block {
/// Get the RLP-encoding of the block with the seal.
pub fn rlp_bytes(&self) -> Bytes {
let mut block_rlp = RlpStream::new_list(3);
block_rlp.append(&self.header);
TypedTransaction::rlp_append_list(&mut block_rlp, &self.transactions);
block_rlp.append_list(&self.uncles);
block_rlp.out()
}
pub fn decode_rlp(rlp: &Rlp, eip1559_transition: BlockNumber) -> Result<Self, DecoderError> {
if rlp.as_raw().len() != rlp.payload_info()?.total() {
return Err(DecoderError::RlpIsTooBig);
}
if rlp.item_count()? != 3 {
return Err(DecoderError::RlpIncorrectListLen);
}
Ok(Block {
header: Header::decode_rlp(&rlp.at(0)?, eip1559_transition)?,
transactions: TypedTransaction::decode_rlp_list(&rlp.at(1)?)?,
uncles: Header::decode_rlp_list(&rlp.at(2)?, eip1559_transition)?,
})
}
}