Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement BlockHeader builder pattern #124

Merged
merged 5 commits into from
Jan 6, 2020
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion blockchain/blocks/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,5 @@ crypto = {path = "../../crypto"}
message = {path = "../../vm/message"}
clock = {path = "../../node/clock"}
cid = "0.3.1"
multihash = "0.8.0"
multihash = "0.8.0"
derive_builder = "0.9"
76 changes: 64 additions & 12 deletions blockchain/blocks/src/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use address::Address;
use cid::{Cid, Codec, Prefix, Version};
use clock::ChainEpoch;
use crypto::Signature;
use derive_builder::Builder;
use message::{SignedMessage, UnsignedMessage};
use multihash::Hash;

Expand All @@ -18,52 +19,94 @@ struct PoStCandidate {}
struct PoStRandomness {}
struct PoStProof {}

fn template_cid() -> Cid {
Cid::new(Codec::DagCBOR, Version::V1, &[])
}

/// BlockHeader defines header of a block in the Filecoin blockchain
#[derive(Clone, Debug, PartialEq)]
///
/// Usage:
/// ```
/// use blocks::{BlockHeader, TipSetKeys, Ticket, TxMeta};
/// use address::Address;
/// use cid::{Cid, Codec, Prefix, Version};
/// use clock::ChainEpoch;
///
/// BlockHeader::builder()
/// .parents(TipSetKeys::default())
/// .miner_address(Address::new_id(0).unwrap())
/// .bls_aggregate(vec![])
/// .weight(0) //optional
/// .epoch(ChainEpoch::default()) //optional
/// .messages(TxMeta::default()) //optional
/// .message_receipts(Cid::new(Codec::DagCBOR, Version::V1, &[])) //optional
/// .state_root(Cid::new(Codec::DagCBOR, Version::V1, &[])) //optional
/// .timestamp(0) //optional
/// .ticket(Ticket::default()) //optional
/// .build()
/// .unwrap();
/// ```
#[derive(Clone, Debug, PartialEq, Builder)]
#[builder(name = "BlockHeaderBuilder")]
pub struct BlockHeader {
/// CHAIN LINKING
///
// CHAIN LINKING
/// Parents is the set of parents this block was based on. Typically one,
/// but can be several in the case where there were multiple winning ticket-
/// holders for an epoch
pub parents: TipSetKeys,

/// weight is the aggregate chain weight of the parent set
#[builder(default)]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Can you consistently add white space

pub weight: u64,

/// epoch is the period in which a new block is generated. There may be multiple rounds in an epoch
#[builder(default)]
pub epoch: ChainEpoch,

/// MINER INFO
///
// MINER INFO
/// miner_address is the address of the miner actor that mined this block
pub miner_address: Address,

/// STATE
///
// STATE
/// messages contains the merkle links for bls_messages and secp_messages
#[builder(default)]
pub messages: TxMeta,

/// message_receipts is the Cid of the root of an array of MessageReceipts
#[builder(default = "template_cid()")]
pub message_receipts: Cid,

/// state_root is a cid pointer to the state tree after application of the transactions state transitions
#[builder(default = "template_cid()")]
pub state_root: Cid,

/// CONSENSUS
///
// CONSENSUS
/// timestamp, in seconds since the Unix epoch, at which this block was created
#[builder(default)]
pub timestamp: u64,

/// ticket is the ticket submitted with this block
#[builder(default)]
pub ticket: Ticket,

// SIGNATURES
//
/// aggregate signature of miner in block
pub bls_aggregate: Signature,

/// CACHE
///
// CACHE
#[builder(default = "template_cid()")]
pub cached_cid: Cid,

#[builder(default)]
pub cached_bytes: u8,
}

impl BlockHeader {
pub fn builder() -> BlockHeaderBuilder {
GregTheGreek marked this conversation as resolved.
Show resolved Hide resolved
BlockHeaderBuilder::default()
}
}

