Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add include_tx_pool: Option<bool> param to ChainRpcImpl::get_live_cell' #4454

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion rpc/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -1070,9 +1070,10 @@ The response looks like below when `verbosity` is 0.

<a id="chain-get_live_cell"></a>
#### Method `get_live_cell`
* `get_live_cell(out_point, with_data)`
* `get_live_cell(out_point, with_data, include_tx_pool)`
* `out_point`: [`OutPoint`](#type-outpoint)
* `with_data`: `boolean`
* `include_tx_pool`: `boolean` `|` `null`
* result: [`CellWithStatus`](#type-cellwithstatus)

Returns the status of a cell. The RPC returns extra information if it is a [live cell](#live-cell).
Expand All @@ -1092,6 +1093,7 @@ result.
* `out_point` - Reference to the cell by transaction hash and output index.
* `with_data` - Whether the RPC should return cell data. Cell data can be huge, if the client
does not need the data, it should set this to `false` to save bandwidth.
* `include_tx_pool` - Whether the RPC check live cell in TxPool, default is false.

###### Examples

Expand Down
31 changes: 24 additions & 7 deletions rpc/src/module/chain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -785,6 +785,7 @@ pub trait ChainRpc {
/// * `out_point` - Reference to the cell by transaction hash and output index.
/// * `with_data` - Whether the RPC should return cell data. Cell data can be huge, if the client
/// does not need the data, it should set this to `false` to save bandwidth.
/// * `include_tx_pool` - Whether the RPC check live cell in TxPool, default is false.
///
/// ## Examples
///
Expand Down Expand Up @@ -832,7 +833,12 @@ pub trait ChainRpc {
/// }
/// ```
#[rpc(name = "get_live_cell")]
fn get_live_cell(&self, out_point: OutPoint, with_data: bool) -> Result<CellWithStatus>;
fn get_live_cell(
&self,
out_point: OutPoint,
with_data: bool,
include_tx_pool: Option<bool>,
) -> Result<CellWithStatus>;

/// Returns the highest block number in the [canonical chain](#canonical-chain).
///
Expand Down Expand Up @@ -1813,12 +1819,23 @@ impl ChainRpc for ChainRpcImpl {
}))
}

fn get_live_cell(&self, out_point: OutPoint, with_data: bool) -> Result<CellWithStatus> {
let cell_status = self
.shared
.snapshot()
.as_ref()
.cell(&out_point.into(), with_data);
fn get_live_cell(
&self,
out_point: OutPoint,
with_data: bool,
include_tx_pool: Option<bool>,
) -> Result<CellWithStatus> {
let cell_status: CellStatus = if include_tx_pool.unwrap_or_default() {
self.shared
.tx_pool_controller()
.get_live_cell(out_point.into(), with_data)
.map_err(|err| RPCError::custom(RPCError::CKBInternalError, err.to_string()))?
} else {
self.shared
.snapshot()
.as_ref()
.cell(&out_point.into(), with_data)
};
Ok(cell_status.into())
}

Expand Down
44 changes: 44 additions & 0 deletions tx-pool/src/service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,10 @@ use ckb_logger::{error, info};
use ckb_network::{NetworkController, PeerIndex};
use ckb_snapshot::Snapshot;
use ckb_stop_handler::new_tokio_exit_rx;
use ckb_store::ChainStore;
use ckb_types::core::cell::{CellProvider, CellStatus, OverlayCellProvider};
use ckb_types::core::tx_pool::{EntryCompleted, PoolTxDetailInfo, TransactionWithStatus, TxStatus};
use ckb_types::packed::OutPoint;
use ckb_types::{
core::{
tx_pool::{Reject, TxPoolEntryInfo, TxPoolIds, TxPoolInfo, TRANSACTION_SIZE_LIMIT},
Expand All @@ -39,6 +42,7 @@ use tokio::sync::{mpsc, RwLock};
use tokio::task::block_in_place;
use tokio_util::sync::CancellationToken;

use crate::pool_cell::PoolCell;
#[cfg(feature = "internal")]
use crate::{component::entry::TxEntry, process::PlugTarget};

Expand Down Expand Up @@ -98,6 +102,7 @@ pub(crate) enum Message {
FetchTxs(Request<HashSet<ProposalShortId>, HashMap<ProposalShortId, TransactionView>>),
FetchTxsWithCycles(Request<HashSet<ProposalShortId>, FetchTxsWithCyclesResult>),
GetTxPoolInfo(Request<(), TxPoolInfo>),
GetLiveCell(Request<(OutPoint, bool), CellStatus>),
GetTxStatus(Request<Byte32, GetTxStatusResult>),
GetTransactionWithStatus(Request<Byte32, GetTransactionWithStatusResult>),
NewUncle(Notify<UncleBlockView>),
Expand Down Expand Up @@ -260,6 +265,15 @@ impl TxPoolController {
send_message!(self, GetTxPoolInfo, ())
}

/// Return tx-pool information
pub fn get_live_cell(
&self,
out_point: OutPoint,
with_data: bool,
) -> Result<CellStatus, AnyError> {
send_message!(self, GetLiveCell, (out_point, with_data))
}

/// Return fresh proposals
pub fn fresh_proposals_filter(
&self,
Expand Down Expand Up @@ -679,6 +693,15 @@ async fn process(mut service: TxPoolService, message: Message) {
error!("Responder sending get_tx_pool_info failed {:?}", e);
};
}
Message::GetLiveCell(Request {
responder,
arguments: (out_point, with_data),
}) => {
let live_cell_status = service.get_live_cell(out_point, with_data).await;
if let Err(e) = responder.send(live_cell_status) {
error!("Responder sending get_live_cell failed {:?}", e);
};
}
Message::BlockTemplate(Request {
responder,
arguments: (_bytes_limit, _proposals_limit, _max_version),
Expand Down Expand Up @@ -955,6 +978,27 @@ impl TxPoolService {
}
}

/// Get Live Cell Status
quake marked this conversation as resolved.
Show resolved Hide resolved
async fn get_live_cell(&self, out_point: OutPoint, eager_load: bool) -> CellStatus {
let tx_pool = self.tx_pool.read().await;
let snapshot = tx_pool.snapshot();
let pool_cell = PoolCell::new(&tx_pool.pool_map, false);
let provider = OverlayCellProvider::new(&pool_cell, snapshot);

match provider.cell(&out_point, false) {
CellStatus::Live(mut cell_meta) => {
if eager_load {
if let Some((data, data_hash)) = snapshot.get_cell_data(&out_point) {
cell_meta.mem_cell_data = Some(data);
cell_meta.mem_cell_data_hash = Some(data_hash);
}
}
CellStatus::live_cell(cell_meta)
}
_ => CellStatus::Unknown,
}
}

pub fn should_notify_block_assembler(&self) -> bool {
self.block_assembler.is_some()
}
Expand Down
Loading