Working test with block reward added
This commit is contained in:
		
							parent
							
								
									16f39487ba
								
							
						
					
					
						commit
						73128039a6
					
				| @ -7,7 +7,8 @@ | ||||
| 		"accountStartNonce": "0x0", | ||||
| 		"maximumExtraDataSize": "0x20", | ||||
| 		"minGasLimit": "0x1388", | ||||
| 		"networkID" : "0x2" | ||||
| 		"networkID" : "0x2", | ||||
|                 "applyReward": false | ||||
| 	}, | ||||
| 	"genesis": { | ||||
| 		"seal": { | ||||
|  | ||||
							
								
								
									
										34
									
								
								ethcore/res/null_morden_with_reward.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								ethcore/res/null_morden_with_reward.json
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,34 @@ | ||||
| { | ||||
| 	"name": "Morden", | ||||
| 	"engine": { | ||||
| 		"null": null | ||||
| 	}, | ||||
| 	"params": { | ||||
| 		"accountStartNonce": "0x0", | ||||
| 		"maximumExtraDataSize": "0x20", | ||||
| 		"minGasLimit": "0x1388", | ||||
| 		"networkID" : "0x2", | ||||
|                 "applyReward": true | ||||
| 	}, | ||||
| 	"genesis": { | ||||
| 		"seal": { | ||||
| 			"ethereum": { | ||||
| 				"nonce": "0x00006d6f7264656e", | ||||
| 				"mixHash": "0x00000000000000000000000000000000000000647572616c65787365646c6578" | ||||
| 			} | ||||
| 		}, | ||||
| 		"difficulty": "0x20000", | ||||
| 		"author": "0x0000000000000000000000000000000000000000", | ||||
| 		"timestamp": "0x00", | ||||
| 		"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", | ||||
| 		"extraData": "0x", | ||||
| 		"gasLimit": "0x2fefd8" | ||||
| 	}, | ||||
| 	"accounts": { | ||||
| 		"0000000000000000000000000000000000000001": { "balance": "1", "nonce": "1048576", "builtin": { "name": "ecrecover", "pricing": { "linear": { "base": 3000, "word": 0 } } } }, | ||||
| 		"0000000000000000000000000000000000000002": { "balance": "1", "nonce": "1048576", "builtin": { "name": "sha256", "pricing": { "linear": { "base": 60, "word": 12 } } } }, | ||||
| 		"0000000000000000000000000000000000000003": { "balance": "1", "nonce": "1048576", "builtin": { "name": "ripemd160", "pricing": { "linear": { "base": 600, "word": 120 } } } }, | ||||
| 		"0000000000000000000000000000000000000004": { "balance": "1", "nonce": "1048576", "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } }, | ||||
| 		"102e61f5d8f9bc71d0ad4a084df4e65e05ce0e1c": { "balance": "1606938044258990275541962092341162602522202993782792835301376", "nonce": "1048576" } | ||||
| 	} | ||||
| } | ||||
| @ -404,12 +404,12 @@ impl<'x> OpenBlock<'x> { | ||||
| 		let unclosed_state = s.block.state.clone(); | ||||
| 
 | ||||
| 		match s.engine.on_close_block(&mut s.block) { | ||||
| 			Ok(outcome) => { | ||||
| 				let t = outcome.trace; | ||||
| 				if t.is_some() { | ||||
| 					s.block.traces.as_mut().map(|traces| traces.push(t.unwrap())); | ||||
| 				} | ||||
| 			} | ||||
| 			Ok(outcome) => match outcome.trace { | ||||
| 				Some(t) => { | ||||
| 					s.block.traces.as_mut().map(|traces| traces.push(t)); | ||||
| 				}, | ||||
| 				None => {}, | ||||
| 			}, | ||||
| 			Err(e) => warn!("Encountered error on closing the block: {}", e), | ||||
| 		} | ||||
| 		
 | ||||
| @ -436,8 +436,14 @@ impl<'x> OpenBlock<'x> { | ||||
| 	pub fn close_and_lock(self) -> LockedBlock { | ||||
| 		let mut s = self; | ||||
| 
 | ||||
| 		if let Err(e) = s.engine.on_close_block(&mut s.block) { | ||||
| 			warn!("Encountered error on closing the block: {}", e); | ||||
| 		match s.engine.on_close_block(&mut s.block) { | ||||
| 			Ok(outcome) => match outcome.trace { | ||||
| 				Some(t) => { | ||||
| 					s.block.traces.as_mut().map(|traces| traces.push(t)); | ||||
| 				}, | ||||
| 				None => {}, | ||||
| 			}, | ||||
| 			Err(e) => warn!("Encountered error on closing the block: {}", e), | ||||
| 		} | ||||
| 
 | ||||
| 		if let Err(e) = s.block.state.commit() { | ||||
|  | ||||
| @ -17,10 +17,16 @@ | ||||
| use std::collections::BTreeMap; | ||||
| use util::Address; | ||||
| use builtin::Builtin; | ||||
| use engines::Engine; | ||||
| use block::*; | ||||
| use util::*; | ||||
| use engines::{Engine, CloseOutcome}; | ||||
| use spec::CommonParams; | ||||
| use evm::Schedule; | ||||
| use header::BlockNumber; | ||||
| use error::Error; | ||||
| use state::CleanupMode; | ||||
| use trace::{Tracer, ExecutiveTracer}; | ||||
| use types::trace_types::trace::{RewardType}; | ||||
| 
 | ||||
| /// An engine which does not provide any consensus mechanism and does not seal blocks.
 | ||||
| pub struct NullEngine { | ||||
| @ -64,4 +70,29 @@ impl Engine for NullEngine { | ||||
| 	fn snapshot_components(&self) -> Option<Box<::snapshot::SnapshotComponents>> { | ||||
| 		Some(Box::new(::snapshot::PowSnapshot(10000))) | ||||
| 	} | ||||
| 
 | ||||
| 	fn on_close_block(&self, block: &mut ExecutedBlock) -> Result<CloseOutcome, Error> { | ||||
| 		if !self.params.apply_reward { | ||||
| 			return Ok(CloseOutcome{trace: None}); | ||||
| 		} | ||||
| 
 | ||||
| 		let fields = block.fields_mut();		
 | ||||
| 		let mut tracer = ExecutiveTracer::default(); | ||||
| 
 | ||||
| 		let result_block_reward = U256::from(1000000000); | ||||
| 		fields.state.add_balance( | ||||
| 			fields.header.author(), | ||||
| 			&result_block_reward, | ||||
| 			CleanupMode::NoEmpty | ||||
| 		)?; | ||||
| 
 | ||||
| 		let block_miner = fields.header.author().clone(); | ||||
| 		tracer.trace_reward(block_miner, result_block_reward, RewardType::Block); | ||||
| 
 | ||||
| 		fields.state.commit()?; | ||||
| 		match *fields.tracing_enabled { | ||||
| 			true => Ok(CloseOutcome{trace: Some(tracer.traces())}), | ||||
| 			false => Ok(CloseOutcome{trace: None}) | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| @ -85,6 +85,8 @@ pub struct CommonParams { | ||||
| 	pub remove_dust_contracts: bool, | ||||
| 	/// Wasm support
 | ||||
| 	pub wasm: bool, | ||||
| 	/// Apply reward
 | ||||
| 	pub apply_reward: bool, | ||||
| } | ||||
| 
 | ||||
| impl CommonParams { | ||||
| @ -139,6 +141,7 @@ impl From<ethjson::spec::Params> for CommonParams { | ||||
| 			nonce_cap_increment: p.nonce_cap_increment.map_or(64, Into::into), | ||||
| 			remove_dust_contracts: p.remove_dust_contracts.unwrap_or(false), | ||||
| 			wasm: p.wasm.unwrap_or(false), | ||||
| 			apply_reward: p.apply_reward.unwrap_or(true), | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| @ -446,6 +449,9 @@ impl Spec { | ||||
| 	/// Create a new Spec which conforms to the Frontier-era Morden chain except that it's a NullEngine consensus.
 | ||||
| 	pub fn new_test() -> Spec { load_bundled!("null_morden") } | ||||
| 
 | ||||
| 	/// Create a new Spec which conforms to the Frontier-era Morden chain except that it's a NullEngine consensus with applying reward on block close.
 | ||||
| 	pub fn new_test_with_reward() -> Spec { load_bundled!("null_morden_with_reward") } | ||||
| 
 | ||||
| 	/// Create a new Spec which is a NullEngine consensus with a premine of address whose secret is sha3('').
 | ||||
| 	pub fn new_null() -> Spec { load_bundled!("null") } | ||||
| 
 | ||||
|  | ||||
| @ -17,6 +17,7 @@ | ||||
| pub mod helpers; | ||||
| mod client; | ||||
| mod evm; | ||||
| mod trace; | ||||
| 
 | ||||
| #[cfg(feature="ipc")] | ||||
| mod rpc; | ||||
|  | ||||
							
								
								
									
										93
									
								
								ethcore/src/tests/trace.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										93
									
								
								ethcore/src/tests/trace.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,93 @@ | ||||
| // Copyright 2015-2017 Parity Technologies (UK) Ltd.
 | ||||
| // This file is part of Parity.
 | ||||
| 
 | ||||
| // Parity is free software: you can redistribute it and/or modify
 | ||||
| // it under the terms of the GNU General Public License as published by
 | ||||
| // the Free Software Foundation, either version 3 of the License, or
 | ||||
| // (at your option) any later version.
 | ||||
| 
 | ||||
| // Parity is distributed in the hope that it will be useful,
 | ||||
| // but WITHOUT ANY WARRANTY; without even the implied warranty of
 | ||||
| // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | ||||
| // GNU General Public License for more details.
 | ||||
| 
 | ||||
| // You should have received a copy of the GNU General Public License
 | ||||
| // along with Parity.  If not, see <http://www.gnu.org/licenses/>.
 | ||||
| 
 | ||||
| //! Client tests of tracing
 | ||||
| 
 | ||||
| use ethkey::KeyPair; | ||||
| use block::*; | ||||
| use util::*; | ||||
| use io::*; | ||||
| use spec::*; | ||||
| use client::*; | ||||
| use tests::helpers::*; | ||||
| use devtools::RandomTempPath; | ||||
| use client::{BlockChainClient, Client, ClientConfig}; | ||||
| use util::kvdb::{Database, DatabaseConfig}; | ||||
| use std::sync::Arc; | ||||
| use header::Header; | ||||
| use miner::Miner; | ||||
| use transaction::{Action, Transaction}; | ||||
| 
 | ||||
| #[test] | ||||
| fn can_trace_block_and_uncle_reward() { | ||||
| 	let dir = RandomTempPath::new(); | ||||
|     let spec = Spec::new_test_with_reward(); | ||||
|     let engine = &*spec.engine; | ||||
|     let genesis_header = spec.genesis_header();    
 | ||||
|     let db = spec.ensure_db_good(get_temp_state_db(), &Default::default()).unwrap();	
 | ||||
|     let last_hashes = Arc::new(vec![genesis_header.hash()]); | ||||
|     let mut b = OpenBlock::new(engine, Default::default(), true, db, &genesis_header, last_hashes, Address::zero(), (3141562.into(), 31415620.into()), vec![], false).unwrap(); | ||||
| 
 | ||||
| 	let kp = KeyPair::from_secret_slice(&"".sha3()).unwrap(); | ||||
| 	let mut n = 0; | ||||
| 	for _ in 0..1 { | ||||
| 			b.push_transaction(Transaction { | ||||
| 				nonce: n.into(), | ||||
| 				gas_price: 0.into(), | ||||
| 				gas: 100000.into(), | ||||
| 				action: Action::Create, | ||||
| 				data: vec![], | ||||
| 				value: U256::zero(), | ||||
| 			}.sign(kp.secret(), Some(spec.network_id())), None).unwrap(); | ||||
| 			n += 1; | ||||
| 	} | ||||
| 
 | ||||
|     let mut uncle = Header::new(); | ||||
|     let uncle_author: Address = "ef2d6d194084c2de36e0dabfce45d046b37d1106".into(); | ||||
|     uncle.set_author(uncle_author); | ||||
|     //b.push_uncle(uncle).unwrap();
 | ||||
|     let b = b.close_and_lock().seal(engine, vec![]).unwrap(); | ||||
| 
 | ||||
|     let db_config = DatabaseConfig::with_columns(::db::NUM_COLUMNS); | ||||
| 	let mut client_config = ClientConfig::default(); | ||||
| 	client_config.tracing.enabled = true; | ||||
|     let client_db = Arc::new(Database::open(&db_config, dir.as_path().to_str().unwrap()).unwrap()); | ||||
|     let client = Client::new( | ||||
| 		client_config, | ||||
| 		&spec, | ||||
| 		client_db, | ||||
| 		Arc::new(Miner::with_spec(&spec)), | ||||
| 		IoChannel::disconnected(), | ||||
| 	).unwrap(); | ||||
| 	
 | ||||
| 	let res = client.import_block(b.rlp_bytes()); | ||||
|     if res.is_err() { | ||||
| 		panic!("error importing block: {:#?}", res.err().unwrap());        
 | ||||
| 	} | ||||
|     
 | ||||
| 	client.flush_queue(); | ||||
| 	client.import_verified_blocks(); | ||||
| 
 | ||||
|     let filter = TraceFilter { | ||||
| 			range: (BlockId::Number(1)..BlockId::Number(1)), | ||||
| 			from_address: vec![], | ||||
| 			to_address: vec![], | ||||
| 		}; | ||||
| 
 | ||||
|     let traces = client.filter_traces(filter);    
 | ||||
|     assert!(traces.is_some(), "Genesis trace should be always present."); | ||||
|     //panic!("Traces size is: {:#?}", traces.unwrap().len());    
 | ||||
| } | ||||
| @ -215,8 +215,7 @@ impl<T> TraceDB<T> where T: DatabaseExtras { | ||||
| 		block_number: BlockNumber, | ||||
| 		tx_number: usize | ||||
| 	) -> Vec<LocalizedTrace> { | ||||
| 		let tx_hash = self.extras.transaction_hash(block_number, tx_number) | ||||
| 			.expect("Expected to find transaction hash. Database is probably corrupted"); | ||||
| 		let tx_hash = self.extras.transaction_hash(block_number, tx_number); | ||||
| 
 | ||||
| 		let flat_traces: Vec<FlatTrace> = traces.into(); | ||||
| 		flat_traces.into_iter() | ||||
| @ -228,7 +227,11 @@ impl<T> TraceDB<T> where T: DatabaseExtras { | ||||
| 						subtraces: trace.subtraces, | ||||
| 						trace_address: trace.trace_address.into_iter().collect(), | ||||
| 						transaction_number: tx_number, | ||||
| 						transaction_hash: tx_hash.clone(), | ||||
| 						transaction_hash: match tx_hash { | ||||
| 							Some(hash) => hash.clone(), | ||||
| 							/// None tx hash means non transaction's trace
 | ||||
| 							None => 0.into(), | ||||
| 						}, | ||||
| 						block_number: block_number, | ||||
| 						block_hash: block_hash | ||||
| 					}), | ||||
|  | ||||
| @ -591,6 +591,7 @@ mod tests { | ||||
| 		let mut params = CommonParams::default(); | ||||
| 		params.dust_protection_transition = 0; | ||||
| 		params.nonce_cap_increment = 2; | ||||
| 		params.apply_reward = false; | ||||
| 
 | ||||
| 		let mut header = Header::default(); | ||||
| 		header.set_number(1); | ||||
|  | ||||
| @ -91,6 +91,9 @@ pub struct Params { | ||||
| 	pub remove_dust_contracts : Option<bool>, | ||||
| 	/// Wasm support flag
 | ||||
| 	pub wasm: Option<bool>, | ||||
| 	/// Apply reward flag
 | ||||
| 	#[serde(rename="applyReward")] | ||||
| 	pub apply_reward: Option<bool>, | ||||
| } | ||||
| 
 | ||||
| #[cfg(test)] | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user