step transition messaging
This commit is contained in:
		
							parent
							
								
									8ac989cbeb
								
							
						
					
					
						commit
						2fa34fd6a8
					
				| @ -38,13 +38,14 @@ use engines::{Engine, EngineError, ProposeCollect}; | ||||
| use blockchain::extras::BlockDetails; | ||||
| use views::HeaderView; | ||||
| use evm::Schedule; | ||||
| use io::IoService; | ||||
| use io::{IoService, IoChannel}; | ||||
| use service::ClientIoMessage; | ||||
| use self::message::ConsensusMessage; | ||||
| use self::timeout::{TimerHandler, NextStep}; | ||||
| use self::params::TendermintParams; | ||||
| use self::vote_collector::VoteCollector; | ||||
| 
 | ||||
| #[derive(Debug, PartialEq, Eq)] | ||||
| #[derive(Debug, PartialEq, Eq, Clone)] | ||||
| pub enum Step { | ||||
| 	Propose, | ||||
| 	Prevote, | ||||
| @ -64,7 +65,7 @@ pub struct Tendermint { | ||||
| 	params: CommonParams, | ||||
| 	our_params: TendermintParams, | ||||
| 	builtins: BTreeMap<Address, Builtin>, | ||||
| 	timeout_service: IoService<NextStep>, | ||||
| 	step_service: IoService<NextStep>, | ||||
| 	/// Address to be used as authority.
 | ||||
| 	authority: RwLock<Address>, | ||||
| 	/// Blockchain height.
 | ||||
| @ -77,6 +78,8 @@ pub struct Tendermint { | ||||
| 	proposer_nonce: AtomicUsize, | ||||
| 	/// Vote accumulator.
 | ||||
| 	votes: VoteCollector, | ||||
| 	/// Proposed block held until seal is gathered.
 | ||||
| 	proposed_block: Mutex<Option<ExecutedBlock>>, | ||||
| 	/// Channel for updating the sealing.
 | ||||
| 	message_channel: Mutex<Option<IoChannel<ClientIoMessage>>> | ||||
| } | ||||
| @ -89,20 +92,30 @@ impl Tendermint { | ||||
| 				params: params, | ||||
| 				our_params: our_params, | ||||
| 				builtins: builtins, | ||||
| 				timeout_service: try!(IoService::<NextStep>::start()), | ||||
| 				step_service: try!(IoService::<NextStep>::start()), | ||||
| 				authority: RwLock::new(Address::default()), | ||||
| 				height: AtomicUsize::new(0), | ||||
| 				round: AtomicUsize::new(0), | ||||
| 				step: RwLock::new(Step::Propose), | ||||
| 				proposer_nonce: AtomicUsize::new(0), | ||||
| 				votes: VoteCollector::new(), | ||||
| 				proposed_block: Mutex::new(None), | ||||
| 				message_channel: Mutex::new(None) | ||||
| 			}); | ||||
| 		let handler = TimerHandler { engine: Arc::downgrade(&engine) }; | ||||
| 		try!(engine.timeout_service.register_handler(Arc::new(handler))); | ||||
| 		try!(engine.step_service.register_handler(Arc::new(handler))); | ||||
| 		Ok(engine) | ||||
| 	} | ||||
| 
 | ||||
