[Altair] Sync committee pools (#2321)

Add pools supporting sync committees:
- naive sync aggregation pool
- observed sync contributions pool
- observed sync contributors pool
- observed sync aggregators pool

Add SSZ types and tests related to sync committee signatures.

Co-authored-by: Michael Sproul <michael@sigmaprime.io>
Co-authored-by: realbigsean <seananderson33@gmail.com>
This commit is contained in:
realbigsean
2021-07-15 00:52:02 +00:00
parent 8fa6e463ca
commit a3a7f39b0d
59 changed files with 5277 additions and 933 deletions

View File

@@ -267,6 +267,32 @@ impl<N: Unsigned + Clone> Bitfield<Fixed<N>> {
pub fn from_bytes(bytes: Vec<u8>) -> Result<Self, Error> {
Self::from_raw_bytes(bytes, Self::capacity())
}
/// Compute the intersection of two fixed-length `Bitfield`s.
///
/// Return a new fixed-length `Bitfield`.
pub fn intersection(&self, other: &Self) -> Self {
let mut result = Self::new();
// Bitwise-and the bytes together, starting from the left of each vector. This takes care
// of masking out any entries beyond `min_len` as well, assuming the bitfield doesn't
// contain any set bits beyond its length.
for i in 0..result.bytes.len() {
result.bytes[i] = self.bytes[i] & other.bytes[i];
}
result
}
/// Compute the union of two fixed-length `Bitfield`s.
///
/// Return a new fixed-length `Bitfield`.
pub fn union(&self, other: &Self) -> Self {
let mut result = Self::new();
for i in 0..result.bytes.len() {
result.bytes[i] =
self.bytes.get(i).copied().unwrap_or(0) | other.bytes.get(i).copied().unwrap_or(0);
}
result
}
}
impl<N: Unsigned + Clone> Default for Bitfield<Fixed<N>> {
@@ -700,6 +726,58 @@ mod bitvector {
assert!(BitVector16::from_ssz_bytes(&[1, 0b0000_0000, 0b0000_0000]).is_err());
}
#[test]
fn intersection() {
let a = BitVector16::from_raw_bytes(vec![0b1100, 0b0001], 16).unwrap();
let b = BitVector16::from_raw_bytes(vec![0b1011, 0b1001], 16).unwrap();
let c = BitVector16::from_raw_bytes(vec![0b1000, 0b0001], 16).unwrap();
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 intersection_diff_length() {
let a = BitVector16::from_bytes(vec![0b0010_1110, 0b0010_1011]).unwrap();
let b = BitVector16::from_bytes(vec![0b0010_1101, 0b0000_0001]).unwrap();
let c = BitVector16::from_bytes(vec![0b0010_1100, 0b0000_0001]).unwrap();
assert_eq!(a.len(), 16);
assert_eq!(b.len(), 16);
assert_eq!(c.len(), 16);
assert_eq!(a.intersection(&b), c);
assert_eq!(b.intersection(&a), c);
}
#[test]
fn union() {
let a = BitVector16::from_raw_bytes(vec![0b1100, 0b0001], 16).unwrap();
let b = BitVector16::from_raw_bytes(vec![0b1011, 0b1001], 16).unwrap();
let c = BitVector16::from_raw_bytes(vec![0b1111, 0b1001], 16).unwrap();
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 union_diff_length() {
let a = BitVector16::from_bytes(vec![0b0010_1011, 0b0010_1110]).unwrap();
let b = BitVector16::from_bytes(vec![0b0000_0001, 0b0010_1101]).unwrap();
let c = BitVector16::from_bytes(vec![0b0010_1011, 0b0010_1111]).unwrap();
assert_eq!(a.len(), c.len());
assert_eq!(a.union(&b), c);
assert_eq!(b.union(&a), c);
}
#[test]
fn ssz_round_trip() {
assert_round_trip(BitVector0::new());