check double signing, tracing

This commit is contained in:
keorn 2016-11-01 18:12:06 +00:00
parent a33e2f2e0d
commit 3a6b56e99c
2 changed files with 18 additions and 10 deletions

View File

@ -128,7 +128,7 @@ struct TransitionHandler {
#[derive(Clone)] #[derive(Clone)]
struct BlockArrived; struct BlockArrived;
const ENGINE_TIMEOUT_TOKEN: TimerToken = 0; const ENGINE_TIMEOUT_TOKEN: TimerToken = 23;
impl IoHandler<BlockArrived> for TransitionHandler { impl IoHandler<BlockArrived> for TransitionHandler {
fn initialize(&self, io: &IoContext<BlockArrived>) { fn initialize(&self, io: &IoContext<BlockArrived>) {
@ -140,12 +140,11 @@ impl IoHandler<BlockArrived> for TransitionHandler {
fn timeout(&self, io: &IoContext<BlockArrived>, timer: TimerToken) { fn timeout(&self, io: &IoContext<BlockArrived>, timer: TimerToken) {
if timer == ENGINE_TIMEOUT_TOKEN { if timer == ENGINE_TIMEOUT_TOKEN {
if let Some(engine) = self.engine.upgrade() { if let Some(engine) = self.engine.upgrade() {
debug!(target: "authorityround", "Timeout step: {}", engine.step.load(AtomicOrdering::Relaxed));
engine.step.fetch_add(1, AtomicOrdering::SeqCst); engine.step.fetch_add(1, AtomicOrdering::SeqCst);
if let Some(ref channel) = *engine.message_channel.try_lock().expect("Could not acquire message channel work.") { if let Some(ref channel) = *engine.message_channel.try_lock().expect("Could not acquire message channel work.") {
match channel.send(ClientIoMessage::UpdateSealing) { match channel.send(ClientIoMessage::UpdateSealing) {
Ok(_) => trace!(target: "authorityround", "timeout: UpdateSealing message sent."), Ok(_) => trace!(target: "poa", "timeout: UpdateSealing message sent for step {}.", engine.step.load(AtomicOrdering::Relaxed)),
Err(_) => trace!(target: "authorityround", "timeout: Could not send a sealing message."), Err(err) => trace!(target: "poa", "timeout: Could not send a sealing message {} for step {}.", err, engine.step.load(AtomicOrdering::Relaxed)),
} }
} }
io.register_timer_once(ENGINE_TIMEOUT_TOKEN, engine.remaining_step_millis()).expect("Failed to restart consensus step timer.") io.register_timer_once(ENGINE_TIMEOUT_TOKEN, engine.remaining_step_millis()).expect("Failed to restart consensus step timer.")
@ -205,10 +204,10 @@ impl Engine for AuthorityRound {
if let Ok(signature) = ap.sign(*header.author(), None, header.bare_hash()) { if let Ok(signature) = ap.sign(*header.author(), None, header.bare_hash()) {
return Some(vec![encode(&step).to_vec(), encode(&(&*signature as &[u8])).to_vec()]); return Some(vec![encode(&step).to_vec(), encode(&(&*signature as &[u8])).to_vec()]);
} else { } else {
trace!(target: "authorityround", "generate_seal: FAIL: accounts secret key unavailable"); trace!(target: "poa", "generate_seal: FAIL: accounts secret key unavailable");
} }
} else { } else {
trace!(target: "authorityround", "generate_seal: FAIL: accounts not provided"); trace!(target: "poa", "generate_seal: FAIL: accounts not provided");
} }
} }
None None
@ -217,7 +216,7 @@ impl Engine for AuthorityRound {
/// Check the number of seal fields. /// Check the number of seal fields.
fn verify_block_basic(&self, header: &Header, _block: Option<&[u8]>) -> Result<(), Error> { fn verify_block_basic(&self, header: &Header, _block: Option<&[u8]>) -> Result<(), Error> {
if header.seal().len() != self.seal_fields() { if header.seal().len() != self.seal_fields() {
trace!(target: "authorityround", "verify_block_basic: wrong number of seal fields"); trace!(target: "poa", "verify_block_basic: wrong number of seal fields");
Err(From::from(BlockError::InvalidSealArity( Err(From::from(BlockError::InvalidSealArity(
Mismatch { expected: self.seal_fields(), found: header.seal().len() } Mismatch { expected: self.seal_fields(), found: header.seal().len() }
))) )))
@ -227,7 +226,6 @@ impl Engine for AuthorityRound {
} }
/// Check if the signature belongs to the correct proposer. /// Check if the signature belongs to the correct proposer.
/// TODO: Keep track of BlockNumber to step relationship
fn verify_block_unordered(&self, header: &Header, _block: Option<&[u8]>) -> Result<(), Error> { fn verify_block_unordered(&self, header: &Header, _block: Option<&[u8]>) -> Result<(), Error> {
let step = try!(UntrustedRlp::new(&header.seal()[0]).as_val::<usize>()); let step = try!(UntrustedRlp::new(&header.seal()[0]).as_val::<usize>());
if step <= self.step() { if step <= self.step() {
@ -236,11 +234,11 @@ impl Engine for AuthorityRound {
if ok_sig { if ok_sig {
Ok(()) Ok(())
} else { } else {
trace!(target: "authorityround", "verify_block_unordered: invalid seal signature"); trace!(target: "poa", "verify_block_unordered: invalid seal signature");
try!(Err(BlockError::InvalidSeal)) try!(Err(BlockError::InvalidSeal))
} }
} else { } else {
trace!(target: "authorityround", "verify_block_unordered: block from the future"); trace!(target: "poa", "verify_block_unordered: block from the future");
try!(Err(BlockError::InvalidSeal)) try!(Err(BlockError::InvalidSeal))
} }
} }
@ -251,6 +249,13 @@ impl Engine for AuthorityRound {
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() })));
} }
// Check if parent is from a previous step.
let parent_step = try!(UntrustedRlp::new(&parent.seal()[0]).as_val::<usize>());
let step = try!(UntrustedRlp::new(&header.seal()[0]).as_val::<usize>());
if step <= parent_step {
try!(Err(BlockError::DoubleVote(header.author().clone())));
}
// Check difficulty is correct given the two timestamps. // Check difficulty is correct given the two timestamps.
if header.difficulty() != parent.difficulty() { if header.difficulty() != parent.difficulty() {
return Err(From::from(BlockError::InvalidDifficulty(Mismatch { expected: *parent.difficulty(), found: *header.difficulty() }))) return Err(From::from(BlockError::InvalidDifficulty(Mismatch { expected: *parent.difficulty(), found: *header.difficulty() })))

View File

@ -164,6 +164,8 @@ pub enum BlockError {
UnknownParent(H256), UnknownParent(H256),
/// Uncle parent given is unknown. /// Uncle parent given is unknown.
UnknownUncleParent(H256), UnknownUncleParent(H256),
/// The same author issued different votes at the same step.
DoubleVote(H160)
} }
impl fmt::Display for BlockError { impl fmt::Display for BlockError {
@ -197,6 +199,7 @@ impl fmt::Display for BlockError {
RidiculousNumber(ref oob) => format!("Implausible block number. {}", oob), RidiculousNumber(ref oob) => format!("Implausible block number. {}", oob),
UnknownParent(ref hash) => format!("Unknown parent: {}", hash), UnknownParent(ref hash) => format!("Unknown parent: {}", hash),
UnknownUncleParent(ref hash) => format!("Unknown uncle parent: {}", hash), UnknownUncleParent(ref hash) => format!("Unknown uncle parent: {}", hash),
DoubleVote(ref address) => format!("Author {} issued to many blocks.", address),
}; };
f.write_fmt(format_args!("Block error ({})", msg)) f.write_fmt(format_args!("Block error ({})", msg))