Skip to content
This repository has been archived by the owner on Jul 27, 2022. It is now read-only.

Problem:(CRO-524) Client may create transactions with potentially spent utxos #701

Merged
merged 1 commit into from
Jan 6, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 33 additions & 2 deletions client-cli/src/command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,12 @@ pub enum Command {
help = "Disable fast forward, which is not secure when connecting to outside nodes"
)]
disable_fast_forward: bool,
#[structopt(
name = "block_height_ensure",
long,
help = "Number of block height to rollback the utxos in pending transactions"
)]
block_height_ensure: u64,
},
}

Expand Down Expand Up @@ -259,6 +265,7 @@ impl Command {
batch_size,
force,
disable_fast_forward,
block_height_ensure,
} => {
let tendermint_client = WebsocketRpcClient::new(&tendermint_url())?;
let tx_obfuscation = get_tx_query(tendermint_client.clone())?;
Expand All @@ -267,8 +274,9 @@ impl Command {
SledStorage::new(storage_path())?,
tendermint_client,
tx_obfuscation,
!disable_fast_forward,
!*disable_fast_forward,
*batch_size,
*block_height_ensure,
);
Self::resync(config, name.clone(), passphrase, *force)
}
Expand Down Expand Up @@ -381,7 +389,30 @@ impl Command {
let passphrase = ask_passphrase(None)?;
let balance = wallet_client.balance(name, &passphrase)?;

success(&format!("Wallet balance: {}", balance));
let rows = vec![
Row::new(vec![
Cell::new("Total", Default::default()),
Cell::new(format!("{}", balance.total).as_str(), Default::default()),
]),
Row::new(vec![
Cell::new("Pending", Default::default()),
Cell::new(format!("{}", balance.pending).as_str(), Default::default()),
]),
Row::new(vec![
Cell::new("Available", Default::default()),
Cell::new(
format!("{}", balance.available).as_str(),
Default::default(),
),
]),
];

let table = Table::new(rows, Default::default());
table
.print_stdout()
.chain(|| (ErrorKind::IoError, "Unable to print table"))?;

success(&format!("Wallet balance: \n {:?}", balance));
devashishdxt marked this conversation as resolved.
Show resolved Hide resolved
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
success(&format!("Wallet balance: \n {:?}", balance));

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

Ok(())
}

Expand Down
66 changes: 52 additions & 14 deletions client-cli/src/command/transaction_command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use chain_core::tx::data::input::TxoPointer;
use chain_core::tx::data::output::TxOut;
use chain_core::tx::TxAux;
use client_common::{Error, ErrorKind, PublicKey, Result, ResultExt};
use client_core::types::TransactionPending;
use client_core::WalletClient;
use client_network::NetworkOpsClient;
use hex::decode;
Expand Down Expand Up @@ -119,21 +120,45 @@ fn new_transaction<T: WalletClient, N: NetworkOpsClient>(
) -> Result<()> {
let passphrase = ask_passphrase(None)?;

let transaction = match transaction_type {
TransactionType::Transfer => new_transfer_transaction(wallet_client, name, &passphrase),
TransactionType::Deposit => new_deposit_transaction(network_ops_client, name, &passphrase),
TransactionType::Unbond => new_unbond_transaction(network_ops_client, name, &passphrase),
match transaction_type {
TransactionType::Transfer => {
let (tx_aux, tx_pending) = new_transfer_transaction(wallet_client, name, &passphrase)?;
wallet_client.broadcast_transaction(&tx_aux)?;
wallet_client.update_tx_pending_state(
&name,
&passphrase,
tx_aux.tx_id(),
tx_pending,
)?;
}
TransactionType::Deposit => {
let tx_aux = new_deposit_transaction(network_ops_client, name, &passphrase)?;
wallet_client.broadcast_transaction(&tx_aux)?;
}
TransactionType::Unbond => {
let tx_aux = new_unbond_transaction(network_ops_client, name, &passphrase)?;
wallet_client.broadcast_transaction(&tx_aux)?;
}
TransactionType::Withdraw => {
new_withdraw_transaction(wallet_client, network_ops_client, name, &passphrase)
let (tx_aux, tx_pending) =
new_withdraw_transaction(wallet_client, network_ops_client, name, &passphrase)?;
wallet_client.broadcast_transaction(&tx_aux)?;
wallet_client.update_tx_pending_state(
&name,
&passphrase,
tx_aux.tx_id(),
tx_pending,
)?;
}
TransactionType::Unjail => {
let tx_aux = new_unjail_transaction(network_ops_client, name, &passphrase)?;
wallet_client.broadcast_transaction(&tx_aux)?;
}
TransactionType::Unjail => new_unjail_transaction(network_ops_client, name, &passphrase),
TransactionType::NodeJoin => {
new_node_join_transaction(network_ops_client, name, &passphrase)
let tx_aux = new_node_join_transaction(network_ops_client, name, &passphrase)?;
wallet_client.broadcast_transaction(&tx_aux)?;
}
}?;

wallet_client.broadcast_transaction(&transaction)?;

};
Ok(())
}

Expand All @@ -142,7 +167,7 @@ fn new_withdraw_transaction<T: WalletClient, N: NetworkOpsClient>(
network_ops_client: &N,
name: &str,
passphrase: &SecUtf8,
) -> Result<TxAux> {
) -> Result<(TxAux, TransactionPending)> {
let from_address = ask_staking_address()?;
let to_address = ask_transfer_address()?;
let view_keys = ask_view_keys()?;
Expand Down Expand Up @@ -204,7 +229,7 @@ fn new_transfer_transaction<T: WalletClient>(
wallet_client: &T,
name: &str,
passphrase: &SecUtf8,
) -> Result<TxAux> {
) -> Result<(TxAux, TransactionPending)> {
let outputs = ask_outputs()?;
let view_keys = ask_view_keys()?;

Expand All @@ -226,7 +251,20 @@ fn new_transfer_transaction<T: WalletClient>(

let return_address = wallet_client.new_transfer_address(name, &passphrase)?;

wallet_client.create_transaction(name, &passphrase, outputs, attributes, None, return_address)
let (transaction, used_inputs, return_amount) = wallet_client.create_transaction(
name,
&passphrase,
outputs,
attributes,
None,
return_address,
)?;
let tx_pending = TransactionPending {
block_height: wallet_client.get_current_block_height()?,
used_inputs,
return_amount,
};
Ok((transaction, tx_pending))
}

fn new_unjail_transaction<N: NetworkOpsClient>(
Expand Down
Loading