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

feat: addition of subcommands for CKB Indexer RPC #579

Merged
merged 6 commits into from
Feb 20, 2024
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
38 changes: 30 additions & 8 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

48 changes: 47 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ hash: 0x0384ebc55b7cb56e51044743e05fb83a4edb7173524339c35df4c71fcdb0854d
### Example: Get live cell (json output format)
```
ckb-cli rpc get_live_cell --tx-hash 0x4ec75b5a8de8d180853d5046760a99285c73283a5dc528f81d6ee056f5335172 --index 0 --output-format json
ckb-cli rpc get_live_cell --tx-hash 0x4ec75b5a8de8d180853d5046760a99285c73283a5dc528f81d6ee056f5335172 --index 0
```

**Response:**
Expand All @@ -90,3 +90,49 @@ ckb-cli rpc get_live_cell --tx-hash 0x4ec75b5a8de8d180853d5046760a99285c73283a5d
"status": "live"
}
```

### Example: Indexer get cells (yaml output format)

Prepare file searchkey.json as input parameters:

```json
{
"script": {
"code_hash": "0xbbad126377d45f90a8ee120da988a2d7332c78ba8fd679aab478a19d6c133494",
"hash_type": "data1",
"args": "0x"
},
"script_type": "type",
"script_search_mode": "prefix",
"filter": {
"output_data": "0xa58618a553",
"output_data_filter_mode": "partial"
},
"with_data": false
}
```

```
ckb-cli rpc get_transactions --json-path ./searchkey.json --order asc --limit 3
```
Response:

```yaml
last_cursor: 0xa0bbad126377d45f90a8ee120da988a2d7332c78ba8fd679aab478a19d6c13349402013368282f4cde04254a3a6a2027b33f7c974046a4d5cbd96bc47d7f058c18090000000000b29e04000000050000000000
objects:
- block_number: 10375179
io_index: 1
io_type: output
tx_hash: 0x551ec96717c336b74bbb2e56a1cb9c73e2a9d4b56321079b454cfc1c0e6036ac
tx_index: 7
- block_number: 11705844
io_index: 0
io_type: output
tx_hash: 0xd690aa336c0d05808e08a97ba2f3031b7691341df9002b305c2d27cb116e2705
tx_index: 5
- block_number: 11705860
io_index: 0
io_type: input
tx_hash: 0xa3282c23227992933eee0a07e5cbf52ca62006b98f2d113ebf579c5e59cf5a62
tx_index: 5
```
169 changes: 167 additions & 2 deletions src/subcommands/rpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use crate::utils::arg_parser::{
FromStrParser, HexParser,
};
use crate::utils::rpc::{
BannedAddr, BlockEconomicState, BlockView, EpochView, HeaderView, HttpRpcClient,
parse_order, BannedAddr, BlockEconomicState, BlockView, EpochView, HeaderView, HttpRpcClient,
RawHttpRpcClient, RemoteNode, Timestamp, TransactionProof, TransactionWithStatus,
};

Expand Down Expand Up @@ -349,7 +349,82 @@ impl<'a> RpcSubCommand<'a> {
.validator(|input| HexParser.validate(input))
.about("Block assembler message (hex format)")
)
.about("[TEST ONLY] Generate an empty block")
.about("[TEST ONLY] Generate an empty block"),
// [`Indexer`]
App::new("get_indexer_tip").about("Returns the indexed tip"),
App::new("get_cells")
.arg(
Arg::with_name("json-path")
.long("json-path")
.takes_value(true)
.validator(|input| FilePathParser::new(true).validate(input))
.required(true)
.about("Indexer search key"))
.arg(
Arg::with_name("order")
.long("order")
.takes_value(true)
.possible_values(&["asc", "desc"])
.required(true)
.about("Indexer search order")
)
.arg(
Arg::with_name("limit")
.long("limit")
.takes_value(true)
.validator(|input| FromStrParser::<u64>::default().validate(input))
.required(true)
.about("Limit the number of results")
)
.arg(
Arg::with_name("after")
.long("after")
.takes_value(true)
.validator(|input| HexParser.validate(input))
.about("Pagination parameter")
)
.about("Returns the live cells collection by the lock or type script"),
App::new("get_transactions")
.arg(
Arg::with_name("json-path")
.long("json-path")
.takes_value(true)
.validator(|input| FilePathParser::new(true).validate(input))
.required(true)
.about("Indexer search key"))
.arg(
Arg::with_name("order")
.long("order")
.takes_value(true)
.possible_values(&["asc", "desc"])
.required(true)
.about("Indexer search order")
)
.arg(
Arg::with_name("limit")
.long("limit")
.takes_value(true)
.validator(|input| FromStrParser::<u64>::default().validate(input))
.required(true)
.about("Limit the number of results")
)
.arg(
Arg::with_name("after")
.long("after")
.takes_value(true)
.validator(|input| HexParser.validate(input))
.about("Pagination parameter")
)
.about("Returns the transactions collection by the lock or type script"),
App::new("get_cells_capacity")
.arg(
Arg::with_name("json-path")
.long("json-path")
.takes_value(true)
.validator(|input| FilePathParser::new(true).validate(input))
.required(true)
.about("Indexer search key"))
.about("Returns the live cells capacity by the lock or type script"),
])
}
}
Expand Down Expand Up @@ -1068,6 +1143,96 @@ impl<'a> CliSubCommand for RpcSubCommand<'a> {
.generate_block(script_opt, message_opt.map(JsonBytes::from_bytes))?;
Ok(Output::new_output(resp))
}
// [Indexer]
("get_indexer_tip", Some(m)) => {
let is_raw_data = is_raw_data || m.is_present("raw-data");
if is_raw_data {
let resp = self
.raw_rpc_client
.get_indexer_tip()
.map_err(|err| err.to_string())?;
Ok(Output::new_output(resp))
} else {
let resp = self.rpc_client.get_indexer_tip()?;
Ok(Output::new_output(resp))
}
}
("get_cells", Some(m)) => {
let json_path: PathBuf = FilePathParser::new(true)
.from_matches_opt(m, "json-path")?
.expect("json-path is required");
let content = fs::read_to_string(json_path).map_err(|err| err.to_string())?;
let search_key = serde_json::from_str(&content).map_err(|err| err.to_string())?;
let order_str = m.value_of("order").expect("order is required");
let order = parse_order(order_str)?;
let limit: u32 = FromStrParser::<u32>::default().from_matches(m, "limit")?;
let after_opt: Option<JsonBytes> = HexParser
.from_matches_opt::<Bytes>(m, "after")?
.map(JsonBytes::from_bytes);

let is_raw_data = is_raw_data || m.is_present("raw-data");
if is_raw_data {
let resp = self
.raw_rpc_client
.get_cells(search_key, order, limit.into(), after_opt)
.map_err(|err| err.to_string())?;
Ok(Output::new_output(resp))
} else {
let resp =
self.rpc_client
.get_cells(search_key, order, limit.into(), after_opt)?;
Ok(Output::new_output(resp))
}
}
("get_transactions", Some(m)) => {
let json_path: PathBuf = FilePathParser::new(true)
.from_matches_opt(m, "json-path")?
.expect("json-path is required");
let content = fs::read_to_string(json_path).map_err(|err| err.to_string())?;
let search_key = serde_json::from_str(&content).map_err(|err| err.to_string())?;
let order_str = m.value_of("order").expect("order is required");
let order = parse_order(order_str)?;
let limit: u32 = FromStrParser::<u32>::default().from_matches(m, "limit")?;
let after_opt: Option<JsonBytes> = HexParser
.from_matches_opt::<Bytes>(m, "after")?
.map(JsonBytes::from_bytes);

let is_raw_data = is_raw_data || m.is_present("raw-data");
if is_raw_data {
let resp = self
.raw_rpc_client
.get_transactions(search_key, order, limit.into(), after_opt)
.map_err(|err| err.to_string())?;
Ok(Output::new_output(resp))
} else {
let resp = self.rpc_client.get_transactions(
search_key,
order,
limit.into(),
after_opt,
)?;
Ok(Output::new_output(resp))
}
}
("get_cells_capacity", Some(m)) => {
let json_path: PathBuf = FilePathParser::new(true)
.from_matches_opt(m, "json-path")?
.expect("json-path is required");
let content = fs::read_to_string(json_path).map_err(|err| err.to_string())?;
let search_key = serde_json::from_str(&content).map_err(|err| err.to_string())?;

let is_raw_data = is_raw_data || m.is_present("raw-data");
if is_raw_data {
let resp = self
.raw_rpc_client
.get_cells_capacity(search_key)
.map_err(|err| err.to_string())?;
Ok(Output::new_output(resp))
} else {
let resp = self.rpc_client.get_cells_capacity(search_key)?;
Ok(Output::new_output(resp))
}
}
_ => Err(Self::subcommand().generate_usage()),
}
}
Expand Down
Loading
Loading