Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(custom-rpc): add flip balance to account info #4119

Merged
merged 2 commits into from
Oct 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
90 changes: 53 additions & 37 deletions state-chain/custom-rpc/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,19 @@ use std::{
#[derive(Serialize, Deserialize)]
#[serde(tag = "role", rename_all = "snake_case")]
pub enum RpcAccountInfo {
None,
Broker,
None {
flip_balance: NumberOrHex,
},
Broker {
flip_balance: NumberOrHex,
},
LiquidityProvider {
balances: HashMap<ForeignChain, HashMap<Asset, NumberOrHex>>,
refund_addresses: HashMap<ForeignChain, Option<String>>,
flip_balance: NumberOrHex,
},
Validator {
balance: NumberOrHex,
flip_balance: NumberOrHex,
bond: NumberOrHex,
last_heartbeat: u32,
online_credits: u32,
Expand All @@ -59,15 +64,15 @@ pub enum RpcAccountInfo {
}

impl RpcAccountInfo {
fn none() -> Self {
Self::None
fn none(balance: u128) -> Self {
Self::None { flip_balance: balance.into() }
}

fn broker() -> Self {
Self::Broker
fn broker(balance: u128) -> Self {
Self::Broker { flip_balance: balance.into() }
}

fn lp(info: LiquidityProviderInfo) -> Self {
fn lp(info: LiquidityProviderInfo, balance: u128) -> Self {
let mut balances = HashMap::new();

for (asset, balance) in info.balances {
Expand All @@ -78,6 +83,7 @@ impl RpcAccountInfo {
}

Self::LiquidityProvider {
flip_balance: balance.into(),
balances,
refund_addresses: info
.refund_addresses
Expand All @@ -96,7 +102,7 @@ impl RpcAccountInfo {

fn validator(info: RuntimeApiAccountInfoV2) -> Self {
Self::Validator {
balance: info.balance.into(),
flip_balance: info.balance.into(),
bond: info.bond.into(),
last_heartbeat: info.last_heartbeat,
online_credits: info.online_credits,
Expand Down Expand Up @@ -529,26 +535,28 @@ where
) -> RpcResult<RpcAccountInfo> {
let api = self.client.runtime_api();

let hash = self.unwrap_or_best(at);

let balance = api.cf_account_flip_balance(hash, &account_id).map_err(to_rpc_error)?;

Ok(
match api
.cf_account_role(self.unwrap_or_best(at), account_id.clone())
.cf_account_role(hash, account_id.clone())
.map_err(to_rpc_error)?
.unwrap_or(AccountRole::None)
{
AccountRole::None => RpcAccountInfo::none(),
AccountRole::Broker => RpcAccountInfo::broker(),
AccountRole::None => RpcAccountInfo::none(balance),
AccountRole::Broker => RpcAccountInfo::broker(balance),
AccountRole::LiquidityProvider => {
let info = api
.cf_liquidity_provider_info(self.unwrap_or_best(at), account_id)
.cf_liquidity_provider_info(hash, account_id)
.map_err(to_rpc_error)?
.expect("role already validated");

RpcAccountInfo::lp(info)
RpcAccountInfo::lp(info, balance)
},
AccountRole::Validator => {
let info = api
.cf_account_info_v2(self.unwrap_or_best(at), account_id)
.map_err(to_rpc_error)?;
let info = api.cf_account_info_v2(hash, &account_id).map_err(to_rpc_error)?;

RpcAccountInfo::validator(info)
},
Expand All @@ -564,7 +572,7 @@ where
let account_info = self
.client
.runtime_api()
.cf_account_info_v2(self.unwrap_or_best(at), account_id)
.cf_account_info_v2(self.unwrap_or_best(at), &account_id)
.map_err(to_rpc_error)?;

Ok(RpcAccountInfoV2 {
Expand Down Expand Up @@ -939,33 +947,41 @@ mod test {
#[test]
fn test_account_info_serialization() {
assert_eq!(
serde_json::to_value(RpcAccountInfo::none()).unwrap(),
json!({ "role": "none" })
serde_json::to_value(RpcAccountInfo::none(0)).unwrap(),
json!({ "role": "none", "flip_balance": "0x0" })
);
assert_eq!(
serde_json::to_value(RpcAccountInfo::broker()).unwrap(),
json!({ "role":"broker" })
serde_json::to_value(RpcAccountInfo::broker(0)).unwrap(),
json!({ "role":"broker", "flip_balance": "0x0" })
);

let lp = RpcAccountInfo::lp(LiquidityProviderInfo {
refund_addresses: vec![
(
ForeignChain::Ethereum,
Some(cf_chains::ForeignChainAddress::Eth(H160::from([1; 20]))),
),
(
ForeignChain::Polkadot,
Some(cf_chains::ForeignChainAddress::Dot(Default::default())),
),
(ForeignChain::Bitcoin, None),
],
balances: vec![(Asset::Eth, u128::MAX), (Asset::Btc, 0), (Asset::Flip, u128::MAX / 2)],
});
let lp = RpcAccountInfo::lp(
LiquidityProviderInfo {
refund_addresses: vec![
(
ForeignChain::Ethereum,
Some(cf_chains::ForeignChainAddress::Eth(H160::from([1; 20]))),
),
(
ForeignChain::Polkadot,
Some(cf_chains::ForeignChainAddress::Dot(Default::default())),
),
(ForeignChain::Bitcoin, None),
],
balances: vec![
(Asset::Eth, u128::MAX),
(Asset::Btc, 0),
(Asset::Flip, u128::MAX / 2),
],
},
0,
);

assert_eq!(
serde_json::to_value(lp).unwrap(),
json!({
"role": "liquidity_provider",
"flip_balance": "0x0",
"balances": {
"Ethereum": {
"Flip": "0x7fffffffffffffffffffffffffffffff",
Expand Down Expand Up @@ -999,7 +1015,7 @@ mod test {
assert_eq!(
serde_json::to_value(validator).unwrap(),
json!({
"balance": "0xde0b6b3a7640000",
"flip_balance": "0xde0b6b3a7640000",
"bond": "0xde0b6b3a7640000",
"bound_redeem_address": "0x0101010101010101010101010101010101010101",
"is_bidding": false,
Expand Down
29 changes: 17 additions & 12 deletions state-chain/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -913,27 +913,32 @@ impl_runtime_apis! {
})
.collect()
}
fn cf_account_info_v2(account_id: AccountId) -> RuntimeApiAccountInfoV2 {
let is_current_backup = pallet_cf_validator::Backups::<Runtime>::get().contains_key(&account_id);
let key_holder_epochs = pallet_cf_validator::HistoricalActiveEpochs::<Runtime>::get(&account_id);
let is_qualified = <<Runtime as pallet_cf_validator::Config>::KeygenQualification as QualifyNode<_>>::is_qualified(&account_id);
let is_current_authority = pallet_cf_validator::CurrentAuthorities::<Runtime>::get().contains(&account_id);
let is_bidding = pallet_cf_funding::ActiveBidder::<Runtime>::get(&account_id);
let bound_redeem_address = pallet_cf_funding::BoundRedeemAddress::<Runtime>::get(&account_id);
let reputation_info = pallet_cf_reputation::Reputations::<Runtime>::get(&account_id);
let account_info = pallet_cf_flip::Account::<Runtime>::get(&account_id);
let restricted_balances = pallet_cf_funding::RestrictedBalances::<Runtime>::get(&account_id);

fn cf_account_flip_balance(account_id: &AccountId) -> u128 {
pallet_cf_flip::Account::<Runtime>::get(account_id).total()
}

fn cf_account_info_v2(account_id: &AccountId) -> RuntimeApiAccountInfoV2 {
let is_current_backup = pallet_cf_validator::Backups::<Runtime>::get().contains_key(account_id);
let key_holder_epochs = pallet_cf_validator::HistoricalActiveEpochs::<Runtime>::get(account_id);
let is_qualified = <<Runtime as pallet_cf_validator::Config>::KeygenQualification as QualifyNode<_>>::is_qualified(account_id);
let is_current_authority = pallet_cf_validator::CurrentAuthorities::<Runtime>::get().contains(account_id);
let is_bidding = pallet_cf_funding::ActiveBidder::<Runtime>::get(account_id);
let bound_redeem_address = pallet_cf_funding::BoundRedeemAddress::<Runtime>::get(account_id);
let reputation_info = pallet_cf_reputation::Reputations::<Runtime>::get(account_id);
let account_info = pallet_cf_flip::Account::<Runtime>::get(account_id);
let restricted_balances = pallet_cf_funding::RestrictedBalances::<Runtime>::get(account_id);
RuntimeApiAccountInfoV2 {
balance: account_info.total(),
bond: account_info.bond(),
last_heartbeat: pallet_cf_reputation::LastHeartbeat::<Runtime>::get(&account_id).unwrap_or(0),
last_heartbeat: pallet_cf_reputation::LastHeartbeat::<Runtime>::get(account_id).unwrap_or(0),
online_credits: reputation_info.online_credits,
reputation_points: reputation_info.reputation_points,
keyholder_epochs: key_holder_epochs,
is_current_authority,
is_current_backup,
is_qualified: is_bidding && is_qualified,
is_online: Reputation::is_qualified(&account_id),
is_online: Reputation::is_qualified(account_id),
is_bidding,
bound_redeem_address,
restricted_balances,
Expand Down
3 changes: 2 additions & 1 deletion state-chain/runtime/src/runtime_apis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,8 @@ decl_runtime_apis!(
/// Returns the flip supply in the form [total_issuance, offchain_funds]
fn cf_flip_supply() -> (u128, u128);
fn cf_accounts() -> Vec<(AccountId32, VanityName)>;
fn cf_account_info_v2(account_id: AccountId32) -> RuntimeApiAccountInfoV2;
fn cf_account_flip_balance(account_id: &AccountId32) -> u128;
fn cf_account_info_v2(account_id: &AccountId32) -> RuntimeApiAccountInfoV2;
fn cf_penalties() -> Vec<(Offence, RuntimeApiPenalty)>;
fn cf_suspensions() -> Vec<(Offence, Vec<(u32, AccountId32)>)>;
fn cf_generate_gov_key_call_hash(call: Vec<u8>) -> GovCallHash;
Expand Down