Merge branch 'blop-pool' into validator-enhancements

This commit is contained in:
Age Manning
2019-03-30 16:16:30 +11:00
24 changed files with 1423 additions and 391 deletions

View File

@@ -1,7 +1,7 @@
use super::PublicKey;
use bls_aggregates::AggregatePublicKey as RawAggregatePublicKey;
/// A single BLS signature.
/// A BLS aggregate public key.
///
/// This struct is a wrapper upon a base type and provides helper functions (e.g., SSZ
/// serialization).
@@ -17,7 +17,7 @@ impl AggregatePublicKey {
self.0.add(public_key.as_raw())
}
/// Returns the underlying signature.
/// Returns the underlying public key.
pub fn as_raw(&self) -> &RawAggregatePublicKey {
&self.0
}

View File

@@ -27,6 +27,11 @@ impl AggregateSignature {
self.0.add(signature.as_raw())
}
/// Add (aggregate) another `AggregateSignature`.
pub fn add_aggregate(&mut self, agg_signature: &AggregateSignature) {
self.0.add_aggregate(&agg_signature.0)
}
/// Verify the `AggregateSignature` against an `AggregatePublicKey`.
///
/// Only returns `true` if the set of keys in the `AggregatePublicKey` match the set of keys

View File

@@ -35,6 +35,11 @@ impl FakeAggregateSignature {
// Do nothing.
}
/// Does glorious nothing.
pub fn add_aggregate(&mut self, _agg_sig: &FakeAggregateSignature) {
// Do nothing.
}
/// _Always_ returns `true`.
pub fn verify(
&self,

View File

@@ -89,6 +89,11 @@ impl BooleanBitfield {
self.len() == 0
}
/// Returns true if all bits are set to 0.
pub fn is_zero(&self) -> bool {
self.0.none()
}
/// Returns the number of bytes required to represent this bitfield.
pub fn num_bytes(&self) -> usize {
self.to_bytes().len()
@@ -104,6 +109,44 @@ impl BooleanBitfield {
pub fn to_bytes(&self) -> Vec<u8> {
self.0.to_bytes()
}
/// Compute the intersection (binary-and) of this bitfield with another. Lengths must match.
pub fn intersection(&self, other: &Self) -> Self {
let mut res = self.clone();
res.intersection_inplace(other);
res
}
/// Like `intersection` but in-place (updates `self`).
pub fn intersection_inplace(&mut self, other: &Self) {
self.0.intersect(&other.0);
}
/// Compute the union (binary-or) of this bitfield with another. Lengths must match.
pub fn union(&self, other: &Self) -> Self {
let mut res = self.clone();
res.union_inplace(other);
res
}
/// Like `union` but in-place (updates `self`).
pub fn union_inplace(&mut self, other: &Self) {
self.0.union(&other.0);
}
/// Compute the difference (binary-minus) of this bitfield with another. Lengths must match.
///
/// Computes `self - other`.
pub fn difference(&self, other: &Self) -> Self {
let mut res = self.clone();
res.difference_inplace(other);
res
}
/// Like `difference` but in-place (updates `self`).
pub fn difference_inplace(&mut self, other: &Self) {
self.0.difference(&other.0);
}
}
impl default::Default for BooleanBitfield {
@@ -125,10 +168,11 @@ impl cmp::PartialEq for BooleanBitfield {
/// Create a new bitfield that is a union of two other bitfields.
///
/// For example `union(0101, 1000) == 1101`
impl std::ops::BitAnd for BooleanBitfield {
// TODO: length-independent intersection for BitAnd
impl std::ops::BitOr for BooleanBitfield {
type Output = Self;
fn bitand(self, other: Self) -> Self {
fn bitor(self, other: Self) -> Self {
let (biggest, smallest) = if self.len() > other.len() {
(&self, &other)
} else {
@@ -421,10 +465,59 @@ mod tests {
}
#[test]
fn test_bitand() {
fn test_bitor() {
let a = BooleanBitfield::from_bytes(&vec![2, 8, 1][..]);
let b = BooleanBitfield::from_bytes(&vec![4, 8, 16][..]);
let c = BooleanBitfield::from_bytes(&vec![6, 8, 17][..]);
assert_eq!(c, a & b);
assert_eq!(c, a | b);
}
#[test]
fn test_is_zero() {
let yes_data: &[&[u8]] = &[&[], &[0], &[0, 0], &[0, 0, 0]];
for bytes in yes_data {
assert!(BooleanBitfield::from_bytes(bytes).is_zero());
}
let no_data: &[&[u8]] = &[&[1], &[6], &[0, 1], &[0, 0, 1], &[0, 0, 255]];
for bytes in no_data {
assert!(!BooleanBitfield::from_bytes(bytes).is_zero());
}
}
#[test]
fn test_intersection() {
let a = BooleanBitfield::from_bytes(&[0b1100, 0b0001]);
let b = BooleanBitfield::from_bytes(&[0b1011, 0b1001]);
let c = BooleanBitfield::from_bytes(&[0b1000, 0b0001]);
assert_eq!(a.intersection(&b), c);
assert_eq!(b.intersection(&a), c);
assert_eq!(a.intersection(&c), c);
assert_eq!(b.intersection(&c), c);
assert_eq!(a.intersection(&a), a);
assert_eq!(b.intersection(&b), b);
assert_eq!(c.intersection(&c), c);
}
#[test]
fn test_union() {
let a = BooleanBitfield::from_bytes(&[0b1100, 0b0001]);
let b = BooleanBitfield::from_bytes(&[0b1011, 0b1001]);
let c = BooleanBitfield::from_bytes(&[0b1111, 0b1001]);
assert_eq!(a.union(&b), c);
assert_eq!(b.union(&a), c);
assert_eq!(a.union(&a), a);
assert_eq!(b.union(&b), b);
assert_eq!(c.union(&c), c);
}
#[test]
fn test_difference() {
let a = BooleanBitfield::from_bytes(&[0b1100, 0b0001]);
let b = BooleanBitfield::from_bytes(&[0b1011, 0b1001]);
let a_b = BooleanBitfield::from_bytes(&[0b0100, 0b0000]);
let b_a = BooleanBitfield::from_bytes(&[0b0011, 0b1000]);
assert_eq!(a.difference(&b), a_b);
assert_eq!(b.difference(&a), b_a);
assert!(a.difference(&a).is_zero());
}
}