seal generation and verificatio
This commit is contained in:
parent
91fbaf935c
commit
45e6b4ac9d
@ -20,6 +20,7 @@ use std::sync::atomic::{AtomicUsize, Ordering as AtomicOrdering};
|
|||||||
use std::sync::Weak;
|
use std::sync::Weak;
|
||||||
use common::*;
|
use common::*;
|
||||||
use rlp::{UntrustedRlp, View, encode};
|
use rlp::{UntrustedRlp, View, encode};
|
||||||
|
use ethkey::{recover, public_to_address};
|
||||||
use account_provider::AccountProvider;
|
use account_provider::AccountProvider;
|
||||||
use block::*;
|
use block::*;
|
||||||
use spec::CommonParams;
|
use spec::CommonParams;
|
||||||
@ -278,15 +279,9 @@ impl Engine for Tendermint {
|
|||||||
///
|
///
|
||||||
/// None is returned if not enough signatures can be collected.
|
/// None is returned if not enough signatures can be collected.
|
||||||
fn generate_seal(&self, block: &ExecutedBlock, accounts: Option<&AccountProvider>) -> Option<Vec<Bytes>> {
|
fn generate_seal(&self, block: &ExecutedBlock, accounts: Option<&AccountProvider>) -> Option<Vec<Bytes>> {
|
||||||
accounts.and_then(|ap| {
|
self.s.try_read().and_then(|s| match *s {
|
||||||
let header = block.header();
|
Step::Commit(ref seal) => Some(seal.clone()),
|
||||||
if header.author() == &self.proposer() {
|
_ => None,
|
||||||
ap.sign(*header.author(), header.bare_hash())
|
|
||||||
.ok()
|
|
||||||
.and_then(|signature| Some(vec![encode(&(&*signature as &[u8])).to_vec()]))
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -302,22 +297,35 @@ impl Engine for Tendermint {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn verify_block_basic(&self, header: &Header, _block: Option<&[u8]>) -> result::Result<(), Error> {
|
fn verify_block_basic(&self, header: &Header, _block: Option<&[u8]>) -> Result<(), Error> {
|
||||||
// check the seal fields.
|
if header.seal().len() < self.threshold() {
|
||||||
// TODO: pull this out into common code.
|
Err(From::from(BlockError::InvalidSealArity(
|
||||||
if header.seal().len() != self.seal_fields() {
|
Mismatch { expected: self.threshold(), found: header.seal().len() }
|
||||||
return Err(From::from(BlockError::InvalidSealArity(
|
)))
|
||||||
Mismatch { expected: self.seal_fields(), found: header.seal().len() }
|
} else {
|
||||||
)));
|
Ok(())
|
||||||
}
|
}
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn verify_block_unordered(&self, _header: &Header, _block: Option<&[u8]>) -> result::Result<(), Error> {
|
fn verify_block_unordered(&self, header: &Header, _block: Option<&[u8]>) -> Result<(), Error> {
|
||||||
Ok(())
|
let to_address = |b: &Vec<u8>| {
|
||||||
|
let sig: H520 = try!(UntrustedRlp::new(b.as_slice()).as_val());
|
||||||
|
Ok(public_to_address(&try!(recover(&sig.into(), &header.bare_hash()))))
|
||||||
|
};
|
||||||
|
let validator_set = self.our_params.validators.iter().cloned().collect();
|
||||||
|
let seal_set = try!(header
|
||||||
|
.seal()
|
||||||
|
.iter()
|
||||||
|
.map(to_address)
|
||||||
|
.collect::<Result<HashSet<_>, Error>>());
|
||||||
|
if self.threshold() < seal_set.intersection(&validator_set).count() {
|
||||||
|
Ok(())
|
||||||
|
} else {
|
||||||
|
try!(Err(BlockError::InvalidSeal))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn verify_block_family(&self, header: &Header, parent: &Header, _block: Option<&[u8]>) -> result::Result<(), Error> {
|
fn verify_block_family(&self, header: &Header, parent: &Header, _block: Option<&[u8]>) -> Result<(), Error> {
|
||||||
// we should not calculate difficulty for genesis blocks
|
// we should not calculate difficulty for genesis blocks
|
||||||
if header.number() == 0 {
|
if header.number() == 0 {
|
||||||
return Err(From::from(BlockError::RidiculousNumber(OutOfBounds { min: Some(1), max: None, found: header.number() })));
|
return Err(From::from(BlockError::RidiculousNumber(OutOfBounds { min: Some(1), max: None, found: header.number() })));
|
||||||
@ -336,7 +344,7 @@ impl Engine for Tendermint {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn verify_transaction_basic(&self, t: &SignedTransaction, _header: &Header) -> result::Result<(), Error> {
|
fn verify_transaction_basic(&self, t: &SignedTransaction, _header: &Header) -> Result<(), Error> {
|
||||||
try!(t.check_low_s());
|
try!(t.check_low_s());
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user