Skip to content

Commit

Permalink
[storage] transaction_info hash mapping support multiple (#772)
Browse files Browse the repository at this point in the history
* [storage] transaction_info hash mapping support multiple

* [storage] remove option package of result

* [storage] refactor mapping of transaction_info hash to ids

* [storage] fix clippy check

* [storage] transaction_info hash mapping support multiple

* [storage] remove option package of result

* [storage] refactor mapping of transaction_info hash to ids
  • Loading branch information
ssyuan authored Jul 3, 2020
1 parent fb5ffa7 commit 432f08c
Show file tree
Hide file tree
Showing 12 changed files with 88 additions and 27 deletions.
7 changes: 7 additions & 0 deletions chain/src/chain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,13 @@ where
.ok_or_else(|| format_err!("Can not find block by number {}", number))
}

pub fn transaction_info_exist(&self, txn_id: HashValue) -> bool {
if let Ok(node) = self.txn_accumulator.get_node(txn_id) {
return !node.is_empty();
}
false
}

pub fn block_exist_by_number(
&self,
block_id: HashValue,
Expand Down
8 changes: 7 additions & 1 deletion chain/src/chain_service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,13 @@ where
}

fn get_transaction_info(&self, txn_hash: HashValue) -> Result<Option<TransactionInfo>, Error> {
self.storage.get_transaction_info_by_hash(txn_hash)
let txn_vec = self.storage.get_transaction_info_ids_by_hash(txn_hash)?;
for txn_info_id in txn_vec {
if self.master.transaction_info_exist(txn_info_id) {
return self.storage.get_transaction_info(txn_info_id);
}
}
Ok(None)
}

