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

Update tipset sorting #412

Merged
merged 4 commits into from
May 13, 2020
Merged
Show file tree
Hide file tree
Changes from all 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
4 changes: 2 additions & 2 deletions .github/workflows/ci-rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,10 @@ jobs:
override: true

- name: Cargo Build Tests
run: make test-all-verbose-no-run
run: make test-all-no-run

- name: Cargo test all
run: make test-all-verbose
run: make test-all

fmt:
name: rustfmt
Expand Down
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,8 @@ test-all: pull-serialization-tests
test-all-verbose: pull-serialization-tests
cargo test --verbose --all-features

test-all-verbose-no-run: pull-serialization-tests
cargo test --verbose --all-features --no-run
test-all-no-run: pull-serialization-tests
cargo test --all-features --no-run

# Checks if all headers are present and adds if not
license:
Expand Down
16 changes: 16 additions & 0 deletions blockchain/blocks/src/header.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ use num_bigint::{
BigUint,
};
use sha2::Digest;
use std::cmp::Ordering;
use std::fmt;
use std::time::{SystemTime, UNIX_EPOCH};
use vm::PoStProof;
Expand Down Expand Up @@ -201,6 +202,21 @@ impl<'de> Deserialize<'de> for BlockHeader {
}
}

impl Ord for BlockHeader {
fn cmp(&self, other: &Self) -> Ordering {
self.ticket()
.cmp(other.ticket())
// Only compare cid bytes when tickets are equal
.then_with(|| self.cid().to_bytes().cmp(&other.cid().to_bytes()))
}
}

impl PartialOrd for BlockHeader {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}

impl BlockHeader {
/// Generates a BlockHeader builder as a constructor
pub fn builder() -> BlockHeaderBuilder {
Expand Down
2 changes: 1 addition & 1 deletion blockchain/blocks/src/ticket.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use vm::PoStProof;
/// 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, Default)]
#[derive(Clone, Debug, PartialEq, PartialOrd, Eq, Default, Ord)]
pub struct Ticket {
/// A proof output by running a VRF on the VDFResult of the parent ticket
pub vrfproof: VRFProof,
Expand Down
15 changes: 4 additions & 11 deletions blockchain/blocks/src/tipset.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,22 +88,20 @@ impl Tipset {
/// A valid tipset contains a non-empty collection of blocks that have distinct miners and all
/// specify identical epoch, parents, weight, height, state root, receipt root;
/// contentID for headers are supposed to be distinct but until encoding is added will be equal.
pub fn new(headers: Vec<BlockHeader>) -> Result<Self, Error> {
pub fn new(mut headers: Vec<BlockHeader>) -> Result<Self, Error> {
verify_blocks(&headers)?;

// TODO Have a check the ensures CIDs are distinct
let cids = headers.iter().map(BlockHeader::cid).cloned().collect();

// sort headers by ticket size
// break ticket ties with the header CIDs, which are distinct
let mut sorted_headers = headers;
sorted_headers
.sort_by_key(|header| (header.ticket().vrfproof.clone(), header.cid().to_bytes()));
headers.sort();

// return tipset where sorted headers have smallest ticket size in the 0th index
// and the distinct keys
Ok(Self {
blocks: sorted_headers,
blocks: headers,
key: TipsetKeys {
// interim until CID check is in place
cids,
Expand Down Expand Up @@ -178,12 +176,7 @@ impl FullTipset {

// sort blocks on creation to allow for more seamless conversions between FullTipset
// and Tipset
blocks.sort_by_key(|block| {
(
block.header.ticket().vrfproof.clone(),
block.header.cid().to_bytes(),
)
});
blocks.sort_by(|block1, block2| block1.header().cmp(block2.header()));
Ok(Self { blocks })
}
/// Returns the first block of the tipset
Expand Down