Skip to content

Commit 7450440

Browse files
authored
Merge pull request #228 from teonite/list_transactions_subcommand
Add `list-transactions` subcommand
2 parents 6c1eaf1 + 8251b0c commit 7450440

File tree

7 files changed

+167
-41
lines changed

7 files changed

+167
-41
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ jsonrpc-lite = "0.6.0"
4545
num-traits = "0.2.15"
4646
once_cell = "1.18.0"
4747
rand = "0.8.5"
48-
reqwest = { version = "0.12.5", features = ["json"] }
48+
reqwest = { version = "0.12.12", features = ["json"] }
4949
schemars = "0.8.18"
5050
serde = { version = "1", default-features = false, features = ["derive"] }
5151
serde-map-to-array = "1.1.1"

lib/error.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,10 @@ pub enum Error {
170170
/// Failed to construct HTTP client.
171171
#[error("failed to construct HTTP client")]
172172
FailedToConstructHttpClient,
173+
174+
/// Failed to parse provided node address as URL.
175+
#[error("failed to parse node address as valid URL")]
176+
FailedToParseNodeAddress,
173177
}
174178

175179
impl From<ToBytesError> for Error {

lib/json_rpc/call.rs

Lines changed: 33 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,17 @@
1+
#[cfg(not(target_arch = "wasm32"))]
2+
use std::time::Duration;
3+
14
use crate::{Error, JsonRpcId, SuccessResponse, Verbosity};
25
use jsonrpc_lite::{JsonRpc, Params};
36
use once_cell::sync::OnceCell;
4-
use reqwest::Client;
7+
use reqwest::{Client, Url};
58
use serde::{de::DeserializeOwned, Serialize};
69
use serde_json::json;
710

811
const RPC_API_PATH: &str = "rpc";
12+
#[cfg(not(target_arch = "wasm32"))]
13+
const REQUEST_TIMEOUT: Duration = Duration::from_secs(5);
14+
915
/// Statically declared client used when making HTTP requests
1016
/// so opened connections are pooled.
1117
static CLIENT: OnceCell<Client> = OnceCell::new();
@@ -14,32 +20,38 @@ static CLIENT: OnceCell<Client> = OnceCell::new();
1420
#[derive(Debug)]
1521
pub(crate) struct Call {
1622
rpc_id: JsonRpcId,
17-
node_address: String,
23+
node_address: Url,
1824
#[allow(dead_code)]
1925
verbosity: Verbosity,
2026
}
2127

2228
/// `Call` encapsulates JSON-RPC calls made to the casper node service.
2329
impl Call {
24-
pub(crate) fn new(rpc_id: JsonRpcId, node_address: &str, verbosity: Verbosity) -> Self {
25-
Self {
30+
pub(crate) fn new(
31+
rpc_id: JsonRpcId,
32+
node_address: &str,
33+
verbosity: Verbosity,
34+
) -> Result<Self, Error> {
35+
let url = if node_address.ends_with(RPC_API_PATH) {
36+
node_address.to_string()
37+
} else {
38+
format!("{}/{}", node_address, RPC_API_PATH)
39+
};
40+
41+
let node_address = Url::parse(&url).map_err(|_| Error::FailedToParseNodeAddress)?;
42+
Ok(Self {
2643
rpc_id,
27-
node_address: node_address.trim_end_matches('/').to_string(),
44+
// node_address: node_address.trim_end_matches('/').to_string(),
45+
node_address,
2846
verbosity,
29-
}
47+
})
3048
}
3149

3250
pub(crate) async fn send_request<P: Serialize, R: DeserializeOwned>(
3351
self,
3452
method: &'static str,
3553
maybe_params: Option<P>,
3654
) -> Result<SuccessResponse<R>, Error> {
37-
let url = if self.node_address.ends_with(RPC_API_PATH) {
38-
self.node_address
39-
} else {
40-
format!("{}/{}", self.node_address, RPC_API_PATH)
41-
};
42-
4355
let rpc_request = match maybe_params {
4456
Some(params) => {
4557
let params = Params::Map(
@@ -56,9 +68,16 @@ impl Call {
5668
#[cfg(feature = "std-fs-io")]
5769
crate::json_pretty_print(&rpc_request, self.verbosity)?;
5870

59-
let client = CLIENT.get_or_init(Client::new);
71+
let client = CLIENT.get_or_init(|| {
72+
let builder = Client::builder();
73+
74+
#[cfg(not(target_arch = "wasm32"))]
75+
let builder = builder.timeout(REQUEST_TIMEOUT);
76+
77+
builder.build().expect("failed to initialize HTTP client")
78+
});
6079
let http_response = client
61-
.post(&url)
80+
.post(self.node_address)
6281
.json(&rpc_request)
6382
.send()
6483
.await

lib/lib.rs

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ pub async fn put_deploy(
141141
verbosity: Verbosity,
142142
deploy: Deploy,
143143
) -> Result<SuccessResponse<PutDeployResult>, Error> {
144-
JsonRpcCall::new(rpc_id, node_address, verbosity)
144+
JsonRpcCall::new(rpc_id, node_address, verbosity)?
145145
.send_request(PUT_DEPLOY_METHOD, Some(PutDeployParams::new(deploy)))
146146
.await
147147
}
@@ -157,7 +157,7 @@ pub async fn put_transaction(
157157
verbosity: Verbosity,
158158
transaction: Transaction,
159159
) -> Result<SuccessResponse<PutTransactionResult>, Error> {
160-
JsonRpcCall::new(rpc_id, node_address, verbosity)
160+
JsonRpcCall::new(rpc_id, node_address, verbosity)?
161161
.send_request(
162162
PUT_TRANSACTION_METHOD,
163163
Some(PutTransactionParams::new(transaction)),
@@ -177,7 +177,7 @@ pub async fn speculative_exec(
177177
verbosity: Verbosity,
178178
deploy: Deploy,
179179
) -> Result<SuccessResponse<SpeculativeExecResult>, Error> {
180-
JsonRpcCall::new(rpc_id, node_address, verbosity)
180+
JsonRpcCall::new(rpc_id, node_address, verbosity)?
181181
.send_request(
182182
SPECULATIVE_EXEC_METHOD,
183183
Some(SpeculativeExecParams::new(deploy)),
@@ -196,7 +196,7 @@ pub async fn speculative_exec_txn(
196196
verbosity: Verbosity,
197197
transaction: Transaction,
198198
) -> Result<SuccessResponse<SpeculativeExecTxnResult>, Error> {
199-
JsonRpcCall::new(rpc_id, node_address, verbosity)
199+
JsonRpcCall::new(rpc_id, node_address, verbosity)?
200200
.send_request(
201201
SPECULATIVE_EXEC_TXN_METHOD,
202202
Some(SpeculativeExecTxnParams::new(transaction)),
@@ -318,7 +318,7 @@ pub async fn get_deploy(
318318
deploy_hash: DeployHash,
319319
finalized_approvals: bool,
320320
) -> Result<SuccessResponse<GetDeployResult>, Error> {
321-
JsonRpcCall::new(rpc_id, node_address, verbosity)
321+
JsonRpcCall::new(rpc_id, node_address, verbosity)?
322322
.send_request(
323323
GET_DEPLOY_METHOD,
324324
Some(GetDeployParams::new(deploy_hash, finalized_approvals)),
@@ -341,7 +341,7 @@ pub async fn get_transaction(
341341
transaction_hash: TransactionHash,
342342
finalized_approvals: bool,
343343
) -> Result<SuccessResponse<GetTransactionResult>, Error> {
344-
JsonRpcCall::new(rpc_id, node_address, verbosity)
344+
JsonRpcCall::new(rpc_id, node_address, verbosity)?
345345
.send_request(
346346
GET_TRANSACTION_METHOD,
347347
Some(GetTransactionParams::new(
@@ -364,7 +364,7 @@ pub async fn get_block(
364364
maybe_block_identifier: Option<BlockIdentifier>,
365365
) -> Result<SuccessResponse<GetBlockResult>, Error> {
366366
let params = maybe_block_identifier.map(GetBlockParams::new);
367-
let success_response = JsonRpcCall::new(rpc_id, node_address, verbosity)
367+
let success_response = JsonRpcCall::new(rpc_id, node_address, verbosity)?
368368
.send_request(GET_BLOCK_METHOD, params)
369369
.await?;
370370
validation::validate_get_block_result(maybe_block_identifier, &success_response.result)?;
@@ -383,7 +383,7 @@ pub async fn get_block_transfers(
383383
maybe_block_identifier: Option<BlockIdentifier>,
384384
) -> Result<SuccessResponse<GetBlockTransfersResult>, Error> {
385385
let params = maybe_block_identifier.map(GetBlockTransfersParams::new);
386-
JsonRpcCall::new(rpc_id, node_address, verbosity)
386+
JsonRpcCall::new(rpc_id, node_address, verbosity)?
387387
.send_request(GET_BLOCK_TRANSFERS_METHOD, params)
388388
.await
389389
}
@@ -400,7 +400,7 @@ pub async fn get_state_root_hash(
400400
maybe_block_identifier: Option<BlockIdentifier>,
401401
) -> Result<SuccessResponse<GetStateRootHashResult>, Error> {
402402
let params = maybe_block_identifier.map(GetStateRootHashParams::new);
403-
JsonRpcCall::new(rpc_id, node_address, verbosity)
403+
JsonRpcCall::new(rpc_id, node_address, verbosity)?
404404
.send_request(GET_STATE_ROOT_HASH_METHOD, params)
405405
.await
406406
}
@@ -417,7 +417,7 @@ pub async fn get_era_summary(
417417
maybe_block_identifier: Option<BlockIdentifier>,
418418
) -> Result<SuccessResponse<GetEraSummaryResult>, Error> {
419419
let params = maybe_block_identifier.map(GetEraSummaryParams::new);
420-
JsonRpcCall::new(rpc_id, node_address, verbosity)
420+
JsonRpcCall::new(rpc_id, node_address, verbosity)?
421421
.send_request(GET_ERA_SUMMARY_METHOD, params)
422422
.await
423423
}
@@ -445,7 +445,7 @@ pub async fn query_global_state(
445445
path: Vec<String>,
446446
) -> Result<SuccessResponse<QueryGlobalStateResult>, Error> {
447447
let params = QueryGlobalStateParams::new(global_state_identifier, key, path);
448-
JsonRpcCall::new(rpc_id, node_address, verbosity)
448+
JsonRpcCall::new(rpc_id, node_address, verbosity)?
449449
.send_request(QUERY_GLOBAL_STATE_METHOD, Some(params))
450450
.await
451451
}
@@ -463,7 +463,7 @@ pub async fn query_balance(
463463
purse_identifier: PurseIdentifier,
464464
) -> Result<SuccessResponse<QueryBalanceResult>, Error> {
465465
let params = QueryBalanceParams::new(maybe_global_state_identifier, purse_identifier);
466-
JsonRpcCall::new(rpc_id, node_address, verbosity)
466+
JsonRpcCall::new(rpc_id, node_address, verbosity)?
467467
.send_request(QUERY_BALANCE_METHOD, Some(params))
468468
.await
469469
}
@@ -481,7 +481,7 @@ pub async fn query_balance_details(
481481
purse_identifier: PurseIdentifier,
482482
) -> Result<SuccessResponse<QueryBalanceDetailsResult>, Error> {
483483
let params = QueryBalanceDetailsParams::new(maybe_global_state_identifier, purse_identifier);
484-
JsonRpcCall::new(rpc_id, node_address, verbosity)
484+
JsonRpcCall::new(rpc_id, node_address, verbosity)?
485485
.send_request(QUERY_BALANCE_DETAILS_METHOD, Some(params))
486486
.await
487487
}
@@ -499,7 +499,7 @@ pub async fn get_dictionary_item(
499499
dictionary_item_identifier: DictionaryItemIdentifier,
500500
) -> Result<SuccessResponse<GetDictionaryItemResult>, Error> {
501501
let params = GetDictionaryItemParams::new(state_root_hash, dictionary_item_identifier);
502-
JsonRpcCall::new(rpc_id, node_address, verbosity)
502+
JsonRpcCall::new(rpc_id, node_address, verbosity)?
503503
.send_request(GET_DICTIONARY_ITEM_METHOD, Some(params))
504504
.await
505505
}
@@ -517,7 +517,7 @@ pub async fn get_balance(
517517
purse: URef,
518518
) -> Result<SuccessResponse<GetBalanceResult>, Error> {
519519
let params = GetBalanceParams::new(state_root_hash, purse);
520-
JsonRpcCall::new(rpc_id, node_address, verbosity)
520+
JsonRpcCall::new(rpc_id, node_address, verbosity)?
521521
.send_request(GET_BALANCE_METHOD, Some(params))
522522
.await
523523
}
@@ -535,7 +535,7 @@ pub async fn get_account(
535535
account_identifier: AccountIdentifier,
536536
) -> Result<SuccessResponse<GetAccountResult>, Error> {
537537
let params = GetAccountParams::new(account_identifier, maybe_block_identifier);
538-
JsonRpcCall::new(rpc_id, node_address, verbosity)
538+
JsonRpcCall::new(rpc_id, node_address, verbosity)?
539539
.send_request(GET_ACCOUNT_METHOD, Some(params))
540540
.await
541541
}
@@ -553,7 +553,7 @@ pub async fn get_entity(
553553
entity_identifier: EntityIdentifier,
554554
) -> Result<SuccessResponse<GetAddressableEntityResult>, Error> {
555555
let params = GetAddressableEntityParams::new(entity_identifier, maybe_block_identifier);
556-
JsonRpcCall::new(rpc_id, node_address, verbosity)
556+
JsonRpcCall::new(rpc_id, node_address, verbosity)?
557557
.send_request(GET_ENTITY_METHOD, Some(params))
558558
.await
559559
}
@@ -572,7 +572,7 @@ pub async fn get_reward(
572572
delegator: Option<PublicKey>,
573573
) -> Result<SuccessResponse<GetRewardResult>, Error> {
574574
let params = GetRewardParams::new(maybe_era_identifier, validator, delegator);
575-
JsonRpcCall::new(rpc_id, node_address, verbosity)
575+
JsonRpcCall::new(rpc_id, node_address, verbosity)?
576576
.send_request(GET_REWARD_METHOD, Some(params))
577577
.await
578578
}
@@ -589,7 +589,7 @@ pub async fn get_auction_info(
589589
maybe_block_identifier: Option<BlockIdentifier>,
590590
) -> Result<SuccessResponse<GetAuctionInfoResult>, Error> {
591591
let params = maybe_block_identifier.map(GetAuctionInfoParams::new);
592-
JsonRpcCall::new(rpc_id, node_address, verbosity)
592+
JsonRpcCall::new(rpc_id, node_address, verbosity)?
593593
.send_request(GET_AUCTION_INFO_METHOD, params)
594594
.await
595595
}
@@ -604,7 +604,7 @@ pub async fn get_validator_changes(
604604
node_address: &str,
605605
verbosity: Verbosity,
606606
) -> Result<SuccessResponse<GetValidatorChangesResult>, Error> {
607-
JsonRpcCall::new(rpc_id, node_address, verbosity)
607+
JsonRpcCall::new(rpc_id, node_address, verbosity)?
608608
.send_request::<(), _>(GET_VALIDATOR_CHANGES_METHOD, None)
609609
.await
610610
}
@@ -619,7 +619,7 @@ pub async fn get_peers(
619619
node_address: &str,
620620
verbosity: Verbosity,
621621
) -> Result<SuccessResponse<GetPeersResult>, Error> {
622-
JsonRpcCall::new(rpc_id, node_address, verbosity)
622+
JsonRpcCall::new(rpc_id, node_address, verbosity)?
623623
.send_request::<(), _>(GET_PEERS_METHOD, None)
624624
.await
625625
}
@@ -634,7 +634,7 @@ pub async fn get_node_status(
634634
node_address: &str,
635635
verbosity: Verbosity,
636636
) -> Result<SuccessResponse<GetNodeStatusResult>, Error> {
637-
JsonRpcCall::new(rpc_id, node_address, verbosity)
637+
JsonRpcCall::new(rpc_id, node_address, verbosity)?
638638
.send_request::<(), _>(GET_NODE_STATUS_METHOD, None)
639639
.await
640640
}
@@ -649,7 +649,7 @@ pub async fn get_chainspec(
649649
node_address: &str,
650650
verbosity: Verbosity,
651651
) -> Result<SuccessResponse<GetChainspecResult>, Error> {
652-
JsonRpcCall::new(rpc_id, node_address, verbosity)
652+
JsonRpcCall::new(rpc_id, node_address, verbosity)?
653653
.send_request::<(), _>(GET_CHAINSPEC_METHOD, None)
654654
.await
655655
}
@@ -665,7 +665,7 @@ pub async fn list_rpcs(
665665
node_address: &str,
666666
verbosity: Verbosity,
667667
) -> Result<SuccessResponse<ListRpcsResult>, Error> {
668-
JsonRpcCall::new(rpc_id, node_address, verbosity)
668+
JsonRpcCall::new(rpc_id, node_address, verbosity)?
669669
.send_request::<(), _>(LIST_RPCS_METHOD, None)
670670
.await
671671
}
@@ -761,7 +761,7 @@ pub async fn get_era_info(
761761
maybe_block_identifier: Option<BlockIdentifier>,
762762
) -> Result<SuccessResponse<GetEraInfoResult>, Error> {
763763
let params = maybe_block_identifier.map(GetEraInfoParams::new);
764-
JsonRpcCall::new(rpc_id, node_address, verbosity)
764+
JsonRpcCall::new(rpc_id, node_address, verbosity)?
765765
.send_request(GET_ERA_INFO_METHOD, params)
766766
.await
767767
}

src/main.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,9 @@ use keygen::Keygen;
5858
use list_rpcs::ListRpcs;
5959
use query_balance::QueryBalance;
6060
use query_global_state::QueryGlobalState;
61-
use transaction::{MakeTransaction, PutTransaction, SendTransaction, SignTransaction};
61+
use transaction::{
62+
ListTransactions, MakeTransaction, PutTransaction, SendTransaction, SignTransaction,
63+
};
6264
use verify_contract::VerifyContract;
6365

6466
const APP_NAME: &str = "Casper client";
@@ -95,6 +97,7 @@ enum DisplayOrder {
9597
GetBlock,
9698
GetBlockTransfers,
9799
ListDeploys,
100+
ListTransactions,
98101
GetStateRootHash,
99102
GetEraSummary,
100103
GetEraInfo,
@@ -145,6 +148,9 @@ fn cli() -> Command {
145148
DisplayOrder::GetBlockTransfers as usize,
146149
))
147150
.subcommand(ListDeploys::build(DisplayOrder::ListDeploys as usize))
151+
.subcommand(ListTransactions::build(
152+
DisplayOrder::ListTransactions as usize,
153+
))
148154
.subcommand(GetStateRootHash::build(
149155
DisplayOrder::GetStateRootHash as usize,
150156
))
@@ -205,6 +211,7 @@ async fn main() {
205211
GetBlock::NAME => GetBlock::run(matches).await,
206212
GetBlockTransfers::NAME => GetBlockTransfers::run(matches).await,
207213
ListDeploys::NAME => ListDeploys::run(matches).await,
214+
ListTransactions::NAME => ListTransactions::run(matches).await,
208215
GetStateRootHash::NAME => GetStateRootHash::run(matches).await,
209216
GetEraSummary::NAME => GetEraSummary::run(matches).await,
210217
GetEraInfo::NAME => GetEraInfo::run(matches).await,

src/transaction.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
mod creation_common;
22
mod get;
3+
mod list;
34
mod make;
45
mod put;
56
mod send;
67
mod sign;
78

89
pub use get::GetTransaction;
10+
pub use list::ListTransactions;
911
pub use make::MakeTransaction;
1012
pub use put::PutTransaction;
1113
pub use send::SendTransaction;

0 commit comments

Comments
 (0)