Add BooleanBitfield struct
This commit is contained in:
parent
4c7b2eec2c
commit
5e362567e6
@ -20,7 +20,7 @@ impl ActiveState {
|
||||
Self {
|
||||
height: 0,
|
||||
randao: Sha256Digest::zero(),
|
||||
ffg_voter_bitfield: Vec::new(),
|
||||
ffg_voter_bitfield: Bitfield::new(),
|
||||
recent_attesters: Vec::new(),
|
||||
partial_crosslinks: Vec::new(),
|
||||
total_skip_count: 0,
|
||||
@ -96,11 +96,11 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_serialization() {
|
||||
fn test_rlp_serialization() {
|
||||
let a = ActiveState {
|
||||
height: 100,
|
||||
randao: Sha256Digest::zero(),
|
||||
ffg_voter_bitfield: Vec::new(),
|
||||
ffg_voter_bitfield: Bitfield::new(),
|
||||
recent_attesters: Vec::new(),
|
||||
partial_crosslinks: Vec::new(),
|
||||
total_skip_count: 99,
|
||||
|
@ -14,7 +14,7 @@ impl AggregateVote {
|
||||
Self {
|
||||
shard_id: 0,
|
||||
shard_block_hash: Sha256Digest::zero(),
|
||||
notary_bitfield: Vec::new(),
|
||||
notary_bitfield: Bitfield::new(),
|
||||
aggregate_sig: AggregateSignature::new()
|
||||
}
|
||||
}
|
||||
@ -46,11 +46,11 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_serialization() {
|
||||
fn test_rlp_serialization() {
|
||||
let a = AggregateVote {
|
||||
shard_id: 100,
|
||||
shard_block_hash: Sha256Digest::zero(),
|
||||
notary_bitfield: Vec::new(),
|
||||
notary_bitfield: Bitfield::new(),
|
||||
aggregate_sig: AggregateSignature::new()
|
||||
};
|
||||
let e = rlp::encode(&a);
|
||||
|
@ -23,7 +23,7 @@ impl Block {
|
||||
parent_hash: parent_hash,
|
||||
skip_count: 0,
|
||||
randao_reveal: randao_reveal,
|
||||
attestation_bitfield: Vec::new(),
|
||||
attestation_bitfield: Bitfield::new(),
|
||||
attestation_aggregate_sig: AggregateSignature::new(),
|
||||
shard_aggregate_votes: Vec::new(),
|
||||
main_chain_ref: main_chain_ref,
|
||||
@ -147,12 +147,12 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_serialization() {
|
||||
fn test_rlp_serialization() {
|
||||
let b = Block {
|
||||
parent_hash: Sha256Digest::zero(),
|
||||
skip_count: 100,
|
||||
randao_reveal: Sha256Digest::zero(),
|
||||
attestation_bitfield: Vec::new(),
|
||||
attestation_bitfield: Bitfield::new(),
|
||||
attestation_aggregate_sig: AggregateSignature::new(),
|
||||
shard_aggregate_votes: Vec::new(),
|
||||
main_chain_ref: Sha256Digest::zero(),
|
||||
|
@ -40,7 +40,7 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_serialization() {
|
||||
fn test_rlp_serialization() {
|
||||
let c = CrosslinkRecord {
|
||||
epoch: 100,
|
||||
hash: Sha256Digest::zero()
|
||||
|
@ -92,7 +92,7 @@ mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_serialization() {
|
||||
fn test_rlp_serialization() {
|
||||
let a = CrystallizedState {
|
||||
active_validators: Vec::new(),
|
||||
queued_validators: Vec::new(),
|
||||
|
@ -13,7 +13,7 @@ impl PartialCrosslinkRecord {
|
||||
PartialCrosslinkRecord {
|
||||
shard_id: shard_id,
|
||||
shard_block_hash: shard_block_hash,
|
||||
voter_bitfield: Vec::new()
|
||||
voter_bitfield: Bitfield::new()
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -45,11 +45,11 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_serialization() {
|
||||
fn test_rlp_serialization() {
|
||||
let p = PartialCrosslinkRecord {
|
||||
shard_id: 1,
|
||||
shard_block_hash: Sha256Digest::zero(),
|
||||
voter_bitfield: Vec::new()
|
||||
voter_bitfield: Bitfield::new()
|
||||
};
|
||||
let e = rlp::encode(&p);
|
||||
assert_eq!(e.len(), 35);
|
||||
|
@ -37,7 +37,7 @@ mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_serialization() {
|
||||
fn test_rlp_serialization() {
|
||||
let index = 1;
|
||||
let randao_commitment = Sha256Digest::zero();
|
||||
let balance_delta = 99;
|
||||
|
@ -81,7 +81,7 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_serialization() {
|
||||
fn test_rlp_serialization() {
|
||||
let keypair = get_dangerous_test_keypair();
|
||||
let v = ValidatorRecord {
|
||||
pubkey: keypair.public,
|
||||
|
142
src/utils/boolean_bitfield.rs
Normal file
142
src/utils/boolean_bitfield.rs
Normal file
@ -0,0 +1,142 @@
|
||||
/*
|
||||
* Implemenation of a bitfield as a vec. Only
|
||||
* supports bytes (Vec<u8>) as the underlying
|
||||
* storage.
|
||||
*
|
||||
* A future implementation should be more efficient,
|
||||
* this is just to get the job done for now.
|
||||
*/
|
||||
extern crate rlp;
|
||||
use self::rlp::{ RlpStream, Encodable };
|
||||
|
||||
pub struct BooleanBitfield{
|
||||
vec: Vec<u8>
|
||||
}
|
||||
|
||||
impl BooleanBitfield {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
vec: vec![]
|
||||
}
|
||||
}
|
||||
|
||||
pub fn with_capacity(capacity: usize) -> Self {
|
||||
Self {
|
||||
vec: Vec::with_capacity(capacity)
|
||||
}
|
||||
}
|
||||
|
||||
// Output the bitfield as a big-endian vec of u8
|
||||
pub fn to_be_vec(&self) -> Vec<u8> {
|
||||
let mut o = self.vec.clone();
|
||||
o.reverse();
|
||||
o
|
||||
}
|
||||
|
||||
pub fn get_bit(&self, i: &usize) -> bool {
|
||||
self.get_bit_on_byte(*i % 8, *i / 8)
|
||||
}
|
||||
|
||||
fn get_bit_on_byte(&self, bit: usize, byte: usize) -> bool {
|
||||
assert!(bit < 8);
|
||||
if byte >= self.vec.len() {
|
||||
false
|
||||
} else {
|
||||
self.vec[byte] & (1 << (bit as u8)) != 0
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_bit(&mut self, bit: &usize, to: &bool) {
|
||||
self.set_bit_on_byte(*bit % 8, *bit / 8, to);
|
||||
}
|
||||
|
||||
fn set_bit_on_byte(&mut self, bit: usize, byte: usize, val: &bool) {
|
||||
assert!(bit < 8);
|
||||
if byte >= self.vec.len() {
|
||||
self.vec.resize(byte + 1, 0);
|
||||
}
|
||||
match val {
|
||||
true => self.vec[byte] = self.vec[byte] | (1 << (bit as u8)),
|
||||
false => self.vec[byte] = self.vec[byte] & !(1 << (bit as u8))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Encodable for BooleanBitfield {
|
||||
// TODO: ensure this is a sensible method of encoding
|
||||
// the bitfield. Currently, it is treated as a list of
|
||||
// bytes not as a string. I do not have any guidance as
|
||||
// to which method is correct -- don't follow my lead
|
||||
// without seeking authoritative advice.
|
||||
fn rlp_append(&self, s: &mut RlpStream) {
|
||||
s.append(&self.to_be_vec());
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use super::rlp;
|
||||
|
||||
#[test]
|
||||
fn test_bitfield_set() {
|
||||
let mut b = BooleanBitfield::new();
|
||||
b.set_bit(&0, &false);
|
||||
assert_eq!(b.to_be_vec(), [0]);
|
||||
|
||||
b = BooleanBitfield::new();
|
||||
b.set_bit(&7, &true);
|
||||
assert_eq!(b.to_be_vec(), [128]);
|
||||
b.set_bit(&7, &false);
|
||||
assert_eq!(b.to_be_vec(), [0]);
|
||||
|
||||
b = BooleanBitfield::new();
|
||||
b.set_bit(&7, &true);
|
||||
b.set_bit(&0, &true);
|
||||
assert_eq!(b.to_be_vec(), [129]);
|
||||
b.set_bit(&7, &false);
|
||||
assert_eq!(b.to_be_vec(), [1]);
|
||||
|
||||
b = BooleanBitfield::new();
|
||||
b.set_bit(&8, &true);
|
||||
assert_eq!(b.to_be_vec(), [1, 0]);
|
||||
b.set_bit(&8, &false);
|
||||
assert_eq!(b.to_be_vec(), [0, 0]);
|
||||
|
||||
b = BooleanBitfield::new();
|
||||
b.set_bit(&15, &true);
|
||||
assert_eq!(b.to_be_vec(), [128, 0]);
|
||||
b.set_bit(&15, &false);
|
||||
assert_eq!(b.to_be_vec(), [0, 0]);
|
||||
|
||||
b = BooleanBitfield::new();
|
||||
b.set_bit(&8, &true);
|
||||
b.set_bit(&15, &true);
|
||||
assert_eq!(b.to_be_vec(), [129, 0]);
|
||||
b.set_bit(&15, &false);
|
||||
assert_eq!(b.to_be_vec(), [1, 0]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_bitfield_get() {
|
||||
let mut b = BooleanBitfield::new();
|
||||
let test_nums = vec![0, 8, 15, 42, 1337];
|
||||
for i in test_nums {
|
||||
b = BooleanBitfield::new();
|
||||
assert_eq!(b.get_bit(&0), false);
|
||||
b.set_bit(&0, &true);
|
||||
assert_eq!(b.get_bit(&0), true);
|
||||
b.set_bit(&0, &true);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_bitfield_rlp_serialization() {
|
||||
let mut b = BooleanBitfield::new();
|
||||
b.set_bit(&15, &true);
|
||||
let e = rlp::encode(&b);
|
||||
assert_eq!(e[0], 130);
|
||||
assert_eq!(e[1], 128);
|
||||
assert_eq!(e[2], 0);
|
||||
}
|
||||
}
|
@ -8,3 +8,4 @@ use super::state::crystallized_state;
|
||||
pub mod types;
|
||||
pub mod bls;
|
||||
pub mod test_helpers;
|
||||
pub mod boolean_bitfield;
|
||||
|
@ -1,6 +1,7 @@
|
||||
use super::ethereum_types::{ H256, H160 };
|
||||
use super::active_state::ActiveState;
|
||||
use super::crystallized_state::CrystallizedState;
|
||||
use super::boolean_bitfield::BooleanBitfield;
|
||||
|
||||
pub use super::blake2::Blake2s;
|
||||
|
||||
@ -33,4 +34,4 @@ impl StateHash {
|
||||
}
|
||||
}
|
||||
|
||||
pub type Bitfield = Vec<u8>;
|
||||
pub type Bitfield = BooleanBitfield;
|
||||
|
Loading…
Reference in New Issue
Block a user