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()
|
.enumerate()
|
||||||
.flat_map(move |(index, (mut logs, tx_hash))| {
|
.flat_map(move |(index, (mut logs, tx_hash))| {
|
||||||
let current_log_index = log_index;
|
let current_log_index = log_index;
|
||||||
log_index -= logs.len();
|
let no_of_logs = logs.len();
|
||||||
|
log_index -= no_of_logs;
|
||||||
|
|
||||||
logs.reverse();
|
logs.reverse();
|
||||||
logs.into_iter()
|
logs.into_iter()
|
||||||
@ -390,6 +391,7 @@ impl BlockProvider for BlockChain {
|
|||||||
transaction_hash: tx_hash,
|
transaction_hash: tx_hash,
|
||||||
// iterating in reverse order
|
// iterating in reverse order
|
||||||
transaction_index: receipts_len - index - 1,
|
transaction_index: receipts_len - index - 1,
|
||||||
|
transaction_log_index: no_of_logs - i - 1,
|
||||||
log_index: current_log_index - i - 1,
|
log_index: current_log_index - i - 1,
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@ -1936,6 +1938,7 @@ mod tests {
|
|||||||
block_number: block1.header().number(),
|
block_number: block1.header().number(),
|
||||||
transaction_hash: tx_hash1.clone(),
|
transaction_hash: tx_hash1.clone(),
|
||||||
transaction_index: 0,
|
transaction_index: 0,
|
||||||
|
transaction_log_index: 0,
|
||||||
log_index: 0,
|
log_index: 0,
|
||||||
},
|
},
|
||||||
LocalizedLogEntry {
|
LocalizedLogEntry {
|
||||||
@ -1944,6 +1947,7 @@ mod tests {
|
|||||||
block_number: block1.header().number(),
|
block_number: block1.header().number(),
|
||||||
transaction_hash: tx_hash1.clone(),
|
transaction_hash: tx_hash1.clone(),
|
||||||
transaction_index: 0,
|
transaction_index: 0,
|
||||||
|
transaction_log_index: 1,
|
||||||
log_index: 1,
|
log_index: 1,
|
||||||
},
|
},
|
||||||
LocalizedLogEntry {
|
LocalizedLogEntry {
|
||||||
@ -1952,6 +1956,7 @@ mod tests {
|
|||||||
block_number: block1.header().number(),
|
block_number: block1.header().number(),
|
||||||
transaction_hash: tx_hash2.clone(),
|
transaction_hash: tx_hash2.clone(),
|
||||||
transaction_index: 1,
|
transaction_index: 1,
|
||||||
|
transaction_log_index: 0,
|
||||||
log_index: 2,
|
log_index: 2,
|
||||||
},
|
},
|
||||||
LocalizedLogEntry {
|
LocalizedLogEntry {
|
||||||
@ -1960,6 +1965,7 @@ mod tests {
|
|||||||
block_number: block2.header().number(),
|
block_number: block2.header().number(),
|
||||||
transaction_hash: tx_hash3.clone(),
|
transaction_hash: tx_hash3.clone(),
|
||||||
transaction_index: 0,
|
transaction_index: 0,
|
||||||
|
transaction_log_index: 0,
|
||||||
log_index: 0,
|
log_index: 0,
|
||||||
}
|
}
|
||||||
]);
|
]);
|
||||||
@ -1970,6 +1976,7 @@ mod tests {
|
|||||||
block_number: block2.header().number(),
|
block_number: block2.header().number(),
|
||||||
transaction_hash: tx_hash3.clone(),
|
transaction_hash: tx_hash3.clone(),
|
||||||
transaction_index: 0,
|
transaction_index: 0,
|
||||||
|
transaction_log_index: 0,
|
||||||
log_index: 0,
|
log_index: 0,
|
||||||
}
|
}
|
||||||
]);
|
]);
|
||||||
|
@ -59,7 +59,7 @@ use client::{
|
|||||||
use client::Error as ClientError;
|
use client::Error as ClientError;
|
||||||
use env_info::EnvInfo;
|
use env_info::EnvInfo;
|
||||||
use executive::{Executive, Executed, TransactOptions, contract_address};
|
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::{TraceDB, ImportRequest as TraceImportRequest, LocalizedTrace, Database as TraceDatabase};
|
||||||
use trace;
|
use trace;
|
||||||
use trace::FlatTransactionTraces;
|
use trace::FlatTransactionTraces;
|
||||||
@ -837,7 +837,6 @@ impl snapshot::DatabaseRestore for Client {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
impl BlockChainClient for Client {
|
impl BlockChainClient for Client {
|
||||||
fn call(&self, t: &SignedTransaction, block: BlockId, analytics: CallAnalytics) -> Result<Executed, CallError> {
|
fn call(&self, t: &SignedTransaction, block: BlockId, analytics: CallAnalytics) -> Result<Executed, CallError> {
|
||||||
let header = self.block_header(block).ok_or(CallError::StatePruned)?;
|
let header = self.block_header(block).ok_or(CallError::StatePruned)?;
|
||||||
@ -1134,53 +1133,23 @@ impl BlockChainClient for Client {
|
|||||||
let chain = self.chain.read();
|
let chain = self.chain.read();
|
||||||
self.transaction_address(id)
|
self.transaction_address(id)
|
||||||
.and_then(|address| chain.block_number(&address.block_hash).and_then(|block_number| {
|
.and_then(|address| chain.block_number(&address.block_hash).and_then(|block_number| {
|
||||||
let t = chain.block_body(&address.block_hash)
|
let transaction = chain.block_body(&address.block_hash)
|
||||||
.and_then(|body| {
|
.and_then(|body| body.view().localized_transaction_at(&address.block_hash, block_number, address.index));
|
||||||
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)));
|
let previous_receipts = (0..address.index + 1)
|
||||||
|
.map(|index| {
|
||||||
match (tx_and_sender, chain.transaction_receipt(&address)) {
|
let mut address = address.clone();
|
||||||
(Some((tx, sender)), Some(receipt)) => {
|
address.index = index;
|
||||||
let block_hash = tx.block_hash.clone();
|
chain.transaction_receipt(&address)
|
||||||
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,
|
|
||||||
})
|
})
|
||||||
},
|
.collect();
|
||||||
_ => None
|
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> {
|
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)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
|
||||||
@ -1570,4 +1582,91 @@ mod tests {
|
|||||||
|
|
||||||
assert!(client.tree_route(&genesis, &new_hash).is_none());
|
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.ready_transactions().len());
|
||||||
assert_eq!(2, client.miner().pending_transactions().len());
|
assert_eq!(2, client.miner().pending_transactions().len());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -97,6 +97,8 @@ pub struct LocalizedLogEntry {
|
|||||||
pub transaction_index: usize,
|
pub transaction_index: usize,
|
||||||
/// Log position in the block.
|
/// Log position in the block.
|
||||||
pub log_index: usize,
|
pub log_index: usize,
|
||||||
|
/// Log position in the transaction.
|
||||||
|
pub transaction_log_index: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Deref for LocalizedLogEntry {
|
impl Deref for LocalizedLogEntry {
|
||||||
|
@ -373,7 +373,7 @@ impl SignedTransaction {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Signed Transaction that is a part of canon blockchain.
|
/// Signed Transaction that is a part of canon blockchain.
|
||||||
#[derive(Debug, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
#[cfg_attr(feature = "ipc", binary)]
|
#[cfg_attr(feature = "ipc", binary)]
|
||||||
pub struct LocalizedTransaction {
|
pub struct LocalizedTransaction {
|
||||||
/// Signed part.
|
/// Signed part.
|
||||||
|
@ -193,6 +193,7 @@ fn rpc_eth_logs() {
|
|||||||
data: vec![1,2,3],
|
data: vec![1,2,3],
|
||||||
},
|
},
|
||||||
transaction_index: 0,
|
transaction_index: 0,
|
||||||
|
transaction_log_index: 0,
|
||||||
transaction_hash: H256::default(),
|
transaction_hash: H256::default(),
|
||||||
log_index: 0,
|
log_index: 0,
|
||||||
}, LocalizedLogEntry {
|
}, LocalizedLogEntry {
|
||||||
@ -204,8 +205,9 @@ fn rpc_eth_logs() {
|
|||||||
data: vec![1,2,3],
|
data: vec![1,2,3],
|
||||||
},
|
},
|
||||||
transaction_index: 0,
|
transaction_index: 0,
|
||||||
|
transaction_log_index: 1,
|
||||||
transaction_hash: H256::default(),
|
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 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 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 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":"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":"0x1","topics":[],"transactionHash":"0x0000000000000000000000000000000000000000000000000000000000000000","transactionIndex":"0x0","transactionLogIndex":"0x1","type":"mined"}],"id":1}"#;
|
||||||
let response3 = r#"{"jsonrpc":"2.0","result":[],"id":1}"#;
|
let response3 = r#"{"jsonrpc":"2.0","result":[],"id":1}"#;
|
||||||
|
|
||||||
assert_eq!(tester.io.handle_request_sync(request1), Some(response1.to_owned()));
|
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],
|
data: vec![1,2,3],
|
||||||
},
|
},
|
||||||
transaction_index: 0,
|
transaction_index: 0,
|
||||||
|
transaction_log_index: 0,
|
||||||
transaction_hash: H256::default(),
|
transaction_hash: H256::default(),
|
||||||
log_index: 0,
|
log_index: 0,
|
||||||
}, LocalizedLogEntry {
|
}, LocalizedLogEntry {
|
||||||
@ -246,8 +249,9 @@ fn rpc_logs_filter() {
|
|||||||
data: vec![1,2,3],
|
data: vec![1,2,3],
|
||||||
},
|
},
|
||||||
transaction_index: 0,
|
transaction_index: 0,
|
||||||
|
transaction_log_index: 1,
|
||||||
transaction_hash: H256::default(),
|
transaction_hash: H256::default(),
|
||||||
log_index: 0,
|
log_index: 1,
|
||||||
}]);
|
}]);
|
||||||
|
|
||||||
// Register filters first
|
// 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_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 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 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":"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":"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_changes1), Some(response1.to_owned()));
|
||||||
assert_eq!(tester.io.handle_request_sync(request_changes2), Some(response2.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,
|
block_number: 0x4510c,
|
||||||
transaction_hash: H256::new(),
|
transaction_hash: H256::new(),
|
||||||
transaction_index: 0,
|
transaction_index: 0,
|
||||||
|
transaction_log_index: 0,
|
||||||
log_index: 1,
|
log_index: 1,
|
||||||
}],
|
}],
|
||||||
log_bloom: 0.into(),
|
log_bloom: 0.into(),
|
||||||
@ -967,7 +972,7 @@ fn rpc_eth_transaction_receipt() {
|
|||||||
"params": ["0xb903239f8543d04b5dc1ba6579132b143087c68db1b2168786408fcbce568238"],
|
"params": ["0xb903239f8543d04b5dc1ba6579132b143087c68db1b2168786408fcbce568238"],
|
||||||
"id": 1
|
"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()));
|
assert_eq!(tester.io.handle_request_sync(request), Some(response.to_owned()));
|
||||||
}
|
}
|
||||||
|
@ -38,9 +38,12 @@ pub struct Log {
|
|||||||
/// Transaction Index
|
/// Transaction Index
|
||||||
#[serde(rename="transactionIndex")]
|
#[serde(rename="transactionIndex")]
|
||||||
pub transaction_index: Option<U256>,
|
pub transaction_index: Option<U256>,
|
||||||
/// Log Index
|
/// Log Index in Block
|
||||||
#[serde(rename="logIndex")]
|
#[serde(rename="logIndex")]
|
||||||
pub log_index: Option<U256>,
|
pub log_index: Option<U256>,
|
||||||
|
/// Log Index in Transaction
|
||||||
|
#[serde(rename="transactionLogIndex")]
|
||||||
|
pub transaction_log_index: Option<U256>,
|
||||||
/// Log Type
|
/// Log Type
|
||||||
#[serde(rename="type")]
|
#[serde(rename="type")]
|
||||||
pub log_type: String,
|
pub log_type: String,
|
||||||
@ -57,6 +60,7 @@ impl From<LocalizedLogEntry> for Log {
|
|||||||
transaction_hash: Some(e.transaction_hash.into()),
|
transaction_hash: Some(e.transaction_hash.into()),
|
||||||
transaction_index: Some(e.transaction_index.into()),
|
transaction_index: Some(e.transaction_index.into()),
|
||||||
log_index: Some(e.log_index.into()),
|
log_index: Some(e.log_index.into()),
|
||||||
|
transaction_log_index: Some(e.transaction_log_index.into()),
|
||||||
log_type: "mined".to_owned(),
|
log_type: "mined".to_owned(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -73,6 +77,7 @@ impl From<LogEntry> for Log {
|
|||||||
transaction_hash: None,
|
transaction_hash: None,
|
||||||
transaction_index: None,
|
transaction_index: None,
|
||||||
log_index: None,
|
log_index: None,
|
||||||
|
transaction_log_index: None,
|
||||||
log_type: "pending".to_owned(),
|
log_type: "pending".to_owned(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -86,7 +91,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn log_serialization() {
|
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 {
|
let log = Log {
|
||||||
address: H160::from_str("33990122638b9132ca29c723bdf037f1a891a70c").unwrap(),
|
address: H160::from_str("33990122638b9132ca29c723bdf037f1a891a70c").unwrap(),
|
||||||
@ -99,6 +104,7 @@ mod tests {
|
|||||||
block_number: Some(U256::from(0x4510c)),
|
block_number: Some(U256::from(0x4510c)),
|
||||||
transaction_hash: Some(H256::default()),
|
transaction_hash: Some(H256::default()),
|
||||||
transaction_index: Some(U256::default()),
|
transaction_index: Some(U256::default()),
|
||||||
|
transaction_log_index: Some(1.into()),
|
||||||
log_index: Some(U256::from(1)),
|
log_index: Some(U256::from(1)),
|
||||||
log_type: "mined".to_owned(),
|
log_type: "mined".to_owned(),
|
||||||
};
|
};
|
||||||
|
@ -109,7 +109,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn receipt_serialization() {
|
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 {
|
let receipt = Receipt {
|
||||||
transaction_hash: Some(0.into()),
|
transaction_hash: Some(0.into()),
|
||||||
@ -130,6 +130,7 @@ mod tests {
|
|||||||
block_number: Some(0x4510c.into()),
|
block_number: Some(0x4510c.into()),
|
||||||
transaction_hash: Some(0.into()),
|
transaction_hash: Some(0.into()),
|
||||||
transaction_index: Some(0.into()),
|
transaction_index: Some(0.into()),
|
||||||
|
transaction_log_index: None,
|
||||||
log_index: Some(1.into()),
|
log_index: Some(1.into()),
|
||||||
log_type: "mined".into(),
|
log_type: "mined".into(),
|
||||||
}],
|
}],
|
||||||
|
Loading…
Reference in New Issue
Block a user