Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added bls aggregate sig check for block validation #371

Merged
merged 3 commits into from
Apr 24, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 35 additions & 7 deletions blockchain/chain_sync/src/sync.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ use blocks::{Block, BlockHeader, FullTipset, TipSetKeys, Tipset, TxMeta};
use chain::ChainStore;
use cid::{multihash::Blake2b256, Cid};
use core::time::Duration;
use crypto::verify_bls_aggregate;
use encoding::{Cbor, Error as EncodingError};
use forest_libp2p::{BlockSyncRequest, NetworkEvent, NetworkMessage, MESSAGES};
use ipld_blockstore::BlockStore;
Expand All @@ -31,6 +32,7 @@ use std::collections::HashMap;
use std::convert::TryFrom;
use std::sync::Arc;
use vm::TokenAmount;

#[derive(PartialEq, Debug, Clone)]
/// Current state of the ChainSyncer
pub enum SyncState {
Expand Down Expand Up @@ -514,12 +516,38 @@ where
Ok(fts)
}
// Block message validation checks
fn check_blk_msgs(&self, block: Block, _tip: &Tipset) -> Result<(), Error> {
// TODO retrieve bls public keys for verify_bls_aggregate
// for _m in block.bls_msgs() {
// }
// TODO verify_bls_aggregate

fn check_block_msgs(&self, block: Block, tip: &Tipset) -> Result<(), Error> {
let mut pub_keys = Vec::new();
let mut cids = Vec::new();
for m in block.bls_msgs() {
let pk = self
.state_manager
.get_bls_public_key(m.from(), tip.parent_state())?;
pub_keys.push(pk);
cids.push(m.cid()?.to_bytes());
}
if let Some(sig) = block.header().bls_aggregate() {
dutterbutter marked this conversation as resolved.
Show resolved Hide resolved
if !verify_bls_aggregate(
cids.iter()
dutterbutter marked this conversation as resolved.
Show resolved Hide resolved
.map(|x| x.as_slice())
.collect::<Vec<&[u8]>>()
.as_slice(),
pub_keys
.iter()
.map(|x| x.as_slice())
.collect::<Vec<&[u8]>>()
.as_slice(),
&sig,
) {
return Err(Error::Validation(
"Bls aggregate signature was invalid".to_owned(),
));
}
} else {
return Err(Error::Validation(
"No bls signature included in the block header".to_owned(),
));
}
// check msgs for validity
fn check_msg<M, ST>(
msg: &M,
Expand Down Expand Up @@ -610,7 +638,7 @@ where
header.validate_timestamps(&base_tipset)?;

// check messages to ensure valid state transitions
self.check_blk_msgs(block.clone(), &parent_tipset)?;
self.check_block_msgs(block.clone(), &parent_tipset)?;

// TODO use computed state_root instead of parent_tipset.parent_state()
let work_addr = self
Expand Down
15 changes: 14 additions & 1 deletion blockchain/state_manager/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ mod errors;

pub use self::errors::*;
use actor::{miner, power, ActorState, STORAGE_POWER_ACTOR_ADDR};
use address::Address;
use address::{Address, Protocol};
use blockstore::BlockStore;
use cid::Cid;
use default_runtime::resolve_to_key_addr;
Expand Down Expand Up @@ -83,4 +83,17 @@ where
))
}
}
/// Returns a bls public key from provided address
pub fn get_bls_public_key(&self, addr: &Address, state_cid: &Cid) -> Result<Vec<u8>, Error> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a note that the public key should probably be an array (I'll make a pass through the Address crate soon I guess)

let state =
HamtStateTree::new_from_root(self.bs.as_ref(), state_cid).map_err(Error::State)?;
let kaddr = resolve_to_key_addr(&state, self.bs.as_ref(), addr)
.map_err(|e| Error::Other(format!("Failed to resolve key address, error: {}", e)))?;
if kaddr.protocol() != Protocol::BLS {
return Err(Error::Other(
"Address must be BLS address to load bls public key".to_owned(),
));
}
Ok(kaddr.payload().to_vec())
}
}
2 changes: 1 addition & 1 deletion crypto/src/signature.rs
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ impl Signature {
}
}
}

/// Aggregates and verifies bls signatures collectively
pub fn verify_bls_aggregate(data: &[&[u8]], pub_keys: &[&[u8]], aggregate_sig: &Signature) -> bool {
// If the number of public keys and data does not match, then return false
if data.len() != pub_keys.len() {
Expand Down