Skip to content

Commit

Permalink
fix fn show (#1027)
Browse files Browse the repository at this point in the history
Co-authored-by: shaorongqiang <[email protected]>
  • Loading branch information
shaorongqiang and shaorongqiang authored Oct 26, 2023
1 parent 8644797 commit 0ba9a56
Show file tree
Hide file tree
Showing 3 changed files with 240 additions and 51 deletions.
1 change: 1 addition & 0 deletions src/components/finutils/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ rand_chacha = "0.2"
curve25519-dalek = { version = "3.0", features = ["serde"] }
wasm-bindgen = { version = "=0.2.84", features = ["serde-serialize"] }
sha2 = "0.10"
sha3 = "0.8"

zei = { git = "https://github.com/FindoraNetwork/zei", branch = "stable-main" }
ruc = "1.0"
Expand Down
79 changes: 29 additions & 50 deletions src/components/finutils/src/common/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
//! This module is the library part of FN.
//!

use std::str::FromStr;

#[cfg(not(target_arch = "wasm32"))]
pub mod dev;

Expand All @@ -18,6 +20,7 @@ pub mod utils;
use {
self::utils::{get_evm_staking_address, get_validator_memo_and_rate},
crate::api::DelegationInfo,
crate::common::utils::mapping_address,
globutils::wallet,
lazy_static::lazy_static,
ledger::{
Expand Down Expand Up @@ -291,11 +294,11 @@ pub fn claim(td_addr: &str, am: Option<&str>, sk_str: Option<&str>) -> Result<()
pub fn show(basic: bool) -> Result<()> {
let kp = get_keypair().c(d!())?;

let serv_addr = ruc::info!(get_serv_addr()).map(|i| {
ruc::info!(get_serv_addr()).map(|i| {
println!("\x1b[31;01mServer URL:\x1b[00m\n{i}\n");
});
})?;

let xfr_account = ruc::info!(get_keypair()).map(|i| {
ruc::info!(get_keypair()).map(|i| {
println!(
"\x1b[31;01mFindora Address:\x1b[00m\n{}\n",
wallet::public_key_to_bech32(&i.get_pk())
Expand All @@ -304,66 +307,42 @@ pub fn show(basic: bool) -> Result<()> {
"\x1b[31;01mFindora Public Key:\x1b[00m\n{}\n",
wallet::public_key_to_base64(&i.get_pk())
);
});
})?;

let self_balance = ruc::info!(utils::get_balance(&kp)).map(|i| {
ruc::info!(utils::get_balance(&kp)).map(|i| {
println!("\x1b[31;01mNode Balance:\x1b[00m\n{i} FRA units\n");
});
})?;

if basic {
return Ok(());
}

let td_info = ruc::info!(get_td_pubkey()).map(|i| {
let (_, addr) = ruc::info!(get_td_pubkey()).map(|i| {
let addr = td_pubkey_to_td_addr(&i);
println!("\x1b[31;01mValidator Node Addr:\x1b[00m\n{addr}\n");
(i, addr)
});
})?;

let di = utils::get_delegation_info(kp.get_pk_ref());
let bond_entries = match di.as_ref() {
Ok(di) => Some(di.bond_entries.clone()),
Err(_) => None,
};
let evm_staking_address = get_evm_staking_address()?;
let url = format!("{}:8545", get_serv_addr()?);
let address = utils::get_trigger_on_contract_address(&url, evm_staking_address)?;
let (bound_amount, unbound_amount) = utils::get_evm_delegation_info(
&url,
address,
H160::from_str(&addr).c(d!())?,
mapping_address(kp.get_pk_ref()),
)?;

let address = utils::get_claim_on_contract_address(&url, evm_staking_address)?;
let reward =
utils::get_reward_info(&url, address, mapping_address(kp.get_pk_ref()))?;

let delegation_info = di.and_then(|di| {
serde_json::to_string_pretty(&di).c(d!("server returned invalid data"))
});
let delegation_info = ruc::info!(delegation_info).map(|i| {
println!("\x1b[31;01mYour Delegation:\x1b[00m\n{i}\n");
});

if let Ok((tpk, addr)) = td_info.as_ref() {
let self_delegation =
bond_entries.map_or(false, |bes| bes.iter().any(|i| &i.0 == addr));
if self_delegation {
let res = utils::get_validator_detail(&td_pubkey_to_td_addr(tpk))
.c(d!("Validator not found"))
.and_then(|di| {
serde_json::to_string_pretty(&di)
.c(d!("server returned invalid data"))
})
.map(|i| {
println!("\x1b[31;01mYour Staking:\x1b[00m\n{i}\n");
});
ruc::info_omit!(res);
}
}
println!(
"\x1b[31;01mYour Delegation:\x1b[00m\nbound_amount:{:?}\nunbound_amount:{:?}\nreward:{:?}",
bound_amount, unbound_amount,reward
);

if [
serv_addr,
xfr_account,
td_info.map(|_| ()),
self_balance,
delegation_info,
]
.iter()
.any(|i| i.is_err())
{
Err(eg!("unable to obtain complete information"))
} else {
Ok(())
}
Ok(())
}

/// Setup for a cli tool
Expand Down
211 changes: 210 additions & 1 deletion src/components/finutils/src/common/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ use {
serde::{self, Deserialize, Serialize},
serde_json::Value,
sha2::{Digest, Sha256},
sha3::Keccak256,
std::{
collections::{BTreeMap, HashMap},
str::FromStr,
Expand All @@ -32,7 +33,7 @@ use {
web3::{
ethabi::{Function, Param, ParamType, StateMutability, Token},
transports::Http,
types::{BlockId, BlockNumber, Bytes, CallRequest, H160},
types::{BlockId, BlockNumber, Bytes, CallRequest, H160, U256},
Web3,
},
zei::xfr::{
Expand Down Expand Up @@ -745,3 +746,211 @@ pub fn get_validator_memo_and_rate(
};
Ok((memo, rate))
}

#[allow(missing_docs)]
pub fn get_evm_delegation_info(
url: &str,
staking_address: H160,
validator_address: H160,
address: H160,
) -> Result<(U256, U256)> {
let transport = Http::new(url).c(d!())?;
let web3 = Web3::new(transport);

#[allow(deprecated)]
let function = Function {
name: "delegators".to_owned(),
inputs: vec![
Param {
name: String::new(),
kind: ParamType::Address,
internal_type: Some(String::from("address")),
},
Param {
name: String::new(),
kind: ParamType::Address,
internal_type: Some(String::from("address")),
},
],
outputs: vec![
Param {
name: String::from("boundAmount"),
kind: ParamType::Uint(256),
internal_type: Some(String::from("uint256")),
},
Param {
name: String::from("unboundAmount"),
kind: ParamType::Uint(256),
internal_type: Some(String::from("uint256")),
},
],
constant: None,
state_mutability: StateMutability::View,
};
let data = function
.encode_input(&[Token::Address(validator_address), Token::Address(address)])
.map_err(|e| eg!("{:?}", e))?;

let ret_data = Runtime::new()
.c(d!())?
.block_on(web3.eth().call(
CallRequest {
to: Some(staking_address),
data: Some(Bytes(data)),
..Default::default()
},
Some(BlockId::Number(BlockNumber::Latest)),
))
.c(d!())?;

let ret = function.decode_output(&ret_data.0).c(d!())?;
let bound_amount = if let Some(Token::Uint(bound_amount)) = ret.get(0) {
bound_amount
} else {
return Err(eg!("bound_amount not found"));
};
let unbound_amount = if let Some(Token::Uint(unbound_amount)) = ret.get(1) {
unbound_amount
} else {
return Err(eg!("unbound_amount not found"));
};
Ok((*bound_amount, *unbound_amount))
}

#[allow(missing_docs)]
pub fn get_reward_info(url: &str, rewards_address: H160, address: H160) -> Result<U256> {
let transport = Http::new(url).c(d!())?;
let web3 = Web3::new(transport);

#[allow(deprecated)]
let function = Function {
name: "rewards".to_owned(),
inputs: vec![Param {
name: String::new(),
kind: ParamType::Address,
internal_type: Some(String::from("address")),
}],
outputs: vec![Param {
name: String::new(),
kind: ParamType::Uint(256),
internal_type: Some(String::from("uint256")),
}],
constant: None,
state_mutability: StateMutability::View,
};
let data = function
.encode_input(&[Token::Address(address)])
.map_err(|e| eg!("{:?}", e))?;

let ret_data = Runtime::new()
.c(d!())?
.block_on(web3.eth().call(
CallRequest {
to: Some(rewards_address),
data: Some(Bytes(data)),
..Default::default()
},
Some(BlockId::Number(BlockNumber::Latest)),
))
.c(d!())?;

let ret = function.decode_output(&ret_data.0).c(d!())?;
let reward = if let Some(Token::Uint(reward)) = ret.get(0) {
reward
} else {
return Err(eg!("reward not found"));
};

Ok(*reward)
}

#[allow(missing_docs)]
pub fn get_trigger_on_contract_address(
url: &str,
staking_address: H160,
) -> Result<H160> {
let transport = Http::new(url).c(d!())?;
let web3 = Web3::new(transport);

#[allow(deprecated)]
let function = Function {
name: "getTriggerOnContractAddress".to_owned(),
inputs: vec![],
outputs: vec![Param {
name: String::new(),
kind: ParamType::Address,
internal_type: Some(String::from("address")),
}],
constant: None,
state_mutability: StateMutability::View,
};
let data = function.encode_input(&[]).map_err(|e| eg!("{:?}", e))?;

let ret_data = Runtime::new()
.c(d!())?
.block_on(web3.eth().call(
CallRequest {
to: Some(staking_address),
data: Some(Bytes(data)),
..Default::default()
},
Some(BlockId::Number(BlockNumber::Latest)),
))
.c(d!())?;

let ret = function.decode_output(&ret_data.0).c(d!())?;
let address = if let Some(Token::Address(address)) = ret.get(0) {
address
} else {
return Err(eg!("staking address not found"));
};

Ok(*address)
}

#[allow(missing_docs)]
pub fn get_claim_on_contract_address(url: &str, staking_address: H160) -> Result<H160> {
let transport = Http::new(url).c(d!())?;
let web3 = Web3::new(transport);

#[allow(deprecated)]
let function = Function {
name: "getClaimOnContractAddress".to_owned(),
inputs: vec![],
outputs: vec![Param {
name: String::new(),
kind: ParamType::Address,
internal_type: Some(String::from("address")),
}],
constant: None,
state_mutability: StateMutability::View,
};
let data = function.encode_input(&[]).map_err(|e| eg!("{:?}", e))?;

let ret_data = Runtime::new()
.c(d!())?
.block_on(web3.eth().call(
CallRequest {
to: Some(staking_address),
data: Some(Bytes(data)),
..Default::default()
},
Some(BlockId::Number(BlockNumber::Latest)),
))
.c(d!())?;

let ret = function.decode_output(&ret_data.0).c(d!())?;
let address = if let Some(Token::Address(address)) = ret.get(0) {
address
} else {
return Err(eg!("reward address not found"));
};

Ok(*address)
}

#[allow(missing_docs)]
pub fn mapping_address(pk: &XfrPublicKey) -> H160 {
let result = <Keccak256 as sha3::Digest>::digest(pk.as_bytes());
H160::from_slice(&result.as_slice()[..20])
}

0 comments on commit 0ba9a56

Please sign in to comment.