LocalizedTransaction

This commit is contained in:
debris 2016-02-09 15:17:01 +01:00
parent ac2ee42804
commit 5d05c36791
7 changed files with 57 additions and 20 deletions

View File

@ -111,19 +111,19 @@ pub trait BlockProvider {
}
/// Get transaction with given transaction hash.
fn transaction(&self, hash: &H256) -> Option<SignedTransaction> {
fn transaction(&self, hash: &H256) -> Option<LocalizedTransaction> {
self.transaction_address(hash).and_then(|address| self.transaction_at(&address))
}
/// Get transaction at given address.
fn transaction_at(&self, address: &TransactionAddress) -> Option<SignedTransaction> {
self.block(&address.block_hash).map(|bytes| BlockView::new(&bytes).transactions()).and_then(|t| t.into_iter().nth(address.index))
fn transaction_at(&self, address: &TransactionAddress) -> Option<LocalizedTransaction> {
self.block(&address.block_hash).map(|bytes| BlockView::new(&bytes).localized_transactions()).and_then(|t| t.into_iter().nth(address.index))
}
/// Get a list of transactions for a given block.
/// Returns None if block deos not exist.
fn transactions(&self, hash: &H256) -> Option<Vec<SignedTransaction>> {
self.block(hash).map(|bytes| BlockView::new(&bytes).transactions())
fn transactions(&self, hash: &H256) -> Option<Vec<LocalizedTransaction>> {
self.block(hash).map(|bytes| BlockView::new(&bytes).localized_transactions())
}
/// Returns reference to genesis hash.

View File

@ -31,7 +31,7 @@ use service::{NetSyncMessage, SyncMessage};
use env_info::LastHashes;
use verification::*;
use block::*;
use transaction::SignedTransaction;
use transaction::LocalizedTransaction;
pub use blockchain::TreeRoute;
/// General block status
@ -106,7 +106,7 @@ pub trait BlockChainClient : Sync + Send {
fn block_total_difficulty_at(&self, n: BlockNumber) -> Option<U256>;
/// Get transaction with given hash.
fn transaction(&self, hash: &H256) -> Option<SignedTransaction>;
fn transaction(&self, hash: &H256) -> Option<LocalizedTransaction>;
/// Get a tree route between `from` and `to`.
/// See `BlockChain::tree_route`.
@ -392,7 +392,7 @@ impl BlockChainClient for Client {
self.chain.read().unwrap().block_hash(n).and_then(|h| self.block_total_difficulty(&h))
}
fn transaction(&self, hash: &H256) -> Option<SignedTransaction> {
fn transaction(&self, hash: &H256) -> Option<LocalizedTransaction> {
self.chain.read().unwrap().transaction(hash)
}

View File

@ -19,6 +19,7 @@
use util::*;
use error::*;
use evm::Schedule;
use header::BlockNumber;
#[derive(Debug, Clone, PartialEq, Eq)]
/// Transaction action type.
@ -289,6 +290,26 @@ impl SignedTransaction {
}
}
/// Signed Transaction that is a part of canon blockchain.
pub struct LocalizedTransaction {
/// Signed part.
pub signed: SignedTransaction,
/// Block number.
pub block_number: BlockNumber,
/// Block hash.
pub block_hash: H256,
/// Transaction index within block.
pub transaction_index: usize
}
impl Deref for LocalizedTransaction {
type Target = SignedTransaction;
fn deref(&self) -> &Self::Target {
&self.signed
}
}
#[test]
fn sender_test() {
let t: SignedTransaction = decode(&FromHex::from_hex("f85f800182520894095e7baea6a6c7c4c2dfeb977efac326af552d870a801ba048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353a0efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804").unwrap());

View File

@ -155,6 +155,22 @@ impl<'a> BlockView<'a> {
self.rlp.val_at(1)
}
/// Return List of transactions with additional localization info.
pub fn localized_transactions(&self) -> Vec<LocalizedTransaction> {
let header = self.header_view();
let block_hash = header.sha3();
let block_number = header.number();
self.rlp.val_at::<Vec<SignedTransaction>>(1)
.into_iter()
.enumerate()
.map(|(i, t)| LocalizedTransaction {
signed: t,
block_hash: block_hash.clone(),
block_number: block_number,
transaction_index: i
}).collect()
}
/// Return number of transactions in given block, without deserializing them.
pub fn transactions_count(&self) -> usize {
self.rlp.at(1).iter().count()

View File

@ -97,8 +97,8 @@ impl Eth for EthClient {
}
fn block_transaction_count(&self, params: Params) -> Result<Value, Error> {
match from_params::<H256>(params) {
Ok(hash) => match self.client.block(&hash) {
match from_params::<(H256,)>(params) {
Ok((hash,)) => match self.client.block(&hash) {
Some(bytes) => to_value(&BlockView::new(&bytes).transactions_count()),
None => Ok(Value::Null)
},
@ -107,8 +107,8 @@ impl Eth for EthClient {
}
fn block_uncles_count(&self, params: Params) -> Result<Value, Error> {
match from_params::<H256>(params) {
Ok(hash) => match self.client.block(&hash) {
match from_params::<(H256,)>(params) {
Ok((hash,)) => match self.client.block(&hash) {
Some(bytes) => to_value(&BlockView::new(&bytes).uncles_count()),
None => Ok(Value::Null)
},
@ -164,14 +164,14 @@ impl Eth for EthClient {
}
fn transaction_at(&self, params: Params) -> Result<Value, Error> {
match from_params::<H256>(params) {
Ok(hash) => match self.client.transaction(&hash) {
match from_params::<(H256,)>(params) {
Ok((hash,)) => match self.client.transaction(&hash) {
Some(t) => to_value(&Transaction {
hash: t.hash(),
nonce: t.nonce,
block_hash: OptionalValue::Value(H256::default()), // todo
block_number: OptionalValue::Value(U256::default()), // todo
transaction_index: U256::default(), // todo
block_hash: OptionalValue::Value(t.block_hash.clone()),
block_number: OptionalValue::Value(U256::from(t.block_number)),
transaction_index: OptionalValue::Value(U256::from(t.transaction_index)),
from: t.sender().unwrap(),
to: match t.action {
Action::Create => OptionalValue::Null,

View File

@ -80,7 +80,7 @@ mod tests {
fn test_serialize_block_transactions() {
let t = BlockTransactions::Full(vec![Transaction::default()]);
let serialized = serde_json::to_string(&t).unwrap();
assert_eq!(serialized, r#"[{"hash":"0x0000000000000000000000000000000000000000000000000000000000000000","nonce":"0x00","blockHash":null,"blockNumber":null,"transactionIndex":"0x00","from":"0x0000000000000000000000000000000000000000","to":null,"value":"0x00","gasPrice":"0x00","gas":"0x00","input":"0x00"}]"#);
assert_eq!(serialized, r#"[{"hash":"0x0000000000000000000000000000000000000000000000000000000000000000","nonce":"0x00","blockHash":null,"blockNumber":null,"transactionIndex":null,"from":"0x0000000000000000000000000000000000000000","to":null,"value":"0x00","gasPrice":"0x00","gas":"0x00","input":"0x00"}]"#);
let t = BlockTransactions::Hashes(vec![H256::default()]);
let serialized = serde_json::to_string(&t).unwrap();

View File

@ -27,7 +27,7 @@ pub struct Transaction {
#[serde(rename="blockNumber")]
pub block_number: OptionalValue<U256>,
#[serde(rename="transactionIndex")]
pub transaction_index: U256,
pub transaction_index: OptionalValue<U256>,
pub from: Address,
pub to: OptionalValue<Address>,
pub value: U256,
@ -46,7 +46,7 @@ mod tests {
fn test_transaction_serialize() {
let t = Transaction::default();
let serialized = serde_json::to_string(&t).unwrap();
assert_eq!(serialized, r#"{"hash":"0x0000000000000000000000000000000000000000000000000000000000000000","nonce":"0x00","blockHash":null,"blockNumber":null,"transactionIndex":"0x00","from":"0x0000000000000000000000000000000000000000","to":null,"value":"0x00","gasPrice":"0x00","gas":"0x00","input":"0x00"}"#);
assert_eq!(serialized, r#"{"hash":"0x0000000000000000000000000000000000000000000000000000000000000000","nonce":"0x00","blockHash":null,"blockNumber":null,"transactionIndex":null,"from":"0x0000000000000000000000000000000000000000","to":null,"value":"0x00","gasPrice":"0x00","gas":"0x00","input":"0x00"}"#);
}
}