Skip to content

Commit

Permalink
Reward pallet RPC (#705)
Browse files Browse the repository at this point in the history
Add reward pallet RPCs to estimate current reward, for both escrow and vault rewards.
Co-authored-by: Gregory Hill <gregorydhill@outlook.com>
  • Loading branch information
theodorebugnet committed Sep 1, 2022
1 parent 8bf8392 commit 9f37048
Show file tree
Hide file tree
Showing 19 changed files with 327 additions and 2 deletions.
30 changes: 30 additions & 0 deletions Cargo.lock

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

16 changes: 16 additions & 0 deletions crates/reward/rpc/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
[package]
authors = ["Interlay Ltd"]
edition = "2021"
name = "module-reward-rpc"
version = '0.3.0'

[dependencies]
codec = { package = "parity-scale-codec", version = "3.0.0" }
jsonrpsee = { version = "0.13.0", features = ["server", "macros"] }
sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24" }
sp-api = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24" }
sp-blockchain = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24" }
module-reward-rpc-runtime-api = { path = "runtime-api" }

[dependencies.module-oracle-rpc-runtime-api]
path = '../../oracle/rpc/runtime-api'
23 changes: 23 additions & 0 deletions crates/reward/rpc/runtime-api/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
[package]
authors = ["Interlay Ltd"]
edition = "2021"
name = "module-reward-rpc-runtime-api"
version = '0.3.0'

[dependencies]
codec = { package = "parity-scale-codec", version = "3.0.0", default-features = false, features = ["derive", "max-encoded-len"] }
sp-api = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false }
frame-support = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false }

[dependencies.module-oracle-rpc-runtime-api]
default-features = false
path = '../../../oracle/rpc/runtime-api'

[features]
default = ["std"]
std = [
"codec/std",
"frame-support/std",
"sp-api/std",
"module-oracle-rpc-runtime-api/std",
]
22 changes: 22 additions & 0 deletions crates/reward/rpc/runtime-api/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
//! Runtime API definition for the Reward Module.

#![cfg_attr(not(feature = "std"), no_std)]

use codec::Codec;
use frame_support::dispatch::DispatchError;
use module_oracle_rpc_runtime_api::BalanceWrapper;

sp_api::decl_runtime_apis! {
pub trait RewardApi<AccountId, VaultId, CurrencyId, Balance> where
AccountId: Codec,
VaultId: Codec,
CurrencyId: Codec,
Balance: Codec
{
/// Get a given user's rewards due
fn compute_escrow_reward(account_id: AccountId, currency_id: CurrencyId) -> Result<BalanceWrapper<Balance>, DispatchError>;

/// Get a given vault's rewards due
fn compute_vault_reward(vault_id: VaultId, currency_id: CurrencyId) -> Result<BalanceWrapper<Balance>, DispatchError>;
}
}
117 changes: 117 additions & 0 deletions crates/reward/rpc/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
//! RPC interface for the Reward Module.

use codec::Codec;
use jsonrpsee::{
core::{async_trait, Error as JsonRpseeError, RpcResult},
proc_macros::rpc,
types::error::{CallError, ErrorCode, ErrorObject},
};
use module_oracle_rpc_runtime_api::BalanceWrapper;
use sp_api::ProvideRuntimeApi;
use sp_blockchain::HeaderBackend;
use sp_runtime::{
generic::BlockId,
traits::{Block as BlockT, MaybeDisplay, MaybeFromStr},
DispatchError,
};
use std::sync::Arc;

pub use module_reward_rpc_runtime_api::RewardApi as RewardRuntimeApi;

#[rpc(client, server)]
pub trait RewardApi<BlockHash, AccountId, VaultId, CurrencyId, Balance>
where
Balance: Codec + MaybeDisplay + MaybeFromStr,
AccountId: Codec,
VaultId: Codec,
CurrencyId: Codec,
{
#[method(name = "reward_computeEscrowReward")]
fn compute_escrow_reward(
&self,
account_id: AccountId,
currency_id: CurrencyId,
at: Option<BlockHash>,
) -> RpcResult<BalanceWrapper<Balance>>;

#[method(name = "reward_computeVaultReward")]
fn compute_vault_reward(
&self,
vault_id: VaultId,
currency_id: CurrencyId,
at: Option<BlockHash>,
) -> RpcResult<BalanceWrapper<Balance>>;
}

fn internal_err<T: ToString>(message: T) -> JsonRpseeError {
JsonRpseeError::Call(CallError::Custom(ErrorObject::owned(
ErrorCode::InternalError.code(),
message.to_string(),
None::<()>,
)))
}

/// A struct that implements the [`RewardApi`].
pub struct Reward<C, B> {
client: Arc<C>,
_marker: std::marker::PhantomData<B>,
}

