Skip to content

Commit

Permalink
Move sigenr index to SeedInfo struct
Browse files Browse the repository at this point in the history
  • Loading branch information
HoOngEe committed Nov 26, 2019
1 parent feeae37 commit 7add5db
Show file tree
Hide file tree
Showing 9 changed files with 151 additions and 181 deletions.
1 change: 1 addition & 0 deletions core/src/consensus/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ pub use self::null_engine::NullEngine;
pub use self::simple_poa::SimplePoA;
pub use self::solo::Solo;
pub use self::sortition::vrf_sortition::{Priority, PriorityInfo, VRFSortition};
pub use self::sortition::PriorityMessage;
pub use self::tendermint::{
ConsensusMessage, Height, Step, Tendermint, TendermintParams, TimeGapParams, View, VoteOn, VoteStep,
};
Expand Down
21 changes: 19 additions & 2 deletions core/src/consensus/sortition/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ mod draw;
pub mod seed;
pub mod vrf_sortition;

use std::cmp::Ordering;
use std::sync::Arc;

use ckey::Public;
Expand All @@ -36,11 +37,27 @@ pub struct PriorityMessage {
pub priority: PriorityInfo,
}

impl Ord for PriorityMessage {
fn cmp(&self, other: &Self) -> Ordering {
self.priority().cmp(&other.priority())
}
}

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