fn get_block_txn_infos(&self, block_id: HashValue) -> Result<Vec<TransactionInfo>, Error> {
Expand Down
15 changes: 9 additions & 6 deletions chain/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ where
self.service.master_blocks_by_number(number, count)?,
)),
ChainRequest::GetBlockTransactionInfos(block_id) => Ok(
ChainResponse::BlockTransactionInfos(self.service.get_block_txn_infos(block_id)?),
ChainResponse::TransactionInfos(self.service.get_block_txn_infos(block_id)?),
),
ChainRequest::GetTransactionInfoByBlockAndIndex { block_id, txn_idx } => {
Ok(ChainResponse::TransactionInfo(
Expand Down Expand Up @@ -318,14 +318,17 @@ where
}
}

async fn get_transaction_info(self, txn_hash: HashValue) -> Result<TransactionInfo, Error> {
async fn get_transaction_info(
self,
txn_hash: HashValue,
) -> Result<Option<TransactionInfo>, Error> {
let response = self
.address
.send(ChainRequest::GetTransactionInfo(txn_hash))
.await
.map_err(Into::<Error>::into)??;
if let ChainResponse::TransactionInfo(Some(txn)) = response {
Ok(txn)
if let ChainResponse::TransactionInfo(txn_info) = response {
Ok(txn_info)
} else {
bail!("get transaction_info error:{:?}", txn_hash)
}
Expand All @@ -337,10 +340,10 @@ where
.send(ChainRequest::GetBlockTransactionInfos(block_id))
.await
.map_err(Into::<Error>::into)??;
if let ChainResponse::BlockTransactionInfos(vec_txn_id) = response {
if let ChainResponse::TransactionInfos(vec_txn_id) = response {
Ok(vec_txn_id)
} else {
bail!("get block's transaction ids error.")
bail!("get block's transaction_info error.")
}
}
async fn get_txn_info_by_block_and_index(
Expand Down
2 changes: 1 addition & 1 deletion chain/src/message/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ pub enum ChainResponse {
ChainInfo(ChainInfo),
Transaction(Box<Transaction>),
VecBlock(Vec<Block>),
BlockTransactionInfos(Vec<TransactionInfo>),
TransactionInfos(Vec<TransactionInfo>),
TransactionInfo(Option<TransactionInfo>),
None,
Conn(ConnectBlockResult),
Expand Down
2 changes: 1 addition & 1 deletion chain/src/mock/mock_chain_service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ impl ChainAsyncService for MockChainService {
unimplemented!()
}

async fn get_transaction_info(self, _txn_id: HashValue) -> Result<TransactionInfo> {
async fn get_transaction_info(self, _txn_id: HashValue) -> Result<Option<TransactionInfo>> {
unimplemented!()
}

Expand Down
2 changes: 1 addition & 1 deletion cmd/starcoin/src/chain/get_txn_cmd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ impl CommandAction for GetTransactionCommand {
type State = CliState;
type GlobalOpt = StarcoinOpt;
type Opt = GetOpt;
type ReturnItem = TransactionInfo;
type ReturnItem = Option<TransactionInfo>;

fn run(
&self,
Expand Down
2 changes: 1 addition & 1 deletion core/traits/src/chain_service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ pub trait ChainAsyncService:
async fn get_block_state_by_hash(self, hash: &HashValue) -> Result<Option<BlockState>>;
async fn get_block_info_by_hash(self, hash: &HashValue) -> Result<Option<BlockInfo>>;
async fn get_transaction(self, txn_hash: HashValue) -> Result<Transaction>;
async fn get_transaction_info(self, txn_hash: HashValue) -> Result<TransactionInfo>;
async fn get_transaction_info(self, txn_hash: HashValue) -> Result<Option<TransactionInfo>>;
async fn get_block_txn_infos(self, block_id: HashValue) -> Result<Vec<TransactionInfo>>;
async fn get_txn_info_by_block_and_index(
self,
Expand Down
5 changes: 4 additions & 1 deletion rpc/api/src/chain/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,10 @@ pub trait ChainApi {
fn get_transaction(&self, transaction_id: HashValue) -> FutureResult<Transaction>;
/// Get chain transactions
#[rpc(name = "chain.get_transaction_info")]
fn get_transaction_info(&self, transaction_id: HashValue) -> FutureResult<TransactionInfo>;
fn get_transaction_info(
&self,
transaction_id: HashValue,
) -> FutureResult<Option<TransactionInfo>>;

/// Get chain transactions infos by block id
#[rpc(name = "chain.get_block_txn_infos")]
Expand Down
7 changes: 5 additions & 2 deletions rpc/client/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -425,11 +425,14 @@ impl RpcClient {
.map_err(map_err)
}

pub fn chain_get_transaction_info(&self, txn_id: HashValue) -> anyhow::Result<TransactionInfo> {
pub fn chain_get_transaction_info(
&self,
txn_hash: HashValue,
) -> anyhow::Result<Option<TransactionInfo>> {
self.call_rpc_blocking(|inner| async move {
inner
.chain_client
.get_transaction_info(txn_id)
.get_transaction_info(txn_hash)
.compat()
.await
})
Expand Down
5 changes: 4 additions & 1 deletion rpc/server/src/module/chain_rpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,10 @@ where
Box::new(fut.compat())
}

fn get_transaction_info(&self, transaction_hash: HashValue) -> FutureResult<TransactionInfo> {
fn get_transaction_info(
&self,
transaction_hash: HashValue,
) -> FutureResult<Option<TransactionInfo>> {
let fut = self
.service
.clone()
Expand Down
27 changes: 20 additions & 7 deletions storage/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,8 @@ pub trait BlockStore {

pub trait TransactionInfoStore {
fn get_transaction_info(&self, id: HashValue) -> Result<Option<TransactionInfo>>;
fn get_transaction_info_by_hash(&self, txn_hash: HashValue) -> Result<Option<TransactionInfo>>;
fn get_transaction_info_by_hash(&self, txn_hash: HashValue) -> Result<Vec<TransactionInfo>>;
fn get_transaction_info_ids_by_hash(&self, txn_hash: HashValue) -> Result<Vec<HashValue>>;
fn save_transaction_info(&self, txn_info: TransactionInfo) -> Result<()> {
self.save_transaction_infos(vec![txn_info])
}
Expand Down Expand Up @@ -331,12 +332,24 @@ impl TransactionInfoStore for Storage {
fn get_transaction_info_by_hash(
&self,
txn_hash: HashValue,
) -> Result<Option<TransactionInfo>, Error> {
let transaction_info_id = self
.transaction_info_hash_storage
.get(txn_hash)
.expect("transaction_info hash must exist");
self.get_transaction_info(transaction_info_id.unwrap())
) -> Result<Vec<TransactionInfo>, Error> {
let mut transaction_info_vec = vec![];
if let Ok(Some(transaction_info_ids)) = self.transaction_info_hash_storage.get(txn_hash) {
for id in transaction_info_ids {
if let Ok(Some(transaction_info)) = self.get_transaction_info(id) {
transaction_info_vec.push(transaction_info);
}
}
}
Ok(transaction_info_vec)
}

fn get_transaction_info_ids_by_hash(
&self,
txn_hash: HashValue,
) -> Result<Vec<HashValue>, Error> {
self.transaction_info_hash_storage
.get_transaction_info_ids_by_hash(txn_hash)
}

fn save_transaction_infos(&self, vec_txn_info: Vec<TransactionInfo>) -> Result<(), Error> {
Expand Down
33 changes: 28 additions & 5 deletions storage/src/transaction_info/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use crate::storage::{CodecStorage, ValueCodec};
use crate::TRANSACTION_INFO_HASH_PREFIX_NAME;
use crate::TRANSACTION_INFO_PREFIX_NAME;
use crate::{define_storage, TransactionInfoStore};
use anyhow::{Error, Result};
use anyhow::{bail, Error, Result};
use crypto::HashValue;
use scs::SCSCodec;
use starcoin_types::transaction::TransactionInfo;
Expand All @@ -22,7 +22,7 @@ define_storage!(
define_storage!(
TransactionInfoHashStorage,
HashValue,
HashValue,
Vec<HashValue>,
TRANSACTION_INFO_HASH_PREFIX_NAME
);

Expand All @@ -44,14 +44,30 @@ impl TransactionInfoStore for TransactionInfoHashStorage {
fn get_transaction_info_by_hash(
&self,
_txn_hash: HashValue,
) -> Result<Option<TransactionInfo>, Error> {
) -> Result<Vec<TransactionInfo>, Error> {
unimplemented!()
}

fn get_transaction_info_ids_by_hash(
&self,
txn_hash: HashValue,
) -> Result<Vec<HashValue>, Error> {
if let Ok(Some(txn_id_vec)) = self.store.get(txn_hash) {
Ok(txn_id_vec)
} else {
bail!("get transaction_info ids error.")
}
}

fn save_transaction_infos(&self, vec_txn_info: Vec<TransactionInfo>) -> Result<(), Error> {
let mut batch = WriteBatch::new();
for txn_info in vec_txn_info {
batch.put(txn_info.transaction_hash(), txn_info.id())?;
if let Ok(Some(mut id_vec)) = self.store.get(txn_info.transaction_hash()) {
id_vec.push(txn_info.id());
batch.put(txn_info.transaction_hash(), id_vec)?;
} else {
batch.put(txn_info.transaction_hash(), vec![txn_info.id()])?;
}
}
self.store.write_batch(batch)
}
Expand All @@ -64,7 +80,14 @@ impl TransactionInfoStore for TransactionInfoStorage {
fn get_transaction_info_by_hash(
&self,
_txn_hash: HashValue,
) -> Result<Option<TransactionInfo>, Error> {
) -> Result<Vec<TransactionInfo>, Error> {
unimplemented!()
}

fn get_transaction_info_ids_by_hash(
&self,
_txn_hash: HashValue,
) -> Result<Vec<HashValue>, Error> {
unimplemented!()
}

Expand Down

0 comments on commit 432f08c

Please sign in to comment.