Disallow unsigned transactions in case EIP-86 is disabled (#8802)
* Disallow unsigned transactions in case EIP-86 is disabled * Add tests for verification * Add disallow unsigned transactions test in machine
This commit is contained in:
		
							parent
							
								
									5d6a0d4dae
								
							
						
					
					
						commit
						123b6ae62e
					
				@ -101,6 +101,9 @@ pub fn new_morden<'a, T: Into<SpecParams<'a>>>(params: T) -> Spec {
 | 
			
		||||
/// Create a new Foundation Frontier-era chain spec as though it never changes to Homestead.
 | 
			
		||||
pub fn new_frontier_test() -> Spec { load(None, include_bytes!("../../res/ethereum/frontier_test.json")) }
 | 
			
		||||
 | 
			
		||||
/// Create a new Ropsten chain spec.
 | 
			
		||||
pub fn new_ropsten_test() -> Spec { load(None, include_bytes!("../../res/ethereum/ropsten.json")) }
 | 
			
		||||
 | 
			
		||||
/// Create a new Foundation Homestead-era chain spec as though it never changed from Frontier.
 | 
			
		||||
pub fn new_homestead_test() -> Spec { load(None, include_bytes!("../../res/ethereum/homestead_test.json")) }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -485,6 +485,25 @@ mod tests {
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	#[test]
 | 
			
		||||
	fn should_disallow_unsigned_transactions() {
 | 
			
		||||
		let rlp = "ea80843b9aca0083015f90948921ebb5f79e9e3920abe571004d0b1d5119c154865af3107a400080038080".into();
 | 
			
		||||
		let transaction: UnverifiedTransaction = ::rlp::decode(&::rustc_hex::FromHex::from_hex(rlp).unwrap()).unwrap();
 | 
			
		||||
		let spec = ::ethereum::new_ropsten_test();
 | 
			
		||||
		let ethparams = get_default_ethash_extensions();
 | 
			
		||||
 | 
			
		||||
		let machine = EthereumMachine::with_ethash_extensions(
 | 
			
		||||
			spec.params().clone(),
 | 
			
		||||
			Default::default(),
 | 
			
		||||
			ethparams,
 | 
			
		||||
		);
 | 
			
		||||
		let mut header = ::header::Header::new();
 | 
			
		||||
		header.set_number(15);
 | 
			
		||||
 | 
			
		||||
		let res = machine.verify_transaction_basic(&transaction, &header);
 | 
			
		||||
		assert_eq!(res, Err(transaction::Error::InvalidSignature("Crypto error (Invalid EC signature)".into())));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	#[test]
 | 
			
		||||
	fn ethash_gas_limit_is_multiple_of_determinant() {
 | 
			
		||||
		use ethereum_types::U256;
 | 
			
		||||
 | 
			
		||||
@ -576,7 +576,17 @@ mod tests {
 | 
			
		||||
			nonce: U256::from(2)
 | 
			
		||||
		}.sign(keypair.secret(), None);
 | 
			
		||||
 | 
			
		||||
		let tr3 = Transaction {
 | 
			
		||||
			action: Action::Call(0x0.into()),
 | 
			
		||||
			value: U256::from(0),
 | 
			
		||||
			data: Bytes::new(),
 | 
			
		||||
			gas: U256::from(30_000),
 | 
			
		||||
			gas_price: U256::from(0),
 | 
			
		||||
			nonce: U256::zero(),
 | 
			
		||||
		}.null_sign(0);
 | 
			
		||||
 | 
			
		||||
		let good_transactions = [ tr1.clone(), tr2.clone() ];
 | 
			
		||||
		let eip86_transactions = [ tr3.clone() ];
 | 
			
		||||
 | 
			
		||||
		let diff_inc = U256::from(0x40);
 | 
			
		||||
 | 
			
		||||
@ -612,6 +622,7 @@ mod tests {
 | 
			
		||||
		uncles_rlp.append_list(&good_uncles);
 | 
			
		||||
		let good_uncles_hash = keccak(uncles_rlp.as_raw());
 | 
			
		||||
		let good_transactions_root = ordered_trie_root(good_transactions.iter().map(|t| ::rlp::encode::<UnverifiedTransaction>(t)));
 | 
			
		||||
		let eip86_transactions_root = ordered_trie_root(eip86_transactions.iter().map(|t| ::rlp::encode::<UnverifiedTransaction>(t)));
 | 
			
		||||
 | 
			
		||||
		let mut parent = good.clone();
 | 
			
		||||
		parent.set_number(9);
 | 
			
		||||
@ -632,6 +643,14 @@ mod tests {
 | 
			
		||||
 | 
			
		||||
		check_ok(basic_test(&create_test_block(&good), engine));
 | 
			
		||||
 | 
			
		||||
		let mut bad_header = good.clone();
 | 
			
		||||
		bad_header.set_transactions_root(eip86_transactions_root.clone());
 | 
			
		||||
		bad_header.set_uncles_hash(good_uncles_hash.clone());
 | 
			
		||||
		match basic_test(&create_test_block_with_data(&bad_header, &eip86_transactions, &good_uncles), engine) {
 | 
			
		||||
			Err(Error(ErrorKind::Transaction(ref e), _)) if e == &::ethkey::Error::InvalidSignature.into() => (),
 | 
			
		||||
			e => panic!("Block verification failed.\nExpected: Transaction Error (Invalid Signature)\nGot: {:?}", e),
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		let mut header = good.clone();
 | 
			
		||||
		header.set_transactions_root(good_transactions_root.clone());
 | 
			
		||||
		header.set_uncles_hash(good_uncles_hash.clone());
 | 
			
		||||
 | 
			
		||||
@ -409,6 +409,10 @@ impl UnverifiedTransaction {
 | 
			
		||||
		if check_low_s && !(allow_empty_signature && self.is_unsigned()) {
 | 
			
		||||
			self.check_low_s()?;
 | 
			
		||||
		}
 | 
			
		||||
		// Disallow unsigned transactions in case EIP-86 is disabled.
 | 
			
		||||
		if !allow_empty_signature && self.is_unsigned() {
 | 
			
		||||
			return Err(ethkey::Error::InvalidSignature.into());
 | 
			
		||||
		}
 | 
			
		||||
		// EIP-86: Transactions of this form MUST have gasprice = 0, nonce = 0, value = 0, and do NOT increment the nonce of account 0.
 | 
			
		||||
		if allow_empty_signature && self.is_unsigned() && !(self.gas_price.is_zero() && self.value.is_zero() && self.nonce.is_zero()) {
 | 
			
		||||
			return Err(ethkey::Error::InvalidSignature.into())
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user