Skip to content

Commit

Permalink
Account show balance by list resource api, and output full token code…
Browse files Browse the repository at this point in the history
… as balance name. (#2658)

* [cli] Account show balance by list resource api, and output full token code as balance name.

* [cli] Fix dev deploy command transaction sender's bug
  • Loading branch information
jolestar authored Jul 4, 2021
1 parent 413861e commit e8fa28d
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 27 deletions.
28 changes: 20 additions & 8 deletions cmd/starcoin/src/account/show_cmd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,11 @@ use crate::StarcoinOpt;
use anyhow::{format_err, Result};
use scmd::{CommandAction, ExecContext};
use starcoin_crypto::{HashValue, ValidCryptoMaterialStringExt};
use starcoin_rpc_api::types::AnnotatedMoveValueView;
use starcoin_rpc_client::RemoteStateReader;
use starcoin_state_api::AccountStateReader;
use starcoin_vm_types::account_address::AccountAddress;
use starcoin_vm_types::account_config::BalanceResource;
use std::collections::HashMap;
use structopt::StructOpt;

Expand Down Expand Up @@ -64,14 +66,24 @@ impl CommandAction for ShowCommand {
.get_account_resource(account.address())?
.map(|res| res.sequence_number());

let accepted_tokens = client.account_accepted_tokens(account_address)?;
let mut balances = HashMap::with_capacity(accepted_tokens.len());
for token in accepted_tokens {
let token_name = token.name.clone();
let balance =
account_state_reader.get_balance_by_token_code(account.address(), token)?;
if let Some(b) = balance {
balances.insert(token_name, b);
let mut balances = HashMap::new();

let state = client.get_account_state_set(*account.address(), None)?;
if let Some(state) = state {
for (token_code, resource) in state.resources.into_iter().filter_map(|(k, v)| {
BalanceResource::token_code(&k.0).map(|token_code| (token_code, v))
}) {
let balance = if let AnnotatedMoveValueView::Struct(token) = &resource.value[0].1 {
if let AnnotatedMoveValueView::U128(value) = token.value[0].1 {
value.0
} else {
0
}
} else {
//this should not happen
0
};
balances.insert(token_code.to_string(), balance);
}
}
let auth_key = account.public_key.authentication_key();
Expand Down
10 changes: 6 additions & 4 deletions cmd/starcoin/src/dev/deploy_cmd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,13 +65,15 @@ impl CommandAction for DeployCommand {
ensure!(*sender == package_address, "please use package address({}) account to deploy package, currently sender is {}.", package_address,sender);
}
None => {
eprintln!(
"Use package address ({}) as transaction sender",
package_address
);
transaction_opts.sender = Some(package_address);
}
};

ctx.state().build_and_execute_transaction(
opt.transaction_opts.clone(),
TransactionPayload::Package(package),
)
ctx.state()
.build_and_execute_transaction(transaction_opts, TransactionPayload::Package(package))
}
}
17 changes: 17 additions & 0 deletions vm/types/src/account_config/resources/balance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// SPDX-License-Identifier: Apache-2.0

use crate::access_path::DataPath;
use crate::token::token_code::TokenCode;
use crate::{
access_path::AccessPath,
account_config::constants::{stc_type_tag, ACCOUNT_MODULE_NAME, CORE_CODE_ADDRESS},
Expand Down Expand Up @@ -39,6 +40,22 @@ impl BalanceResource {
pub fn access_path_for(token_type_tag: StructTag) -> DataPath {
AccessPath::resource_data_path(BalanceResource::struct_tag_for_token(token_type_tag))
}

/// Get token code from Balance StructTag, return None if struct tag is not a valid Balance StructTag
pub fn token_code(struct_tag: &StructTag) -> Option<TokenCode> {
if struct_tag.address == CORE_CODE_ADDRESS
&& struct_tag.module.as_str() == Self::MODULE_NAME
&& struct_tag.name.as_str() == Self::STRUCT_NAME
{
if let Some(TypeTag::Struct(token_tag)) = struct_tag.type_params.get(0) {
Some(token_tag.clone().into())
} else {
None
}
} else {
None
}
}
}

impl MoveResource for BalanceResource {
Expand Down
34 changes: 19 additions & 15 deletions vm/types/src/token/token_code.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use crate::language_storage::TypeTag;
use crate::move_resource::MoveResource;
use crate::parser::parse_type_tag;
use crate::token::TOKEN_MODULE_NAME;
use anyhow::{bail, ensure, Result};
use anyhow::{bail, Result};
use move_core_types::account_address::AccountAddress;
use move_core_types::language_storage::StructTag;
use serde::{Deserialize, Serialize};
Expand All @@ -15,11 +15,11 @@ use std::str::FromStr;

#[derive(Debug, Ord, PartialOrd, Eq, PartialEq, Hash, Clone, Serialize, Deserialize)]
pub struct TokenCode {
//Token module's address
///Token module's address
pub address: AccountAddress,
//Token module's name
///Token module's name
pub module: String,
//Token's struct name
///Token's struct name
pub name: String,
}

Expand Down Expand Up @@ -51,23 +51,22 @@ impl TryFrom<TypeTag> for TokenCode {

fn try_from(value: TypeTag) -> Result<Self, Self::Error> {
match value {
TypeTag::Struct(struct_tag) => TokenCode::try_from(struct_tag),
TypeTag::Struct(struct_tag) => Ok(TokenCode::from(struct_tag)),
type_tag => bail!("{:?} is not a Token's type tag", type_tag),
}
}
}
impl TryFrom<StructTag> for TokenCode {
type Error = anyhow::Error;

fn try_from(struct_tag: StructTag) -> Result<Self, Self::Error> {
impl From<StructTag> for TokenCode {
fn from(struct_tag: StructTag) -> Self {
let tag_str = struct_tag.to_string();
let s: Vec<_> = tag_str.splitn(3, "::").collect();
ensure!(s.len() == 3, "invalid struct tag format");
Ok(Self::new(
//this should not happen
assert_eq!(s.len(), 3, "invalid struct tag format");
Self::new(
struct_tag.address,
struct_tag.module.into_string(),
s[2].to_string(),
))
)
}
}
impl FromStr for TokenCode {
Expand Down Expand Up @@ -101,9 +100,14 @@ mod test {

#[test]
fn test_token_code() {
let token = "0x2::LiquidityToken::LiquidityToken<0x569ab535990a17ac9afd1bc57faec683::Ddd::Ddd, 0x569ab535990a17ac9afd1bc57faec683::Bot::Bot>";
let token = "0x00000000000000000000000000000002::LiquidityToken::LiquidityToken<0x569ab535990a17ac9afd1bc57faec683::Ddd::Ddd, 0x569ab535990a17ac9afd1bc57faec683::Bot::Bot>";
let tc = TokenCode::from_str(token).unwrap();
let type_tag: StructTag = tc.try_into().unwrap();
assert_eq!(parse_type_tag(token).unwrap(), TypeTag::Struct(type_tag));
let type_tag: StructTag = tc.clone().try_into().unwrap();
assert_eq!(token.to_string(), tc.to_string());
assert_eq!(
parse_type_tag(token).unwrap(),
TypeTag::Struct(type_tag.clone())
);
assert_eq!(tc, type_tag.try_into().unwrap());
}
}

0 comments on commit e8fa28d

Please sign in to comment.