Initial commit
This commit is contained in:
commit
7db81b167f
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
/target
|
||||||
|
**/*.rs.bk
|
||||||
|
Cargo.lock
|
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
[submodule "parity"]
|
||||||
|
path = parity
|
||||||
|
url = git@github.com:paritytech/parity.git
|
17
Cargo.toml
Normal file
17
Cargo.toml
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
[package]
|
||||||
|
name = "rust_beacon"
|
||||||
|
version = "0.1.0"
|
||||||
|
authors = ["Paul Hauner <paul@paulhauner.com>"]
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
ethereum-types = ""
|
||||||
|
rand = ""
|
||||||
|
bls = { git = "https://github.com/sigp/bls" }
|
||||||
|
rlp = { path = "parity/util/rlp" }
|
||||||
|
|
||||||
|
[dependencies.pairing]
|
||||||
|
git = "https://github.com/mmaker/pairing"
|
||||||
|
branch = "feature/hashing"
|
||||||
|
|
||||||
|
[patch.crates-io]
|
||||||
|
ring = { git = "https://github.com/paritytech/ring" }
|
39
README.md
Normal file
39
README.md
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
# rust_beacon_chain
|
||||||
|
|
||||||
|
A *work-in-progress* implementation of the Ethereum beacon_chain in Rust.
|
||||||
|
|
||||||
|
It is an implementation of [this
|
||||||
|
spec](https://notes.ethereum.org/SCIg8AH5SA-O4C1G1LYZHQ?view) and is also
|
||||||
|
largely based upon the
|
||||||
|
[ethereum/beacon_chain](https://github.com/ethereum/beacon_chain) repo.
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
Presently this is just a bunch of data structures and some tests.
|
||||||
|
|
||||||
|
```
|
||||||
|
$ git clone --recurse-submodules <url>
|
||||||
|
$ cd rust_beacon_chain
|
||||||
|
$ cargo test
|
||||||
|
```
|
||||||
|
|
||||||
|
_Note: don't forget to clone/pull with respect to submodules. Parity is
|
||||||
|
included as a submodule so we can use their handy RLP module without compiling
|
||||||
|
all the things._
|
||||||
|
|
||||||
|
## Contact
|
||||||
|
|
||||||
|
This repo is presently authored by Paul Hauner (@paulhauner) as a Sigma Prime
|
||||||
|
project.
|
||||||
|
|
||||||
|
Best place for discussion is probably the [ethereum/sharding
|
||||||
|
gitter](https://gitter.im/ethereum/sharding).
|
||||||
|
|
||||||
|
## TODO:
|
||||||
|
|
||||||
|
- [] Implement crystallized state.
|
||||||
|
- [] Implement state transition.
|
||||||
|
- [] Implement integration tests (some unit tests are implemented now).
|
||||||
|
- [] Implement RLP serialization across-the-board.
|
||||||
|
- [] Ensure bls library is legit (i.e., functioning and secure).
|
||||||
|
- [] Implement the things, optimise them & scale to 1000000000 nodes.
|
1
parity
Submodule
1
parity
Submodule
@ -0,0 +1 @@
|
|||||||
|
Subproject commit aa67bd5d00e48bac71ab81a384ac2902757eebed
|
2
src/lib.rs
Normal file
2
src/lib.rs
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
pub mod state;
|
||||||
|
pub mod utils;
|
69
src/state/active_state.rs
Normal file
69
src/state/active_state.rs
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
use super::partial_crosslink_record::PartialCrosslinkRecord;
|
||||||
|
use super::recent_proposer_record::RecentPropserRecord;
|
||||||
|
use super::utils::types::*;
|
||||||
|
|
||||||
|
pub struct ActiveState {
|
||||||
|
pub height: u64,
|
||||||
|
pub randao: Sha256Digest,
|
||||||
|
pub ffg_voter_bitfield: Bitfield,
|
||||||
|
pub recent_attesters: Vec<u32>, // TODO: should be u24
|
||||||
|
pub partial_crosslinks: Vec<PartialCrosslinkRecord>,
|
||||||
|
pub total_skip_count: u64,
|
||||||
|
pub recent_proposers: Vec<RecentPropserRecord>
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ActiveState {
|
||||||
|
pub fn new_for_height(height: u64) -> ActiveState {
|
||||||
|
ActiveState {
|
||||||
|
height: height,
|
||||||
|
randao: Sha256Digest::random(),
|
||||||
|
ffg_voter_bitfield: Vec::new(),
|
||||||
|
recent_attesters: Vec::new(),
|
||||||
|
partial_crosslinks: Vec::new(),
|
||||||
|
total_skip_count: 0,
|
||||||
|
recent_proposers: Vec::new()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn num_recent_proposers(&self) -> usize {
|
||||||
|
self.recent_proposers.len()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn num_recent_attesters(&self) -> usize {
|
||||||
|
self.recent_attesters.len()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_new_for_height() {
|
||||||
|
let h = 1;
|
||||||
|
let a = ActiveState::new_for_height(h);
|
||||||
|
assert_eq!(a.height, h);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_num_recent_proposers() {
|
||||||
|
let mut a = ActiveState::new_for_height(1);
|
||||||
|
for _ in 1..5 {
|
||||||
|
a.recent_proposers.push(RecentPropserRecord::new(
|
||||||
|
1,
|
||||||
|
Sha256Digest::random(),
|
||||||
|
2));
|
||||||
|
}
|
||||||
|
assert_eq!(a.num_recent_proposers(), 4)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_num_recent_attesters() {
|
||||||
|
let mut a = ActiveState::new_for_height(1);
|
||||||
|
for _ in 1..5 {
|
||||||
|
a.recent_attesters.push(1);
|
||||||
|
}
|
||||||
|
assert_eq!(a.num_recent_attesters(), 4)
|
||||||
|
}
|
||||||
|
}
|
37
src/state/aggregate_vote.rs
Normal file
37
src/state/aggregate_vote.rs
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
use super::utils::types::*;
|
||||||
|
use super::utils::bls::AggregateSignature;
|
||||||
|
|
||||||
|
pub struct AggregateVote {
|
||||||
|
pub shard_id: u16,
|
||||||
|
pub shard_block_hash: Sha256Digest,
|
||||||
|
pub notary_bitfield: Bitfield,
|
||||||
|
pub aggregate_sig: AggregateSignature,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AggregateVote {
|
||||||
|
pub fn new_for_shard(shard_id: u16,
|
||||||
|
shard_block_hash: Sha256Digest)
|
||||||
|
-> AggregateVote {
|
||||||
|
AggregateVote {
|
||||||
|
shard_id: shard_id,
|
||||||
|
shard_block_hash: shard_block_hash,
|
||||||
|
notary_bitfield: Vec::new(),
|
||||||
|
aggregate_sig: AggregateSignature::new()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_new_for_shard() {
|
||||||
|
let id = 1;
|
||||||
|
let hash = Sha256Digest::random();
|
||||||
|
let v = AggregateVote::new_for_shard(id, hash);
|
||||||
|
assert_eq!(v.shard_id, id);
|
||||||
|
assert_eq!(v.shard_block_hash, hash);
|
||||||
|
}
|
||||||
|
}
|
160
src/state/block.rs
Normal file
160
src/state/block.rs
Normal file
@ -0,0 +1,160 @@
|
|||||||
|
use super::utils::types::{ Sha256Digest, Bitfield };
|
||||||
|
use super::utils::bls::{ Signature, AggregateSignature, Keypair, PublicKey };
|
||||||
|
use super::aggregate_vote::AggregateVote;
|
||||||
|
use super::rlp::{ RlpStream, Encodable } ;
|
||||||
|
|
||||||
|
pub struct Block {
|
||||||
|
pub parent_hash: Sha256Digest,
|
||||||
|
pub skip_count: u64,
|
||||||
|
pub randao_reveal: Sha256Digest,
|
||||||
|
pub attestation_bitfield: Bitfield,
|
||||||
|
pub attestation_aggregate_sig: AggregateSignature,
|
||||||
|
pub shard_aggregate_votes: Vec<AggregateVote>,
|
||||||
|
pub main_chain_ref: Sha256Digest,
|
||||||
|
pub state_hash: Sha256Digest,
|
||||||
|
pub sig: Option<Signature>
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Block {
|
||||||
|
pub fn new(parent_hash: Sha256Digest,
|
||||||
|
randao_reveal: Sha256Digest,
|
||||||
|
main_chain_ref: Sha256Digest,
|
||||||
|
state_hash: Sha256Digest) -> Block {
|
||||||
|
Block {
|
||||||
|
parent_hash: parent_hash,
|
||||||
|
skip_count: 0,
|
||||||
|
randao_reveal: randao_reveal,
|
||||||
|
attestation_bitfield: Vec::new(),
|
||||||
|
attestation_aggregate_sig: AggregateSignature::new(),
|
||||||
|
shard_aggregate_votes: Vec::new(),
|
||||||
|
main_chain_ref: main_chain_ref,
|
||||||
|
state_hash: state_hash,
|
||||||
|
sig: None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Take a Block and covert it into an array of u8 for BLS signing
|
||||||
|
* or verfication. The `sig` field is purposefully omitted.
|
||||||
|
*/
|
||||||
|
pub fn encode_to_signable_message(&self) -> [u8; 9140] {
|
||||||
|
// Using biggest avg. block size from v2 spec
|
||||||
|
let mut message: [u8; 9140] = [0; 9140];
|
||||||
|
|
||||||
|
// Create the RLP vector
|
||||||
|
let mut s = RlpStream::new();
|
||||||
|
s.append(&self.parent_hash);
|
||||||
|
s.append(&self.skip_count);
|
||||||
|
s.append(&self.randao_reveal);
|
||||||
|
s.append(&self.attestation_bitfield);
|
||||||
|
// TODO: represent attestation_aggregate_sig
|
||||||
|
// TODO: represent shard_aggregate_votes
|
||||||
|
s.append(&self.main_chain_ref);
|
||||||
|
s.append(&self.state_hash);
|
||||||
|
let rlp_vec = s.out();
|
||||||
|
|
||||||
|
// Parse the RLP vector into an array compatible with the BLS signer
|
||||||
|
let len = rlp_vec.len();
|
||||||
|
message[..len].copy_from_slice(&rlp_vec[..len]);
|
||||||
|
message
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Sign the block with the given keypair.
|
||||||
|
*/
|
||||||
|
pub fn sig_sign(&mut self, keypair: &Keypair) {
|
||||||
|
let message = self.encode_to_signable_message();
|
||||||
|
self.sig = Some(keypair.sign(&message));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Verify a block signature given some keypair.
|
||||||
|
*/
|
||||||
|
pub fn sig_verify(&self, pub_key: &PublicKey) -> bool {
|
||||||
|
let message = self.encode_to_signable_message();
|
||||||
|
match &self.sig {
|
||||||
|
None => false,
|
||||||
|
Some(sig) => {
|
||||||
|
pub_key.verify(&message, &sig)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Encodable for Block {
|
||||||
|
fn rlp_append(&self, s: &mut RlpStream) {
|
||||||
|
s.append(&self.parent_hash);
|
||||||
|
s.append(&self.skip_count);
|
||||||
|
s.append(&self.randao_reveal);
|
||||||
|
s.append(&self.attestation_bitfield);
|
||||||
|
// TODO: represent attestation_aggregate_sig
|
||||||
|
// TODO: represent shard_aggregate_votes
|
||||||
|
s.append(&self.main_chain_ref);
|
||||||
|
s.append(&self.state_hash);
|
||||||
|
// TODO: represent sig
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
extern crate rand;
|
||||||
|
|
||||||
|
use super::*;
|
||||||
|
use self::rand::{ SeedableRng, XorShiftRng };
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_new_for_parent_hash() {
|
||||||
|
let parent_hash = Sha256Digest::random();
|
||||||
|
let randao_reveal = Sha256Digest::random();
|
||||||
|
let main_chain_ref = Sha256Digest::random();
|
||||||
|
let state_hash = Sha256Digest::random();
|
||||||
|
let b = Block::new(parent_hash,
|
||||||
|
randao_reveal,
|
||||||
|
main_chain_ref,
|
||||||
|
state_hash);
|
||||||
|
assert_eq!(b.parent_hash, parent_hash);
|
||||||
|
assert_eq!(b.randao_reveal, randao_reveal);
|
||||||
|
assert_eq!(b.main_chain_ref, main_chain_ref);
|
||||||
|
assert_eq!(b.state_hash, state_hash);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_signable_message_encoding() {
|
||||||
|
let parent_hash = Sha256Digest::from([0; 32]);
|
||||||
|
let randao_reveal = Sha256Digest::from([1; 32]);
|
||||||
|
let main_chain_ref = Sha256Digest::from([2; 32]);
|
||||||
|
let state_hash = Sha256Digest::from([3; 32]);
|
||||||
|
let mut b = Block::new(parent_hash,
|
||||||
|
randao_reveal,
|
||||||
|
main_chain_ref,
|
||||||
|
state_hash);
|
||||||
|
b.skip_count = 2;
|
||||||
|
let output = b.encode_to_signable_message();
|
||||||
|
// TODO: test this better
|
||||||
|
assert_eq!(output[0], 160);
|
||||||
|
assert_eq!(output[1..21], [0; 20]);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_sign_and_verify() {
|
||||||
|
let mut rng = XorShiftRng::from_seed([0xbc4f6d44, 0xd62f276c, 0xb963afd0, 0x5455863d]);
|
||||||
|
let alice_keypair = Keypair::generate(&mut rng);
|
||||||
|
let bob_keypair = Keypair::generate(&mut rng);
|
||||||
|
let mut b = Block::new(Sha256Digest::random(),
|
||||||
|
Sha256Digest::random(),
|
||||||
|
Sha256Digest::random(),
|
||||||
|
Sha256Digest::random());
|
||||||
|
|
||||||
|
// Both signatures fail before signing
|
||||||
|
assert_eq!(b.sig_verify(&alice_keypair.public), false);
|
||||||
|
assert_eq!(b.sig_verify(&bob_keypair.public), false);
|
||||||
|
|
||||||
|
// Sign as Alice
|
||||||
|
b.sig_sign(&alice_keypair);
|
||||||
|
|
||||||
|
// Alice signature passes, bobs fails
|
||||||
|
assert_eq!(b.sig_verify(&alice_keypair.public), true);
|
||||||
|
assert_eq!(b.sig_verify(&bob_keypair.public), false);
|
||||||
|
}
|
||||||
|
}
|
29
src/state/crosslink_record.rs
Normal file
29
src/state/crosslink_record.rs
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
use super::utils::types::Sha256Digest;
|
||||||
|
|
||||||
|
pub struct CrosslinkRecord {
|
||||||
|
pub epoch: u64,
|
||||||
|
pub hash: Sha256Digest
|
||||||
|
}
|
||||||
|
|
||||||
|
impl CrosslinkRecord {
|
||||||
|
pub fn new(epoch: u64, hash: Sha256Digest) -> CrosslinkRecord {
|
||||||
|
CrosslinkRecord {
|
||||||
|
epoch: epoch,
|
||||||
|
hash: hash
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_new() {
|
||||||
|
let epoch = 1;
|
||||||
|
let hash = Sha256Digest::random();
|
||||||
|
let c = CrosslinkRecord::new(epoch, hash);
|
||||||
|
assert_eq!(c.epoch, epoch);
|
||||||
|
assert_eq!(c.hash, hash);
|
||||||
|
}
|
||||||
|
}
|
11
src/state/mod.rs
Normal file
11
src/state/mod.rs
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
extern crate rlp;
|
||||||
|
|
||||||
|
use super::utils;
|
||||||
|
|
||||||
|
pub mod active_state;
|
||||||
|
pub mod aggregate_vote;
|
||||||
|
pub mod block;
|
||||||
|
pub mod crosslink_record;
|
||||||
|
pub mod partial_crosslink_record;
|
||||||
|
pub mod recent_proposer_record;
|
||||||
|
pub mod validator_record;
|
33
src/state/partial_crosslink_record.rs
Normal file
33
src/state/partial_crosslink_record.rs
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
use super::utils::types::{ Sha256Digest, Bitfield };
|
||||||
|
|
||||||
|
pub struct PartialCrosslinkRecord {
|
||||||
|
pub shard_id: u16,
|
||||||
|
pub shard_block_hash: Sha256Digest,
|
||||||
|
pub voter_bitfield: Bitfield
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PartialCrosslinkRecord {
|
||||||
|
pub fn new_for_shard(shard_id: u16,
|
||||||
|
shard_block_hash: Sha256Digest) -> PartialCrosslinkRecord {
|
||||||
|
PartialCrosslinkRecord {
|
||||||
|
shard_id: shard_id,
|
||||||
|
shard_block_hash: shard_block_hash,
|
||||||
|
voter_bitfield: Vec::new()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_new_for_shard() {
|
||||||
|
let id = 1;
|
||||||
|
let hash = Sha256Digest::random();
|
||||||
|
let p = PartialCrosslinkRecord::new_for_shard(id, hash);
|
||||||
|
assert_eq!(p.shard_id, id);
|
||||||
|
assert_eq!(p.shard_block_hash, hash);
|
||||||
|
}
|
||||||
|
}
|
19
src/state/recent_proposer_record.rs
Normal file
19
src/state/recent_proposer_record.rs
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
use super::utils::types::*;
|
||||||
|
|
||||||
|
pub struct RecentPropserRecord {
|
||||||
|
pub index: u32, // TODO: make u24
|
||||||
|
pub randao_commitment: Sha256Digest,
|
||||||
|
pub balance_delta: u32, // TODO: make u24
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RecentPropserRecord {
|
||||||
|
pub fn new(index: u32,
|
||||||
|
randao_commitment: Sha256Digest,
|
||||||
|
balance_delta: u32) -> RecentPropserRecord {
|
||||||
|
RecentPropserRecord {
|
||||||
|
index: index,
|
||||||
|
randao_commitment: randao_commitment,
|
||||||
|
balance_delta: balance_delta
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
65
src/state/validator_record.rs
Normal file
65
src/state/validator_record.rs
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
use super::utils::types::{ Sha256Digest, Address };
|
||||||
|
use super::utils::bls::PublicKey;
|
||||||
|
|
||||||
|
pub struct ValidatorRecord {
|
||||||
|
pub pubkey: PublicKey,
|
||||||
|
pub withdrawal_shard: u16,
|
||||||
|
pub withdrawal_address: Address,
|
||||||
|
pub randao_commitment: Sha256Digest,
|
||||||
|
pub balance: u64,
|
||||||
|
pub switch_dynasty: u64
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ValidatorRecord {
|
||||||
|
pub fn new(pubkey: PublicKey,
|
||||||
|
withdrawal_shard: u16,
|
||||||
|
withdrawal_address: Address,
|
||||||
|
randao_commitment: Sha256Digest,
|
||||||
|
balance: u64,
|
||||||
|
switch_dynasty: u64) -> ValidatorRecord {
|
||||||
|
ValidatorRecord {
|
||||||
|
pubkey: pubkey,
|
||||||
|
withdrawal_shard: withdrawal_shard,
|
||||||
|
withdrawal_address: withdrawal_address,
|
||||||
|
randao_commitment: randao_commitment,
|
||||||
|
balance: balance,
|
||||||
|
switch_dynasty: switch_dynasty
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
extern crate rand;
|
||||||
|
|
||||||
|
use super::*;
|
||||||
|
use super::super::utils::bls::Keypair;
|
||||||
|
use self::rand::{ SeedableRng, XorShiftRng };
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_new() {
|
||||||
|
let mut rng = XorShiftRng::from_seed([0xbc4f6d44, 0xd62f276c, 0xb963afd0, 0x5455863d]);
|
||||||
|
let keypair = Keypair::generate(&mut rng);
|
||||||
|
let withdrawal_shard = 1;
|
||||||
|
let withdrawal_address = Address::random();
|
||||||
|
let randao_commitment = Sha256Digest::random();
|
||||||
|
let balance = 100;
|
||||||
|
let switch_dynasty = 10;
|
||||||
|
|
||||||
|
let v = ValidatorRecord::new(
|
||||||
|
keypair.public,
|
||||||
|
withdrawal_shard,
|
||||||
|
withdrawal_address,
|
||||||
|
randao_commitment,
|
||||||
|
balance,
|
||||||
|
switch_dynasty);
|
||||||
|
// TODO: figure out how to compare keys
|
||||||
|
// assert_eq!(v.pubkey, keypair.public);
|
||||||
|
assert_eq!(v.withdrawal_shard, withdrawal_shard);
|
||||||
|
assert_eq!(v.withdrawal_address, withdrawal_address);
|
||||||
|
assert_eq!(v.randao_commitment, randao_commitment);
|
||||||
|
assert_eq!(v.balance, balance);
|
||||||
|
assert_eq!(v.switch_dynasty, switch_dynasty);
|
||||||
|
}
|
||||||
|
}
|
13
src/utils/bls.rs
Normal file
13
src/utils/bls.rs
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
extern crate bls;
|
||||||
|
extern crate pairing;
|
||||||
|
|
||||||
|
use self::bls::AggregateSignature as GenericAggregateSignature;
|
||||||
|
use self::bls::Signature as GenericSignature;
|
||||||
|
use self::bls::Keypair as GenericKeypair;
|
||||||
|
use self::bls::PublicKey as GenericPublicKey;
|
||||||
|
use self::pairing::bls12_381::Bls12;
|
||||||
|
|
||||||
|
pub type AggregateSignature = GenericAggregateSignature<Bls12>;
|
||||||
|
pub type Signature = GenericSignature<Bls12>;
|
||||||
|
pub type Keypair = GenericKeypair<Bls12>;
|
||||||
|
pub type PublicKey = GenericPublicKey<Bls12>;
|
4
src/utils/mod.rs
Normal file
4
src/utils/mod.rs
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
extern crate ethereum_types;
|
||||||
|
|
||||||
|
pub mod types;
|
||||||
|
pub mod bls;
|
7
src/utils/types.rs
Normal file
7
src/utils/types.rs
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
use super::ethereum_types::{ H256, H160 };
|
||||||
|
|
||||||
|
pub type Sha256Digest = H256;
|
||||||
|
|
||||||
|
pub type Address = H160;
|
||||||
|
|
||||||
|
pub type Bitfield = Vec<u8>;
|
7
tests/aggregate_vote.rs
Normal file
7
tests/aggregate_vote.rs
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
#[test]
|
||||||
|
fn it_works() {
|
||||||
|
assert_eq!(2 + 2, 4);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user