Skip to content
This repository has been archived by the owner on Dec 28, 2023. It is now read-only.

Commit

Permalink
filter feature for txs/outputs/payments command (mimblewimble#16)
Browse files Browse the repository at this point in the history
* misc filter feature for txs/outputs/payments command

* rustfmt

* modify the command help info
  • Loading branch information
garyyu authored May 3, 2019
1 parent 2d93c08 commit 8934180
Show file tree
Hide file tree
Showing 7 changed files with 324 additions and 16 deletions.
14 changes: 14 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

124 changes: 118 additions & 6 deletions controller/src/command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
// limitations under the License.

use crate::util::{Mutex, ZeroingString};
use chrono::NaiveDateTime as DateTime;
use std::collections::HashMap;
/// Grin wallet command-line function implementations
use std::fs::File;
Expand All @@ -35,7 +36,7 @@ use crate::impls::{
LMDBBackend, NullWalletCommAdapter,
};
use crate::impls::{HTTPNodeClient, WalletSeed};
use crate::libwallet::{InitTxArgs, NodeClient, WalletInst};
use crate::libwallet::{InitTxArgs, NodeClient, OutputStatus, TxLogEntryType, WalletInst};
use crate::{controller, display};

/// Arguments common to all wallet commands
Expand Down Expand Up @@ -419,29 +420,102 @@ pub fn info(
Ok(())
}

/// Outputs command args
pub struct OutputsArgs {
pub minvalue: Option<u64>,
pub status: Option<OutputStatus>,
pub limit: Option<u64>,
}

pub fn outputs(
wallet: Arc<Mutex<WalletInst<impl NodeClient + 'static, keychain::ExtKeychain>>>,
g_args: &GlobalArgs,
args: OutputsArgs,
dark_scheme: bool,
) -> Result<(), Error> {
controller::owner_single_use(wallet.clone(), |api| {
let res = api.node_height()?;
let (validated, outputs) = api.retrieve_outputs(g_args.show_spent, true, None)?;
display::outputs(&g_args.account, res.height, validated, outputs, dark_scheme)?;

// filter by value
let mut filtered_outputs = if let Some(minvalue) = args.minvalue {
outputs
.into_iter()
.filter(|out| out.output.value >= minvalue)
.collect::<Vec<_>>()
} else {
outputs
};

// filter by status
if let Some(status) = args.status {
filtered_outputs = filtered_outputs
.into_iter()
.filter(|out| out.output.status == status)
.collect::<Vec<_>>();
}

// limit the display lines
if let Some(limit) = args.limit {
if (limit as usize) < filtered_outputs.len() {
let drop = filtered_outputs.len() - limit as usize;
filtered_outputs = filtered_outputs.drain(drop..).collect();
}
}

display::outputs(
&g_args.account,
res.height,
validated,
filtered_outputs,
dark_scheme,
)?;
Ok(())
})?;
Ok(())
}

/// Payments command args
pub struct PaymentsArgs {
pub status: Option<OutputStatus>,
pub limit: Option<u64>,
}

pub fn payments(
wallet: Arc<Mutex<WalletInst<impl NodeClient + 'static, keychain::ExtKeychain>>>,
g_args: &GlobalArgs,
args: PaymentsArgs,
dark_scheme: bool,
) -> Result<(), Error> {
controller::owner_single_use(wallet.clone(), |api| {
let res = api.node_height()?;
let (validated, outputs) = api.retrieve_payments(true, None)?;
display::payments(&g_args.account, res.height, validated, outputs, dark_scheme)?;

// filter by status
let mut filtered_outputs = if let Some(status) = args.status {
outputs
.into_iter()
.filter(|out| out.output.status == status)
.collect::<Vec<_>>()
} else {
outputs
};

// limit the display lines
if let Some(limit) = args.limit {
if (limit as usize) < filtered_outputs.len() {
let drop = filtered_outputs.len() - limit as usize;
filtered_outputs = filtered_outputs.drain(drop..).collect();
}
}

display::payments(
&g_args.account,
res.height,
validated,
filtered_outputs,
dark_scheme,
)?;
Ok(())
})?;
Ok(())
Expand All @@ -450,6 +524,10 @@ pub fn payments(
/// Txs command args
pub struct TxsArgs {
pub id: Option<u32>,
pub tx_type: Option<TxLogEntryType>,
pub start_date: Option<DateTime>,
pub end_date: Option<DateTime>,
pub limit: Option<u64>,
}

pub fn txs(
Expand All @@ -462,11 +540,45 @@ pub fn txs(
let res = api.node_height()?;
let (validated, txs) = api.retrieve_txs(true, args.id, None)?;
let include_status = !args.id.is_some();

let mut filtered_txs;
{
// Filter by tx type
filtered_txs = if let Some(tx_type) = args.tx_type {
txs.into_iter()
.filter(|tx| tx.tx_type == tx_type)
.collect::<Vec<_>>()
} else {
txs
};

// Filter by date
if let Some(start_date) = args.start_date {
if let Some(end_date) = args.end_date {
filtered_txs = filtered_txs
.into_iter()
.filter(|tx| {
tx.creation_ts.naive_local() >= start_date
&& tx.creation_ts.naive_local() <= end_date
})
.collect::<Vec<_>>();
}
}

// limit the display lines
if let Some(limit) = args.limit {
if (limit as usize) < filtered_txs.len() {
let drop = filtered_txs.len() - limit as usize;
filtered_txs = filtered_txs.drain(drop..).collect();
}
}
}

display::txs(
&g_args.account,
res.height,
validated,
&txs,
&filtered_txs,
include_status,
dark_scheme,
)?;
Expand All @@ -476,7 +588,7 @@ pub fn txs(
let (_, outputs) = api.retrieve_outputs(true, false, args.id)?;
display::outputs(&g_args.account, res.height, validated, outputs, dark_scheme)?;
// should only be one here, but just in case
for tx in &txs {
for tx in &filtered_txs {
let (_, outputs) = api.retrieve_payments(true, tx.tx_slate_id)?;
if outputs.len() > 0 {
display::payments(
Expand All @@ -490,7 +602,7 @@ pub fn txs(
}

// should only be one here, but just in case
for tx in &txs {
for tx in &filtered_txs {
display::tx_messages(tx, dark_scheme)?;
}
};
Expand Down
5 changes: 5 additions & 0 deletions controller/src/display.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ pub fn outputs(
bMG->"Tx"
]);

let len = outputs.len();
for m in outputs {
let commit = format!("{}", util::to_hex(m.commit.as_ref().to_vec()));
let index = match m.output.mmr_index {
Expand Down Expand Up @@ -108,6 +109,7 @@ pub fn outputs(
table.set_format(*prettytable::format::consts::FORMAT_NO_COLSEP);
table.printstd();
println!();
println!("total displayed outputs: {}", len);

if !validated {
println!(
Expand Down Expand Up @@ -149,6 +151,7 @@ pub fn payments(
bMG->"Shared Transaction Id"
]);

let len = outputs.len();
for payment in outputs {
let commit = format!("{}", util::to_hex(payment.commit.as_ref().to_vec()));
let out = payment.output;
Expand Down Expand Up @@ -191,6 +194,7 @@ pub fn payments(
table.set_format(*prettytable::format::consts::FORMAT_NO_COLSEP);
table.printstd();
println!();
println!("total displayed payments: {}", len);

if !validated {
println!(
Expand Down Expand Up @@ -328,6 +332,7 @@ pub fn txs(
table.set_format(*prettytable::format::consts::FORMAT_NO_COLSEP);
table.printstd();
println!();
println!("total displayed txs: {}", txs.len());

if !validated && include_status {
println!(
Expand Down
3 changes: 3 additions & 0 deletions controller/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ extern crate prettytable;
extern crate log;
#[macro_use]
extern crate lazy_static;
extern crate chrono;

use failure;
use grin_wallet_api as apiwallet;
use grin_wallet_config as config;
Expand All @@ -37,3 +39,4 @@ pub mod display;
mod error;

pub use crate::error::{Error, ErrorKind};
pub use chrono::NaiveDateTime as DateTime;
2 changes: 2 additions & 0 deletions libwallet/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ log = "0.4"
uuid = { version = "0.7", features = ["serde", "v4"] }
chrono = { version = "0.4.4", features = ["serde"] }
lazy_static = "1"
custom_derive = "0.1.7"
enum_derive = "0.1.7"

grin_wallet_util = { path = "../util", version = "1.1.0-beta.2" }

Expand Down
Loading

0 comments on commit 8934180

Please sign in to comment.