diff --git a/ethcore/src/tests/trace.rs b/ethcore/src/tests/trace.rs index 2389a3c2e..c345d9502 100644 --- a/ethcore/src/tests/trace.rs +++ b/ethcore/src/tests/trace.rs @@ -40,7 +40,7 @@ fn can_trace_block_and_uncle_reward() { let spec = Spec::new_test_with_reward(); let engine = &*spec.engine; - /// Create client + // Create client let db_config = DatabaseConfig::with_columns(::db::NUM_COLUMNS); let mut client_config = ClientConfig::default(); client_config.tracing.enabled = true; @@ -53,7 +53,15 @@ fn can_trace_block_and_uncle_reward() { IoChannel::disconnected(), ).unwrap(); - /// Create test data + // Create test data: + // genesis + // | + // root_block + // | + // parent_block + // | + // block with transaction and uncle + let genesis_header = spec.genesis_header(); let mut db = spec.ensure_db_good(get_temp_state_db(), &Default::default()).unwrap(); let mut rolling_timestamp = 40; @@ -64,7 +72,7 @@ fn can_trace_block_and_uncle_reward() { let kp = KeyPair::from_secret_slice(&"".sha3()).unwrap(); let author = kp.address(); - /// Add root block first + // Add root block first let mut root_block = OpenBlock::new( engine, Default::default(), @@ -93,7 +101,7 @@ fn can_trace_block_and_uncle_reward() { last_hashes.push(last_header.hash()); - /// Add parent block + // Add parent block let mut parent_block = OpenBlock::new( engine, Default::default(), @@ -121,7 +129,7 @@ fn can_trace_block_and_uncle_reward() { last_hashes.push(last_header.hash()); - /// Add testing block with transactions and uncles + // Add testing block with transaction and uncle let mut block = OpenBlock::new( engine, Default::default(), @@ -172,7 +180,7 @@ fn can_trace_block_and_uncle_reward() { client.flush_queue(); client.import_verified_blocks(); - /// Filter the resuliting data + // Test0. Check overall filter let filter = TraceFilter { range: (BlockId::Number(1)..BlockId::Number(3)), from_address: vec![], @@ -180,7 +188,7 @@ fn can_trace_block_and_uncle_reward() { }; let traces = client.filter_traces(filter); - assert!(traces.is_some(), "Traces should be present"); + assert!(traces.is_some(), "Filtered traces should be present"); let traces_vec = traces.unwrap(); let block_reward_traces: Vec = traces_vec.clone().into_iter().filter(|trace| match (trace).action { Reward(ref a) => a.reward_type == RewardType::Block, @@ -192,4 +200,8 @@ fn can_trace_block_and_uncle_reward() { _ => false, }).collect(); assert_eq!(uncle_reward_traces.len(), 1); + + // Test1. Check block filter + let traces = client.block_traces(BlockId::Number(3)); + assert_eq!(traces.unwrap().len(), 3); } \ No newline at end of file diff --git a/ethcore/src/trace/db.rs b/ethcore/src/trace/db.rs index afb0fef49..504648d38 100644 --- a/ethcore/src/trace/db.rs +++ b/ethcore/src/trace/db.rs @@ -215,7 +215,20 @@ impl TraceDB where T: DatabaseExtras { block_number: BlockNumber, tx_number: usize ) -> Vec { - let tx_hash = self.extras.transaction_hash(block_number, tx_number); + let trace_tx_number; + let trace_tx_hash; + + match self.extras.transaction_hash(block_number, tx_number) { + Some(hash) => { + trace_tx_hash = Some(hash.clone()); + trace_tx_number = Some(tx_number); + }, + None => { + //None means trace without transaction (reward) + trace_tx_hash = None; + trace_tx_number = None; + } + } let flat_traces: Vec = traces.into(); flat_traces.into_iter() @@ -226,12 +239,8 @@ impl TraceDB where T: DatabaseExtras { result: trace.result, subtraces: trace.subtraces, trace_address: trace.trace_address.into_iter().collect(), - transaction_number: tx_number, - transaction_hash: match tx_hash { - Some(hash) => hash.clone(), - /// None tx hash means non transaction's trace - None => 0.into(), - }, + transaction_number: trace_tx_number, + transaction_hash: trace_tx_hash, block_number: block_number, block_hash: block_hash }), @@ -324,8 +333,8 @@ impl TraceDatabase for TraceDB where T: DatabaseExtras { result: trace.result, subtraces: trace.subtraces, trace_address: trace.trace_address.into_iter().collect(), - transaction_number: tx_position, - transaction_hash: tx_hash, + transaction_number: Some(tx_position), + transaction_hash: Some(tx_hash), block_number: block_number, block_hash: block_hash, } @@ -348,8 +357,8 @@ impl TraceDatabase for TraceDB where T: DatabaseExtras { result: trace.result, subtraces: trace.subtraces, trace_address: trace.trace_address.into_iter().collect(), - transaction_number: tx_position, - transaction_hash: tx_hash.clone(), + transaction_number: Some(tx_position), + transaction_hash: Some(tx_hash.clone()), block_number: block_number, block_hash: block_hash }) @@ -366,8 +375,20 @@ impl TraceDatabase for TraceDB where T: DatabaseExtras { .map(Into::>::into) .enumerate() .flat_map(|(tx_position, traces)| { - let tx_hash = self.extras.transaction_hash(block_number, tx_position) - .expect("Expected to find transaction hash. Database is probably corrupted"); + let trace_tx_number; + let trace_tx_hash; + + match self.extras.transaction_hash(block_number, tx_position) { + Some(hash) => { + trace_tx_hash = Some(hash.clone()); + trace_tx_number = Some(tx_position); + }, + None => { + //None means trace without transaction (reward) + trace_tx_hash = None; + trace_tx_number = None; + } + } traces.into_iter() .map(|trace| LocalizedTrace { @@ -375,8 +396,8 @@ impl TraceDatabase for TraceDB where T: DatabaseExtras { result: trace.result, subtraces: trace.subtraces, trace_address: trace.trace_address.into_iter().collect(), - transaction_number: tx_position, - transaction_hash: tx_hash.clone(), + transaction_number: trace_tx_number, + transaction_hash: trace_tx_hash, block_number: block_number, block_hash: block_hash, }) @@ -546,8 +567,8 @@ mod tests { result: Res::FailedCall(TraceError::OutOfGas), trace_address: vec![], subtraces: 0, - transaction_number: 0, - transaction_hash: tx_hash, + transaction_number: Some(0), + transaction_hash: Some(tx_hash), block_number: block_number, block_hash: block_hash, } diff --git a/ethcore/src/trace/types/localized.rs b/ethcore/src/trace/types/localized.rs index 39a4b08cc..2d4850a8a 100644 --- a/ethcore/src/trace/types/localized.rs +++ b/ethcore/src/trace/types/localized.rs @@ -34,9 +34,9 @@ pub struct LocalizedTrace { /// [index in root, index in first CALL, index in second CALL, ...] pub trace_address: Vec, /// Transaction number within the block. - pub transaction_number: usize, + pub transaction_number: Option, /// Signed transaction hash. - pub transaction_hash: H256, + pub transaction_hash: Option, /// Block number. pub block_number: BlockNumber, /// Block hash. diff --git a/rpc/src/v1/tests/mocked/traces.rs b/rpc/src/v1/tests/mocked/traces.rs index b1b297eb1..c87595ad1 100644 --- a/rpc/src/v1/tests/mocked/traces.rs +++ b/rpc/src/v1/tests/mocked/traces.rs @@ -47,8 +47,8 @@ fn io() -> Tester { result: Res::None, subtraces: 0, trace_address: vec![0], - transaction_number: 0, - transaction_hash: 5.into(), + transaction_number: Some(0), + transaction_hash: Some(5.into()), block_number: 10, block_hash: 10.into(), }]); diff --git a/rpc/src/v1/types/trace.rs b/rpc/src/v1/types/trace.rs index d64a0347a..5c656f4ec 100644 --- a/rpc/src/v1/types/trace.rs +++ b/rpc/src/v1/types/trace.rs @@ -472,9 +472,9 @@ pub struct LocalizedTrace { /// Subtraces subtraces: usize, /// Transaction position - transaction_position: usize, + transaction_position: Option, /// Transaction hash - transaction_hash: H256, + transaction_hash: Option, /// Block Number block_number: u64, /// Block Hash @@ -531,8 +531,8 @@ impl From for LocalizedTrace { result: t.result.into(), trace_address: t.trace_address.into_iter().map(Into::into).collect(), subtraces: t.subtraces.into(), - transaction_position: t.transaction_number.into(), - transaction_hash: t.transaction_hash.into(), + transaction_position: t.transaction_number.map(Into::into), + transaction_hash: t.transaction_hash.map(Into::into), block_number: t.block_number.into(), block_hash: t.block_hash.into(), } @@ -665,8 +665,8 @@ mod tests { }), trace_address: vec![10], subtraces: 1, - transaction_position: 11, - transaction_hash: 12.into(), + transaction_position: Some(11), + transaction_hash: Some(12.into()), block_number: 13, block_hash: 14.into(), }; @@ -688,8 +688,8 @@ mod tests { result: Res::FailedCall(TraceError::OutOfGas), trace_address: vec![10], subtraces: 1, - transaction_position: 11, - transaction_hash: 12.into(), + transaction_position: Some(11), + transaction_hash: Some(12.into()), block_number: 13, block_hash: 14.into(), }; @@ -713,8 +713,8 @@ mod tests { }), trace_address: vec![10], subtraces: 1, - transaction_position: 11, - transaction_hash: 12.into(), + transaction_position: Some(11), + transaction_hash: Some(12.into()), block_number: 13, block_hash: 14.into(), }; @@ -734,8 +734,8 @@ mod tests { result: Res::FailedCreate(TraceError::OutOfGas), trace_address: vec![10], subtraces: 1, - transaction_position: 11, - transaction_hash: 12.into(), + transaction_position: Some(11), + transaction_hash: Some(12.into()), block_number: 13, block_hash: 14.into(), }; @@ -754,8 +754,8 @@ mod tests { result: Res::None, trace_address: vec![10], subtraces: 1, - transaction_position: 11, - transaction_hash: 12.into(), + transaction_position: Some(11), + transaction_hash: Some(12.into()), block_number: 13, block_hash: 14.into(), }; @@ -774,13 +774,13 @@ mod tests { result: Res::None, trace_address: vec![10], subtraces: 1, - transaction_position: 11, - transaction_hash: 12.into(), + transaction_position: None, + transaction_hash: None, block_number: 13, block_hash: 14.into(), }; let serialized = serde_json::to_string(&t).unwrap(); - assert_eq!(serialized, r#"{"type":"reward","action":{"miner":"0x0000000000000000000000000000000000000004","value":"0x6","rewardType":"block"},"result":null,"traceAddress":[10],"subtraces":1,"transactionPosition":11,"transactionHash":"0x000000000000000000000000000000000000000000000000000000000000000c","blockNumber":13,"blockHash":"0x000000000000000000000000000000000000000000000000000000000000000e"}"#); + assert_eq!(serialized, r#"{"type":"reward","action":{"miner":"0x0000000000000000000000000000000000000004","value":"0x6","rewardType":"block"},"result":null,"traceAddress":[10],"subtraces":1,"transactionPosition":null,"transactionHash":null,"blockNumber":13,"blockHash":"0x000000000000000000000000000000000000000000000000000000000000000e"}"#); } #[test]