Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
…etwork into master
  • Loading branch information
tuminfei committed Nov 12, 2020
2 parents a338745 + 75290ff commit 2b42130
Show file tree
Hide file tree
Showing 12 changed files with 238 additions and 8 deletions.
40 changes: 36 additions & 4 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 node/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ frame-benchmarking-cli = { version = "2.0.0" }


uart-runtime = { path = "../runtime" }
pallet-staking-rpc = { path = "../pallets/staking/rpc" }

[build-dependencies]
substrate-build-script-utils = { version = "2.0.0" }
Expand Down
6 changes: 6 additions & 0 deletions node/src/rpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,13 @@ pub fn create_full<C, P>(
C: Send + Sync + 'static,
C::Api: substrate_frame_rpc_system::AccountNonceApi<Block, AccountId, Index>,
C::Api: pallet_transaction_payment_rpc::TransactionPaymentRuntimeApi<Block, Balance>,
C::Api: pallet_staking_rpc::StakingRuntimeApi<Block, AccountId, Balance>,
C::Api: BlockBuilder<Block>,
P: TransactionPool + 'static,
{
use substrate_frame_rpc_system::{FullSystem, SystemApi};
use pallet_transaction_payment_rpc::{TransactionPayment, TransactionPaymentApi};
use pallet_staking_rpc::{Staking, StakingApi};

let mut io = jsonrpc_core::IoHandler::default();
let FullDeps {
Expand All @@ -55,6 +57,10 @@ pub fn create_full<C, P>(
TransactionPaymentApi::to_delegate(TransactionPayment::new(client.clone()))
);

io.extend_with(
StakingApi::to_delegate(Staking::new(client.clone()))
);

// Extend this RPC with a custom API by using the following syntax.
// `YourRpcStruct` should have a reference to a client, which is needed
// to call into the runtime.
Expand Down
3 changes: 2 additions & 1 deletion pallets/staking/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,5 @@ frame-support = { version = "2.0.0", default-features = false }
frame-system = { version = "2.0.0", default-features = false }
sp-std = { version = "2.0.0", default-features = false }
sp-core = { version = "2.0.0", default-features = false }
sp-runtime = { version = "2.0.0", default-features = false }
sp-runtime = { version = "2.0.0", default-features = false }
sp-api = { version = "2.0.0", default-features = false }
21 changes: 21 additions & 0 deletions pallets/staking/rpc/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
[package]
name = "pallet-staking-rpc"
version = "0.1.0"
authors = ["yxf <[email protected]>"]
edition = "2018"

[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]

[dependencies]
codec = { package = "parity-scale-codec", version = "1.3.1" }
jsonrpc-core = "15.0.0"
jsonrpc-core-client = "15.0.0"
jsonrpc-derive = "15.0.0"
sp-core = { version = "2.0.0" }
sp-rpc = { version = "2.0.0" }
serde = { version = "1.0.101", features = ["derive"] }
sp-runtime = { version = "2.0.0" }
sp-api = { version = "2.0.0" }
sp-blockchain = { version = "2.0.0" }
pallet-staking-rpc-runtime-api = { version = "0.1.0", path = "./runtime-api" }
29 changes: 29 additions & 0 deletions pallets/staking/rpc/runtime-api/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
[package]
name = "pallet-staking-rpc-runtime-api"
version = "0.1.0"
authors = ["yxf <[email protected]>"]
edition = "2018"


[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]

[dependencies]
codec = { package = "parity-scale-codec", version = "1.3.1", default-features = false, features = ["derive"] }
serde = { version = "1.0.101", optional = true, features = ["derive"] }
sp-api = { version = "2.0.0", default-features = false }
sp-std = { version = "2.0.0", default-features = false }
sp-runtime = { version = "2.0.0", default-features = false }
frame-support = { version = "2.0.0", default-features = false }


[features]
default = ["std"]
std = [
"serde",
"sp-api/std",
"codec/std",
"sp-std/std",
"sp-runtime/std",
"frame-support/std",
]
38 changes: 38 additions & 0 deletions pallets/staking/rpc/runtime-api/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#![cfg_attr(not(feature = "std"), no_std)]

use sp_std::prelude::*;
use codec::{Encode, Decode};
#[cfg(feature = "std")]
use serde::{Serialize, Deserialize, Serializer, Deserializer};

#[derive(Eq, PartialEq, Encode, Decode, Default)]
#[cfg_attr(feature = "std", derive(Debug, Serialize, Deserialize))]
pub struct Reward<Balance>(
#[cfg_attr(feature = "std", serde(bound(serialize = "Balance: std::fmt::Display")))]
#[cfg_attr(feature = "std", serde(serialize_with = "serialize_as_string"))]
#[cfg_attr(feature = "std", serde(bound(deserialize = "Balance: std::str::FromStr")))]
#[cfg_attr(feature = "std", serde(deserialize_with = "deserialize_from_string"))]
pub Balance
);

#[cfg(feature = "std")]
fn serialize_as_string<S: Serializer, T: std::fmt::Display>(t: &T, serializer: S) -> Result<S::Ok, S::Error> {
serializer.serialize_str(&t.to_string())
}

#[cfg(feature = "std")]
fn deserialize_from_string<'de, D: Deserializer<'de>, T: std::str::FromStr>(deserializer: D) -> Result<T, D::Error> {
let s = String::deserialize(deserializer)?;
s.parse::<T>().map_err(|_| serde::de::Error::custom("Parse from string failed"))
}

sp_api::decl_runtime_apis! {
pub trait StakingApi<AccountId, Balance> where
AccountId: codec::Codec,
Balance: codec::Codec
{
fn staking_module_account_id() -> AccountId;
fn pool_account_id(id: u32) -> AccountId;
fn pending_rewards(pool_id: u32, account_id: AccountId) -> Balance;
}
}
67 changes: 67 additions & 0 deletions pallets/staking/rpc/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
use std::sync::Arc;
use codec::{Codec};
use jsonrpc_derive::rpc;
use jsonrpc_core::{Error as RpcError, ErrorCode, Result};
use sp_blockchain::HeaderBackend;
use sp_runtime::{generic::BlockId, traits::{Block as BlockT, MaybeDisplay, MaybeFromStr}};
use sp_api::ProvideRuntimeApi;
use pallet_staking_rpc_runtime_api::Reward;
pub use pallet_staking_rpc_runtime_api::StakingApi as StakingRuntimeApi;

#[rpc]
pub trait StakingApi<AccountId, ResponseType> {
#[rpc(name = "staking_pendingRewards")]
fn pending_rewards(
&self,
account_id: AccountId
) -> Result<ResponseType>;

#[rpc(name = "staking_poolAccountId")]
fn pool_account_id(&self) -> Result<AccountId>;
}

pub struct Staking<C, P> {
client: Arc<C>,
_marker: std::marker::PhantomData<P>,
}

impl<C, P> Staking<C, P> {
pub fn new(client: Arc<C>) -> Self {
Staking { client, _marker: Default::default() }
}
}


impl<C, Block, AccountId, Balance> StakingApi<AccountId, Reward<Balance>>
for Staking<C, Block>
where
Block: BlockT,
C: Send + Sync + 'static + ProvideRuntimeApi<Block> + HeaderBackend<Block>,
C::Api: StakingRuntimeApi<Block, AccountId, Balance>,
Balance: Codec + MaybeDisplay + MaybeFromStr + std::default::Default + std::fmt::Debug,
AccountId: Codec
{

fn pending_rewards(&self, account_id: AccountId) -> Result<Reward<Balance>> {
let api = self.client.runtime_api();
let at = BlockId::hash(self.client.info().best_hash);
api.pending_rewards(&at, 0, account_id).map_err(|e| RpcError {
code: ErrorCode::InternalError,
message: "Unable to query pending rewards".into(),
data: Some(format!("{:?}", e).into()),
}).map(|value| Reward(value))

// println!("balance = {:?}", balance);
// Ok(Reward { value: Default::default() })
}

fn pool_account_id(&self) -> Result<AccountId> {
let api = self.client.runtime_api();
let at = BlockId::hash(self.client.info().best_hash);
api.staking_module_account_id(&at).map_err(|e| RpcError {
code: ErrorCode::InternalError,
message: "Unable to query pool account_id".into(),
data: Some(format!("{:?}", e).into()),
})
}
}
22 changes: 21 additions & 1 deletion pallets/staking/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ use sp_runtime::{
use codec::{Encode, Decode};
use sp_std::prelude::*;


pub type BalanceOf<T> =
<<T as Trait>::Currency as Currency<<T as frame_system::Trait>::AccountId>>::Balance;
pub type AccountId<T> = <T as frame_system::Trait>::AccountId;
Expand Down Expand Up @@ -291,5 +290,26 @@ impl<T: Trait> Module<T> {
// TODO: adjust rewards of staking
T::RewardPerBlock::get()
}

/// Pending rewards of staker
pub fn pending_rewards(pool_id: T::Id, account_id: T::AccountId) -> BalanceOf<T> {
let staker_key = (pool_id, account_id);
let staker = Self::stakers(&staker_key);
let pool = Self::pools(pool_id);

let block_number = frame_system::Module::<T>::block_number();
let reward_per_block: BalanceOf<T> = Self::reward_per_block();
let factor: BalanceOf<T> = T::AmpFactor::get();

let delta = block_number.saturating_sub(pool.last_reward_block);
let blocks: BalanceOf<T> = T::ConvertNumberToBalance::convert(delta);
let rewards = reward_per_block.saturating_mul(blocks);
if pool.total_balance == Zero::zero() {
return Zero::zero();
}
let rewards_per_share = rewards.saturating_mul(factor) / pool.total_balance;
let acc_rewards_per_share = pool.acc_rewards_per_share.saturating_add(rewards_per_share);
staker.amount.saturating_mul(acc_rewards_per_share) / factor - staker.debt
}
}

2 changes: 1 addition & 1 deletion primitives/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,4 @@ std = [
"sp-runtime/std",
"sp-core/std",
"sp-std/std",
]
]
3 changes: 2 additions & 1 deletion runtime/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,10 @@ pallet-treasury = { version = "2.0.0", default-features = false }
pallet-identity = { version = "2.0.0", default-features = false }
pallet-scheduler = { version = "2.0.0", default-features = false }

# Used for the node template's RPCs
# Used for RPCs
frame-system-rpc-runtime-api = { version = "2.0.0", default-features = false }
pallet-transaction-payment-rpc-runtime-api = { version = "2.0.0", default-features = false }
pallet-staking-rpc-runtime-api = { version = "0.1.0", default-features = false, path = "../pallets/staking/rpc/runtime-api"}

# Uni-Arts pallets
pallet-certificate = { path = "../pallets/certificate", default-features = false }
Expand Down
14 changes: 14 additions & 0 deletions runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -822,4 +822,18 @@ impl_runtime_apis! {
TransactionPayment::query_info(uxt, len)
}
}

impl pallet_staking_rpc_runtime_api::StakingApi<Block, AccountId, Balance> for Runtime {
fn staking_module_account_id() -> AccountId {
Staking::account_id()
}

fn pool_account_id(id: u32) -> AccountId {
Staking::pool_account_id(id)
}

fn pending_rewards(pool_id: u32, account_id: AccountId) -> Balance {
Staking::pending_rewards(pool_id, account_id)
}
}
}

0 comments on commit 2b42130

Please sign in to comment.