Skip to content

Commit

Permalink
Merge pull request #1530 from mintlayer/fix/transaction-summary
Browse files Browse the repository at this point in the history
Create TextSummary trait
  • Loading branch information
TheQuantumPhysicist authored Feb 5, 2024
2 parents f630721 + a5e0a6f commit cd4b27d
Show file tree
Hide file tree
Showing 7 changed files with 244 additions and 172 deletions.
31 changes: 30 additions & 1 deletion common/src/chain/transaction/input.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

use serialization::{Decode, Encode};

use crate::chain::AccountNonce;
use crate::{chain::AccountNonce, text_summary::TextSummary};

use super::{AccountCommand, AccountOutPoint, AccountSpending, OutPointSourceId, UtxoOutPoint};

Expand Down Expand Up @@ -56,3 +56,32 @@ impl From<UtxoOutPoint> for TxInput {
TxInput::Utxo(outpoint)
}
}

impl TextSummary for TxInput {
fn text_summary(&self, _chain_config: &crate::chain::ChainConfig) -> String {
match self {
TxInput::Utxo(utxo) => {
let source_id = utxo.source_id();
let n = utxo.output_index();
match source_id {
OutPointSourceId::Transaction(ref id) => {
let id_str = format!("{:?}", id.to_hash())
.strip_prefix("0x")
.expect("0x exists for some hellish reason")
.to_string();
format!("Transaction({id_str}, {n})")
}
OutPointSourceId::BlockReward(id) => {
let id_str = format!("{:?}", id.to_hash())
.strip_prefix("0x")
.expect("0x exists for some hellish reason")
.to_string();
format!("BlockReward({id_str}, {n})")
}
}
}
TxInput::Account(acc_out) => format!("{acc_out:?}"),
TxInput::AccountCommand(nonce, cmd) => format!("AccountCommand({nonce}, {cmd:?})"),
}
}
}
5 changes: 4 additions & 1 deletion common/src/chain/transaction/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ use serialization::{DirectDecode, DirectEncode};
use typename::TypeName;

use crate::primitives::{id::WithId, Id, Idable, H256};
use crate::text_summary::TextSummary;

pub mod input;
pub use input::*;
Expand Down Expand Up @@ -143,8 +144,10 @@ impl Transaction {
}
SignedTransaction::new(self, witnesses)
}
}

pub fn printable(&self, chain_config: &ChainConfig) -> String {
impl TextSummary for Transaction {
fn text_summary(&self, chain_config: &ChainConfig) -> String {
printout::transaction_summary(self, chain_config)
}
}
Expand Down
165 changes: 163 additions & 2 deletions common/src/chain/transaction/output/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,18 @@

use crate::{
address::{
hexified::HexifiedAddress, pubkeyhash::PublicKeyHash, traits::Addressable, AddressError,
hexified::HexifiedAddress, pubkeyhash::PublicKeyHash, traits::Addressable, Address,
AddressError,
},
chain::{
output_value::OutputValue,
tokens::{NftIssuance, TokenId, TokenIssuance},
tokens::{IsTokenFreezable, NftIssuance, TokenId, TokenIssuance, TokenTotalSupply},
ChainConfig, DelegationId, PoolId,
},
primitives::{Amount, Id},
text_summary::TextSummary,
};
use crypto::vrf::VRFPublicKey;
use script::Script;
use serialization::{Decode, DecodeAll, Encode};
use variant_count::VariantCount;
Expand Down Expand Up @@ -128,3 +131,161 @@ impl TxOutput {
}
}
}

