| 
							
							
							
						 |  |  | @ -1,3 +1,4 @@ | 
		
	
		
			
				|  |  |  |  | //! Transaction Execution environment.
 | 
		
	
		
			
				|  |  |  |  | use std::collections::HashSet; | 
		
	
		
			
				|  |  |  |  | use std::cmp; | 
		
	
		
			
				|  |  |  |  | use std::ptr; | 
		
	
	
		
			
				
					
					|  |  |  | @ -139,11 +140,11 @@ impl<'a> Executive<'a> { | 
		
	
		
			
				|  |  |  |  | 	} | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 	/// This funtion should be used to execute transaction.
 | 
		
	
		
			
				|  |  |  |  | 	pub fn transact(e: &mut Executive<'a>, t: &Transaction) -> ExecutionResult { | 
		
	
		
			
				|  |  |  |  | 	pub fn transact(&mut self, t: &Transaction) -> ExecutionResult { | 
		
	
		
			
				|  |  |  |  | 		// TODO: validate transaction signature ?/ sender
 | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 		let sender = t.sender(); | 
		
	
		
			
				|  |  |  |  | 		let nonce = e.state.nonce(&sender); | 
		
	
		
			
				|  |  |  |  | 		let nonce = self.state.nonce(&sender); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 		// validate transaction nonce
 | 
		
	
		
			
				|  |  |  |  | 		if t.nonce != nonce { | 
		
	
	
		
			
				
					
					|  |  |  | @ -151,16 +152,16 @@ impl<'a> Executive<'a> { | 
		
	
		
			
				|  |  |  |  | 		} | 
		
	
		
			
				|  |  |  |  | 		
 | 
		
	
		
			
				|  |  |  |  | 		// validate if transaction fits into given block
 | 
		
	
		
			
				|  |  |  |  | 		if e.info.gas_used + t.gas > e.info.gas_limit { | 
		
	
		
			
				|  |  |  |  | 		if self.info.gas_used + t.gas > self.info.gas_limit { | 
		
	
		
			
				|  |  |  |  | 			return Err(ExecutionError::BlockGasLimitReached { 
 | 
		
	
		
			
				|  |  |  |  | 				gas_limit: e.info.gas_limit, 
 | 
		
	
		
			
				|  |  |  |  | 				gas_used: e.info.gas_used, 
 | 
		
	
		
			
				|  |  |  |  | 				gas_limit: self.info.gas_limit, 
 | 
		
	
		
			
				|  |  |  |  | 				gas_used: self.info.gas_used, 
 | 
		
	
		
			
				|  |  |  |  | 				gas: t.gas 
 | 
		
	
		
			
				|  |  |  |  | 			}); | 
		
	
		
			
				|  |  |  |  | 		} | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 		// TODO: we might need bigints here, or at least check overflows.
 | 
		
	
		
			
				|  |  |  |  | 		let balance = e.state.balance(&sender); | 
		
	
		
			
				|  |  |  |  | 		let balance = self.state.balance(&sender); | 
		
	
		
			
				|  |  |  |  | 		let gas_cost = t.gas * t.gas_price; | 
		
	
		
			
				|  |  |  |  | 		let total_cost = t.value + gas_cost; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
	
		
			
				
					
					|  |  |  | @ -170,7 +171,7 @@ impl<'a> Executive<'a> { | 
		
	
		
			
				|  |  |  |  | 		} | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 		// NOTE: there can be no invalid transactions from this point.
 | 
		
	
		
			
				|  |  |  |  | 		e.state.inc_nonce(&sender); | 
		
	
		
			
				|  |  |  |  | 		self.state.inc_nonce(&sender); | 
		
	
		
			
				|  |  |  |  | 		let mut substate = Substate::new(); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 		let res = match t.kind() { | 
		
	
	
		
			
				
					
					|  |  |  | @ -185,7 +186,7 @@ impl<'a> Executive<'a> { | 
		
	
		
			
				|  |  |  |  | 					code: t.data.clone(), | 
		
	
		
			
				|  |  |  |  | 					data: vec![], | 
		
	
		
			
				|  |  |  |  | 				}; | 
		
	
		
			
				|  |  |  |  | 				Executive::call(e, ¶ms, &mut substate, &mut []) | 
		
	
		
			
				|  |  |  |  | 				self.call(¶ms, &mut substate, &mut []) | 
		
	
		
			
				|  |  |  |  | 			}, | 
		
	
		
			
				|  |  |  |  | 			TransactionKind::MessageCall => { | 
		
	
		
			
				|  |  |  |  | 				let params = EvmParams { | 
		
	
	
		
			
				
					
					|  |  |  | @ -195,15 +196,15 @@ impl<'a> Executive<'a> { | 
		
	
		
			
				|  |  |  |  | 					gas: t.gas, | 
		
	
		
			
				|  |  |  |  | 					gas_price: t.gas_price, | 
		
	
		
			
				|  |  |  |  | 					value: t.value, | 
		
	
		
			
				|  |  |  |  | 					code: e.state.code(&t.to.clone().unwrap()).unwrap_or(vec![]), | 
		
	
		
			
				|  |  |  |  | 					code: self.state.code(&t.to.clone().unwrap()).unwrap_or(vec![]), | 
		
	
		
			
				|  |  |  |  | 					data: t.data.clone(), | 
		
	
		
			
				|  |  |  |  | 				}; | 
		
	
		
			
				|  |  |  |  | 				Executive::create(e, ¶ms, &mut substate) | 
		
	
		
			
				|  |  |  |  | 				self.create(¶ms, &mut substate) | 
		
	
		
			
				|  |  |  |  | 			} | 
		
	
		
			
				|  |  |  |  | 		}; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 		// finalize here!
 | 
		
	
		
			
				|  |  |  |  | 		e.finalize(substate, &sender, U256::zero(), U256::zero(), t.gas_price); | 
		
	
		
			
				|  |  |  |  | 		self.finalize(substate, &sender, U256::zero(), U256::zero(), t.gas_price); | 
		
	
		
			
				|  |  |  |  | 		//res
 | 
		
	
		
			
				|  |  |  |  | 		Ok(Executed::new()) | 
		
	
		
			
				|  |  |  |  | 	} | 
		
	
	
		
			
				
					
					|  |  |  | @ -212,23 +213,23 @@ impl<'a> Executive<'a> { | 
		
	
		
			
				|  |  |  |  | 	/// NOTE. It does not finalize the transaction (doesn't do refunds, nor suicides).
 | 
		
	
		
			
				|  |  |  |  | 	/// Modifies the substate and the output.
 | 
		
	
		
			
				|  |  |  |  | 	/// Returns either gas_left or `EvmError`.
 | 
		
	
		
			
				|  |  |  |  | 	fn call(e: &mut Executive<'a>, params: &EvmParams, substate: &mut Substate, output: &mut [u8]) -> EvmResult { | 
		
	
		
			
				|  |  |  |  | 	fn call(&mut self, params: &EvmParams, substate: &mut Substate, output: &mut [u8]) -> EvmResult { | 
		
	
		
			
				|  |  |  |  | 		// at first, transfer value to destination
 | 
		
	
		
			
				|  |  |  |  | 		e.state.transfer_balance(¶ms.sender, ¶ms.address, ¶ms.value); | 
		
	
		
			
				|  |  |  |  | 		self.state.transfer_balance(¶ms.sender, ¶ms.address, ¶ms.value); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 		if e.engine.is_builtin(¶ms.address) { | 
		
	
		
			
				|  |  |  |  | 		if self.engine.is_builtin(¶ms.address) { | 
		
	
		
			
				|  |  |  |  | 			// if destination is builtin, try to execute it
 | 
		
	
		
			
				|  |  |  |  | 			let cost = e.engine.cost_of_builtin(¶ms.address, ¶ms.data); | 
		
	
		
			
				|  |  |  |  | 			let cost = self.engine.cost_of_builtin(¶ms.address, ¶ms.data); | 
		
	
		
			
				|  |  |  |  | 			match cost <= params.gas { | 
		
	
		
			
				|  |  |  |  | 				true => { | 
		
	
		
			
				|  |  |  |  | 					e.engine.execute_builtin(¶ms.address, ¶ms.data, output); | 
		
	
		
			
				|  |  |  |  | 					self.engine.execute_builtin(¶ms.address, ¶ms.data, output); | 
		
	
		
			
				|  |  |  |  | 					Ok(params.gas - cost) | 
		
	
		
			
				|  |  |  |  | 				}, | 
		
	
		
			
				|  |  |  |  | 				false => Err(EvmError::OutOfGas) | 
		
	
		
			
				|  |  |  |  | 			} | 
		
	
		
			
				|  |  |  |  | 		} else if params.code.len() > 0 { | 
		
	
		
			
				|  |  |  |  | 			// if destination is a contract, do normal message call
 | 
		
	
		
			
				|  |  |  |  | 			let mut ext = Externalities::new(e.state, e.info, e.engine, e.depth, params, substate, OutputPolicy::Return(output)); | 
		
	
		
			
				|  |  |  |  | 			let mut ext = Externalities::new(self.state, self.info, self.engine, self.depth, params, substate, OutputPolicy::Return(output)); | 
		
	
		
			
				|  |  |  |  | 			let evm = VmFactory::create(); | 
		
	
		
			
				|  |  |  |  | 			evm.exec(¶ms, &mut ext) | 
		
	
		
			
				|  |  |  |  | 		} else { | 
		
	
	
		
			
				
					
					|  |  |  | @ -240,13 +241,13 @@ impl<'a> Executive<'a> { | 
		
	
		
			
				|  |  |  |  | 	/// Creates contract with given contract params.
 | 
		
	
		
			
				|  |  |  |  | 	/// NOTE. It does not finalize the transaction (doesn't do refunds, nor suicides).
 | 
		
	
		
			
				|  |  |  |  | 	/// Modifies the substate.
 | 
		
	
		
			
				|  |  |  |  | 	fn create(e: &mut Executive<'a>, params: &EvmParams, substate: &mut Substate) -> EvmResult { | 
		
	
		
			
				|  |  |  |  | 	fn create(&mut self, params: &EvmParams, substate: &mut Substate) -> EvmResult { | 
		
	
		
			
				|  |  |  |  | 		// at first create new contract
 | 
		
	
		
			
				|  |  |  |  | 		e.state.new_contract(¶ms.address); | 
		
	
		
			
				|  |  |  |  | 		self.state.new_contract(¶ms.address); | 
		
	
		
			
				|  |  |  |  | 		// then transfer value to it
 | 
		
	
		
			
				|  |  |  |  | 		e.state.transfer_balance(¶ms.sender, ¶ms.address, ¶ms.value); | 
		
	
		
			
				|  |  |  |  | 		self.state.transfer_balance(¶ms.sender, ¶ms.address, ¶ms.value); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 		let mut ext = Externalities::new(e.state, e.info, e.engine, e.depth, params, substate, OutputPolicy::InitContract); | 
		
	
		
			
				|  |  |  |  | 		let mut ext = Externalities::new(self.state, self.info, self.engine, self.depth, params, substate, OutputPolicy::InitContract); | 
		
	
		
			
				|  |  |  |  | 		let evm = VmFactory::create(); | 
		
	
		
			
				|  |  |  |  | 		evm.exec(¶ms, &mut ext) | 
		
	
		
			
				|  |  |  |  | 	} | 
		
	
	
		
			
				
					
					|  |  |  | @ -351,7 +352,7 @@ impl<'a> Ext for Externalities<'a> { | 
		
	
		
			
				|  |  |  |  | 		} | 
		
	
		
			
				|  |  |  |  | 	} | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 	fn create(&mut self, gas: u64, endowment: &U256, code: &[u8]) -> Option<(Address, u64)> { | 
		
	
		
			
				|  |  |  |  | 	fn create(&mut self, gas: u64, endowment: &U256, code: &[u8]) -> Option<(u64, Address)> { | 
		
	
		
			
				|  |  |  |  | 		// if balance is insufficient or we are to deep, return
 | 
		
	
		
			
				|  |  |  |  | 		if self.state.balance(&self.params.address) < *endowment && self.depth >= 1024 { | 
		
	
		
			
				|  |  |  |  | 			return None | 
		
	
	
		
			
				
					
					|  |  |  | @ -376,14 +377,14 @@ impl<'a> Ext for Externalities<'a> { | 
		
	
		
			
				|  |  |  |  | 		{ | 
		
	
		
			
				|  |  |  |  | 			let mut ex = Executive::from_parent(self); | 
		
	
		
			
				|  |  |  |  | 			ex.state.inc_nonce(&address); | 
		
	
		
			
				|  |  |  |  | 			let res = Executive::create(&mut ex, ¶ms, &mut substate); | 
		
	
		
			
				|  |  |  |  | 			let res = ex.create(¶ms, &mut substate); | 
		
	
		
			
				|  |  |  |  | 		} | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 		self.substate.accrue(substate); | 
		
	
		
			
				|  |  |  |  | 		Some((address, gas)) | 
		
	
		
			
				|  |  |  |  | 		Some((gas, address)) | 
		
	
		
			
				|  |  |  |  | 	} | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 	fn call(&mut self, gas: u64, call_gas: u64, receive_address: &Address, value: &U256, data: &[u8], code_address: &Address) -> Option<(Vec<u8>, u64)> { | 
		
	
		
			
				|  |  |  |  | 	fn call(&mut self, gas: u64, call_gas: u64, receive_address: &Address, value: &U256, data: &[u8], code_address: &Address, output: &mut [u8]) -> Option<u64> { | 
		
	
		
			
				|  |  |  |  | 		// TODO: validation of the call
 | 
		
	
		
			
				|  |  |  |  | 		
 | 
		
	
		
			
				|  |  |  |  | 		println!("gas: {:?}", gas); | 
		
	
	
		
			
				
					
					|  |  |  | @ -431,12 +432,12 @@ impl<'a> Ext for Externalities<'a> { | 
		
	
		
			
				|  |  |  |  | 		{ | 
		
	
		
			
				|  |  |  |  | 			let mut ex = Executive::from_parent(self); | 
		
	
		
			
				|  |  |  |  | 			// TODO: take output into account
 | 
		
	
		
			
				|  |  |  |  | 			Executive::call(&mut ex, ¶ms, &mut substate, &mut []); | 
		
	
		
			
				|  |  |  |  | 			ex.call(¶ms, &mut substate, output); | 
		
	
		
			
				|  |  |  |  | 		} | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 		self.substate.accrue(substate); | 
		
	
		
			
				|  |  |  |  | 		// TODO: replace call_gas with what's actually left
 | 
		
	
		
			
				|  |  |  |  | 		Some((vec![], gas - gas_cost + call_gas)) | 
		
	
		
			
				|  |  |  |  | 		Some(gas - gas_cost + call_gas) | 
		
	
		
			
				|  |  |  |  | 	} | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 	fn extcode(&self, address: &Address) -> Vec<u8> { | 
		
	
	
		
			
				
					
					|  |  |  | 
 |