mirror of
https://github.com/jwinterm/grin-wallet.git
synced 2026-10-17 15:21:39 +02:00
Implement fee inclusive transactions (#657)
* Add amount_includes_fee option in TX building * Add --amount_includes_fee CLI option * Implement send 'max' amount Co-authored-by: cliik <cliik@example.com>
This commit is contained in:
+153
-7
@@ -281,6 +281,85 @@ fn command_line_test_impl(test_dir: &str) -> Result<(), grin_wallet_controller::
|
||||
},
|
||||
)?;
|
||||
|
||||
// Send to wallet 2 with --amount_includes_fee
|
||||
let mut old_balance = 0;
|
||||
grin_wallet_controller::controller::owner_single_use(
|
||||
Some(wallet1.clone()),
|
||||
mask1,
|
||||
None,
|
||||
|api, m| {
|
||||
api.set_active_account(m, "mining")?;
|
||||
let (_, wallet1_info) = api.retrieve_summary_info(m, true, 1)?;
|
||||
old_balance = wallet1_info.amount_currently_spendable;
|
||||
Ok(())
|
||||
},
|
||||
)?;
|
||||
let arg_vec = vec![
|
||||
"grin-wallet",
|
||||
"-p",
|
||||
"password1",
|
||||
"-a",
|
||||
"mining",
|
||||
"send",
|
||||
"--amount_includes_fee",
|
||||
"10",
|
||||
];
|
||||
execute_command(&app, test_dir, "wallet1", &client1, arg_vec)?;
|
||||
let file_name = format!(
|
||||
"{}/wallet1/slatepack/0436430c-2b02-624c-2032-570501212b01.S1.slatepack",
|
||||
test_dir
|
||||
);
|
||||
let arg_vec = vec![
|
||||
"grin-wallet",
|
||||
"-p",
|
||||
"password2",
|
||||
"-a",
|
||||
"account_1",
|
||||
"receive",
|
||||
"-i",
|
||||
&file_name,
|
||||
];
|
||||
execute_command(&app, test_dir, "wallet2", &client2, arg_vec.clone())?;
|
||||
let file_name = format!(
|
||||
"{}/wallet2/slatepack/0436430c-2b02-624c-2032-570501212b01.S2.slatepack",
|
||||
test_dir
|
||||
);
|
||||
let arg_vec = vec![
|
||||
"grin-wallet",
|
||||
"-a",
|
||||
"mining",
|
||||
"-p",
|
||||
"password1",
|
||||
"finalize",
|
||||
"-i",
|
||||
&file_name,
|
||||
];
|
||||
execute_command(&app, test_dir, "wallet1", &client1, arg_vec)?;
|
||||
bh += 1;
|
||||
|
||||
// Mine some blocks to confirm the transaction
|
||||
let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), mask1, 10, false);
|
||||
bh += 10;
|
||||
|
||||
// Check the new balance of wallet 1 reduced by EXACTLY the tx amount (instead of amount + fee)
|
||||
// This confirms that the TX amount was correctly computed to allow for the fee
|
||||
grin_wallet_controller::controller::owner_single_use(
|
||||
Some(wallet1.clone()),
|
||||
mask1,
|
||||
None,
|
||||
|api, m| {
|
||||
api.set_active_account(m, "mining")?;
|
||||
let (_, wallet1_info) = api.retrieve_summary_info(m, true, 1)?;
|
||||
// make sure the new balance is exactly equal to the old balance - the tx amount + the amount mined since then
|
||||
let amt_mined = 10 * 60_000_000_000;
|
||||
assert_eq!(
|
||||
wallet1_info.amount_currently_spendable + 10_000_000_000,
|
||||
old_balance + amt_mined
|
||||
);
|
||||
Ok(())
|
||||
},
|
||||
)?;
|
||||
|
||||
// Send encrypted from wallet 1 to wallet 2
|
||||
// output wallet 2's address for test creation purposes,
|
||||
let arg_vec = vec![
|
||||
@@ -308,7 +387,7 @@ fn command_line_test_impl(test_dir: &str) -> Result<(), grin_wallet_controller::
|
||||
execute_command(&app, test_dir, "wallet1", &client1, arg_vec)?;
|
||||
|
||||
let file_name = format!(
|
||||
"{}/wallet1/slatepack/0436430c-2b02-624c-2032-570501212b01.S1.slatepack",
|
||||
"{}/wallet1/slatepack/0436430c-2b02-624c-2032-570501212b02.S1.slatepack",
|
||||
test_dir
|
||||
);
|
||||
let arg_vec = vec![
|
||||
@@ -324,7 +403,7 @@ fn command_line_test_impl(test_dir: &str) -> Result<(), grin_wallet_controller::
|
||||
execute_command(&app, test_dir, "wallet2", &client2, arg_vec.clone())?;
|
||||
|
||||
let file_name = format!(
|
||||
"{}/wallet2/slatepack/0436430c-2b02-624c-2032-570501212b01.S2.slatepack",
|
||||
"{}/wallet2/slatepack/0436430c-2b02-624c-2032-570501212b02.S2.slatepack",
|
||||
test_dir
|
||||
);
|
||||
|
||||
@@ -381,7 +460,7 @@ fn command_line_test_impl(test_dir: &str) -> Result<(), grin_wallet_controller::
|
||||
execute_command(&app, test_dir, "wallet1", &client1, arg_vec)?;
|
||||
|
||||
let file_name = format!(
|
||||
"{}/wallet1/slatepack/0436430c-2b02-624c-2032-570501212b02.S1.slatepack",
|
||||
"{}/wallet1/slatepack/0436430c-2b02-624c-2032-570501212b03.S1.slatepack",
|
||||
test_dir
|
||||
);
|
||||
let arg_vec = vec![
|
||||
@@ -397,7 +476,7 @@ fn command_line_test_impl(test_dir: &str) -> Result<(), grin_wallet_controller::
|
||||
execute_command(&app, test_dir, "wallet1", &client1, arg_vec.clone())?;
|
||||
|
||||
let file_name = format!(
|
||||
"{}/wallet1/slatepack/0436430c-2b02-624c-2032-570501212b02.S2.slatepack",
|
||||
"{}/wallet1/slatepack/0436430c-2b02-624c-2032-570501212b03.S2.slatepack",
|
||||
test_dir
|
||||
);
|
||||
|
||||
@@ -475,7 +554,7 @@ fn command_line_test_impl(test_dir: &str) -> Result<(), grin_wallet_controller::
|
||||
"mining",
|
||||
"cancel",
|
||||
"-i",
|
||||
"25",
|
||||
"36",
|
||||
];
|
||||
execute_command(&app, test_dir, "wallet1", &client1, arg_vec)?;
|
||||
|
||||
@@ -483,7 +562,7 @@ fn command_line_test_impl(test_dir: &str) -> Result<(), grin_wallet_controller::
|
||||
let arg_vec = vec!["grin-wallet", "-p", "password2", "invoice", "65"];
|
||||
execute_command(&app, test_dir, "wallet2", &client2, arg_vec)?;
|
||||
let file_name = format!(
|
||||
"{}/wallet2/slatepack/0436430c-2b02-624c-2032-570501212b05.I1.slatepack",
|
||||
"{}/wallet2/slatepack/0436430c-2b02-624c-2032-570501212b06.I1.slatepack",
|
||||
test_dir
|
||||
);
|
||||
|
||||
@@ -501,7 +580,7 @@ fn command_line_test_impl(test_dir: &str) -> Result<(), grin_wallet_controller::
|
||||
execute_command(&app, test_dir, "wallet1", &client1, arg_vec)?;
|
||||
|
||||
let file_name = format!(
|
||||
"{}/wallet1/slatepack/0436430c-2b02-624c-2032-570501212b05.I2.slatepack",
|
||||
"{}/wallet1/slatepack/0436430c-2b02-624c-2032-570501212b06.I2.slatepack",
|
||||
test_dir
|
||||
);
|
||||
|
||||
@@ -565,6 +644,73 @@ fn command_line_test_impl(test_dir: &str) -> Result<(), grin_wallet_controller::
|
||||
let arg_vec = vec!["grin-wallet", "-p", "password2", "txs", "-t", &tx_id[..]];
|
||||
execute_command(&app, test_dir, "wallet2", &client2, arg_vec)?;
|
||||
|
||||
// bit of mining
|
||||
let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), mask1, 10, false);
|
||||
|
||||
// Test wallet sweep
|
||||
let arg_vec = vec![
|
||||
"grin-wallet",
|
||||
"-p",
|
||||
"password1",
|
||||
"-a",
|
||||
"mining",
|
||||
"send",
|
||||
"max",
|
||||
];
|
||||
execute_command(&app, test_dir, "wallet1", &client1, arg_vec)?;
|
||||
let file_name = format!(
|
||||
"{}/wallet1/slatepack/0436430c-2b02-624c-2032-570501212b07.S1.slatepack",
|
||||
test_dir
|
||||
);
|
||||
let arg_vec = vec![
|
||||
"grin-wallet",
|
||||
"-p",
|
||||
"password2",
|
||||
"-a",
|
||||
"account_1",
|
||||
"receive",
|
||||
"-i",
|
||||
&file_name,
|
||||
];
|
||||
execute_command(&app, test_dir, "wallet2", &client2, arg_vec.clone())?;
|
||||
let file_name = format!(
|
||||
"{}/wallet2/slatepack/0436430c-2b02-624c-2032-570501212b07.S2.slatepack",
|
||||
test_dir
|
||||
);
|
||||
let arg_vec = vec![
|
||||
"grin-wallet",
|
||||
"-a",
|
||||
"mining",
|
||||
"-p",
|
||||
"password1",
|
||||
"finalize",
|
||||
"-i",
|
||||
&file_name,
|
||||
];
|
||||
execute_command(&app, test_dir, "wallet1", &client1, arg_vec)?;
|
||||
|
||||
// Mine some blocks to confirm the transaction
|
||||
let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), mask1, 10, false);
|
||||
|
||||
// Check wallet 1 is now empty, except for immature coinbase outputs from recent mining),
|
||||
// and recently matured coinbase outputs, which were not mature at time of spending.
|
||||
// This confirms that the TX amount was correctly computed to allow for the fee
|
||||
grin_wallet_controller::controller::owner_single_use(
|
||||
Some(wallet1.clone()),
|
||||
mask1,
|
||||
None,
|
||||
|api, m| {
|
||||
api.set_active_account(m, "mining")?;
|
||||
let (_, wallet1_info) = api.retrieve_summary_info(m, true, 10)?;
|
||||
// Entire 'spendable' wallet balance should have been swept, except the coinbase outputs
|
||||
// which matured in the last batch of mining. Check that the new spendable balance is
|
||||
// exactly equal to those matured coins.
|
||||
let amt_mined = 10 * 60_000_000_000;
|
||||
assert_eq!(wallet1_info.amount_currently_spendable, amt_mined);
|
||||
Ok(())
|
||||
},
|
||||
)?;
|
||||
|
||||
// let logging finish
|
||||
thread::sleep(Duration::from_millis(200));
|
||||
clean_output_dir(test_dir);
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
"args": {
|
||||
"src_acct_name": null,
|
||||
"amount": "600000000000",
|
||||
"amount_includes_fee": false,
|
||||
"minimum_confirmations": 2,
|
||||
"max_outputs": 500,
|
||||
"num_change_outputs": 1,
|
||||
|
||||
Reference in New Issue
Block a user