header methods
This commit is contained in:
		
							parent
							
								
									03c9760de2
								
							
						
					
					
						commit
						00a3619392
					
				| @ -14,14 +14,14 @@ | |||||||
| // You should have received a copy of the GNU General Public License
 | // You should have received a copy of the GNU General Public License
 | ||||||
| // along with Parity.  If not, see <http://www.gnu.org/licenses/>.
 | // along with Parity.  If not, see <http://www.gnu.org/licenses/>.
 | ||||||
| 
 | 
 | ||||||
| //! A blockchain engine that supports a basic, non-BFT proof-of-authority.
 | //! A blockchain engine that supports a non-instant BFT proof-of-authority.
 | ||||||
| 
 | 
 | ||||||
| use std::sync::atomic::{AtomicUsize, Ordering as AtomicOrdering}; | use std::sync::atomic::{AtomicUsize, Ordering as AtomicOrdering}; | ||||||
| use std::sync::Weak; | use std::sync::Weak; | ||||||
| use std::time::{UNIX_EPOCH, Duration}; | use std::time::{UNIX_EPOCH, Duration}; | ||||||
| use util::*; | use util::*; | ||||||
| use ethkey::verify_address; | use ethkey::{verify_address, Signature}; | ||||||
| use rlp::{UntrustedRlp, View, encode, decode}; | use rlp::{UntrustedRlp, View, encode}; | ||||||
| use account_provider::AccountProvider; | use account_provider::AccountProvider; | ||||||
| use block::*; | use block::*; | ||||||
| use spec::CommonParams; | use spec::CommonParams; | ||||||
| @ -71,6 +71,17 @@ pub struct AuthorityRound { | |||||||
| 	step: AtomicUsize | 	step: AtomicUsize | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | impl Header { | ||||||
|  |     fn step(&self) -> Result<usize, ::rlp::DecoderError> { | ||||||
|  |         UntrustedRlp::new(&self.seal()[0]).as_val() | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     fn signature(&self) -> Result<Signature, ::rlp::DecoderError> { | ||||||
|  |         UntrustedRlp::new(&self.seal()[1]).as_val::<H520>().map(Into::into) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| trait AsMillis { | trait AsMillis { | ||||||
| 	fn as_millis(&self) -> u64; | 	fn as_millis(&self) -> u64; | ||||||
| } | } | ||||||
| @ -202,12 +213,13 @@ impl Engine for AuthorityRound { | |||||||
| 			if let Some(ap) = accounts { | 			if let Some(ap) = accounts { | ||||||
| 				// Account should be permanently unlocked, otherwise sealing will fail.
 | 				// Account should be permanently unlocked, otherwise sealing will fail.
 | ||||||
| 				if let Ok(signature) = ap.sign(*header.author(), None, header.bare_hash()) { | 				if let Ok(signature) = ap.sign(*header.author(), None, header.bare_hash()) { | ||||||
|  | 					trace!(target: "poa", "generate_seal: Issuing a block for step {}.", step); | ||||||
| 					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: "poa", "generate_seal: FAIL: accounts secret key unavailable"); | 					trace!(target: "poa", "generate_seal: FAIL: Accounts secret key unavailable."); | ||||||
| 				} | 				} | ||||||
| 			} else { | 			} else { | ||||||
| 				trace!(target: "poa", "generate_seal: FAIL: accounts not provided"); | 				trace!(target: "poa", "generate_seal: FAIL: Accounts not provided."); | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 		None | 		None | ||||||
| @ -227,10 +239,10 @@ impl Engine for AuthorityRound { | |||||||
| 
 | 
 | ||||||
| 	/// Check if the signature belongs to the correct proposer.
 | 	/// Check if the signature belongs to the correct proposer.
 | ||||||
| 	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 header_step = try!(header.step()); | ||||||
| 		if step <= self.step() { |         // Give one step slack if step is lagging, double vote is still not possible.
 | ||||||
| 			let sig = try!(UntrustedRlp::new(&header.seal()[1]).as_val::<H520>()); | 		if header_step <= self.step() + 1 { | ||||||
| 			let ok_sig = try!(verify_address(self.step_proposer(step), &sig.into(), &header.bare_hash())); | 			let ok_sig = try!(verify_address(self.step_proposer(header_step), &try!(header.signature()), &header.bare_hash())); | ||||||
| 			if ok_sig { | 			if ok_sig { | ||||||
| 				Ok(()) | 				Ok(()) | ||||||
| 			} else { | 			} else { | ||||||
| @ -250,9 +262,7 @@ impl Engine for AuthorityRound { | |||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		// Check if parent is from a previous step.
 | 		// Check if parent is from a previous step.
 | ||||||
| 		let parent_step = try!(UntrustedRlp::new(&parent.seal()[0]).as_val::<usize>()); | 		if try!(header.step()) == try!(parent.step()) { 
 | ||||||
| 		let step = try!(UntrustedRlp::new(&header.seal()[0]).as_val::<usize>()); |  | ||||||
| 		if step <= parent_step { 
 |  | ||||||
| 			try!(Err(BlockError::DoubleVote(header.author().clone()))); | 			try!(Err(BlockError::DoubleVote(header.author().clone()))); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| @ -284,13 +294,6 @@ impl Engine for AuthorityRound { | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl Header { |  | ||||||
| 	/// Get the none field of the header.
 |  | ||||||
| 	pub fn signature(&self) -> H520 { |  | ||||||
| 		decode(&self.seal()[0]) |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| #[cfg(test)] | #[cfg(test)] | ||||||
| mod tests { | mod tests { | ||||||
| 	use common::*; | 	use common::*; | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user