/// Block defines a full block
pub struct Block {
header: BlockHeader,
Expand All @@ -79,6 +122,15 @@ pub struct TxMeta {
pub secp_messages: Cid,
}

impl Default for TxMeta {
fn default() -> Self {
Self {
bls_messages: template_cid(),
secp_messages: template_cid(),
}
}
}

/// ElectionPoStVerifyInfo seems to be connected to VRF
/// see https://github.com/filecoin-project/lotus/blob/master/chain/sync.go#L1099
struct ElectionPoStVerifyInfo {
Expand Down
9 changes: 8 additions & 1 deletion blockchain/blocks/src/ticket.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,15 @@ use crypto::VRFResult;
/// A Ticket is a marker of a tick of the blockchain's clock. It is the source
/// of randomness for proofs of storage and leader election. It is generated
/// by the miner of a block using a VRF and a VDF.
#[derive(Clone, Debug, PartialEq, PartialOrd, Eq)]
#[derive(Clone, Debug, PartialEq, PartialOrd, Eq, Default)]
pub struct Ticket {
/// A proof output by running a VRF on the VDFResult of the parent ticket
pub vrfproof: VRFResult,
}

impl Ticket {
/// Ticket constructor
pub fn new(vrfproof: VRFResult) -> Self {
Self { vrfproof }
}
}
49 changes: 25 additions & 24 deletions blockchain/blocks/src/tipset.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,38 @@ use super::errors::Error;
use super::ticket::Ticket;
use cid::Cid;
use clock::ChainEpoch;
/// TipSet is an immutable set of blocks at the same height with the same parent set
/// Blocks in a tipset are canonically ordered by ticket size
#[derive(Clone, PartialEq, Debug)]
pub struct Tipset {
blocks: Vec<BlockHeader>,
key: TipSetKeys,
}

/// TipSetKeys is a set of CIDs forming a unique key for a TipSet
/// Equal keys will have equivalent iteration order, but note that the CIDs are *not* maintained in
/// the same order as the canonical iteration order of blocks in a tipset (which is by ticket)
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
#[derive(Clone, Debug, PartialEq, Eq, Hash, Default)]
pub struct TipSetKeys {
pub cids: Vec<Cid>,
}

impl TipSetKeys {
/// equals checks whether the set contains exactly the same CIDs as another.
fn equals(&self, key: TipSetKeys) -> bool {
if self.cids.len() != key.cids.len() {
return false;
}
for i in 0..key.cids.len() {
if self.cids[i] != key.cids[i] {
return false;
}
}
true
}
}

/// TipSet is an immutable set of blocks at the same height with the same parent set
/// Blocks in a tipset are canonically ordered by ticket size
#[derive(Clone, PartialEq, Debug)]
pub struct Tipset {
blocks: Vec<BlockHeader>,
key: TipSetKeys,
}

impl Tipset {
/// blocks returns vec of blocks from tipset
pub fn blocks(&self) -> Vec<BlockHeader> {
Expand Down Expand Up @@ -142,7 +158,7 @@ impl Tipset {
self.blocks[0].parents.clone()
}
/// weight returns the tipset's calculated weight
fn weight(&self) -> u64 {
pub fn weight(&self) -> u64 {
self.blocks[0].weight
}
/// tip_epoch returns the tipset's epoch
Expand All @@ -151,21 +167,6 @@ impl Tipset {
}
}

impl TipSetKeys {
/// equals checks whether the set contains exactly the same CIDs as another.
fn equals(&self, key: TipSetKeys) -> bool {
if self.cids.len() != key.cids.len() {
return false;
}
for i in 0..key.cids.len() {
if self.cids[i] != key.cids[i] {
return false;
}
}
true
}
}

#[cfg(test)]
mod tests {
use super::*;
Expand Down
2 changes: 1 addition & 1 deletion crypto/src/vrf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ impl VRFPublicKey {
}

/// VRFResult is the output from running a VRF
#[derive(Clone, Debug, PartialEq, Eq, Ord, PartialOrd)]
#[derive(Clone, Debug, PartialEq, Eq, Ord, PartialOrd, Default)]
pub struct VRFResult(Vec<u8>);

impl VRFResult {
Expand Down
2 changes: 1 addition & 1 deletion node/clock/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use chrono::{DateTime, NaiveDateTime, SecondsFormat, Utc};
const _ISO_FORMAT: &str = "%FT%X.%.9F";
const EPOCH_DURATION: i32 = 15;

#[derive(Clone, Debug, PartialEq, Eq, Hash)]
#[derive(Clone, Debug, PartialEq, Eq, Hash, Default)]
pub struct ChainEpoch(i64);

/// ChainEpochClock is used by the system node to assume weak clock synchrony amongst the other
Expand Down