| 	fn update_sealing(&self) { | ||||
| 		if let Some(ref channel) = *self.message_channel.lock() { | ||||
| 			match channel.send(ClientIoMessage::UpdateSealing) { | ||||
| 				Ok(_) => trace!(target: "poa", "timeout: UpdateSealing message sent."), | ||||
| 				Err(err) => warn!(target: "poa", "timeout: Could not send a sealing message {}.", err), | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	fn nonce_proposer(&self, proposer_nonce: usize) -> &Address { | ||||
| 		let ref p = self.our_params; | ||||
| 		p.authorities.get(proposer_nonce % p.authority_n).unwrap() | ||||
| @ -191,7 +204,6 @@ impl Engine for Tendermint { | ||||
| 	} | ||||
| 
 | ||||
| 	/// Set the correct round in the seal.
 | ||||
| 	/// This assumes that all uncles are valid uncles (i.e. of at least one generation before the current).
 | ||||
| 	fn on_close_block(&self, block: &mut ExecutedBlock) { | ||||
| 		let round = self.round.load(AtomicOrdering::SeqCst); | ||||
| 		block.fields_mut().header.set_seal(vec![::rlp::encode(&round).to_vec(), Vec::new(), Vec::new()]); | ||||
|  | ||||
| @ -16,9 +16,10 @@ | ||||
| 
 | ||||
| //! Tendermint timeout handling.
 | ||||
| 
 | ||||
| use util::Mutex; | ||||
| use std::sync::atomic::{Ordering as AtomicOrdering}; | ||||
| use std::sync::Weak; | ||||
| use io::{IoContext, IoHandler, TimerToken}; | ||||
| use io::{IoContext, IoHandler, TimerToken, IoChannel}; | ||||
| use super::{Tendermint, Step}; | ||||
| use time::{get_time, Duration}; | ||||
| use service::ClientIoMessage; | ||||
| @ -59,7 +60,7 @@ impl Default for TendermintTimeouts { | ||||
| } | ||||
| 
 | ||||
| #[derive(Clone)] | ||||
| pub struct NextStep; | ||||
| pub struct NextStep(Step); | ||||
| 
 | ||||
| /// Timer token representing the consensus step timeouts.
 | ||||
| pub const ENGINE_TIMEOUT_TOKEN: TimerToken = 23; | ||||
| @ -69,15 +70,6 @@ fn set_timeout(io: &IoContext<NextStep>, timeout: Duration) { | ||||
| 		.unwrap_or_else(|e| warn!(target: "poa", "Failed to set consensus step timeout: {}.", e)) | ||||
| } | ||||
| 
 | ||||
| fn update_sealing(io_channel: Mutex<Option<IoChannel<ClientIoMessage>>>) { | ||||
| 	if let Some(ref channel) = *io_channel.lock() { | ||||
| 		match channel.send(ClientIoMessage::UpdateSealing) { | ||||
| 			Ok(_) => trace!(target: "poa", "timeout: UpdateSealing message sent for round {}.", engine.round.load(AtomicOrdering::SeqCst)), | ||||
| 			Err(err) => trace!(target: "poa", "timeout: Could not send a sealing message {} for round {}.", err, engine.round.load(AtomicOrdering::SeqCst)), | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| impl IoHandler<NextStep> for TimerHandler { | ||||
| 	fn initialize(&self, io: &IoContext<NextStep>) { | ||||
| 		if let Some(engine) = self.engine.upgrade() { | ||||
| @ -112,18 +104,29 @@ impl IoHandler<NextStep> for TimerHandler { | ||||
| 				}; | ||||
| 
 | ||||
| 				if let Some(step) = next_step { | ||||
| 					*engine.step.write() = step | ||||
| 					*engine.step.write() = step; | ||||
| 					if step == Step::Propose { | ||||
| 						engine.update_sealing(); | ||||
| 					} | ||||
| 				} | ||||
| 
 | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	fn message(&self, io: &IoContext<NextStep>, _net_message: &NextStep) { | ||||
| 	fn message(&self, io: &IoContext<NextStep>, message: &NextStep) { | ||||
| 		if let Some(engine) = self.engine.upgrade() { | ||||
| 			println!("Message: {:?}", get_time().sec); | ||||
| 			io.clear_timer(ENGINE_TIMEOUT_TOKEN).expect("Failed to restart consensus step timer."); | ||||
| 			io.register_timer_once(ENGINE_TIMEOUT_TOKEN, engine.next_timeout()).expect("Failed to restart consensus step timer.") | ||||
| 			io.clear_timer(ENGINE_TIMEOUT_TOKEN); | ||||
| 			let NextStep(next_step) = *message; | ||||
| 			*engine.step.write() = next_step; | ||||
| 			match next_step { | ||||
| 				Step::Propose => { | ||||
| 					engine.update_sealing(); | ||||
| 					set_timeout(io, engine.our_params.timeouts.propose) | ||||
| 				}, | ||||
| 				Step::Prevote => set_timeout(io, engine.our_params.timeouts.prevote), | ||||
| 				Step::Precommit => set_timeout(io, engine.our_params.timeouts.precommit), | ||||
| 				Step::Commit => set_timeout(io, engine.our_params.timeouts.commit), | ||||
| 			}; | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| @ -39,8 +39,5 @@ pub use self::engine::Engine; | ||||
| pub use self::state::State; | ||||
| pub use self::ethash::{Ethash, EthashParams}; | ||||
| pub use self::basic_authority::{BasicAuthority, BasicAuthorityParams}; | ||||
| <<<<<<< HEAD | ||||
| pub use self::tendermint::{Tendermint, TendermintParams}; | ||||
| ======= | ||||
| pub use self::authority_round::{AuthorityRound, AuthorityRoundParams}; | ||||
| >>>>>>> parity/master | ||||
| pub use self::tendermint::{Tendermint, TendermintParams}; | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user