diff --git a/blockchain/blocks/Cargo.toml b/blockchain/blocks/Cargo.toml index 1e84f8480385..ce4386b0e5c6 100644 --- a/blockchain/blocks/Cargo.toml +++ b/blockchain/blocks/Cargo.toml @@ -14,3 +14,4 @@ multihash = "0.9.3" derive_builder = "0.9" serde = { version = "1.0", features = ["derive"] } encoding = { path = "../../encoding" } +num-bigint = { git = "https://github.com/austinabell/num-bigint", rev = "f7084a9ed5a2b08d9bfb67790cb4ce9212193f31" } diff --git a/blockchain/blocks/src/header.rs b/blockchain/blocks/src/header.rs index 92d9a56a88eb..aa37d4cc62e1 100644 --- a/blockchain/blocks/src/header.rs +++ b/blockchain/blocks/src/header.rs @@ -9,6 +9,7 @@ use crypto::Signature; use derive_builder::Builder; use encoding::{Cbor, Error as EncodingError}; use multihash::Hash; +use num_bigint::BigUint; use serde::{Deserialize, Serialize}; use std::fmt; @@ -20,13 +21,14 @@ use std::fmt; /// use address::Address; /// use cid::{Cid, Codec, Prefix, Version}; /// use clock::ChainEpoch; +/// use num_bigint::BigUint; /// use crypto::Signature; /// /// BlockHeader::builder() /// .miner_address(Address::new_id(0).unwrap()) // optional /// .bls_aggregate(Signature::new_bls(vec![])) // optional /// .parents(TipSetKeys::default()) // optional -/// .weight(0) // optional +/// .weight(BigUint::from(0u8)) // optional /// .epoch(ChainEpoch::default()) // optional /// .messages(TxMeta::default()) // optional /// .message_receipts(Cid::default()) // optional @@ -48,7 +50,7 @@ pub struct BlockHeader { /// weight is the aggregate chain weight of the parent set #[builder(default)] - weight: u64, + weight: BigUint, /// epoch is the period in which a new block is generated. /// There may be multiple rounds in an epoch @@ -136,8 +138,8 @@ impl BlockHeader { &self.parents } /// Getter for BlockHeader weight - pub fn weight(&self) -> u64 { - self.weight + pub fn weight(&self) -> &BigUint { + &self.weight } /// Getter for BlockHeader epoch pub fn epoch(&self) -> &ChainEpoch { diff --git a/blockchain/blocks/src/tipset.rs b/blockchain/blocks/src/tipset.rs index b0edd9bc0827..2d8608924645 100644 --- a/blockchain/blocks/src/tipset.rs +++ b/blockchain/blocks/src/tipset.rs @@ -7,12 +7,17 @@ use super::{Block, BlockHeader, Error, Ticket}; use cid::Cid; use clock::ChainEpoch; -use serde::{Deserialize, Serialize}; +use encoding::{ + de::{self, Deserializer}, + ser::{self, Serializer}, +}; +use num_bigint::BigUint; +use serde::Deserialize; /// 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, Default, Serialize, Deserialize)] +#[derive(Clone, Debug, PartialEq, Eq, Hash, Default)] pub struct TipSetKeys { pub cids: Vec, } @@ -35,6 +40,26 @@ impl TipSetKeys { } } +impl ser::Serialize for TipSetKeys { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + let value = self.cids.clone(); + value.serialize(serializer) + } +} + +impl<'de> de::Deserialize<'de> for TipSetKeys { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + let cids: Vec = Deserialize::deserialize(deserializer)?; + Ok(TipSetKeys { cids }) + } +} + /// 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, Default)] @@ -158,8 +183,8 @@ impl Tipset { &self.blocks[0].parents() } /// Returns the tipset's calculated weight - pub fn weight(&self) -> u64 { - self.blocks[0].weight() + pub fn weight(&self) -> &BigUint { + &self.blocks[0].weight() } /// Returns the tipset's epoch pub fn tip_epoch(&self) -> &ChainEpoch { @@ -198,6 +223,7 @@ mod tests { use address::Address; use cid::Cid; use crypto::VRFResult; + use num_bigint::BigUint; const WEIGHT: u64 = 1; const CACHED_BYTES: [u8; 1] = [0]; @@ -228,7 +254,7 @@ mod tests { .ticket(Ticket { vrfproof: VRFResult::new(ticket_p), }) - .weight(WEIGHT) + .weight(BigUint::from(WEIGHT)) .cached_cid(cid) .build() .unwrap(); @@ -302,7 +328,7 @@ mod tests { #[test] fn weight_test() { let tipset = setup(); - assert_eq!(tipset.weight(), WEIGHT); + assert_eq!(tipset.weight(), &BigUint::from(WEIGHT)); } #[test] diff --git a/blockchain/sync_manager/Cargo.toml b/blockchain/sync_manager/Cargo.toml index e5918364568b..c45d63b9e3ee 100644 --- a/blockchain/sync_manager/Cargo.toml +++ b/blockchain/sync_manager/Cargo.toml @@ -11,4 +11,5 @@ libp2p = { git = "https://github.com/SigP/rust-libp2p", rev = "776d13ef04635896 chain = { path ="../chain" } [dev-dependencies] -cid = { package = "ferret_cid", path = "../../ipld/cid" } \ No newline at end of file +cid = { package = "ferret_cid", path = "../../ipld/cid" } +num-bigint = { git = "https://github.com/austinabell/num-bigint", rev = "f7084a9ed5a2b08d9bfb67790cb4ce9212193f31" } diff --git a/blockchain/sync_manager/src/bucket.rs b/blockchain/sync_manager/src/bucket.rs index eaf94a8abbdb..78058f8b1adb 100644 --- a/blockchain/sync_manager/src/bucket.rs +++ b/blockchain/sync_manager/src/bucket.rs @@ -74,10 +74,11 @@ mod tests { use super::*; use blocks::BlockHeader; use cid::Cid; + use num_bigint::BigUint; fn create_header(weight: u64, parent_bz: &[u8], cached_bytes: &[u8]) -> BlockHeader { let header = BlockHeader::builder() - .weight(weight) + .weight(BigUint::from(weight)) .cached_bytes(cached_bytes.to_vec()) .cached_cid(Cid::from_bytes_default(parent_bz).unwrap()) .build() @@ -97,12 +98,18 @@ mod tests { // Test the comparison of tipsets let bucket = SyncBucket::new(vec![&l_tip, &h_tip]); - assert_eq!(bucket.heaviest_tipset().unwrap().weight(), 3); + assert_eq!( + bucket.heaviest_tipset().unwrap().weight(), + &BigUint::from(3u8) + ); assert_eq!(bucket.tips.len(), 2); // assert bucket with just one tipset still resolves let bucket = SyncBucket::new(vec![&l_tip]); - assert_eq!(bucket.heaviest_tipset().unwrap().weight(), 1); + assert_eq!( + bucket.heaviest_tipset().unwrap().weight(), + &BigUint::from(1u8) + ); } #[test] diff --git a/blockchain/sync_manager/src/sync.rs b/blockchain/sync_manager/src/sync.rs index cea91ccf04a4..ccdad2fd40b0 100644 --- a/blockchain/sync_manager/src/sync.rs +++ b/blockchain/sync_manager/src/sync.rs @@ -42,9 +42,10 @@ impl<'a> Syncer<'a> { // TODO send pubsub message indicating incoming blocks // TODO Add peer to blocksync - // compare targetweight to heaviest weight stored; ignore otherwise + // compare target_weight to heaviest weight stored; ignore otherwise let best_weight = self.chain_store.get_heaviest_tipset().blocks()[0].weight(); - let target_weight = fts.tipset()?.blocks()[0].weight(); + let target_weight = fts.blocks()[0].to_header().weight(); + if !target_weight.lt(&best_weight) { // Store incoming block header self.chain_store.persist_headers(&fts.tipset()?).ok(); diff --git a/blockchain/sync_manager/tests/manager_test.rs b/blockchain/sync_manager/tests/manager_test.rs index bedcf1ab38f0..57d941322960 100644 --- a/blockchain/sync_manager/tests/manager_test.rs +++ b/blockchain/sync_manager/tests/manager_test.rs @@ -3,11 +3,12 @@ use blocks::{BlockHeader, Tipset}; use cid::Cid; +use num_bigint::BigUint; use sync_manager::SyncManager; fn create_header(weight: u64, parent_bz: &[u8], cached_bytes: &[u8]) -> BlockHeader { let header = BlockHeader::builder() - .weight(weight) + .weight(BigUint::from(weight)) .cached_bytes(cached_bytes.to_vec()) .cached_cid(Cid::from_bytes_default(parent_bz).unwrap()) .build()