Skip to content

Commit f484708

Browse files
committed
feat: support async api
1 parent 8e6217d commit f484708

28 files changed

+866
-271
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ parking_lot = "0.12"
3131
lru = "0.7.1"
3232
dashmap = "5.4"
3333
dyn-clone = "1.0"
34+
async-trait = "0.1"
3435

3536
ckb-types = "0.119.0"
3637
ckb-dao-utils = "0.119.0"
@@ -50,7 +51,6 @@ ckb-mock-tx-types = { version = "0.119.0" }
5051
ckb-chain-spec = "0.119.0"
5152

5253
sparse-merkle-tree = "0.6.1"
53-
lazy_static = "1.3.0"
5454

5555
[features]
5656
default = ["default-tls"]

deny.toml

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,8 @@ ignore = [
7474
#{ id = "RUSTSEC-0000-0000", reason = "you can specify a reason the advisory is ignored" },
7575
#"a-crate-that-is-yanked@0.1.1", # you can also ignore yanked crate versions if you wish
7676
#{ crate = "a-crate-that-is-yanked@0.1.1", reason = "you can specify why you are ignoring the yanked crate"
77-
"RUSTSEC-2024-0370" # proc-macro-error's maintainer seems to be unreachable, ignore this
77+
"RUSTSEC-2024-0370", # proc-macro-error's maintainer seems to be unreachable, ignore this
78+
"RUSTSEC-2024-0384", # instant is no longer maintained, ignore this
7879
]
7980
# If this is true, then cargo deny will use the git executable to fetch advisory database.
8081
# If this is false, then it uses a built-in git library.
@@ -97,8 +98,8 @@ allow = [
9798
"ISC",
9899
"MIT",
99100
"Unicode-DFS-2016",
100-
"BSL-1.0", # xxhash-rust 0.8.10
101-
101+
"BSL-1.0", # xxhash-rust 0.8.10
102+
"Unicode-3.0",
102103
#"MIT",
103104
#"Apache-2.0",
104105
#"Apache-2.0 WITH LLVM-exception",

examples/script_unlocker_example.rs

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,14 @@ use std::collections::HashMap;
1717
/// [CapacityDiff]: https://github.com/doitian/ckb-sdk-examples-capacity-diff
1818
struct CapacityDiffUnlocker {}
1919

20+
#[async_trait::async_trait]
2021
impl ScriptUnlocker for CapacityDiffUnlocker {
2122
// This works for any args
2223
fn match_args(&self, _args: &[u8]) -> bool {
2324
true
2425
}
2526

26-
fn unlock(
27+
async fn unlock_async(
2728
&self,
2829
tx: &TransactionView,
2930
script_group: &ScriptGroup,
@@ -45,12 +46,14 @@ impl ScriptUnlocker for CapacityDiffUnlocker {
4546

4647
let mut total = 0i64;
4748
for i in &script_group.input_indices {
48-
let cell = tx_dep_provider.get_cell(
49-
&tx.inputs()
50-
.get(*i)
51-
.ok_or_else(|| other_unlock_error("input index out of bound"))?
52-
.previous_output(),
53-
)?;
49+
let cell = tx_dep_provider
50+
.get_cell_async(
51+
&tx.inputs()
52+
.get(*i)
53+
.ok_or_else(|| other_unlock_error("input index out of bound"))?
54+
.previous_output(),
55+
)
56+
.await?;
5457
let capacity: u64 = cell.capacity().unpack();
5558
total -= capacity as i64;
5659
}
@@ -71,7 +74,7 @@ impl ScriptUnlocker for CapacityDiffUnlocker {
7174

7275
// This is called before balancer. It's responsible to fill witness for inputs added manually
7376
// by users.
74-
fn fill_placeholder_witness(
77+
async fn fill_placeholder_witness_async(
7578
&self,
7679
tx: &TransactionView,
7780
script_group: &ScriptGroup,

rust-toolchain

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
1.75.0
1+
1.81.0

src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ pub mod test_util;
1616
#[cfg(test)]
1717
mod tests;
1818

19-
pub use rpc::{CkbRpcClient, IndexerRpcClient, RpcError};
19+
pub use rpc::{CkbRpcAsyncClient, CkbRpcClient, IndexerRpcAsyncClient, IndexerRpcClient, RpcError};
2020
pub use types::{
2121
Address, AddressPayload, AddressType, CodeHashIndex, HumanCapacity, NetworkInfo, NetworkType,
2222
OldAddress, OldAddressFormat, ScriptGroup, ScriptGroupType, ScriptId, Since, SinceType,

src/rpc/ckb.rs

Lines changed: 204 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ crate::jsonrpc!(pub struct CkbRpcClient {
110110
pub fn calculate_dao_maximum_withdraw(&self, out_point: OutPoint, kind: DaoWithdrawingCalculationKind) -> Capacity;
111111
});
112112

113-
crate::jsonrpc_async!(pub struct CkbRpcAyncClient {
113+
crate::jsonrpc_async!(pub struct CkbRpcAsyncClient {
114114
// Chain
115115
pub fn get_block(&self, hash: H256) -> Option<BlockView>;
116116
pub fn get_block_by_number(&self, number: BlockNumber) -> Option<BlockView>;
@@ -212,6 +212,15 @@ fn transform_cycles(cycles: Option<Vec<ckb_jsonrpc_types::Cycle>>) -> Vec<Cycle>
212212
.unwrap_or_default()
213213
}
214214

215+
impl From<&CkbRpcClient> for CkbRpcAsyncClient {
216+
fn from(value: &CkbRpcClient) -> Self {
217+
Self {
218+
client: value.client.clone(),
219+
id: 0.into(),
220+
}
221+
}
222+
}
223+
215224
impl CkbRpcClient {
216225
pub fn get_packed_block(&self, hash: H256) -> Result<Option<JsonBytes>, crate::RpcError> {
217226
self.post("get_block", (hash, Some(Uint32::from(0u32))))
@@ -386,3 +395,197 @@ impl CkbRpcClient {
386395
self.post::<_, Option<JsonBytes>>("get_fork_block", (block_hash, Some(Uint32::from(0u32))))
387396
}
388397
}
398+
399+
impl CkbRpcAsyncClient {
400+
pub async fn get_packed_block(&self, hash: H256) -> Result<Option<JsonBytes>, crate::RpcError> {
401+
self.post("get_block", (hash, Some(Uint32::from(0u32))))
402+
.await
403+
}
404+
405+
// turn block response into BlockView and cycle vec
406+
fn transform_block_view_with_cycle(
407+
opt_resp: Option<BlockResponse>,
408+
) -> Result<Option<(BlockView, Vec<Cycle>)>, crate::rpc::RpcError> {
409+
opt_resp
410+
.map(|resp| match resp {
411+
BlockResponse::Regular(block_view) => Ok((block_view.get_value()?, vec![])),
412+
BlockResponse::WithCycles(block_cycles) => {
413+
let cycles = transform_cycles(block_cycles.cycles);
414+
Ok((block_cycles.block.get_value()?, cycles))
415+
}
416+
})
417+
.transpose()
418+
}
419+
/// Same as get_block except with parameter with_cycles and return BlockResponse
420+
pub async fn get_block_with_cycles(
421+
&self,
422+
hash: H256,
423+
) -> Result<Option<(BlockView, Vec<Cycle>)>, crate::rpc::RpcError> {
424+
let res = self
425+
.post::<_, Option<BlockResponse>>("get_block", (hash, None::<u32>, true))
426+
.await?;
427+
Self::transform_block_view_with_cycle(res)
428+
}
429+
430+
// turn BlockResponse to JsonBytes and Cycle tuple
431+
fn blockresponse2bytes(
432+
opt_resp: Option<BlockResponse>,
433+
) -> Result<Option<(JsonBytes, Vec<Cycle>)>, crate::rpc::RpcError> {
434+
opt_resp
435+
.map(|resp| match resp {
436+
BlockResponse::Regular(block_view) => Ok((block_view.get_json_bytes()?, vec![])),
437+
BlockResponse::WithCycles(block_cycles) => {
438+
let cycles = transform_cycles(block_cycles.cycles);
439+
Ok((block_cycles.block.get_json_bytes()?, cycles))
440+
}
441+
})
442+
.transpose()
443+
}
444+
445+
pub async fn get_packed_block_with_cycles(
446+
&self,
447+
hash: H256,
448+
) -> Result<Option<(JsonBytes, Vec<Cycle>)>, crate::rpc::RpcError> {
449+
let res = self
450+
.post::<_, Option<BlockResponse>>("get_block", (hash, Some(Uint32::from(0u32)), true))
451+
.await?;
452+
Self::blockresponse2bytes(res)
453+
}
454+
455+
/// Same as get_block_by_number except with parameter with_cycles and return BlockResponse
456+
pub async fn get_packed_block_by_number(
457+
&self,
458+
number: BlockNumber,
459+
) -> Result<Option<JsonBytes>, crate::rpc::RpcError> {
460+
self.post("get_block_by_number", (number, Some(Uint32::from(0u32))))
461+
.await
462+
}
463+
464+
pub async fn get_block_by_number_with_cycles(
465+
&self,
466+
number: BlockNumber,
467+
) -> Result<Option<(BlockView, Vec<Cycle>)>, crate::rpc::RpcError> {
468+
let res = self
469+
.post::<_, Option<BlockResponse>>("get_block_by_number", (number, None::<u32>, true))
470+
.await?;
471+
Self::transform_block_view_with_cycle(res)
472+
}
473+
474+
pub async fn get_packed_block_by_number_with_cycles(
475+
&self,
476+
number: BlockNumber,
477+
) -> Result<Option<(JsonBytes, Vec<Cycle>)>, crate::rpc::RpcError> {
478+
let res = self
479+
.post::<_, Option<BlockResponse>>(
480+
"get_block_by_number",
481+
(number, Some(Uint32::from(0u32)), true),
482+
)
483+
.await?;
484+
Self::blockresponse2bytes(res)
485+
}
486+
487+
pub async fn get_packed_header(
488+
&self,
489+
hash: H256,
490+
) -> Result<Option<JsonBytes>, crate::rpc::RpcError> {
491+
self.post::<_, Option<JsonBytes>>("get_header", (hash, Some(Uint32::from(0u32))))
492+
.await
493+
}
494+
495+
pub async fn get_packed_header_by_number(
496+
&self,
497+
number: BlockNumber,
498+
) -> Result<Option<JsonBytes>, crate::rpc::RpcError> {
499+
self.post::<_, Option<JsonBytes>>(
500+
"get_header_by_number",
501+
(number, Some(Uint32::from(0u32))),
502+
)
503+
.await
504+
}
505+
506+
pub async fn get_live_cell_with_include_tx_pool(
507+
&self,
508+
out_point: OutPoint,
509+
with_data: bool,
510+
include_tx_pool: bool,
511+
) -> Result<CellWithStatus, crate::rpc::RpcError> {
512+
self.post::<_, CellWithStatus>(
513+
"get_live_cell",
514+
(out_point, with_data, Some(include_tx_pool)),
515+
)
516+
.await
517+
}
518+
519+
// get transaction with only_committed=true
520+
pub async fn get_only_committed_transaction(
521+
&self,
522+
hash: H256,
523+
) -> Result<TransactionWithStatusResponse, crate::rpc::RpcError> {
524+
self.post::<_, TransactionWithStatusResponse>(
525+
"get_transaction",
526+
(hash, Some(Uint32::from(2u32)), true),
527+
)
528+
.await
529+
}
530+
531+
// get transaction with verbosity=0
532+
pub async fn get_packed_transaction(
533+
&self,
534+
hash: H256,
535+
) -> Result<TransactionWithStatusResponse, crate::rpc::RpcError> {
536+
self.post::<_, TransactionWithStatusResponse>(
537+
"get_transaction",
538+
(hash, Some(Uint32::from(0u32))),
539+
)
540+
.await
541+
}
542+
543+
// get transaction with verbosity=0 and only_committed=true
544+
pub async fn get_only_committed_packed_transaction(
545+
&self,
546+
hash: H256,
547+
) -> Result<TransactionWithStatusResponse, crate::rpc::RpcError> {
548+
self.post::<_, TransactionWithStatusResponse>(
549+
"get_transaction",
550+
(hash, Some(Uint32::from(0u32)), true),
551+
)
552+
.await
553+
}
554+
555+
// get transaction with verbosity=1, so the result transaction field is None
556+
pub async fn get_transaction_status(
557+
&self,
558+
hash: H256,
559+
) -> Result<TransactionWithStatusResponse, crate::rpc::RpcError> {
560+
self.post::<_, TransactionWithStatusResponse>(
561+
"get_transaction",
562+
(hash, Some(Uint32::from(1u32))),
563+
)
564+
.await
565+
}
566+
567+
// get transaction with verbosity=1 and only_committed=true, so the result transaction field is None
568+
pub async fn get_only_committed_transaction_status(
569+
&self,
570+
hash: H256,
571+
) -> Result<TransactionWithStatusResponse, crate::rpc::RpcError> {
572+
self.post::<_, TransactionWithStatusResponse>(
573+
"get_transaction",
574+
(hash, Some(Uint32::from(1u32)), true),
575+
)
576+
.await
577+
}
578+
579+
pub async fn get_packed_tip_header(&self) -> Result<JsonBytes, crate::rpc::RpcError> {
580+
self.post::<_, JsonBytes>("get_tip_header", (Some(Uint32::from(0u32)),))
581+
.await
582+
}
583+
584+
pub async fn get_packed_fork_block(
585+
&self,
586+
block_hash: H256,
587+
) -> Result<Option<JsonBytes>, crate::rpc::RpcError> {
588+
self.post::<_, Option<JsonBytes>>("get_fork_block", (block_hash, Some(Uint32::from(0u32))))
589+
.await
590+
}
591+
}

src/rpc/ckb_indexer.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,3 +202,12 @@ crate::jsonrpc_async!(pub struct IndexerRpcAsyncClient {
202202
pub fn get_transactions(&self, search_key: SearchKey, order: Order, limit: Uint32, after: Option<JsonBytes>) -> Pagination<Tx>;
203203
pub fn get_cells_capacity(&self, search_key: SearchKey) -> Option<CellsCapacity>;
204204
});
205+
206+
impl From<&IndexerRpcClient> for IndexerRpcAsyncClient {
207+
fn from(value: &IndexerRpcClient) -> Self {
208+
Self {
209+
client: value.client.clone(),
210+
id: 0.into(),
211+
}
212+
}
213+
}

src/rpc/ckb_light_client.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,3 +199,12 @@ crate::jsonrpc_async!(pub struct LightClientRpcAsyncClient {
199199
pub fn get_peers(&self) -> Vec<RemoteNode>;
200200
pub fn local_node_info(&self) -> LocalNode;
201201
});
202+
203+
impl From<&LightClientRpcClient> for LightClientRpcAsyncClient {
204+
fn from(value: &LightClientRpcClient) -> Self {
205+
Self {
206+
client: value.client.clone(),
207+
id: 0.into(),
208+
}
209+
}
210+
}

0 commit comments

Comments
 (0)