Skip to content

Commit

Permalink
feat(gsdk): upgrade subxt to v0.32.0 (#3392)
Browse files Browse the repository at this point in the history
  • Loading branch information
clearloop authored Oct 12, 2023
1 parent 5b931e2 commit 128765b
Show file tree
Hide file tree
Showing 24 changed files with 1,402 additions and 1,376 deletions.
2,014 changes: 1,111 additions & 903 deletions Cargo.lock

Large diffs are not rendered by default.

10 changes: 5 additions & 5 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -155,9 +155,9 @@ static_assertions = "1"
#
# 4. subxt-metadata and subxt-codegen are just used by gsdk-codegen for now
# gathering them here for easy management.
subxt = { version = "0.29.0", git = "https://github.com/gear-tech/subxt", branch = "v0.29.0" }
subxt-metadata = { version = "0.29.0", git = "https://github.com/gear-tech/subxt", branch = "v0.29.0" }
subxt-codegen = { version = "0.29.0", git = "https://github.com/gear-tech/subxt", branch = "v0.29.0" }
subxt = { version = "0.32.1" }
subxt-metadata = { version = "0.32.1" }
subxt-codegen = { version = "0.32.1" }
syn = "2.0.31"
thiserror = "1.0.48"
tokio = { version = "1.27.0" }
Expand Down Expand Up @@ -449,10 +449,10 @@ wasm-opt = "0.111.0" # util
wasmprinter = "0.2" # utils/wasm-gen
whoami = "1.4.0" # gcli
fail = "0.5" # gear-common
scale-value = "^0.10" # gsdk
scale-value = "^0.12" # gsdk
heck = "0.4.1" # gsdk-api-gen
etc = "0.1.16" # gcli
scale-decode = "0.7.0" # gsdk
scale-decode = "0.9.0" # gsdk
directories = "5.0.1" # utils/key-finder
num-traits = { version = "0.2", default-features = false } # gear-core

Expand Down
4 changes: 2 additions & 2 deletions gclient/src/api/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -131,14 +131,14 @@ impl GearApi {
/// identifier of the transaction sent by the current account. The nonce
/// shows how many prior transactions have occurred from this account. This
/// helps protect against replay attacks or accidental double-submissions.
pub fn set_nonce(&mut self, nonce: u32) {
pub fn set_nonce(&mut self, nonce: u64) {
self.0.set_nonce(nonce)
}

/// Get the next number used once (`nonce`) from the node.
///
/// Actually sends the `system_accountNextIndex` RPC to the node.
pub async fn rpc_nonce(&self) -> Result<u32> {
pub async fn rpc_nonce(&self) -> Result<u64> {
self.0
.api()
.tx()
Expand Down
2 changes: 1 addition & 1 deletion gclient/src/api/rpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -432,7 +432,7 @@ impl GearApi {
async fn rpc_request<T: gsdk::ext::sp_runtime::DeserializeOwned>(
&self,
method: &str,
params: subxt::rpc::RpcParams,
params: subxt::backend::rpc::RpcParams,
) -> Result<T> {
self.0
.api()
Expand Down
39 changes: 24 additions & 15 deletions gclient/src/api/storage/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@

use super::{GearApi, Result};
use crate::Error;
use gsdk::{config::GearConfig, ext::sp_core::H256, metadata::gear_runtime::RuntimeEvent};
use subxt::{config::Header, rpc::types::ChainBlock};
use gsdk::{config::Header, ext::sp_core::H256, metadata::gear_runtime::RuntimeEvent};
use subxt::config::Header as _;

type GearBlock = ChainBlock<GearConfig>;
type GearBlock = Header;

impl GearApi {
/// Return the total gas limit per block (also known as a gas budget).
Expand All @@ -41,24 +41,33 @@ impl GearApi {

// Get block data
async fn get_block_at(&self, block_hash: Option<H256>) -> Result<GearBlock> {
Ok(self
.0
let hash = if let Some(hash) = block_hash {
hash
} else {
self.0
.api()
.backend()
.latest_finalized_block_ref()
.await?
.hash()
};

self.0
.api()
.rpc()
.block(block_hash)
.backend()
.block_header(hash)
.await?
.ok_or(Error::BlockDataNotFound)?
.block)
.ok_or(Error::BlockDataNotFound)
}

/// Return a hash of the last block.
pub async fn last_block_hash(&self) -> Result<H256> {
Ok(self.get_block_at(None).await?.header.hash())
Ok(self.get_block_at(None).await?.hash())
}

/// Return a number of the last block (also known as block height).
pub async fn last_block_number(&self) -> Result<u32> {
Ok(self.get_block_at(None).await?.header.number)
Ok(self.get_block_at(None).await?.number())
}

/// Return vector of events contained in the last block.
Expand All @@ -68,15 +77,15 @@ impl GearApi {

/// Return a number of the specified block identified by the `block_hash`.
pub async fn block_number_at(&self, block_hash: H256) -> Result<u32> {
Ok(self.get_block_at(Some(block_hash)).await?.header.number)
Ok(self.get_block_at(Some(block_hash)).await?.number())
}

/// Get a hash of a block identified by its `block_number`.
pub async fn get_block_hash(&self, block_number: u32) -> Result<H256> {
self.0
.api()
.rpc()
.block_hash(Some(block_number.into()))
.chain_get_block_hash(Some(block_number.into()))
.await?
.ok_or(Error::BlockHashNotFound)
}
Expand Down Expand Up @@ -114,14 +123,14 @@ impl GearApi {

let mut current = self.get_block_at(None).await?;
for _ in 0..max_depth {
let current_hash = current.header.hash();
let current_hash = current.hash();
block_hashes.push(current_hash);

if current_hash == block_hash {
break;
}

current = self.get_block_at(Some(current.header.parent_hash)).await?;
current = self.get_block_at(Some(current.parent_hash)).await?;
}

if block_hashes.contains(&block_hash) {
Expand Down
29 changes: 3 additions & 26 deletions gsdk/api-gen/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
use color_eyre::eyre::Result;
use frame_metadata::RuntimeMetadataPrefixed;
use heck::ToSnakeCase as _;
use parity_scale_codec::Decode;
use proc_macro2::{Ident, Span, TokenStream};
Expand Down Expand Up @@ -70,10 +69,8 @@ fn main() -> Result<()> {
}

// NOTE: [4..] here for removing the magic number.
let metadata = <RuntimeMetadataPrefixed as Decode>::decode(&mut encoded[4..].as_ref())
.expect("decode metadata failed");

let metadata = Metadata::try_from(metadata).expect("Failed to convert metadata");
let metadata =
Metadata::decode(&mut encoded[4..].as_ref()).expect("Failed to convert metadata");
let calls = generate_calls(&metadata);
let storage = generate_storage(&metadata);
let impls = generate_impls(&metadata);
Expand Down Expand Up @@ -260,6 +257,7 @@ fn generate_storage(metadata: &Metadata) -> ItemMod {
let storage = pallet.storage().map(|storage| {
storage
.entries()
.iter()
.map(|entry| entry.name().into())
.collect::<Vec<_>>()
});
Expand Down Expand Up @@ -386,27 +384,6 @@ fn generate_impls(metadata: &Metadata) -> TokenStream {
}

quote! {
pub mod impls {
use crate::metadata::Event;

impl subxt::events::RootEvent for Event {
fn root_event(
pallet_bytes: &[u8],
pallet_name: &str,
pallet_ty: u32,
metadata: &subxt::Metadata
) -> Result<Self, subxt::Error> {
use subxt::metadata::DecodeWithMetadata;

#( #root_event_if_arms )*

Err(subxt::ext::scale_decode::Error::custom(
format!("Pallet name '{}' not found in root Event enum", pallet_name)
).into())
}
}
}

pub mod exports {
use crate::metadata::runtime_types;

Expand Down
17 changes: 13 additions & 4 deletions gsdk/src/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,8 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.

use crate::{client::RpcClient, config::GearConfig, signer::Signer, Blocks, Events, Result};
use crate::{client::Rpc, config::GearConfig, signer::Signer, Blocks, Events, Result};
use core::ops::{Deref, DerefMut};
use std::sync::Arc;
use subxt::OnlineClient;

/// Gear api wrapper.
Expand All @@ -27,6 +26,9 @@ pub struct Api {
/// How many times we'll retry when rpc requests failed.
pub retry: u16,
client: OnlineClient<GearConfig>,

/// Gear RPC client
rpc: Rpc,
}

impl Api {
Expand All @@ -35,13 +37,20 @@ impl Api {
Self::new_with_timeout(url, None).await
}

/// Gear RPC Client
pub fn rpc(&self) -> Rpc {
self.rpc.clone()
}

/// Create new API client with timeout.
pub async fn new_with_timeout(url: Option<&str>, timeout: Option<u64>) -> Result<Self> {
let rpc = Rpc::new(url, timeout).await?;

Ok(Self {
// Retry our failed RPC requests for 5 times by default.
retry: 5,
client: OnlineClient::from_rpc_client(Arc::new(RpcClient::new(url, timeout).await?))
.await?,
client: OnlineClient::from_rpc_client(rpc.client()).await?,
rpc,
})
}

Expand Down
54 changes: 30 additions & 24 deletions gsdk/src/backtrace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,49 +27,55 @@ use std::{collections::BTreeMap, sync::Arc, time::SystemTime};
/// Transaction Status for Backtrace
#[derive(Clone, Debug, Eq, PartialEq)]
pub enum BacktraceStatus {
Future,
Ready,
Broadcast(Vec<String>),
InBlock {
Validated,
NoLongerInBestBlock,
Broadcasted {
num_peers: u32,
},
InBestBlock {
block_hash: H256,
extrinsic_hash: H256,
},
Retracted {
InFinalizedBlock {
block_hash: H256,
extrinsic_hash: H256,
},
FinalityTimeout {
block_hash: H256,
Error {
message: String,
},
Finalized {
block_hash: H256,
extrinsic_hash: H256,
Dropped {
message: String,
},
Usurped {
extrinsic_hash: H256,
Invalid {
message: String,
},
Dropped,
Invalid,
}

impl<'s> From<&'s TxStatus> for BacktraceStatus {
fn from(status: &'s TxStatus) -> BacktraceStatus {
match status {
TxStatus::Future => BacktraceStatus::Future,
TxStatus::Ready => BacktraceStatus::Ready,
TxStatus::Broadcast(v) => BacktraceStatus::Broadcast(v.clone()),
TxStatus::InBlock(b) => BacktraceStatus::InBlock {
TxStatus::Validated => BacktraceStatus::Validated,
TxStatus::NoLongerInBestBlock => BacktraceStatus::NoLongerInBestBlock,
TxStatus::Broadcasted { num_peers } => BacktraceStatus::Broadcasted {
num_peers: *num_peers,
},
TxStatus::InBestBlock(b) => BacktraceStatus::InBestBlock {
block_hash: b.block_hash(),
extrinsic_hash: b.extrinsic_hash(),
},
TxStatus::Retracted(h) => BacktraceStatus::Retracted { block_hash: *h },
TxStatus::FinalityTimeout(h) => BacktraceStatus::FinalityTimeout { block_hash: *h },
TxStatus::Finalized(b) => BacktraceStatus::Finalized {
TxStatus::InFinalizedBlock(b) => BacktraceStatus::InFinalizedBlock {
block_hash: b.block_hash(),
extrinsic_hash: b.extrinsic_hash(),
},
TxStatus::Usurped(h) => BacktraceStatus::Usurped { extrinsic_hash: *h },
TxStatus::Dropped => BacktraceStatus::Dropped,
TxStatus::Invalid => BacktraceStatus::Invalid,
TxStatus::Error { message } => BacktraceStatus::Error {
message: message.clone(),
},
TxStatus::Dropped { message } => BacktraceStatus::Dropped {
message: message.clone(),
},
TxStatus::Invalid { message } => BacktraceStatus::Invalid {
message: message.clone(),
},
}
}
}
Expand Down
54 changes: 51 additions & 3 deletions gsdk/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,10 @@
// along with this program. If not, see <https://www.gnu.org/licenses/>.

//! RPC client for Gear API.
use crate::result::{Error, Result};
use crate::{
config::GearConfig,
result::{Error, Result},
};
use futures_util::{StreamExt, TryStreamExt};
use jsonrpsee::{
core::{
Expand All @@ -29,10 +32,17 @@ use jsonrpsee::{
types::SubscriptionId,
ws_client::{WsClient, WsClientBuilder},
};
use std::{result::Result as StdResult, time::Duration};
use sp_runtime::DeserializeOwned;
use std::{ops::Deref, result::Result as StdResult, time::Duration};
use subxt::{
backend::{
legacy::LegacyRpcMethods,
rpc::{
RawRpcFuture as RpcFuture, RawRpcSubscription as RpcSubscription, RawValue,
RpcClient as SubxtRpcClient, RpcClientT, RpcParams,
},
},
error::RpcError,
rpc::{RawValue, RpcClientT, RpcFuture, RpcSubscription},
};

const DEFAULT_GEAR_ENDPOINT: &str = "wss://rpc.vara-network.io:443";
Expand Down Expand Up @@ -146,3 +156,41 @@ async fn subscription_stream<C: SubscriptionClientT>(
.await
.map_err(|e| RpcError::ClientError(Box::new(e)))
}

/// RPC client for Gear API.
#[derive(Clone)]
pub struct Rpc {
rpc: SubxtRpcClient,
methods: LegacyRpcMethods<GearConfig>,
}

impl Rpc {
/// Create RPC client from url and timeout.
pub async fn new(url: Option<&str>, timeout: Option<u64>) -> Result<Self> {
let rpc = SubxtRpcClient::new(RpcClient::new(url, timeout).await?);
let methods = LegacyRpcMethods::new(rpc.clone());
Ok(Self { rpc, methods })
}

/// Get RPC client.
pub fn client(&self) -> SubxtRpcClient {
self.rpc.clone()
}

/// Raw RPC request
pub async fn request<Res: DeserializeOwned>(
&self,
method: &str,
params: RpcParams,
) -> Result<Res> {
self.rpc.request(method, params).await.map_err(Into::into)
}
}

impl Deref for Rpc {
type Target = LegacyRpcMethods<GearConfig>;

fn deref(&self) -> &Self::Target {
&self.methods
}
}
Loading

0 comments on commit 128765b

Please sign in to comment.