impl PriorityMessage {
pub fn seed(&self) -> &VRFSeed {
self.seed.seed()
}

pub fn seed_signer_idx(&self) -> usize {
self.seed.signer_idx()
}

pub fn verify_seed(
&self,
height: Height,
Expand Down Expand Up @@ -109,7 +126,7 @@ mod priority_message_tests {
sortition_scheme.create_highest_priority_info(seed.into(), &signer, voting_power).unwrap().unwrap();

let priority_message = PriorityMessage {
seed: SeedInfo::from_seed_and_proof(seed.to_vec(), vec![]),
seed: SeedInfo::from_fields(0, seed.to_vec(), vec![]),
priority: priority_info,
};
assert!(priority_message.verify_priority(&pub_key, voting_power, &sortition_scheme).unwrap());
Expand All @@ -133,7 +150,7 @@ mod priority_message_tests {
sortition_scheme.create_highest_priority_info(seed.into(), &signer, voting_power).unwrap().unwrap();

let priority_message = PriorityMessage {
seed: SeedInfo::from_seed_and_proof(seed.to_vec(), vec![]),
seed: SeedInfo::from_fields(0, seed.to_vec(), vec![]),
priority: priority_info,
};
rlp_encode_and_decode_test!(priority_message);
Expand Down
8 changes: 7 additions & 1 deletion core/src/consensus/sortition/seed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,18 +75,24 @@ impl VRFSeed {

#[derive(Debug, Eq, PartialEq, Clone, RlpEncodable, RlpDecodable)]
pub struct SeedInfo {
seed_signer_idx: usize,
seed: VRFSeed,
proof: Vec<u8>,
}

impl SeedInfo {
pub fn from_seed_and_proof(seed: Vec<u8>, proof: Vec<u8>) -> Self {
pub fn from_fields(seed_signer_idx: usize, seed: Vec<u8>, proof: Vec<u8>) -> Self {
Self {
seed_signer_idx,
seed: H256::from_slice(&seed).into(),
proof,
}
}

pub fn signer_idx(&self) -> usize {
self.seed_signer_idx
}

pub fn seed(&self) -> &VRFSeed {
&self.seed
}
Expand Down
11 changes: 5 additions & 6 deletions core/src/consensus/tendermint/message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ use snap;

pub use super::super::sortition::PriorityMessage;
use super::super::BitSet;
use super::sortition_info_collector::SortitionInfo;
use super::{Height, Step, View};
use crate::consensus::Priority;

Expand Down Expand Up @@ -117,7 +116,7 @@ pub enum TendermintMessage {
ConsensusMessage(Vec<Bytes>),
ProposalBlock {
signature: SchnorrSignature,
sortition_info: SortitionInfo,
priority_message: PriorityMessage,
view: View,
message: Bytes,
},
Expand Down Expand Up @@ -154,14 +153,14 @@ impl Encodable for TendermintMessage {
}
TendermintMessage::ProposalBlock {
signature,
sortition_info,
priority_message,
view,
message,
} => {
s.begin_list(5);
s.append(&MESSAGE_ID_PROPOSAL_BLOCK);
s.append(signature);
s.append(sortition_info);
s.append(priority_message);
s.append(view);
// FIXME: Consider compressing

Expand Down Expand Up @@ -246,7 +245,7 @@ impl Decodable for TendermintMessage {
})
}
let signature = rlp.at(1)?;
let sortition_info = rlp.at(2)?;
let priority_message = rlp.at(2)?;
let view = rlp.at(3)?;
let compressed_message: Vec<u8> = rlp.val_at(4)?;
let uncompressed_message = {
Expand All @@ -260,7 +259,7 @@ impl Decodable for TendermintMessage {

TendermintMessage::ProposalBlock {
signature: signature.as_val()?,
sortition_info: sortition_info.as_val()?,
priority_message: priority_message.as_val()?,
view: view.as_val()?,
message: uncompressed_message,
}
Expand Down
2 changes: 1 addition & 1 deletion core/src/consensus/tendermint/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ mod tests {
}

fn create_dummy_seed_info() -> SeedInfo {
SeedInfo::from_seed_and_proof(vec![0x0], vec![0x22])
SeedInfo::from_fields(0, vec![0x0], vec![0x22])
}

#[test]
Expand Down
15 changes: 7 additions & 8 deletions core/src/consensus/tendermint/network.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ use rlp::{Encodable, Rlp};
use super::super::BitSet;
use super::message::*;
use super::params::TimeoutParams;
use super::sortition_info_collector::SortitionInfo;
use super::types::{PeerState, Step, View};
use super::worker;
use crate::consensus::{EngineError, Priority};
Expand Down Expand Up @@ -141,14 +140,14 @@ impl TendermintExtension {
fn broadcast_proposal_block(
&self,
signature: SchnorrSignature,
sortition_info: SortitionInfo,
priority_message: PriorityMessage,
view: View,
message: Bytes,
) {
let message = Arc::new(
TendermintMessage::ProposalBlock {
signature,
sortition_info,
priority_message,
message,
view,
}
Expand Down Expand Up @@ -280,15 +279,15 @@ impl NetworkExtension<Event> for TendermintExtension {
}
Ok(TendermintMessage::ProposalBlock {
signature,
sortition_info,
priority_message,
view,
message,
}) => {
let (result, receiver) = crossbeam::bounded(1);
self.inner
.send(worker::Event::ProposalBlock {
signature,
sortition_info: sortition_info.clone(),
priority_message: priority_message.clone(),
view,
message: message.clone(),
result,
Expand Down Expand Up @@ -448,11 +447,11 @@ impl NetworkExtension<Event> for TendermintExtension {
} => self.set_timer_step(step, view, expired_token_nonce),
Event::BroadcastProposalBlock {
signature,
sortition_info,
priority_message,
view,
message,
} => {
self.broadcast_proposal_block(signature, sortition_info, view, message);
self.broadcast_proposal_block(signature, priority_message, view, message);
}
}
}
Expand Down Expand Up @@ -483,7 +482,7 @@ pub enum Event {
},
BroadcastProposalBlock {
signature: SchnorrSignature,
sortition_info: SortitionInfo,
priority_message: PriorityMessage,
view: View,
message: Bytes,
},
Expand Down
97 changes: 25 additions & 72 deletions core/src/consensus/tendermint/sortition_info_collector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,76 +14,30 @@
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.

use std::cmp::Ordering;
use std::collections::{BTreeMap, BinaryHeap};

use rug::{integer::Order, Integer};

use super::{PriorityMessage, SortitionRound};
use crate::consensus::Priority;

/// Storing Priorities
#[derive(Default)]
pub struct SortitionInfoCollector {
priorities: BTreeMap<SortitionRound, BinaryHeap<SortitionInfo>>,
}

#[derive(Debug, Eq, Clone, PartialEq, RlpEncodable, RlpDecodable)]
pub struct SortitionInfo {
message: PriorityMessage,
signer_idx: usize,
}

impl Ord for SortitionInfo {
fn cmp(&self, other: &Self) -> Ordering {
let self_as_int = Integer::from_digits(&self.message.priority(), Order::MsfBe);
let other_as_int = Integer::from_digits(&other.message.priority(), Order::MsfBe);

self_as_int.cmp(&other_as_int)
}
}

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

impl SortitionInfo {
pub fn from_message_and_idx(message: &PriorityMessage, signer_idx: usize) -> Self {
Self {
message: message.clone(),
signer_idx,
}
}

pub fn signer_idx(&self) -> usize {
self.signer_idx
}

pub fn message(&self) -> &PriorityMessage {
&self.message
}

pub fn priority(&self) -> Priority {
self.message.priority()
}
pub struct PriorityMessageCollector {
messages: BTreeMap<SortitionRound, BinaryHeap<PriorityMessage>>,
}

impl SortitionInfoCollector {
pub fn insert(&mut self, info: SortitionInfo, round: SortitionRound) {
self.priorities.entry(round).or_insert_with(Default::default).push(info);
impl PriorityMessageCollector {
pub fn insert(&mut self, info: PriorityMessage, round: SortitionRound) {
self.messages.entry(round).or_insert_with(Default::default).push(info);
}

pub fn get_highest_priority(&self, round: &SortitionRound) -> Option<SortitionInfo> {
self.priorities.get(round).and_then(|heap| heap.peek()).cloned()
pub fn get_highest_priority_message(&self, round: &SortitionRound) -> Option<PriorityMessage> {
self.messages.get(round).and_then(|heap| heap.peek()).cloned()
}

/// Throw away priorities older than the given round.
pub fn throw_away_old(&mut self, round: &SortitionRound) {
let new_collector = self.priorities.split_off(round);
let new_collector = self.messages.split_off(round);
assert!(!new_collector.is_empty());
self.priorities = new_collector;
self.messages = new_collector;
}
}

Expand All @@ -92,53 +46,52 @@ mod sortition_info_collector_tests {
use super::*;
use crate::consensus::{Priority, PriorityInfo, SeedInfo};

fn create_sortition_info_with_priority_and_signer_idx(priority: Priority, signer_idx: usize) -> SortitionInfo {
let message = PriorityMessage {
seed: SeedInfo::from_seed_and_proof(vec![0x0], vec![0x22]),
fn create_message_with_priority_and_signer_idx(priority: Priority, signer_idx: usize) -> PriorityMessage {
PriorityMessage {
seed: SeedInfo::from_fields(signer_idx, vec![0x0], vec![0x22]),
priority: PriorityInfo::create_from_members(priority, 0, vec![], vec![]),
};
SortitionInfo::from_message_and_idx(&message, signer_idx)
}
}

#[test]
fn compare_sortition_info() {
let greater_priority_info_summary = create_sortition_info_with_priority_and_signer_idx(0xffu64.into(), 0);
let less_priority_info_summary = create_sortition_info_with_priority_and_signer_idx(0x7fu64.into(), 1);
let greater_priority_info_summary = create_message_with_priority_and_signer_idx(0xffu64.into(), 0);
let less_priority_info_summary = create_message_with_priority_and_signer_idx(0x7fu64.into(), 1);
assert!(greater_priority_info_summary > less_priority_info_summary);
}

#[test]
fn compare_sortition_info2() {
let greater_priority_info_summary = create_sortition_info_with_priority_and_signer_idx(0x55555544u64.into(), 0);
let less_priority_info_summary = create_sortition_info_with_priority_and_signer_idx(0x55555523u64.into(), 22);
let greater_priority_info_summary = create_message_with_priority_and_signer_idx(0x55555544u64.into(), 0);
let less_priority_info_summary = create_message_with_priority_and_signer_idx(0x55555523u64.into(), 22);
assert!(greater_priority_info_summary > less_priority_info_summary);
}

fn add_fixed_priorities(collector: &mut SortitionInfoCollector, round: SortitionRound) {
fn add_fixed_priorities(collector: &mut PriorityMessageCollector, round: SortitionRound) {
[0x55u64, 0xffu64, 0x44u64, 0xeeu64]
.into_iter()
.zip([1, 2, 3, 4].iter())
.map(|(priority, idx)| create_sortition_info_with_priority_and_signer_idx((*priority).into(), *idx))
.map(|(priority, idx)| create_message_with_priority_and_signer_idx((*priority).into(), *idx))
.for_each(|sortition_info| collector.insert(sortition_info, round));
}

#[test]
fn insert_and_get_highest() {
let mut collector: SortitionInfoCollector = Default::default();
let mut collector: PriorityMessageCollector = Default::default();
let round = SortitionRound {
height: 1,
view: 0,
};
add_fixed_priorities(&mut collector, round);
assert_eq!(
collector.get_highest_priority(&round).unwrap(),
create_sortition_info_with_priority_and_signer_idx(0xffu64.into(), 2)
collector.get_highest_priority_message(&round).unwrap(),
create_message_with_priority_and_signer_idx(0xffu64.into(), 2)
);
}

#[test]
fn throw_away_old() {
let mut collector: SortitionInfoCollector = Default::default();
let mut collector: PriorityMessageCollector = Default::default();
let rounds = [(1, 0), (3, 1), (5, 2), (100, 7), (0, 8)].into_iter().map(|(height, view)| SortitionRound {
height: *height,
view: *view,
Expand All @@ -152,9 +105,9 @@ mod sortition_info_collector_tests {
rounds
.clone()
.filter(|round| round >= &target_round)
.for_each(|round_gte| assert!(collector.get_highest_priority(&round_gte).is_some()));
.for_each(|round_gte| assert!(collector.get_highest_priority_message(&round_gte).is_some()));
rounds
.filter(|round| round < &target_round)
.for_each(|round_lt| assert!(collector.get_highest_priority(&round_lt).is_none()))
.for_each(|round_lt| assert!(collector.get_highest_priority_message(&round_lt).is_none()))
}
}
Loading

0 comments on commit 7add5db

Please sign in to comment.