Skip to content

Commit

Permalink
feat(custom-rpc): add flip balance to account info (#4119)
Browse files Browse the repository at this point in the history
  • Loading branch information
acdibble committed Oct 13, 2023
1 parent 99c3e0a commit 4e73511
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 50 deletions.
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

0 comments on commit 4e73511

Please sign in to comment.