impl TextSummary for TxOutput {
fn text_summary(&self, chain_config: &ChainConfig) -> String {
let fmt_ml = |v: &Amount| v.into_fixedpoint_str(chain_config.coin_decimals());
let fmt_val = |val: &OutputValue| {
match val {
OutputValue::Coin(amount) => fmt_ml(amount),
OutputValue::TokenV0(token_data) => format!("{token_data:?}"), // Not important since it's deprecated
OutputValue::TokenV1(id, amount) => {
format!(
"TokenV1({}, {amount:?})",
Address::new(chain_config, id)
.expect("Cannot fail due to TokenId being fixed size")
)
}
}
};
let fmt_timelock = |tl: &OutputTimeLock| match tl {
OutputTimeLock::UntilHeight(h) => format!("OutputTimeLock::UntilHeight({h})"),
OutputTimeLock::UntilTime(t) => format!("OutputTimeLock::UntilTime({})", t.into_time()),
OutputTimeLock::ForBlockCount(n) => {
format!("OutputTimeLock::ForBlockCount({n} blocks)")
}
OutputTimeLock::ForSeconds(secs) => {
format!("OutputTimeLock::ForSeconds({secs} seconds)")
}
};
let fmt_dest =
|d: &Destination| format!("{}", Address::new(chain_config, d).expect("addressable"));
let fmt_vrf =
|k: &VRFPublicKey| format!("{}", Address::new(chain_config, k).expect("addressable"));
let fmt_poolid = |id: &PoolId| {
Address::new(chain_config, id).expect("Cannot fail because fixed size addressable")
};
let fmt_tknid = |id: &TokenId| {
Address::new(chain_config, id).expect("Cannot fail because fixed size addressable")
};
let fmt_delid = |id: &DelegationId| {
Address::new(chain_config, id).expect("Cannot fail because fixed size addressable")
};
let fmt_stakepooldata = |p: &StakePoolData| {
let pledge = fmt_ml(&p.pledge());
format!(
"Pledge({pledge}), Staker({}), VRFPubKey({}), DecommissionKey({}), MarginRatio({}), CostPerBlock({})",
fmt_dest(p.staker()),
fmt_vrf(p.vrf_public_key()),
fmt_dest(p.decommission_key()),
p.margin_ratio_per_thousand().into_percentage_str(),
fmt_ml(&p.cost_per_block())
)
};
let fmt_tkn_supply = |s: &TokenTotalSupply, d: u8| match s {
TokenTotalSupply::Fixed(v) => format!("Fixed({})", v.into_fixedpoint_str(d)),
TokenTotalSupply::Lockable => "Lockable".to_string(),
TokenTotalSupply::Unlimited => "Unlimited".to_string(),
};
let fmt_tkn_frzble = |f: &IsTokenFreezable| match f {
IsTokenFreezable::No => "Yes".to_string(),
IsTokenFreezable::Yes => "No".to_string(),
};
let fmt_tkn_iss = |iss: &TokenIssuance| {
match iss {
TokenIssuance::V1(iss1) => format!(
"TokenIssuance(Ticker({}), Decimals({}), MetadataUri({}), TotalSupply({}), Authority({}), IsFreezable({}))",
String::from_utf8_lossy(&iss1.token_ticker),
iss1.number_of_decimals,
String::from_utf8_lossy(&iss1.metadata_uri),
fmt_tkn_supply(&iss1.total_supply, iss1.number_of_decimals),
fmt_dest(&iss1.authority),
fmt_tkn_frzble(&iss1.is_freezable)
),
}
};
let fmt_nft_iss = |iss: &NftIssuance| match iss {
NftIssuance::V0(iss1) => {
let md = &iss1.metadata;
let creator = match &md.creator {
Some(c) => hex::encode(c.public_key.encode()).to_string(),
None => "Unspecified".to_string(),
};
format!(
"Create({}), Name({}), Description({}), Ticker({}), IconUri({}), AdditionalMetaData({}), MediaUri({}), MediaHash(0x{})",
creator,
String::from_utf8_lossy(&md.name),
String::from_utf8_lossy(&md.description),
String::from_utf8_lossy(&md.ticker),
String::from_utf8_lossy(md.icon_uri.as_ref().as_ref().unwrap_or(&vec![])),
String::from_utf8_lossy(
md.additional_metadata_uri.as_ref().as_ref().unwrap_or(&vec![])
),
String::from_utf8_lossy(
md.media_uri.as_ref().as_ref().unwrap_or(&vec![])
),
hex::encode(&md.media_hash),

)
}
};

match self {
TxOutput::Transfer(val, dest) => {
let val_str = fmt_val(val);
format!("Transfer({}, {val_str})", fmt_dest(dest))
}
TxOutput::LockThenTransfer(val, dest, timelock) => {
let val_str = fmt_val(val);
format!(
"LockThenTransfer({}, {val_str}, {})",
fmt_dest(dest),
fmt_timelock(timelock)
)
}
TxOutput::Burn(val) => format!("Burn({})", fmt_val(val)),
TxOutput::CreateStakePool(id, data) => {
format!(
"CreateStakePool(Id({}), {})",
fmt_poolid(id),
fmt_stakepooldata(data)
)
}
TxOutput::ProduceBlockFromStake(dest, pool_id) => {
format!(
"ProduceBlockFromStake({}, {})",
fmt_dest(dest),
fmt_poolid(pool_id)
)
}
TxOutput::CreateDelegationId(owner, pool_id) => {
format!(
"CreateDelegationId(Owner({}), StakingPool({}))",
fmt_dest(owner),
fmt_poolid(pool_id)
)
}
TxOutput::DelegateStaking(amount, del_ig) => {
format!(
"DelegateStaking(Owner({}), StakingPool({}))",
fmt_ml(amount),
fmt_delid(del_ig)
)
}
TxOutput::IssueFungibleToken(issuance) => {
format!("IssueFungibleToken({})", fmt_tkn_iss(issuance))
}
TxOutput::IssueNft(token_id, iss, receiver) => {
format!(
"IssueNft(Id({}), NftIssuance({}), Receiver({}))",
fmt_tknid(token_id),
fmt_nft_iss(iss),
fmt_dest(receiver)
)
}
TxOutput::DataDeposit(data) => {
format!("DataDeposit(0x{})", hex::encode(data))
}
}
}
}
Loading

0 comments on commit cd4b27d

Please sign in to comment.