Correct log index in transaction receipt (#3995)
* Moving logs to separate, testable function * Adding test * Fixing log index * Adding transaction log index * Fixing rpc tests * Making interface of a bit cleaner.
This commit is contained in:
		
							parent
							
								
									9814251a28
								
							
						
					
					
						commit
						b24fc97cb6
					
				| @ -378,7 +378,8 @@ impl BlockProvider for BlockChain { | ||||
| 					.enumerate() | ||||
| 					.flat_map(move |(index, (mut logs, tx_hash))| { | ||||
| 						let current_log_index = log_index; | ||||
| 						log_index -= logs.len(); | ||||
| 						let no_of_logs = logs.len(); | ||||
| 						log_index -= no_of_logs; | ||||
| 
 | ||||
| 						logs.reverse(); | ||||
| 						logs.into_iter() | ||||
| @ -390,6 +391,7 @@ impl BlockProvider for BlockChain { | ||||
| 								transaction_hash: tx_hash, | ||||
| 								// iterating in reverse order
 | ||||
| 								transaction_index: receipts_len - index - 1, | ||||
| 								transaction_log_index: no_of_logs - i - 1, | ||||
| 								log_index: current_log_index - i - 1, | ||||
| 							}) | ||||
| 					}) | ||||
| @ -1936,6 +1938,7 @@ mod tests { | ||||
| 				block_number: block1.header().number(), | ||||
| 				transaction_hash: tx_hash1.clone(), | ||||
| 				transaction_index: 0, | ||||
| 				transaction_log_index: 0, | ||||
| 				log_index: 0, | ||||
| 			}, | ||||
| 			LocalizedLogEntry { | ||||
| @ -1944,6 +1947,7 @@ mod tests { | ||||
| 				block_number: block1.header().number(), | ||||
| 				transaction_hash: tx_hash1.clone(), | ||||
| 				transaction_index: 0, | ||||
| 				transaction_log_index: 1, | ||||
| 				log_index: 1, | ||||
| 			}, | ||||
| 			LocalizedLogEntry { | ||||
| @ -1952,6 +1956,7 @@ mod tests { | ||||
| 				block_number: block1.header().number(), | ||||
| 				transaction_hash: tx_hash2.clone(), | ||||
| 				transaction_index: 1, | ||||
| 				transaction_log_index: 0, | ||||
| 				log_index: 2, | ||||
| 			}, | ||||
| 			LocalizedLogEntry { | ||||
| @ -1960,6 +1965,7 @@ mod tests { | ||||
| 				block_number: block2.header().number(), | ||||
| 				transaction_hash: tx_hash3.clone(), | ||||
| 				transaction_index: 0, | ||||
| 				transaction_log_index: 0, | ||||
| 				log_index: 0, | ||||
| 			} | ||||
| 		]); | ||||
| @ -1970,6 +1976,7 @@ mod tests { | ||||
| 				block_number: block2.header().number(), | ||||
| 				transaction_hash: tx_hash3.clone(), | ||||
| 				transaction_index: 0, | ||||
| 				transaction_log_index: 0, | ||||
| 				log_index: 0, | ||||
| 			} | ||||
| 		]); | ||||
|  | ||||
| @ -59,7 +59,7 @@ use client::{ | ||||
| use client::Error as ClientError; | ||||
| use env_info::EnvInfo; | ||||
| use executive::{Executive, Executed, TransactOptions, contract_address}; | ||||
| use receipt::LocalizedReceipt; | ||||
| use receipt::{Receipt, LocalizedReceipt}; | ||||
| use trace::{TraceDB, ImportRequest as TraceImportRequest, LocalizedTrace, Database as TraceDatabase}; | ||||
| use trace; | ||||
| use trace::FlatTransactionTraces; | ||||
| @ -837,7 +837,6 @@ impl snapshot::DatabaseRestore for Client { | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| impl BlockChainClient for Client { | ||||
| 	fn call(&self, t: &SignedTransaction, block: BlockId, analytics: CallAnalytics) -> Result<Executed, CallError> { | ||||
| 		let header = self.block_header(block).ok_or(CallError::StatePruned)?; | ||||
| @ -1134,53 +1133,23 @@ impl BlockChainClient for Client { | ||||
| 		let chain = self.chain.read(); | ||||
| 		self.transaction_address(id) | ||||
| 			.and_then(|address| chain.block_number(&address.block_hash).and_then(|block_number| { | ||||
| 			let t = chain.block_body(&address.block_hash) | ||||
| 				.and_then(|body| { | ||||
| 					body.view().localized_transaction_at(&address.block_hash, block_number, address.index) | ||||
| 				}); | ||||
| 				let transaction = chain.block_body(&address.block_hash) | ||||
| 					.and_then(|body| body.view().localized_transaction_at(&address.block_hash, block_number, address.index)); | ||||
| 
 | ||||
| 			let tx_and_sender = t.and_then(|tx| tx.sender().ok().map(|sender| (tx, sender))); | ||||
| 
 | ||||
| 			match (tx_and_sender, chain.transaction_receipt(&address)) { | ||||
| 				(Some((tx, sender)), Some(receipt)) => { | ||||
| 					let block_hash = tx.block_hash.clone(); | ||||
| 					let block_number = tx.block_number.clone(); | ||||
| 					let transaction_hash = tx.hash(); | ||||
| 					let transaction_index = tx.transaction_index; | ||||
| 					let prior_gas_used = match tx.transaction_index { | ||||
| 						0 => U256::zero(), | ||||
| 						i => { | ||||
| 							let prior_address = TransactionAddress { block_hash: address.block_hash, index: i - 1 }; | ||||
| 							let prior_receipt = chain.transaction_receipt(&prior_address).expect("Transaction receipt at `address` exists; `prior_address` has lower index in same block; qed"); | ||||
| 							prior_receipt.gas_used | ||||
| 						} | ||||
| 					}; | ||||
| 					Some(LocalizedReceipt { | ||||
| 						transaction_hash: tx.hash(), | ||||
| 						transaction_index: tx.transaction_index, | ||||
| 						block_hash: tx.block_hash, | ||||
| 						block_number: tx.block_number, | ||||
| 						cumulative_gas_used: receipt.gas_used, | ||||
| 						gas_used: receipt.gas_used - prior_gas_used, | ||||
| 						contract_address: match tx.action { | ||||
| 							Action::Call(_) => None, | ||||
| 							Action::Create => Some(contract_address(&sender, &tx.nonce)) | ||||
| 						}, | ||||
| 						logs: receipt.logs.into_iter().enumerate().map(|(i, log)| LocalizedLogEntry { | ||||
| 							entry: log, | ||||
| 							block_hash: block_hash.clone(), | ||||
| 							block_number: block_number, | ||||
| 							transaction_hash: transaction_hash.clone(), | ||||
| 							transaction_index: transaction_index, | ||||
| 							log_index: i | ||||
| 						}).collect(), | ||||
| 						log_bloom: receipt.log_bloom, | ||||
| 						state_root: receipt.state_root, | ||||
| 				let previous_receipts = (0..address.index + 1) | ||||
| 					.map(|index| { | ||||
| 						let mut address = address.clone(); | ||||
| 						address.index = index; | ||||
| 						chain.transaction_receipt(&address) | ||||
| 					}) | ||||
| 				}, | ||||
| 				_ => None | ||||
| 			} | ||||
| 		})) | ||||
| 					.collect(); | ||||
| 				match (transaction, previous_receipts) { | ||||
| 					(Some(transaction), Some(previous_receipts)) => { | ||||
| 						Some(transaction_receipt(transaction, previous_receipts)) | ||||
| 					}, | ||||
| 					_ => None, | ||||
| 				} | ||||
| 			})) | ||||
| 	} | ||||
| 
 | ||||
| 	fn tree_route(&self, from: &H256, to: &H256) -> Option<TreeRoute> { | ||||
| @ -1535,6 +1504,49 @@ impl Drop for Client { | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| /// Returns `LocalizedReceipt` given `LocalizedTransaction`
 | ||||
| /// and a vector of receipts from given block up to transaction index.
 | ||||
| fn transaction_receipt(tx: LocalizedTransaction, mut receipts: Vec<Receipt>) -> LocalizedReceipt { | ||||
| 	assert_eq!(receipts.len(), tx.transaction_index + 1, "All previous receipts are provided."); | ||||
| 
 | ||||
| 	let sender = tx.sender() | ||||
| 		.expect("LocalizedTransaction is part of the blockchain; We have only valid transactions in chain; qed"); | ||||
| 	let receipt = receipts.pop().expect("Current receipt is provided; qed"); | ||||
| 	let prior_gas_used = match tx.transaction_index { | ||||
| 		0 => 0.into(), | ||||
| 		i => receipts.get(i - 1).expect("All previous receipts are provided; qed").gas_used, | ||||
| 	}; | ||||
| 	let no_of_logs = receipts.into_iter().map(|receipt| receipt.logs.len()).sum::<usize>(); | ||||
| 	let transaction_hash = tx.hash(); | ||||
| 	let block_hash = tx.block_hash; | ||||
| 	let block_number = tx.block_number; | ||||
| 	let transaction_index = tx.transaction_index; | ||||
| 
 | ||||
| 	LocalizedReceipt { | ||||
| 		transaction_hash: transaction_hash, | ||||
| 		transaction_index: transaction_index, | ||||
| 		block_hash: block_hash, | ||||
| 		block_number:block_number, | ||||
| 		cumulative_gas_used: receipt.gas_used, | ||||
| 		gas_used: receipt.gas_used - prior_gas_used, | ||||
| 		contract_address: match tx.action { | ||||
| 			Action::Call(_) => None, | ||||
| 			Action::Create => Some(contract_address(&sender, &tx.nonce)) | ||||
| 		}, | ||||
| 		logs: receipt.logs.into_iter().enumerate().map(|(i, log)| LocalizedLogEntry { | ||||
| 			entry: log, | ||||
| 			block_hash: block_hash, | ||||
| 			block_number: block_number, | ||||
| 			transaction_hash: transaction_hash, | ||||
| 			transaction_index: transaction_index, | ||||
| 			transaction_log_index: i, | ||||
| 			log_index: no_of_logs + i, | ||||
| 		}).collect(), | ||||
| 		log_bloom: receipt.log_bloom, | ||||
| 		state_root: receipt.state_root, | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| #[cfg(test)] | ||||
| mod tests { | ||||
| 
 | ||||
| @ -1570,4 +1582,91 @@ mod tests { | ||||
| 
 | ||||
| 		assert!(client.tree_route(&genesis, &new_hash).is_none()); | ||||
| 	} | ||||
| 
 | ||||
| 	#[test] | ||||
| 	fn should_return_correct_log_index() { | ||||
| 		use super::transaction_receipt; | ||||
| 		use ethkey::KeyPair; | ||||
| 		use log_entry::{LogEntry, LocalizedLogEntry}; | ||||
| 		use receipt::{Receipt, LocalizedReceipt}; | ||||
| 		use transaction::{Transaction, LocalizedTransaction, Action}; | ||||
| 		use util::Hashable; | ||||
| 
 | ||||
| 		// given
 | ||||
| 		let key = KeyPair::from_secret("test".sha3()).unwrap(); | ||||
| 		let secret = key.secret(); | ||||
| 
 | ||||
| 		let block_number = 1; | ||||
| 		let block_hash = 5.into(); | ||||
| 		let state_root = 99.into(); | ||||
| 		let gas_used = 10.into(); | ||||
| 		let raw_tx = Transaction { | ||||
| 			nonce: 0.into(), | ||||
| 			gas_price: 0.into(), | ||||
| 			gas: 21000.into(), | ||||
| 			action: Action::Call(10.into()), | ||||
| 			value: 0.into(), | ||||
| 			data: vec![], | ||||
| 		}; | ||||
| 		let tx1 = raw_tx.clone().sign(secret, None); | ||||
| 		let transaction = LocalizedTransaction { | ||||
| 			signed: tx1.clone(), | ||||
| 			block_number: block_number, | ||||
| 			block_hash: block_hash, | ||||
| 			transaction_index: 1, | ||||
| 		}; | ||||
| 		let logs = vec![LogEntry { | ||||
| 			address: 5.into(), | ||||
| 			topics: vec![], | ||||
| 			data: vec![], | ||||
| 		}, LogEntry { | ||||
| 			address: 15.into(), | ||||
| 			topics: vec![], | ||||
| 			data: vec![], | ||||
| 		}]; | ||||
| 		let receipts = vec![Receipt { | ||||
| 			state_root: state_root, | ||||
| 			gas_used: 5.into(), | ||||
| 			log_bloom: Default::default(), | ||||
| 			logs: vec![logs[0].clone()], | ||||
| 		}, Receipt { | ||||
| 			state_root: state_root, | ||||
| 			gas_used: gas_used, | ||||
| 			log_bloom: Default::default(), | ||||
| 			logs: logs.clone(), | ||||
| 		}]; | ||||
| 
 | ||||
| 		// when
 | ||||
| 		let receipt = transaction_receipt(transaction, receipts); | ||||
| 
 | ||||
| 		// then
 | ||||
| 		assert_eq!(receipt, LocalizedReceipt { | ||||
| 			transaction_hash: tx1.hash(), | ||||
| 			transaction_index: 1, | ||||
| 			block_hash: block_hash, | ||||
| 			block_number: block_number, | ||||
| 			cumulative_gas_used: gas_used, | ||||
| 			gas_used: gas_used - 5.into(), | ||||
| 			contract_address: None, | ||||
| 			logs: vec![LocalizedLogEntry { | ||||
| 				entry: logs[0].clone(), | ||||
| 				block_hash: block_hash, | ||||
| 				block_number: block_number, | ||||
| 				transaction_hash: tx1.hash(), | ||||
| 				transaction_index: 1, | ||||
| 				transaction_log_index: 0, | ||||
| 				log_index: 1, | ||||
| 			}, LocalizedLogEntry { | ||||
| 				entry: logs[1].clone(), | ||||
| 				block_hash: block_hash, | ||||
| 				block_number: block_number, | ||||
| 				transaction_hash: tx1.hash(), | ||||
| 				transaction_index: 1, | ||||
| 				transaction_log_index: 1, | ||||
| 				log_index: 2, | ||||
| 			}], | ||||
| 			log_bloom: Default::default(), | ||||
| 			state_root: state_root, | ||||
| 		}); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| @ -320,4 +320,3 @@ fn does_not_propagate_delayed_transactions() { | ||||
| 	assert_eq!(2, client.ready_transactions().len()); | ||||
| 	assert_eq!(2, client.miner().pending_transactions().len()); | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -97,6 +97,8 @@ pub struct LocalizedLogEntry { | ||||
| 	pub transaction_index: usize, | ||||
| 	/// Log position in the block.
 | ||||
| 	pub log_index: usize, | ||||
| 	/// Log position in the transaction.
 | ||||
| 	pub transaction_log_index: usize, | ||||
| } | ||||
| 
 | ||||
| impl Deref for LocalizedLogEntry { | ||||
|  | ||||
| @ -373,7 +373,7 @@ impl SignedTransaction { | ||||
| } | ||||
| 
 | ||||
| /// Signed Transaction that is a part of canon blockchain.
 | ||||
| #[derive(Debug, PartialEq, Eq)] | ||||
| #[derive(Debug, Clone, PartialEq, Eq)] | ||||
| #[cfg_attr(feature = "ipc", binary)] | ||||
| pub struct LocalizedTransaction { | ||||
| 	/// Signed part.
 | ||||
|  | ||||
| @ -193,6 +193,7 @@ fn rpc_eth_logs() { | ||||
| 			data: vec![1,2,3], | ||||
| 		}, | ||||
| 		transaction_index: 0, | ||||
| 		transaction_log_index: 0, | ||||
| 		transaction_hash: H256::default(), | ||||
| 		log_index: 0, | ||||
| 	}, LocalizedLogEntry { | ||||
| @ -204,8 +205,9 @@ fn rpc_eth_logs() { | ||||
| 			data: vec![1,2,3], | ||||
| 		}, | ||||
| 		transaction_index: 0, | ||||
| 		transaction_log_index: 1, | ||||
| 		transaction_hash: H256::default(), | ||||
| 		log_index: 0, | ||||
| 		log_index: 1, | ||||
| 	}]); | ||||
| 
 | ||||
| 
 | ||||
| @ -213,8 +215,8 @@ fn rpc_eth_logs() { | ||||
| 	let request2 = r#"{"jsonrpc": "2.0", "method": "eth_getLogs", "params": [{"limit":1}], "id": 1}"#; | ||||
| 	let request3 = r#"{"jsonrpc": "2.0", "method": "eth_getLogs", "params": [{"limit":0}], "id": 1}"#; | ||||
| 
 | ||||
| 	let response1 = r#"{"jsonrpc":"2.0","result":[{"address":"0x0000000000000000000000000000000000000000","blockHash":"0x0000000000000000000000000000000000000000000000000000000000000000","blockNumber":"0x1","data":"0x010203","logIndex":"0x0","topics":[],"transactionHash":"0x0000000000000000000000000000000000000000000000000000000000000000","transactionIndex":"0x0","type":"mined"},{"address":"0x0000000000000000000000000000000000000000","blockHash":"0x0000000000000000000000000000000000000000000000000000000000000000","blockNumber":"0x1","data":"0x010203","logIndex":"0x0","topics":[],"transactionHash":"0x0000000000000000000000000000000000000000000000000000000000000000","transactionIndex":"0x0","type":"mined"}],"id":1}"#; | ||||
| 	let response2 = r#"{"jsonrpc":"2.0","result":[{"address":"0x0000000000000000000000000000000000000000","blockHash":"0x0000000000000000000000000000000000000000000000000000000000000000","blockNumber":"0x1","data":"0x010203","logIndex":"0x0","topics":[],"transactionHash":"0x0000000000000000000000000000000000000000000000000000000000000000","transactionIndex":"0x0","type":"mined"}],"id":1}"#; | ||||
| 	let response1 = r#"{"jsonrpc":"2.0","result":[{"address":"0x0000000000000000000000000000000000000000","blockHash":"0x0000000000000000000000000000000000000000000000000000000000000000","blockNumber":"0x1","data":"0x010203","logIndex":"0x0","topics":[],"transactionHash":"0x0000000000000000000000000000000000000000000000000000000000000000","transactionIndex":"0x0","transactionLogIndex":"0x0","type":"mined"},{"address":"0x0000000000000000000000000000000000000000","blockHash":"0x0000000000000000000000000000000000000000000000000000000000000000","blockNumber":"0x1","data":"0x010203","logIndex":"0x1","topics":[],"transactionHash":"0x0000000000000000000000000000000000000000000000000000000000000000","transactionIndex":"0x0","transactionLogIndex":"0x1","type":"mined"}],"id":1}"#; | ||||
| 	let response2 = r#"{"jsonrpc":"2.0","result":[{"address":"0x0000000000000000000000000000000000000000","blockHash":"0x0000000000000000000000000000000000000000000000000000000000000000","blockNumber":"0x1","data":"0x010203","logIndex":"0x1","topics":[],"transactionHash":"0x0000000000000000000000000000000000000000000000000000000000000000","transactionIndex":"0x0","transactionLogIndex":"0x1","type":"mined"}],"id":1}"#; | ||||
| 	let response3 = r#"{"jsonrpc":"2.0","result":[],"id":1}"#; | ||||
| 
 | ||||
| 	assert_eq!(tester.io.handle_request_sync(request1), Some(response1.to_owned())); | ||||
| @ -235,6 +237,7 @@ fn rpc_logs_filter() { | ||||
| 			data: vec![1,2,3], | ||||
| 		}, | ||||
| 		transaction_index: 0, | ||||
| 		transaction_log_index: 0, | ||||
| 		transaction_hash: H256::default(), | ||||
| 		log_index: 0, | ||||
| 	}, LocalizedLogEntry { | ||||
| @ -246,8 +249,9 @@ fn rpc_logs_filter() { | ||||
| 			data: vec![1,2,3], | ||||
| 		}, | ||||
| 		transaction_index: 0, | ||||
| 		transaction_log_index: 1, | ||||
| 		transaction_hash: H256::default(), | ||||
| 		log_index: 0, | ||||
| 		log_index: 1, | ||||
| 	}]); | ||||
| 
 | ||||
| 	// Register filters first
 | ||||
| @ -261,8 +265,8 @@ fn rpc_logs_filter() { | ||||
| 
 | ||||
| 	let request_changes1 = r#"{"jsonrpc": "2.0", "method": "eth_getFilterChanges", "params": ["0x0"], "id": 1}"#; | ||||
| 	let request_changes2 = r#"{"jsonrpc": "2.0", "method": "eth_getFilterChanges", "params": ["0x1"], "id": 1}"#; | ||||
| 	let response1 = r#"{"jsonrpc":"2.0","result":[{"address":"0x0000000000000000000000000000000000000000","blockHash":"0x0000000000000000000000000000000000000000000000000000000000000000","blockNumber":"0x1","data":"0x010203","logIndex":"0x0","topics":[],"transactionHash":"0x0000000000000000000000000000000000000000000000000000000000000000","transactionIndex":"0x0","type":"mined"},{"address":"0x0000000000000000000000000000000000000000","blockHash":"0x0000000000000000000000000000000000000000000000000000000000000000","blockNumber":"0x1","data":"0x010203","logIndex":"0x0","topics":[],"transactionHash":"0x0000000000000000000000000000000000000000000000000000000000000000","transactionIndex":"0x0","type":"mined"}],"id":1}"#; | ||||
| 	let response2 = r#"{"jsonrpc":"2.0","result":[{"address":"0x0000000000000000000000000000000000000000","blockHash":"0x0000000000000000000000000000000000000000000000000000000000000000","blockNumber":"0x1","data":"0x010203","logIndex":"0x0","topics":[],"transactionHash":"0x0000000000000000000000000000000000000000000000000000000000000000","transactionIndex":"0x0","type":"mined"}],"id":1}"#; | ||||
| 	let response1 = r#"{"jsonrpc":"2.0","result":[{"address":"0x0000000000000000000000000000000000000000","blockHash":"0x0000000000000000000000000000000000000000000000000000000000000000","blockNumber":"0x1","data":"0x010203","logIndex":"0x0","topics":[],"transactionHash":"0x0000000000000000000000000000000000000000000000000000000000000000","transactionIndex":"0x0","transactionLogIndex":"0x0","type":"mined"},{"address":"0x0000000000000000000000000000000000000000","blockHash":"0x0000000000000000000000000000000000000000000000000000000000000000","blockNumber":"0x1","data":"0x010203","logIndex":"0x1","topics":[],"transactionHash":"0x0000000000000000000000000000000000000000000000000000000000000000","transactionIndex":"0x0","transactionLogIndex":"0x1","type":"mined"}],"id":1}"#; | ||||
| 	let response2 = r#"{"jsonrpc":"2.0","result":[{"address":"0x0000000000000000000000000000000000000000","blockHash":"0x0000000000000000000000000000000000000000000000000000000000000000","blockNumber":"0x1","data":"0x010203","logIndex":"0x1","topics":[],"transactionHash":"0x0000000000000000000000000000000000000000000000000000000000000000","transactionIndex":"0x0","transactionLogIndex":"0x1","type":"mined"}],"id":1}"#; | ||||
| 
 | ||||
| 	assert_eq!(tester.io.handle_request_sync(request_changes1), Some(response1.to_owned())); | ||||
| 	assert_eq!(tester.io.handle_request_sync(request_changes2), Some(response2.to_owned())); | ||||
| @ -951,6 +955,7 @@ fn rpc_eth_transaction_receipt() { | ||||
| 			block_number: 0x4510c, | ||||
| 			transaction_hash: H256::new(), | ||||
| 			transaction_index: 0, | ||||
| 			transaction_log_index: 0, | ||||
| 			log_index: 1, | ||||
| 		}], | ||||
| 		log_bloom: 0.into(), | ||||
| @ -967,7 +972,7 @@ fn rpc_eth_transaction_receipt() { | ||||
| 		"params": ["0xb903239f8543d04b5dc1ba6579132b143087c68db1b2168786408fcbce568238"], | ||||
| 		"id": 1 | ||||
| 	}"#;
 | ||||
| 	let response = r#"{"jsonrpc":"2.0","result":{"blockHash":"0xed76641c68a1c641aee09a94b3b471f4dc0316efe5ac19cf488e2674cf8d05b5","blockNumber":"0x4510c","contractAddress":null,"cumulativeGasUsed":"0x20","gasUsed":"0x10","logs":[{"address":"0x33990122638b9132ca29c723bdf037f1a891a70c","blockHash":"0xed76641c68a1c641aee09a94b3b471f4dc0316efe5ac19cf488e2674cf8d05b5","blockNumber":"0x4510c","data":"0x","logIndex":"0x1","topics":["0xa6697e974e6a320f454390be03f74955e8978f1a6971ea6730542e37b66179bc","0x4861736852656700000000000000000000000000000000000000000000000000"],"transactionHash":"0x0000000000000000000000000000000000000000000000000000000000000000","transactionIndex":"0x0","type":"mined"}],"logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","root":"0x0000000000000000000000000000000000000000000000000000000000000000","transactionHash":"0x0000000000000000000000000000000000000000000000000000000000000000","transactionIndex":"0x0"},"id":1}"#; | ||||
| 	let response = r#"{"jsonrpc":"2.0","result":{"blockHash":"0xed76641c68a1c641aee09a94b3b471f4dc0316efe5ac19cf488e2674cf8d05b5","blockNumber":"0x4510c","contractAddress":null,"cumulativeGasUsed":"0x20","gasUsed":"0x10","logs":[{"address":"0x33990122638b9132ca29c723bdf037f1a891a70c","blockHash":"0xed76641c68a1c641aee09a94b3b471f4dc0316efe5ac19cf488e2674cf8d05b5","blockNumber":"0x4510c","data":"0x","logIndex":"0x1","topics":["0xa6697e974e6a320f454390be03f74955e8978f1a6971ea6730542e37b66179bc","0x4861736852656700000000000000000000000000000000000000000000000000"],"transactionHash":"0x0000000000000000000000000000000000000000000000000000000000000000","transactionIndex":"0x0","transactionLogIndex":"0x0","type":"mined"}],"logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","root":"0x0000000000000000000000000000000000000000000000000000000000000000","transactionHash":"0x0000000000000000000000000000000000000000000000000000000000000000","transactionIndex":"0x0"},"id":1}"#; | ||||
| 
 | ||||
| 	assert_eq!(tester.io.handle_request_sync(request), Some(response.to_owned())); | ||||
| } | ||||
|  | ||||
| @ -38,9 +38,12 @@ pub struct Log { | ||||
| 	/// Transaction Index
 | ||||
| 	#[serde(rename="transactionIndex")] | ||||
| 	pub transaction_index: Option<U256>, | ||||
| 	/// Log Index
 | ||||
| 	/// Log Index in Block
 | ||||
| 	#[serde(rename="logIndex")] | ||||
| 	pub log_index: Option<U256>, | ||||
| 	/// Log Index in Transaction
 | ||||
| 	#[serde(rename="transactionLogIndex")] | ||||
| 	pub transaction_log_index: Option<U256>, | ||||
| 	/// Log Type
 | ||||
| 	#[serde(rename="type")] | ||||
| 	pub log_type: String, | ||||
| @ -57,6 +60,7 @@ impl From<LocalizedLogEntry> for Log { | ||||
| 			transaction_hash: Some(e.transaction_hash.into()), | ||||
| 			transaction_index: Some(e.transaction_index.into()), | ||||
| 			log_index: Some(e.log_index.into()), | ||||
| 			transaction_log_index: Some(e.transaction_log_index.into()), | ||||
| 			log_type: "mined".to_owned(), | ||||
| 		} | ||||
| 	} | ||||
| @ -73,6 +77,7 @@ impl From<LogEntry> for Log { | ||||
| 			transaction_hash: None, | ||||
| 			transaction_index: None, | ||||
| 			log_index: None, | ||||
| 			transaction_log_index: None, | ||||
| 			log_type: "pending".to_owned(), | ||||
| 		} | ||||
| 	} | ||||
| @ -86,7 +91,7 @@ mod tests { | ||||
| 
 | ||||
| 	#[test] | ||||
| 	fn log_serialization() { | ||||
| 		let s = r#"{"address":"0x33990122638b9132ca29c723bdf037f1a891a70c","topics":["0xa6697e974e6a320f454390be03f74955e8978f1a6971ea6730542e37b66179bc","0x4861736852656700000000000000000000000000000000000000000000000000"],"data":"0x","blockHash":"0xed76641c68a1c641aee09a94b3b471f4dc0316efe5ac19cf488e2674cf8d05b5","blockNumber":"0x4510c","transactionHash":"0x0000000000000000000000000000000000000000000000000000000000000000","transactionIndex":"0x0","logIndex":"0x1","type":"mined"}"#; | ||||
| 		let s = r#"{"address":"0x33990122638b9132ca29c723bdf037f1a891a70c","topics":["0xa6697e974e6a320f454390be03f74955e8978f1a6971ea6730542e37b66179bc","0x4861736852656700000000000000000000000000000000000000000000000000"],"data":"0x","blockHash":"0xed76641c68a1c641aee09a94b3b471f4dc0316efe5ac19cf488e2674cf8d05b5","blockNumber":"0x4510c","transactionHash":"0x0000000000000000000000000000000000000000000000000000000000000000","transactionIndex":"0x0","logIndex":"0x1","transactionLogIndex":"0x1","type":"mined"}"#; | ||||
| 
 | ||||
| 		let log = Log { | ||||
| 			address: H160::from_str("33990122638b9132ca29c723bdf037f1a891a70c").unwrap(), | ||||
| @ -99,6 +104,7 @@ mod tests { | ||||
| 			block_number: Some(U256::from(0x4510c)), | ||||
| 			transaction_hash: Some(H256::default()), | ||||
| 			transaction_index: Some(U256::default()), | ||||
| 			transaction_log_index: Some(1.into()), | ||||
| 			log_index: Some(U256::from(1)), | ||||
| 			log_type: "mined".to_owned(), | ||||
| 		}; | ||||
|  | ||||
| @ -109,7 +109,7 @@ mod tests { | ||||
| 
 | ||||
| 	#[test] | ||||
| 	fn receipt_serialization() { | ||||
| 		let s = r#"{"transactionHash":"0x0000000000000000000000000000000000000000000000000000000000000000","transactionIndex":"0x0","blockHash":"0xed76641c68a1c641aee09a94b3b471f4dc0316efe5ac19cf488e2674cf8d05b5","blockNumber":"0x4510c","cumulativeGasUsed":"0x20","gasUsed":"0x10","contractAddress":null,"logs":[{"address":"0x33990122638b9132ca29c723bdf037f1a891a70c","topics":["0xa6697e974e6a320f454390be03f74955e8978f1a6971ea6730542e37b66179bc","0x4861736852656700000000000000000000000000000000000000000000000000"],"data":"0x","blockHash":"0xed76641c68a1c641aee09a94b3b471f4dc0316efe5ac19cf488e2674cf8d05b5","blockNumber":"0x4510c","transactionHash":"0x0000000000000000000000000000000000000000000000000000000000000000","transactionIndex":"0x0","logIndex":"0x1","type":"mined"}],"root":"0x000000000000000000000000000000000000000000000000000000000000000a","logsBloom":"0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f"}"#; | ||||
| 		let s = r#"{"transactionHash":"0x0000000000000000000000000000000000000000000000000000000000000000","transactionIndex":"0x0","blockHash":"0xed76641c68a1c641aee09a94b3b471f4dc0316efe5ac19cf488e2674cf8d05b5","blockNumber":"0x4510c","cumulativeGasUsed":"0x20","gasUsed":"0x10","contractAddress":null,"logs":[{"address":"0x33990122638b9132ca29c723bdf037f1a891a70c","topics":["0xa6697e974e6a320f454390be03f74955e8978f1a6971ea6730542e37b66179bc","0x4861736852656700000000000000000000000000000000000000000000000000"],"data":"0x","blockHash":"0xed76641c68a1c641aee09a94b3b471f4dc0316efe5ac19cf488e2674cf8d05b5","blockNumber":"0x4510c","transactionHash":"0x0000000000000000000000000000000000000000000000000000000000000000","transactionIndex":"0x0","logIndex":"0x1","transactionLogIndex":null,"type":"mined"}],"root":"0x000000000000000000000000000000000000000000000000000000000000000a","logsBloom":"0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f"}"#; | ||||
| 
 | ||||
| 		let receipt = Receipt { | ||||
| 			transaction_hash: Some(0.into()), | ||||
| @ -130,6 +130,7 @@ mod tests { | ||||
| 				block_number: Some(0x4510c.into()), | ||||
| 				transaction_hash: Some(0.into()), | ||||
| 				transaction_index: Some(0.into()), | ||||
| 				transaction_log_index: None, | ||||
| 				log_index: Some(1.into()), | ||||
| 				log_type: "mined".into(), | ||||
| 			}], | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user