Skip to content

Commit

Permalink
feat: structured error return types for rpcs
Browse files Browse the repository at this point in the history
  • Loading branch information
dandanlen committed Oct 24, 2024
1 parent 106de29 commit e1ee366
Show file tree
Hide file tree
Showing 16 changed files with 646 additions and 896 deletions.
2 changes: 2 additions & 0 deletions Cargo.lock

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

1 change: 1 addition & 0 deletions api/bin/chainflip-broker-api/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ jsonrpsee = { workspace = true, features = ["full"] }
serde = { workspace = true, default-features = true, features = ["derive"] }
sp-core = { workspace = true }
sp-rpc = { workspace = true }
thiserror = { workspace = true }
tokio = { workspace = true }
tracing = { workspace = true }
tracing-subscriber = { workspace = true, features = ["env-filter"] }
Expand Down
64 changes: 45 additions & 19 deletions api/bin/chainflip-broker-api/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,55 @@ use chainflip_api::{
SwapDepositAddress, SwapPayload, WithdrawFeesDetail,
};
use clap::Parser;
use custom_rpc::to_rpc_error;
use futures::FutureExt;
use jsonrpsee::{
core::{async_trait, RpcResult},
core::{async_trait, ClientError},
proc_macros::rpc,
server::ServerBuilder,
types::{ErrorCode, ErrorObject, ErrorObjectOwned},
};
use std::{
path::PathBuf,
sync::{atomic::AtomicBool, Arc},
};
use tracing::log;

#[derive(thiserror::Error, Debug)]
pub enum BrokerApiError {
#[error(transparent)]
ErrorObject(#[from] ErrorObjectOwned),
#[error(transparent)]
ClientError(#[from] jsonrpsee::core::ClientError),
#[error(transparent)]
Other(#[from] anyhow::Error),
}

type RpcResult<T> = Result<T, BrokerApiError>;

impl From<BrokerApiError> for ErrorObjectOwned {
fn from(error: BrokerApiError) -> Self {
match error {
BrokerApiError::ErrorObject(error) => error,
BrokerApiError::ClientError(error) => match error {
ClientError::Call(obj) => obj,
internal => {
log::error!("Internal rpc client error: {internal:?}");
ErrorObject::owned(
ErrorCode::InternalError.code(),
"Internal rpc client error",
None::<()>,
)
},
},
BrokerApiError::Other(error) => jsonrpsee::types::error::ErrorObjectOwned::owned(
ErrorCode::ServerError(0xcf).code(),
error.to_string(),
None::<()>,
),
}
}
}

#[rpc(server, client, namespace = "broker")]
pub trait Rpc {
#[method(name = "register_account", aliases = ["broker_registerAccount"])]
Expand Down Expand Up @@ -90,8 +126,7 @@ impl RpcServer for RpcServerImpl {
.operator_api()
.register_account_role(AccountRole::Broker)
.await
.map(|tx_hash| format!("{tx_hash:#x}"))
.map_err(to_rpc_error)?)
.map(|tx_hash| format!("{tx_hash:#x}"))?)
}

async fn request_swap_deposit_address(
Expand Down Expand Up @@ -120,21 +155,15 @@ impl RpcServer for RpcServerImpl {
refund_parameters,
dca_parameters,
)
.await
.map_err(to_rpc_error)?)
.await?)
}

async fn withdraw_fees(
&self,
asset: Asset,
destination_address: AddressString,
) -> RpcResult<WithdrawFeesDetail> {
Ok(self
.api
.broker_api()
.withdraw_fees(asset, destination_address)
.await
.map_err(to_rpc_error)?)
Ok(self.api.broker_api().withdraw_fees(asset, destination_address).await?)
}

async fn request_swap_parameter_encoding(
Expand All @@ -157,14 +186,13 @@ impl RpcServer for RpcServerImpl {
destination_asset,
destination_address,
broker_commission,
try_parse_number_or_hex(min_output_amount).map_err(to_rpc_error)?,
try_parse_number_or_hex(min_output_amount)?,
retry_duration,
boost_fee,
affiliate_fees,
dca_parameters,
)
.await
.map_err(to_rpc_error)?)
.await?)
}
}

Expand Down Expand Up @@ -222,11 +250,9 @@ async fn main() -> anyhow::Result<()> {
let server = ServerBuilder::default()
.max_connections(opts.max_connections)
.build(format!("0.0.0.0:{}", opts.port))
.await
.map_err(to_rpc_error)?;
.await?;
let server_addr = server.local_addr()?;
let server = server
.start(RpcServerImpl::new(scope, opts).await.map_err(to_rpc_error)?.into_rpc());
let server = server.start(RpcServerImpl::new(scope, opts).await?.into_rpc());

log::info!("🎙 Server is listening on {server_addr}.");

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -396,12 +396,14 @@ mod tests {
BlockInfo,
};
use frame_support::storage::types::QueryKindTrait;
use jsonrpsee::core::RpcResult;
use jsonrpsee::core::ClientError;
use mockall::mock;
use pallet_cf_ingress_egress::DepositWitness;
use sp_core::{storage::StorageKey, H160};
use std::collections::HashMap;

type RpcResult<T> = Result<T, ClientError>;

#[derive(Default)]
struct MockStore {
storage: HashMap<String, serde_json::Value>,
Expand Down
1 change: 1 addition & 0 deletions api/bin/chainflip-lp-api/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ cf-primitives = { workspace = true, default-features = true }
custom-rpc = { workspace = true }
frame-system = { workspace = true, default-features = true }
sc-rpc = { workspace = true, default-features = true }
thiserror = { workspace = true, default-features = true }

# Local
chainflip-api = { workspace = true }
Expand Down
Loading

0 comments on commit e1ee366

Please sign in to comment.