From 5c6ab41e1bc4df87f7dfafad39c49608a7621d3c Mon Sep 17 00:00:00 2001 From: Marko Petrlic Date: Mon, 2 Dec 2024 18:32:38 +0100 Subject: [PATCH] Enabled RPC recconection --- avail-rust/Cargo.toml | 6 +- avail-rust/docs/book/src/SUMMARY.md | 1 - .../book/src/examples/insecure_connection.md | 5 - .../book/src/examples/insecure_connection.rs | 6 - avail-rust/docs/book/src/examples/mod.rs | 2 - avail-rust/src/account.rs | 5 +- avail-rust/src/block.rs | 14 +- avail-rust/src/error.rs | 18 ++ avail-rust/src/rpcs.rs | 241 +++++++++--------- avail-rust/src/sdk.rs | 59 +++-- avail-rust/src/transactions/balances.rs | 2 +- avail-rust/src/transactions/da.rs | 2 +- avail-rust/src/transactions/mod.rs | 5 +- avail-rust/src/transactions/nom_pools.rs | 2 +- avail-rust/src/transactions/options.rs | 2 +- avail-rust/src/transactions/session.rs | 2 +- avail-rust/src/transactions/staking.rs | 2 +- avail-rust/src/utils.rs | 14 +- 18 files changed, 219 insertions(+), 169 deletions(-) delete mode 100644 avail-rust/docs/book/src/examples/insecure_connection.md delete mode 100644 avail-rust/docs/book/src/examples/insecure_connection.rs diff --git a/avail-rust/Cargo.toml b/avail-rust/Cargo.toml index c1a58a3d3..c19c21263 100644 --- a/avail-rust/Cargo.toml +++ b/avail-rust/Cargo.toml @@ -12,7 +12,7 @@ crate-type = ["cdylib", "rlib"] [target.'cfg(not(target_arch = "wasm32"))'.dependencies] derive_more = { version = "1", features = ["full"] } kate-recovery = { git = "https://github.com/availproject/avail-core", tag = "core-node-4", features = ["serde"] } -subxt = { version = "0.38.0" } +subxt = { version = "0.38.0", features = ["reconnecting-rpc-client"] } subxt-core = { version = "0.38.0" } subxt-signer = { version = "0.38.0" } tokio = { version = "1.21.2" } @@ -20,7 +20,7 @@ tokio = { version = "1.21.2" } [target.'cfg(target_arch = "wasm32")'.dependencies] derive_more = { version = "1", default-features = false, features = ["from", "constructor"] } kate-recovery = { git = "https://github.com/availproject/avail-core", default-features = false, tag = "core-node-4", features = ["serde"] } -subxt = { version = "0.38.0", default-features = false, features = ["web", "jsonrpsee"] } +subxt = { version = "0.38.0", default-features = false, features = ["web", "jsonrpsee", "reconnecting-rpc-client"] } subxt-core = { version = "0.38.0", default-features = false } subxt-signer = { version = "0.38.0", default-features = false, features = ["web", "sr25519", "subxt"] } tokio = { version = "1.21.2", default-features = false } @@ -28,7 +28,7 @@ sp-io = { version = "30", default-features = false, features = [ "disable_panic_ [dependencies] serde = { version = "1.0.195", features = ["derive", ] } -serde_json = { version = "1.0.124" } +serde_json = { version = "1.0.124", features = ["raw_value"] } codec = { package = "parity-scale-codec", version = "3", default-features = false, features = [ "derive", "full", diff --git a/avail-rust/docs/book/src/SUMMARY.md b/avail-rust/docs/book/src/SUMMARY.md index 28cbed96c..715ccbcc6 100644 --- a/avail-rust/docs/book/src/SUMMARY.md +++ b/avail-rust/docs/book/src/SUMMARY.md @@ -9,6 +9,5 @@ - [Events](./examples/events.md) - [Transactions](./examples/transactions.md) - [Validator](./examples/validator.md) - - [Insecure Connection](./examples/insecure_connection.md) - [Batch](./examples/batch.md) diff --git a/avail-rust/docs/book/src/examples/insecure_connection.md b/avail-rust/docs/book/src/examples/insecure_connection.md deleted file mode 100644 index f9c19967a..000000000 --- a/avail-rust/docs/book/src/examples/insecure_connection.md +++ /dev/null @@ -1,5 +0,0 @@ -# Insecure Connection - -```rs -{{#include ./insecure_connection.rs}} -``` diff --git a/avail-rust/docs/book/src/examples/insecure_connection.rs b/avail-rust/docs/book/src/examples/insecure_connection.rs deleted file mode 100644 index 587ea7bb3..000000000 --- a/avail-rust/docs/book/src/examples/insecure_connection.rs +++ /dev/null @@ -1,6 +0,0 @@ -use avail_rust::{error::ClientError, SDK}; - -pub async fn run() -> Result<(), ClientError> { - let _ = SDK::new_insecure(SDK::local_endpoint()).await?; - Ok(()) -} diff --git a/avail-rust/docs/book/src/examples/mod.rs b/avail-rust/docs/book/src/examples/mod.rs index ba38b6c78..6ca609ecc 100644 --- a/avail-rust/docs/book/src/examples/mod.rs +++ b/avail-rust/docs/book/src/examples/mod.rs @@ -1,7 +1,6 @@ mod batch; mod data_submission; mod events; -mod insecure_connection; mod transactions; mod validator; @@ -10,7 +9,6 @@ use avail_rust::error::ClientError; pub async fn run() -> Result<(), ClientError> { data_submission::run().await?; events::run().await?; - insecure_connection::run().await?; transactions::run().await?; validator::run().await?; batch::run().await?; diff --git a/avail-rust/src/account.rs b/avail-rust/src/account.rs index 7584c8c48..6619a38fc 100644 --- a/avail-rust/src/account.rs +++ b/avail-rust/src/account.rs @@ -1,5 +1,8 @@ use std::str::FromStr; -use subxt::{backend::rpc::RpcClient, blocks::StaticExtrinsic, ext::scale_encode::EncodeAsFields}; +use subxt::{ + backend::rpc::reconnecting_rpc_client::RpcClient, blocks::StaticExtrinsic, + ext::scale_encode::EncodeAsFields, +}; use crate::{ avail, diff --git a/avail-rust/src/block.rs b/avail-rust/src/block.rs index 156251508..630b5a277 100644 --- a/avail-rust/src/block.rs +++ b/avail-rust/src/block.rs @@ -9,7 +9,7 @@ use crate::{ }; use primitive_types::H256; -use subxt::backend::rpc::RpcClient; +use subxt::backend::rpc::reconnecting_rpc_client::RpcClient; use subxt::backend::StreamOfResults; use subxt::blocks::StaticExtrinsic; use subxt::storage::StorageKeyValuePair; @@ -21,7 +21,7 @@ pub struct Block { } impl Block { - pub async fn new(client: &AOnlineClient, block_hash: H256) -> Result { + pub async fn new(client: &AOnlineClient, block_hash: H256) -> Result { let (block, transactions) = fetch_transactions(client, block_hash).await?; Ok(Self { block, @@ -32,7 +32,7 @@ impl Block { pub async fn new_best_block( online_client: &AOnlineClient, rpc_client: &RpcClient, - ) -> Result { + ) -> Result { let block_hash = Self::fetch_best_block_hash(rpc_client).await?; Self::new(online_client, block_hash).await } @@ -40,7 +40,7 @@ impl Block { pub async fn new_finalized_block( online_client: &AOnlineClient, rpc_client: &RpcClient, - ) -> Result { + ) -> Result { let block_hash = Self::fetch_finalized_block_hash(rpc_client).await?; Self::new(online_client, block_hash).await } @@ -57,7 +57,7 @@ impl Block { online_client: &AOnlineClient, rpc_client: &RpcClient, block_number: u32, - ) -> Result { + ) -> Result { let block_hash = rpcs::get_block_hash(rpc_client, Some(block_number)).await?; Self::new(online_client, block_hash).await } @@ -176,11 +176,11 @@ impl Block { self.block.storage().iter(address).await } - pub async fn fetch_best_block_hash(client: &RpcClient) -> Result { + pub async fn fetch_best_block_hash(client: &RpcClient) -> Result { rpcs::get_block_hash(client, None).await } - pub async fn fetch_finalized_block_hash(client: &RpcClient) -> Result { + pub async fn fetch_finalized_block_hash(client: &RpcClient) -> Result { rpcs::get_finalized_head(client).await } } diff --git a/avail-rust/src/error.rs b/avail-rust/src/error.rs index ade7e0a07..d23b22145 100644 --- a/avail-rust/src/error.rs +++ b/avail-rust/src/error.rs @@ -5,10 +5,14 @@ use subxt_signer::SecretUriError; use crate::transactions::TransactionFailed; use crate::utils::TransactionExecutionError; +type RpcError = subxt::backend::rpc::reconnecting_rpc_client::Error; + #[derive(Debug)] pub enum ClientError { Custom(String), TransactionExecution(TransactionExecutionError), + RpcError(RpcError), + SerdeJson(serde_json::Error), Subxt(subxt::Error), SubxtSigner(SecretUriError), Sr25519(sr25519::Error), @@ -19,6 +23,8 @@ impl ClientError { match self { ClientError::Custom(e) => e.clone(), ClientError::TransactionExecution(e) => e.to_string(), + ClientError::RpcError(e) => e.to_string(), + ClientError::SerdeJson(e) => e.to_string(), ClientError::Subxt(e) => e.to_string(), ClientError::SubxtSigner(e) => e.to_string(), ClientError::Sr25519(e) => e.to_string(), @@ -67,3 +73,15 @@ impl From for ClientError { value.reason } } + +impl From for ClientError { + fn from(value: RpcError) -> Self { + Self::RpcError(value) + } +} + +impl From for ClientError { + fn from(value: serde_json::Error) -> Self { + Self::SerdeJson(value) + } +} diff --git a/avail-rust/src/rpcs.rs b/avail-rust/src/rpcs.rs index 5d6666f9c..1e9ae5709 100644 --- a/avail-rust/src/rpcs.rs +++ b/avail-rust/src/rpcs.rs @@ -1,13 +1,11 @@ use avail_core::data_proof::ProofResponse; -use subxt::backend::legacy::LegacyRpcMethods; use crate::avail::runtime_types::frame_system::limits::BlockLength; +use crate::error::ClientError; use crate::from_substrate::{FeeDetails, NodeRole, PeerInfo, RuntimeDispatchInfo, SyncState}; -use crate::{ - ABlockDetailsRPC, AvailConfig, AvailHeader, BlockHash, BlockNumber, Cell, GDataProof, GRow, -}; +use crate::{ABlockDetailsRPC, AvailHeader, BlockHash, BlockNumber, Cell, GDataProof, GRow}; use subxt::backend::legacy::rpc_methods::{Bytes, SystemHealth}; -use subxt::backend::rpc::RpcClient; +use subxt::backend::rpc::reconnecting_rpc_client::RpcClient; use subxt::rpc_params; /// Arbitrary properties defined in chain spec as a JSON object @@ -16,7 +14,6 @@ pub type Properties = serde_json::map::Map; #[derive(Clone)] pub struct Rpc { pub client: RpcClient, - pub legacy_methods: LegacyRpcMethods, pub kate: Kate, pub author: Author, pub chain: Chain, @@ -26,7 +23,6 @@ pub struct Rpc { impl Rpc { pub async fn new(client: RpcClient) -> Self { - let legacy_methods = LegacyRpcMethods::new(client.clone()); let kate = Kate::new(client.clone()); let author = Author::new(client.clone()); let chain: Chain = Chain::new(client.clone()); @@ -35,7 +31,6 @@ impl Rpc { Self { client, - legacy_methods, kate, author, chain, @@ -59,7 +54,7 @@ impl Payment { &self, extrinsic: Bytes, at: Option, - ) -> Result { + ) -> Result { query_fee_details(&self.client, extrinsic, at).await } @@ -67,7 +62,7 @@ impl Payment { &self, extrinsic: Bytes, at: Option, - ) -> Result { + ) -> Result { query_info(&self.client, extrinsic, at).await } } @@ -76,22 +71,22 @@ pub async fn query_fee_details( client: &RpcClient, extrinsic: Bytes, at: Option, -) -> Result { - let value: FeeDetails = client - .request("payment_queryFeeDetails", rpc_params![extrinsic, at]) +) -> Result { + let params = rpc_params![extrinsic, at].build(); + let value = client + .request("payment_queryFeeDetails".into(), params) .await?; - Ok(value) + Ok(serde_json::from_str(value.get())?) } pub async fn query_info( client: &RpcClient, extrinsic: Bytes, at: Option, -) -> Result { - let value: RuntimeDispatchInfo = client - .request("payment_queryInfo", rpc_params![extrinsic, at]) - .await?; - Ok(value) +) -> Result { + let params = rpc_params![extrinsic, at].build(); + let value = client.request("payment_queryInfo".into(), params).await?; + Ok(serde_json::from_str(value.get())?) } #[derive(Clone)] @@ -104,117 +99,129 @@ impl System { Self { client } } - pub async fn account_next_index(&self, account: String) -> Result { + pub async fn account_next_index(&self, account: String) -> Result { account_next_index(&self.client, account).await } - pub async fn chain(&self) -> Result { + pub async fn chain(&self) -> Result { chain(&self.client).await } - pub async fn chain_type(&self) -> Result { + pub async fn chain_type(&self) -> Result { chain_type(&self.client).await } - pub async fn health(&self) -> Result { + pub async fn health(&self) -> Result { health(&self.client).await } - pub async fn local_listen_addresses(&self) -> Result, subxt::Error> { + pub async fn local_listen_addresses(&self) -> Result, ClientError> { local_listen_addresses(&self.client).await } - pub async fn local_peer_id(&self) -> Result { + pub async fn local_peer_id(&self) -> Result { local_peer_id(&self.client).await } - pub async fn name(&self) -> Result { + pub async fn name(&self) -> Result { name(&self.client).await } - pub async fn node_roles(&self) -> Result, subxt::Error> { + pub async fn node_roles(&self) -> Result, ClientError> { node_roles(&self.client).await } - pub async fn peers(&self) -> Result, subxt::Error> { + pub async fn peers(&self) -> Result, ClientError> { peers(&self.client).await } - pub async fn properties(&self) -> Result { + pub async fn properties(&self) -> Result { properties(&self.client).await } - pub async fn sync_state(&self) -> Result { + pub async fn sync_state(&self) -> Result { sync_state(&self.client).await } - pub async fn version(&self) -> Result { + pub async fn version(&self) -> Result { version(&self.client).await } } -pub async fn account_next_index(client: &RpcClient, account: String) -> Result { - let value: u32 = client - .request("system_accountNextIndex", rpc_params![account]) +pub async fn account_next_index(client: &RpcClient, account: String) -> Result { + let params = rpc_params![account].build(); + let value = client + .request("system_accountNextIndex".into(), params) .await?; - Ok(value) + Ok(serde_json::from_str(value.get())?) } -pub async fn chain(client: &RpcClient) -> Result { - let value: String = client.request("system_chain", rpc_params![]).await?; - Ok(value) +pub async fn chain(client: &RpcClient) -> Result { + let params = rpc_params![].build(); + let value = client.request("system_chain".into(), params).await?; + Ok(serde_json::from_str(value.get())?) } -pub async fn chain_type(client: &RpcClient) -> Result { - let value: String = client.request("system_chainType", rpc_params![]).await?; - Ok(value) +pub async fn chain_type(client: &RpcClient) -> Result { + let params = rpc_params![].build(); + let value = client.request("system_chainType".into(), params).await?; + Ok(serde_json::from_str(value.get())?) } -pub async fn health(client: &RpcClient) -> Result { - let value: SystemHealth = client.request("system_health", rpc_params![]).await?; - Ok(value) +pub async fn health(client: &RpcClient) -> Result { + let params = rpc_params![].build(); + let value = client.request("system_health".into(), params).await?; + Ok(serde_json::from_str(value.get())?) } -pub async fn local_listen_addresses(client: &RpcClient) -> Result, subxt::Error> { - let value: Vec = client - .request("system_localListenAddresses", rpc_params![]) +pub async fn local_listen_addresses(client: &RpcClient) -> Result, ClientError> { + let params = rpc_params![].build(); + let value = client + .request("system_localListenAddresses".into(), params) .await?; - Ok(value) + Ok(serde_json::from_str(value.get())?) } -pub async fn local_peer_id(client: &RpcClient) -> Result { - let value: String = client.request("system_localPeerId", rpc_params![]).await?; - Ok(value) +pub async fn local_peer_id(client: &RpcClient) -> Result { + let params = rpc_params![].build(); + let value = client.request("system_localPeerId".into(), params).await?; + Ok(serde_json::from_str(value.get())?) } -pub async fn name(client: &RpcClient) -> Result { - let value: String = client.request("system_name", rpc_params![]).await?; - Ok(value) +pub async fn name(client: &RpcClient) -> Result { + let params = rpc_params![].build(); + let value = client.request("system_name".into(), params).await?; + Ok(serde_json::from_str(value.get())?) } -pub async fn node_roles(client: &RpcClient) -> Result, subxt::Error> { - let value: Vec = client.request("system_nodeRoles", rpc_params![]).await?; - Ok(value) +pub async fn node_roles(client: &RpcClient) -> Result, ClientError> { + let params = rpc_params![].build(); + let value = client.request("system_nodeRoles".into(), params).await?; + Ok(serde_json::from_str(value.get())?) } -pub async fn peers(client: &RpcClient) -> Result, subxt::Error> { - let value: Vec = client.request("system_peers", rpc_params![]).await?; - Ok(value) +pub async fn peers(client: &RpcClient) -> Result, ClientError> { + let params = rpc_params![].build(); + let value = client.request("system_peers".into(), params).await?; + Ok(serde_json::from_str(value.get())?) } -pub async fn properties(client: &RpcClient) -> Result { - let value: Properties = client.request("system_properties", rpc_params![]).await?; - Ok(value) +pub async fn properties(client: &RpcClient) -> Result { + let params = rpc_params![].build(); + let value = client.request("system_properties".into(), params).await?; + Ok(serde_json::from_str(value.get())?) } -pub async fn sync_state(client: &RpcClient) -> Result { - let value: SyncState = client.request("system_syncState", rpc_params![]).await?; - Ok(value) +pub async fn sync_state(client: &RpcClient) -> Result { + let params = rpc_params![].build(); + let value = client.request("system_syncState".into(), params).await?; + Ok(serde_json::from_str(value.get())?) } -pub async fn version(client: &RpcClient) -> Result { - let value: String = client.request("system_version", rpc_params![]).await?; - Ok(value) +pub async fn version(client: &RpcClient) -> Result { + let params = rpc_params![].build(); + let value = client.request("system_version".into(), params).await?; + Ok(serde_json::from_str(value.get())?) } #[derive(Clone)] @@ -227,22 +234,22 @@ impl Chain { Self { client } } - pub async fn get_block(&self, at: Option) -> Result { + pub async fn get_block(&self, at: Option) -> Result { get_block(&self.client, at).await } pub async fn get_block_hash( &self, block_number: Option, - ) -> Result { + ) -> Result { get_block_hash(&self.client, block_number).await } - pub async fn get_finalized_head(&self) -> Result { + pub async fn get_finalized_head(&self) -> Result { get_finalized_head(&self.client).await } - pub async fn get_header(&self, at: Option) -> Result { + pub async fn get_header(&self, at: Option) -> Result { get_header(&self.client, at).await } } @@ -250,16 +257,17 @@ impl Chain { pub async fn get_block( client: &RpcClient, at: Option, -) -> Result { - let value: ABlockDetailsRPC = client.request("chain_getBlock", rpc_params![at]).await?; - Ok(value) +) -> Result { + let params = rpc_params![at].build(); + let value = client.request("chain_getBlock".into(), params).await?; + Ok(serde_json::from_str(value.get())?) } -pub async fn get_best_block(client: &RpcClient) -> Result { +pub async fn get_best_block(client: &RpcClient) -> Result { get_block(client, None).await } -pub async fn get_finalized_block(client: &RpcClient) -> Result { +pub async fn get_finalized_block(client: &RpcClient) -> Result { let hash = get_finalized_head(client).await?; get_block(client, Some(hash)).await } @@ -267,26 +275,27 @@ pub async fn get_finalized_block(client: &RpcClient) -> Result, -) -> Result { - let value: BlockHash = client - .request("chain_getBlockHash", rpc_params![block_number]) - .await?; - Ok(value) +) -> Result { + let params = rpc_params![block_number].build(); + let value = client.request("chain_getBlockHash".into(), params).await?; + Ok(serde_json::from_str(value.get())?) } -pub async fn get_finalized_head(client: &RpcClient) -> Result { - let value: BlockHash = client - .request("chain_getFinalizedHead", rpc_params![]) +pub async fn get_finalized_head(client: &RpcClient) -> Result { + let params = rpc_params![].build(); + let value = client + .request("chain_getFinalizedHead".into(), params) .await?; - Ok(value) + Ok(serde_json::from_str(value.get())?) } pub async fn get_header( client: &RpcClient, at: Option, -) -> Result { - let value: AvailHeader = client.request("chain_getHeader", rpc_params![at]).await?; - Ok(value) +) -> Result { + let params = rpc_params![at].build(); + let value = client.request("chain_getHeader".into(), params).await?; + Ok(serde_json::from_str(value.get())?) } #[derive(Clone)] @@ -299,14 +308,16 @@ impl Author { Self { client } } - pub async fn rotate_keys(&self) -> Result, subxt::Error> { + pub async fn rotate_keys(&self) -> Result, ClientError> { rotate_keys(&self.client).await } } -pub async fn rotate_keys(client: &RpcClient) -> Result, subxt::Error> { - let bytes: Bytes = client.request("author_rotateKeys", rpc_params![]).await?; - Ok(bytes.0) +pub async fn rotate_keys(client: &RpcClient) -> Result, ClientError> { + let params = rpc_params![].build(); + let value = client.request("author_rotateKeys".into(), params).await?; + let value: Bytes = serde_json::from_str(value.get())?; + Ok(value.0) } #[derive(Clone)] @@ -319,7 +330,7 @@ impl Kate { Self { client } } - pub async fn block_length(&self, at: Option) -> Result { + pub async fn block_length(&self, at: Option) -> Result { block_length(&self.client, at).await } @@ -327,7 +338,7 @@ impl Kate { &self, transaction_index: u32, at: Option, - ) -> Result { + ) -> Result { query_data_proof(&self.client, transaction_index, at).await } @@ -335,7 +346,7 @@ impl Kate { &self, cells: Vec, at: Option, - ) -> Result, subxt::Error> { + ) -> Result, ClientError> { query_proof(&self.client, cells, at).await } @@ -343,7 +354,7 @@ impl Kate { &self, rows: Vec, at: Option, - ) -> Result, subxt::Error> { + ) -> Result, ClientError> { query_rows(&self.client, rows, at).await } } @@ -351,40 +362,38 @@ impl Kate { pub async fn block_length( client: &RpcClient, at: Option, -) -> Result { - let result: BlockLength = client.request("kate_blockLength", rpc_params![at]).await?; - Ok(result) +) -> Result { + let params = rpc_params![at].build(); + let value = client.request("kate_blockLength".into(), params).await?; + Ok(serde_json::from_str(value.get())?) } pub async fn query_data_proof( client: &RpcClient, transaction_index: u32, at: Option, -) -> Result { - let result: ProofResponse = client - .request("kate_queryDataProof", rpc_params![transaction_index, at]) - .await?; - Ok(result) +) -> Result { + let params = rpc_params![transaction_index, at].build(); + let value = client.request("kate_queryDataProof".into(), params).await?; + Ok(serde_json::from_str(value.get())?) } pub async fn query_proof( client: &RpcClient, cells: Vec, at: Option, -) -> Result, subxt::Error> { - let result: Vec = client - .request("kate_queryProof", rpc_params![cells, at]) - .await?; - Ok(result) +) -> Result, ClientError> { + let params = rpc_params![cells, at].build(); + let value = client.request("kate_queryProof".into(), params).await?; + Ok(serde_json::from_str(value.get())?) } pub async fn query_rows( client: &RpcClient, rows: Vec, at: Option, -) -> Result, subxt::Error> { - let result: Vec = client - .request("kate_queryRows", rpc_params![rows, at]) - .await?; - Ok(result) +) -> Result, ClientError> { + let params = rpc_params![rows, at].build(); + let value = client.request("kate_queryRows".into(), params).await?; + Ok(serde_json::from_str(value.get())?) } diff --git a/avail-rust/src/sdk.rs b/avail-rust/src/sdk.rs index 73cc73262..36ffb3aa5 100644 --- a/avail-rust/src/sdk.rs +++ b/avail-rust/src/sdk.rs @@ -1,6 +1,6 @@ -use std::str::FromStr; +use std::{str::FromStr, time::Duration}; -use subxt::backend::rpc::RpcClient; +use subxt::backend::rpc::reconnecting_rpc_client::{ExponentialBackoff, RpcClient}; use subxt_signer::{sr25519::Keypair, SecretUri}; use crate::{error::ClientError, rpcs::Rpc, transactions::Transactions, AOnlineClient}; @@ -15,16 +15,28 @@ pub struct SDK { impl SDK { pub async fn new(endpoint: &str) -> Result { - Self::new_inner(endpoint, true).await - } + env_logger::builder().init(); + let (online_client, rpc_client) = initialize_api(endpoint).await?; - pub async fn new_insecure(endpoint: &str) -> Result { - Self::new_inner(endpoint, false).await + let rpc = Rpc::new(rpc_client.clone()).await; + let tx = Transactions::new(online_client.clone(), rpc_client.clone()); + + Ok(SDK { + online_client, + rpc_client, + tx, + rpc, + }) } - async fn new_inner(endpoint: &str, secure: bool) -> Result { - env_logger::builder().format_timestamp_millis().init(); - let (online_client, rpc_client) = initialize_api(endpoint, secure).await?; + pub async fn new_custom( + online_client: AOnlineClient, + rpc_client: RpcClient, + enable_logging: bool, + ) -> Result { + if enable_logging { + env_logger::builder().init(); + } let rpc = Rpc::new(rpc_client.clone()).await; let tx = Transactions::new(online_client.clone(), rpc_client.clone()); @@ -37,6 +49,10 @@ impl SDK { }) } + fn enable_logging() { + env_logger::builder().init(); + } + pub fn alice() -> Result { let secret_uri = SecretUri::from_str("//Alice")?; Ok(Keypair::from_uri(&secret_uri)?) @@ -74,14 +90,16 @@ impl SDK { } } -pub async fn initialize_api( - endpoint: &str, - secure: bool, -) -> Result<(AOnlineClient, RpcClient), ClientError> { - let rpc_client: RpcClient = match secure { - true => RpcClient::from_url(endpoint).await?, - false => RpcClient::from_insecure_url(endpoint).await?, - }; +pub async fn initialize_api(endpoint: &str) -> Result<(AOnlineClient, RpcClient), ClientError> { + let rpc_client = RpcClient::builder() + .retry_policy( + ExponentialBackoff::from_millis(1000) + .max_delay(Duration::from_secs(3)) + .take(3), + ) + .build(endpoint) + .await + .map_err(|e| e.to_string())?; // Cloning RpcClient is cheaper and doesn't create a new WS connection let api = AOnlineClient::from_rpc_client(rpc_client.clone()).await?; @@ -89,6 +107,13 @@ pub async fn initialize_api( Ok((api, rpc_client)) } +pub async fn initialize_api_custom(rpc_client: RpcClient) -> Result { + // Cloning RpcClient is cheaper and doesn't create a new WS connection + let online_client = AOnlineClient::from_rpc_client(rpc_client.clone()).await?; + + Ok(online_client) +} + #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] pub enum WaitFor { BlockInclusion, diff --git a/avail-rust/src/transactions/balances.rs b/avail-rust/src/transactions/balances.rs index 590008656..bc4d69930 100644 --- a/avail-rust/src/transactions/balances.rs +++ b/avail-rust/src/transactions/balances.rs @@ -2,7 +2,7 @@ use crate::AOnlineClient; use crate::{avail, AccountId}; use super::Transaction; -use subxt::backend::rpc::RpcClient; +use subxt::backend::rpc::reconnecting_rpc_client::RpcClient; pub type TransferAllCall = avail::balances::calls::types::TransferAll; pub type TransferAllowDeathCall = avail::balances::calls::types::TransferAllowDeath; diff --git a/avail-rust/src/transactions/da.rs b/avail-rust/src/transactions/da.rs index 9b9d5571f..1339a06be 100644 --- a/avail-rust/src/transactions/da.rs +++ b/avail-rust/src/transactions/da.rs @@ -3,7 +3,7 @@ use crate::api_dev::api::data_availability::calls::types::submit_data::Data; use crate::{avail, AOnlineClient}; use super::Transaction; -use subxt::backend::rpc::RpcClient; +use subxt::backend::rpc::reconnecting_rpc_client::RpcClient; pub type SubmitDataCall = avail::data_availability::calls::types::SubmitData; pub type CreateApplicationKeyCall = avail::data_availability::calls::types::CreateApplicationKey; diff --git a/avail-rust/src/transactions/mod.rs b/avail-rust/src/transactions/mod.rs index 54bf2391f..743d7f22b 100644 --- a/avail-rust/src/transactions/mod.rs +++ b/avail-rust/src/transactions/mod.rs @@ -19,7 +19,7 @@ use subxt_signer::sr25519::Keypair; use std::sync::Arc; use subxt::{ - backend::rpc::RpcClient, blocks::StaticExtrinsic, events::StaticEvent, + backend::rpc::reconnecting_rpc_client::RpcClient, blocks::StaticExtrinsic, events::StaticEvent, ext::scale_encode::EncodeAsFields, tx::DefaultPayload, }; @@ -96,7 +96,6 @@ impl TransactionDetails { let formatted_string = format!( r#" TransactionDetails {{ - tx_in_block: TxInBlock {{...}}, events: ExtrinsicEvents {{ ext_hash: {:?}, idx: {}, @@ -126,7 +125,7 @@ TransactionDetails {{ pub async fn fetch_block( &self, client: &AOnlineClient, - ) -> Result { + ) -> Result { crate::block::Block::new(client, self.block_hash).await } diff --git a/avail-rust/src/transactions/nom_pools.rs b/avail-rust/src/transactions/nom_pools.rs index 01d797637..1d15083df 100644 --- a/avail-rust/src/transactions/nom_pools.rs +++ b/avail-rust/src/transactions/nom_pools.rs @@ -5,7 +5,7 @@ use crate::avail::{ use crate::{AOnlineClient, AccountId}; use super::Transaction; -use subxt::backend::rpc::RpcClient; +use subxt::backend::rpc::reconnecting_rpc_client::RpcClient; pub use crate::avail::nomination_pools::calls::types::set_claim_permission::Permission; pub use crate::avail::nomination_pools::calls::types::set_state::State; diff --git a/avail-rust/src/transactions/options.rs b/avail-rust/src/transactions/options.rs index 06326fc00..ff7c91cdd 100644 --- a/avail-rust/src/transactions/options.rs +++ b/avail-rust/src/transactions/options.rs @@ -1,4 +1,4 @@ -use subxt::backend::rpc::RpcClient; +use subxt::backend::rpc::reconnecting_rpc_client::RpcClient; use crate::error::ClientError; use crate::rpcs::{account_next_index, get_block_hash, get_header}; diff --git a/avail-rust/src/transactions/session.rs b/avail-rust/src/transactions/session.rs index 4a977a875..8c0936228 100644 --- a/avail-rust/src/transactions/session.rs +++ b/avail-rust/src/transactions/session.rs @@ -2,7 +2,7 @@ use crate::avail::runtime_types::da_runtime::primitives::SessionKeys; use crate::{avail, AOnlineClient}; use super::Transaction; -use subxt::backend::rpc::RpcClient; +use subxt::backend::rpc::reconnecting_rpc_client::RpcClient; pub type SetKeysCall = avail::session::calls::types::SetKeys; diff --git a/avail-rust/src/transactions/staking.rs b/avail-rust/src/transactions/staking.rs index 47b5a6268..1bdf9512a 100644 --- a/avail-rust/src/transactions/staking.rs +++ b/avail-rust/src/transactions/staking.rs @@ -3,7 +3,7 @@ use crate::api_dev::api::runtime_types::sp_arithmetic::per_things::Perbill; use crate::{avail, AOnlineClient, AccountId, RewardDestination}; use super::Transaction; -use subxt::backend::rpc::RpcClient; +use subxt::backend::rpc::reconnecting_rpc_client::RpcClient; use subxt_core::utils::MultiAddress; pub type BondCall = avail::staking::calls::types::Bond; diff --git a/avail-rust/src/utils.rs b/avail-rust/src/utils.rs index 7744041d2..57237d022 100644 --- a/avail-rust/src/utils.rs +++ b/avail-rust/src/utils.rs @@ -1,7 +1,7 @@ use log::{debug, info, log_enabled, warn}; use primitive_types::H256; use subxt::{ - backend::{legacy::rpc_methods::Bytes, rpc::RpcClient}, + backend::{legacy::rpc_methods::Bytes, rpc::reconnecting_rpc_client::RpcClient}, blocks::StaticExtrinsic, error::DispatchError, ext::scale_encode::EncodeAsFields, @@ -179,7 +179,17 @@ pub async fn watch_transaction( return Err(TransactionExecutionError::BlockStreamFailure); }; - let block = block?; + let block = match block { + Ok(b) => b, + Err(e) => { + if e.is_disconnected_will_reconnect() { + debug!("The RPC connection was lost and we may have missed a few blocks"); + continue; + } + + return Err(TransactionExecutionError::SubxtError(e)); + }, + }; block_hash = block.hash(); block_number = block.number();