diff --git a/src/bin/grin.rs b/src/bin/grin.rs index df67be01e..7db582d6e 100644 --- a/src/bin/grin.rs +++ b/src/bin/grin.rs @@ -489,6 +489,14 @@ fn wallet_command(wallet_args: &ArgMatches, global_config: GlobalConfig) { amount_to_hr_string(available), ); } + Err(wallet::Error::FeeExceedsAmount {sender_amount, recipient_fee}) => { + error!( + LOGGER, + "Recipient rejected the transfer because transaction fee ({}) exceeded amount ({}).", + amount_to_hr_string(recipient_fee), + amount_to_hr_string(sender_amount) + ); + } Err(e) => { error!(LOGGER, "Tx not sent: {:?}", e); } diff --git a/wallet/src/receiver.rs b/wallet/src/receiver.rs index 18a5d5c0b..384fba352 100644 --- a/wallet/src/receiver.rs +++ b/wallet/src/receiver.rs @@ -24,7 +24,7 @@ use serde_json; use api; use core::consensus::reward; -use core::core::{build, Block, Output, Transaction, TxKernel}; +use core::core::{build, Block, Output, Transaction, TxKernel, amount_to_hr_string}; use core::ser; use keychain::{Identifier, Keychain}; use types::*; @@ -66,6 +66,19 @@ fn handle_sender_initiation( }); } + if fee > amount { + info!( + LOGGER, + "Rejected the transfer because transaction fee ({}) exceeds received amount ({}).", + amount_to_hr_string(fee), + amount_to_hr_string(amount) + ); + return Err(Error::FeeExceedsAmount { + sender_amount: amount, + recipient_fee: fee, + }); + } + let out_amount = amount - fee; //First step is just to get the excess sum of the outputs we're participating in @@ -310,6 +323,19 @@ fn build_final_transaction( }); } + if fee > amount { + info!( + LOGGER, + "Rejected the transfer because transaction fee ({}) exceeds received amount ({}).", + amount_to_hr_string(fee), + amount_to_hr_string(amount) + ); + return Err(Error::FeeExceedsAmount { + sender_amount: amount, + recipient_fee: fee, + }); + } + let out_amount = amount - fee; // Get output we created in earlier step diff --git a/wallet/src/sender.rs b/wallet/src/sender.rs index 7e683fd4c..6023497d4 100644 --- a/wallet/src/sender.rs +++ b/wallet/src/sender.rs @@ -15,7 +15,7 @@ use api; use client; use checker; -use core::core::{build, Transaction}; +use core::core::{build, Transaction, amount_to_hr_string}; use core::ser; use keychain::{BlindingFactor, Identifier, Keychain}; use receiver::TxWrapper; @@ -97,7 +97,16 @@ pub fn issue_send_tx( debug!(LOGGER, "Posting partial transaction to {}", url); let res = client::send_partial_tx(&url, &partial_tx); if let Err(e) = res { - error!(LOGGER, "Communication with receiver failed on SenderInitiation send. Aborting transaction"); + match e { + Error::FeeExceedsAmount {sender_amount, recipient_fee} => + error!( + LOGGER, + "Recipient rejected the transfer because transaction fee ({}) exceeded amount ({}).", + amount_to_hr_string(recipient_fee), + amount_to_hr_string(sender_amount) + ), + _ => error!(LOGGER, "Communication with receiver failed on SenderInitiation send. Aborting transaction"), + } rollback_wallet()?; return Err(e); } @@ -124,7 +133,16 @@ pub fn issue_send_tx( // And send again let res = client::send_partial_tx(&url, &partial_tx); if let Err(e) = res { - error!(LOGGER, "Communication with receiver failed on SenderConfirmation send. Aborting transaction"); + match e { + Error::FeeExceedsAmount {sender_amount, recipient_fee} => + error!( + LOGGER, + "Recipient rejected the transfer because transaction fee ({}) exceeded amount ({}).", + amount_to_hr_string(recipient_fee), + amount_to_hr_string(sender_amount) + ), + _ => error!(LOGGER, "Communication with receiver failed on SenderConfirmation send. Aborting transaction"), + } rollback_wallet()?; return Err(e); } diff --git a/wallet/src/types.rs b/wallet/src/types.rs index fe5fc4e88..26a95bac1 100644 --- a/wallet/src/types.rs +++ b/wallet/src/types.rs @@ -66,6 +66,7 @@ pub fn tx_fee(input_len: usize, output_len: usize, base_fee: Option) -> u64 pub enum Error { NotEnoughFunds(u64), FeeDispute { sender_fee: u64, recipient_fee: u64 }, + FeeExceedsAmount { sender_amount: u64, recipient_fee: u64 }, Keychain(keychain::Error), Transaction(transaction::Error), Secp(secp::Error),