impl<C, B> Reward<C, B> {
/// Create new `Reward` with the given reference to the client.
pub fn new(client: Arc<C>) -> Self {
Reward {
client,
_marker: Default::default(),
}
}
}

fn handle_response<T, E: std::fmt::Debug>(result: Result<Result<T, DispatchError>, E>, msg: String) -> RpcResult<T> {
result
.map_err(|err| internal_err(format!("Runtime error: {:?}: {:?}", msg, err)))?
.map_err(|err| internal_err(format!("Execution error: {:?}: {:?}", msg, err)))
}

#[async_trait]
impl<C, Block, AccountId, VaultId, CurrencyId, Balance>
RewardApiServer<<Block as BlockT>::Hash, AccountId, VaultId, CurrencyId, Balance> for Reward<C, Block>
where
Block: BlockT,
C: Send + Sync + 'static + ProvideRuntimeApi<Block> + HeaderBackend<Block>,
C::Api: RewardRuntimeApi<Block, AccountId, VaultId, CurrencyId, Balance>,
AccountId: Codec,
VaultId: Codec,
CurrencyId: Codec,
Balance: Codec + MaybeDisplay + MaybeFromStr,
{
fn compute_escrow_reward(
&self,
account_id: AccountId,
currency_id: CurrencyId,
at: Option<<Block as BlockT>::Hash>,
) -> RpcResult<BalanceWrapper<Balance>> {
let api = self.client.runtime_api();
let at = BlockId::hash(at.unwrap_or_else(|| self.client.info().best_hash));

handle_response(
api.compute_escrow_reward(&at, account_id, currency_id),
"Unable to obtain the current reward".into(),
)
}

fn compute_vault_reward(
&self,
vault_id: VaultId,
currency_id: CurrencyId,
at: Option<<Block as BlockT>::Hash>,
) -> RpcResult<BalanceWrapper<Balance>> {
let api = self.client.runtime_api();
let at = BlockId::hash(at.unwrap_or_else(|| self.client.info().best_hash));

handle_response(
api.compute_vault_reward(&at, vault_id, currency_id),
"Unable to obtain the current reward".into(),
)
}
}
1 change: 1 addition & 0 deletions parachain/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ module-btc-relay-rpc-runtime-api = { path = "../crates/btc-relay/rpc/runtime-api
module-oracle-rpc-runtime-api = { path = "../crates/oracle/rpc/runtime-api" }
module-vault-registry-rpc-runtime-api = { path = "../crates/vault-registry/rpc/runtime-api" }
module-escrow-rpc-runtime-api = { path = "../crates/escrow/rpc/runtime-api" }
module-reward-rpc-runtime-api = { path = "../crates/reward/rpc/runtime-api" }
module-issue-rpc-runtime-api = { path = "../crates/issue/rpc/runtime-api" }
module-redeem-rpc-runtime-api = { path = "../crates/redeem/rpc/runtime-api" }
module-replace-rpc-runtime-api = { path = "../crates/replace/rpc/runtime-api" }
Expand Down
2 changes: 2 additions & 0 deletions parachain/runtime/interlay/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ module-btc-relay-rpc-runtime-api = { path = "../../../crates/btc-relay/rpc/runti
module-oracle-rpc-runtime-api = { path = "../../../crates/oracle/rpc/runtime-api", default-features = false }
module-vault-registry-rpc-runtime-api = { path = "../../../crates/vault-registry/rpc/runtime-api", default-features = false }
module-escrow-rpc-runtime-api = { path = "../../../crates/escrow/rpc/runtime-api", default-features = false }
module-reward-rpc-runtime-api = { path = "../../../crates/reward/rpc/runtime-api", default-features = false }
module-issue-rpc-runtime-api = { path = "../../../crates/issue/rpc/runtime-api", default-features = false }
module-redeem-rpc-runtime-api = { path = "../../../crates/redeem/rpc/runtime-api", default-features = false }
module-replace-rpc-runtime-api = { path = "../../../crates/replace/rpc/runtime-api", default-features = false }
Expand Down Expand Up @@ -213,6 +214,7 @@ std = [
"module-oracle-rpc-runtime-api/std",
"module-vault-registry-rpc-runtime-api/std",
"module-escrow-rpc-runtime-api/std",
"module-reward-rpc-runtime-api/std",
"module-issue-rpc-runtime-api/std",
"module-redeem-rpc-runtime-api/std",
"module-replace-rpc-runtime-api/std",
Expand Down
20 changes: 20 additions & 0 deletions parachain/runtime/interlay/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1417,6 +1417,26 @@ impl_runtime_apis! {
}
}

impl module_reward_rpc_runtime_api::RewardApi<
Block,
AccountId,
VaultId,
CurrencyId,
Balance
> for Runtime {
fn compute_escrow_reward(account_id: AccountId, currency_id: CurrencyId) -> Result<BalanceWrapper<Balance>, DispatchError> {
let amount = <EscrowRewards as reward::Rewards<AccountId, Balance, CurrencyId>>::compute_reward(&account_id, currency_id)?;
let balance = BalanceWrapper::<Balance> { amount };
Ok(balance)
}

fn compute_vault_reward(vault_id: VaultId, currency_id: CurrencyId) -> Result<BalanceWrapper<Balance>, DispatchError> {
let amount = <VaultRewards as reward::Rewards<VaultId, Balance, CurrencyId>>::compute_reward(&vault_id, currency_id)?;
let balance = BalanceWrapper::<Balance> { amount };
Ok(balance)
}
}

impl module_issue_rpc_runtime_api::IssueApi<
Block,
AccountId,
Expand Down
2 changes: 2 additions & 0 deletions parachain/runtime/kintsugi/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ module-btc-relay-rpc-runtime-api = { path = "../../../crates/btc-relay/rpc/runti
module-oracle-rpc-runtime-api = { path = "../../../crates/oracle/rpc/runtime-api", default-features = false }
module-vault-registry-rpc-runtime-api = { path = "../../../crates/vault-registry/rpc/runtime-api", default-features = false }
module-escrow-rpc-runtime-api = { path = "../../../crates/escrow/rpc/runtime-api", default-features = false }
module-reward-rpc-runtime-api = { path = "../../../crates/reward/rpc/runtime-api", default-features = false }
module-issue-rpc-runtime-api = { path = "../../../crates/issue/rpc/runtime-api", default-features = false }
module-redeem-rpc-runtime-api = { path = "../../../crates/redeem/rpc/runtime-api", default-features = false }
module-replace-rpc-runtime-api = { path = "../../../crates/replace/rpc/runtime-api", default-features = false }
Expand Down Expand Up @@ -217,6 +218,7 @@ std = [
"module-oracle-rpc-runtime-api/std",
"module-vault-registry-rpc-runtime-api/std",
"module-escrow-rpc-runtime-api/std",
"module-reward-rpc-runtime-api/std",
"module-issue-rpc-runtime-api/std",
"module-redeem-rpc-runtime-api/std",
"module-replace-rpc-runtime-api/std",
Expand Down
20 changes: 20 additions & 0 deletions parachain/runtime/kintsugi/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1515,6 +1515,26 @@ impl_runtime_apis! {
}
}

impl module_reward_rpc_runtime_api::RewardApi<
Block,
AccountId,
VaultId,
CurrencyId,
Balance
> for Runtime {
fn compute_escrow_reward(account_id: AccountId, currency_id: CurrencyId) -> Result<BalanceWrapper<Balance>, DispatchError> {
let amount = <EscrowRewards as reward::Rewards<AccountId, Balance, CurrencyId>>::compute_reward(&account_id, currency_id)?;
let balance = BalanceWrapper::<Balance> { amount };
Ok(balance)
}

fn compute_vault_reward(vault_id: VaultId, currency_id: CurrencyId) -> Result<BalanceWrapper<Balance>, DispatchError> {
let amount = <VaultRewards as reward::Rewards<VaultId, Balance, CurrencyId>>::compute_reward(&vault_id, currency_id)?;
let balance = BalanceWrapper::<Balance> { amount };
Ok(balance)
}
}

impl module_issue_rpc_runtime_api::IssueApi<
Block,
AccountId,
Expand Down
2 changes: 2 additions & 0 deletions parachain/runtime/testnet-interlay/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ module-btc-relay-rpc-runtime-api = { path = "../../../crates/btc-relay/rpc/runti
module-oracle-rpc-runtime-api = { path = "../../../crates/oracle/rpc/runtime-api", default-features = false }
module-vault-registry-rpc-runtime-api = { path = "../../../crates/vault-registry/rpc/runtime-api", default-features = false }
module-escrow-rpc-runtime-api = { path = "../../../crates/escrow/rpc/runtime-api", default-features = false }
module-reward-rpc-runtime-api = { path = "../../../crates/reward/rpc/runtime-api", default-features = false }
module-issue-rpc-runtime-api = { path = "../../../crates/issue/rpc/runtime-api", default-features = false }
module-redeem-rpc-runtime-api = { path = "../../../crates/redeem/rpc/runtime-api", default-features = false }
module-replace-rpc-runtime-api = { path = "../../../crates/replace/rpc/runtime-api", default-features = false }
Expand Down Expand Up @@ -218,6 +219,7 @@ std = [
"module-oracle-rpc-runtime-api/std",
"module-vault-registry-rpc-runtime-api/std",
"module-escrow-rpc-runtime-api/std",
"module-reward-rpc-runtime-api/std",
"module-issue-rpc-runtime-api/std",
"module-redeem-rpc-runtime-api/std",
"module-replace-rpc-runtime-api/std",
Expand Down
Loading

0 comments on commit 9f37048

Please sign in to comment.