diff --git a/src/monero_fee_utils.cpp b/src/monero_fee_utils.cpp index fd8c739..c848825 100644 --- a/src/monero_fee_utils.cpp +++ b/src/monero_fee_utils.cpp @@ -56,22 +56,6 @@ uint64_t monero_fee_utils::get_base_fee( // added as of v8 ) { return fee_per_b; } -uint64_t monero_fee_utils::get_fee_quantization_mask( - use_fork_rules_fn_type use_fork_rules_fn -) { -// if(m_light_wallet) { - return 1; // "TODO" -// } -// bool use_per_byte_fee = use_fork_rules(HF_VERSION_PER_BYTE_FEE, 0); -// if (!use_per_byte_fee) -// return 1; -// -// uint64_t fee_quantization_mask; -// boost::optional result = m_node_rpc_proxy.get_fee_quantization_mask(fee_quantization_mask); -// if (result) -// return 1; -// return fee_quantization_mask; -} // uint64_t monero_fee_utils::estimated_tx_network_fee( uint64_t base_fee, diff --git a/src/monero_fee_utils.hpp b/src/monero_fee_utils.hpp index 84f3c42..7ba1d28 100644 --- a/src/monero_fee_utils.hpp +++ b/src/monero_fee_utils.hpp @@ -56,7 +56,6 @@ namespace monero_fee_utils uint64_t get_fee_multiplier(uint32_t priority, uint32_t default_priority, int fee_algorithm, use_fork_rules_fn_type use_fork_rules_fn); int get_fee_algorithm(use_fork_rules_fn_type use_fork_rules_fn); uint64_t get_base_fee(uint64_t fee_per_b); - uint64_t get_fee_quantization_mask(use_fork_rules_fn_type use_fork_rules_fn); // uint64_t estimate_fee(bool use_per_byte_fee, bool use_rct, int n_inputs, int mixin, int n_outputs, size_t extra_size, bool bulletproof, uint64_t base_fee, uint64_t fee_multiplier, uint64_t fee_quantization_mask); // diff --git a/src/monero_send_routine.cpp b/src/monero_send_routine.cpp index b598756..54282fe 100644 --- a/src/monero_send_routine.cpp +++ b/src/monero_send_routine.cpp @@ -112,6 +112,7 @@ LightwalletAPI_Res_GetUnspentOuts monero_send_routine::new__parsed_res__get_unsp const public_key &pub_spendKey ) { uint64_t final__per_byte_fee = 0; + uint64_t fee_mask = 10000; // just a fallback value - no real reason to set this here normally try { optional possible__uint64 = _possible_uint64_from_json(res, "per_byte_fee"); if (possible__uint64 != none) { @@ -122,7 +123,20 @@ LightwalletAPI_Res_GetUnspentOuts monero_send_routine::new__parsed_res__get_unsp string err_msg = "Unspent outs: Unrecognized per-byte fee format"; return { err_msg, - none, none + none, none, none + }; + } + try { + optional possible__uint64 = _possible_uint64_from_json(res, "fee_mask"); + if (possible__uint64 != none) { + fee_mask = *possible__uint64; + } + } catch (const std::exception &e) { + cout << "Unspent outs fee_mask parse error: " << e.what() << endl; + string err_msg = "Unspent outs: Unrecognized fee_mask format"; + return { + err_msg, + none, none, none }; } if (final__per_byte_fee == 0) { @@ -130,13 +144,14 @@ LightwalletAPI_Res_GetUnspentOuts monero_send_routine::new__parsed_res__get_unsp optional possible__uint64 = _possible_uint64_from_json(res, "per_kb_fee"); if (possible__uint64 != none) { final__per_byte_fee = (*possible__uint64) / 1024; // scale from kib to b + fee_mask = 10000; // just to be explicit } } catch (const std::exception &e) { cout << "Unspent outs per-kb-fee parse error: " << e.what() << endl; string err_msg = "Unspent outs: Unrecognized per-kb fee format"; return { err_msg, - none, none + none, none, none }; } } @@ -144,7 +159,7 @@ LightwalletAPI_Res_GetUnspentOuts monero_send_routine::new__parsed_res__get_unsp string err_msg = "Unable to get a per-byte fee from server response."; return { err_msg, - none, none + none, none, none }; } vector unspent_outs; @@ -164,7 +179,7 @@ LightwalletAPI_Res_GetUnspentOuts monero_send_routine::new__parsed_res__get_unsp string err_msg = "Invalid tx pub key"; return { err_msg, - none, none + none, none, none }; } } @@ -177,7 +192,7 @@ LightwalletAPI_Res_GetUnspentOuts monero_send_routine::new__parsed_res__get_unsp string err_msg = "Expected unspent output to have an \"index\""; return { err_msg, - none, none + none, none, none }; } } catch (const std::exception &e) { @@ -185,7 +200,7 @@ LightwalletAPI_Res_GetUnspentOuts monero_send_routine::new__parsed_res__get_unsp string err_msg = "Unspent outs: Unrecognized output index format"; return { err_msg, - none, none + none, none, none }; } bool isOutputSpent = false; // let's seeā€¦ @@ -203,7 +218,7 @@ LightwalletAPI_Res_GetUnspentOuts monero_send_routine::new__parsed_res__get_unsp string err_msg = "Unable to generate key image"; return { err_msg, - none, none + none, none, none }; } auto calculated_key_image_string = epee::string_tools::pod_to_hex(retVals.calculated_key_image); @@ -229,7 +244,7 @@ LightwalletAPI_Res_GetUnspentOuts monero_send_routine::new__parsed_res__get_unsp } return LightwalletAPI_Res_GetUnspentOuts{ none, - final__per_byte_fee, unspent_outs + final__per_byte_fee, fee_mask, unspent_outs }; } LightwalletAPI_Res_GetRandomOuts monero_send_routine::new__parsed_res__get_random_outs( @@ -296,6 +311,7 @@ struct _SendFunds_ConstructAndSendTx_Args // const vector &unspent_outs; uint64_t fee_per_b; + uint64_t fee_quantization_mask; // // cached const secret_key &sec_viewKey; @@ -327,6 +343,7 @@ void _reenterable_construct_and_send_tx( }, args.unspent_outs, args.fee_per_b, + args.fee_quantization_mask, // passedIn_attemptAt_fee // use this for passing step2 "must-reconstruct" return values back in, i.e. re-entry; when nil, defaults to attempt at network min ); @@ -367,6 +384,7 @@ void _reenterable_construct_and_send_tx( args.simple_priority, step1_retVals.using_outs, args.fee_per_b, + args.fee_quantization_mask, *(parsed_res.mix_outs), [] (uint8_t version, int64_t early_blocks) -> bool { @@ -508,6 +526,7 @@ void monero_send_routine::async__send_funds(Async_SendFunds_Args args) // *(parsed_res.unspent_outs), *(parsed_res.per_byte_fee), + *(parsed_res.fee_mask), // sec_viewKey, sec_spendKey }); diff --git a/src/monero_send_routine.hpp b/src/monero_send_routine.hpp index 0ee444c..e791e46 100644 --- a/src/monero_send_routine.hpp +++ b/src/monero_send_routine.hpp @@ -156,6 +156,7 @@ namespace monero_send_routine optional err_msg; // OR optional per_byte_fee; + optional fee_mask; optional> unspent_outs; }; struct LightwalletAPI_Res_GetRandomOuts diff --git a/src/monero_transfer_utils.cpp b/src/monero_transfer_utils.cpp index d311ed2..69044c8 100644 --- a/src/monero_transfer_utils.cpp +++ b/src/monero_transfer_utils.cpp @@ -218,6 +218,7 @@ void monero_transfer_utils::send_step1__prepare_params_for_get_decoys( // const vector &unspent_outs, uint64_t fee_per_b, // per v8 + uint64_t fee_quantization_mask, // optional passedIn_attemptAt_fee ) { @@ -252,7 +253,6 @@ void monero_transfer_utils::send_step1__prepare_params_for_get_decoys( } const uint64_t base_fee = get_base_fee(fee_per_b); // in other words, fee_per_b const uint64_t fee_multiplier = get_fee_multiplier(simple_priority, default_priority(), get_fee_algorithm(use_fork_rules_fn), use_fork_rules_fn); - const uint64_t fee_quantization_mask = get_fee_quantization_mask(use_fork_rules_fn); // uint64_t attempt_at_min_fee; if (passedIn_attemptAt_fee == none) { @@ -391,6 +391,7 @@ void monero_transfer_utils::send_step2__try_create_transaction( uint32_t simple_priority, const vector &using_outs, uint64_t fee_per_b, // per v8 + uint64_t fee_quantization_mask, vector &mix_outs, // cannot be const due to convenience__create_transaction's mutability requirement use_fork_rules_fn_type use_fork_rules_fn, uint64_t unlock_time, // or 0 @@ -422,7 +423,7 @@ void monero_transfer_utils::send_step2__try_create_transaction( *create_tx__retVals.tx, blob_size, get_base_fee(fee_per_b)/*i.e. fee_per_b*/, get_fee_multiplier(simple_priority, default_priority(), get_fee_algorithm(use_fork_rules_fn), use_fork_rules_fn), - get_fee_quantization_mask(use_fork_rules_fn) + fee_quantization_mask ); if (fee_actually_needed > fee_amount) { // cout << "Need to reconstruct tx with fee of at least " << fee_actually_needed << "." << endl; diff --git a/src/monero_transfer_utils.hpp b/src/monero_transfer_utils.hpp index 74a8e9f..4abfb47 100644 --- a/src/monero_transfer_utils.hpp +++ b/src/monero_transfer_utils.hpp @@ -197,6 +197,7 @@ namespace monero_transfer_utils // const vector &unspent_outs, uint64_t fee_per_b, // per v8 + uint64_t fee_quantization_mask, // optional passedIn_attemptAt_fee // use this for passing step2 "must-reconstruct" return values back in, i.e. re-entry; when nil, defaults to attempt at network min ); @@ -229,6 +230,7 @@ namespace monero_transfer_utils uint32_t simple_priority, const vector &using_outs, uint64_t fee_per_b, // per v8 + uint64_t fee_quantization_mask, vector &mix_outs, // it gets sorted use_fork_rules_fn_type use_fork_rules_fn, uint64_t unlock_time, // or 0 diff --git a/src/serial_bridge_index.cpp b/src/serial_bridge_index.cpp index 99bc6cd..57a2f31 100644 --- a/src/serial_bridge_index.cpp +++ b/src/serial_bridge_index.cpp @@ -431,6 +431,7 @@ string serial_bridge::send_step1__prepare_params_for_get_decoys(const string &ar }, unspent_outs, stoull(json_root.get("fee_per_b")), // per v8 + stoull(json_root.get("fee_mask")), // optl__passedIn_attemptAt_fee // use this for passing step2 "must-reconstruct" return values back in, i.e. re-entry; when nil, defaults to attempt at network min ); @@ -525,6 +526,7 @@ string serial_bridge::send_step2__try_create_transaction(const string &args_stri stoul(json_root.get("priority")), using_outs, stoull(json_root.get("fee_per_b")), + stoull(json_root.get("fee_mask")), mix_outs, [] (uint8_t version, int64_t early_blocks) -> bool { diff --git a/test/test_all.cpp b/test/test_all.cpp index 447fb73..2d63e24 100644 --- a/test/test_all.cpp +++ b/test/test_all.cpp @@ -176,6 +176,7 @@ BOOST_AUTO_TEST_CASE(bridge__transfers__send__sweepDust) root.put("payment_id_string", "d2f602b240fbe624"); // optl root.put("sending_amount", "0"); root.put("fee_per_b", "24658"); + root.put("fee_mask", "10000"); root.put("priority", "1"); root.add_child("unspent_outs", unspent_outs); if (fee_actually_needed_string != none) { @@ -324,6 +325,7 @@ BOOST_AUTO_TEST_CASE(bridge__transfers__send__amountWOnlyDusty) root.put("payment_id_string", "d2f602b240fbe624"); // optl root.put("sending_amount", "1000000"); root.put("fee_per_b", "24658"); + root.put("fee_mask", "10000"); root.put("priority", "1"); root.add_child("unspent_outs", unspent_outs); @@ -380,6 +382,7 @@ BOOST_AUTO_TEST_CASE(bridge__transfers__send__amount) root.put("payment_id_string", "d2f602b240fbe624"); // optl root.put("sending_amount", "200000000"); root.put("fee_per_b", "24658"); + root.put("fee_mask", "10000"); root.put("priority", "1"); root.add_child("unspent_outs", unspent_outs); if (fee_actually_needed_string != none) { @@ -465,6 +468,7 @@ BOOST_AUTO_TEST_CASE(bridge__transfers__send__amount) root.put("sec_viewKey_string", "7bea1907940afdd480eff7c4bcadb478a0fbb626df9e3ed74ae801e18f53e104"); root.put("sec_spendKey_string", "4e6d43cd03812b803c6f3206689f5fcc910005fc7e91d50d79b0776dbefcd803"); root.put("fee_per_b", "24658"); + root.put("fee_mask", "10000"); root.put("unlock_time", "0"); root.put("priority", "1"); root.add_child("mix_outs", mix_outs); @@ -847,6 +851,7 @@ BOOST_AUTO_TEST_CASE(bridged__estimated_tx_network_fee) // boost::property_tree::ptree root; root.put("fee_per_b", "24658"); + root.put("fee_mask", "10000"); root.put("priority", "2"); // auto ret_string = serial_bridge::estimated_tx_network_fee(args_string_from_root(root)); @@ -1320,6 +1325,7 @@ BOOST_AUTO_TEST_CASE(bridge__transfers__send_stagenet_coinbase) root.put("payment_id_string", "d2f602b240fbe624"); // optl root.put("sending_amount", "1000000000000"); root.put("fee_per_b", "166333"); + root.put("fee_mask", "10000"); root.put("priority", "1"); root.add_child("unspent_outs", unspent_outs); if (fee_actually_needed_string != none) { @@ -1404,6 +1410,7 @@ BOOST_AUTO_TEST_CASE(bridge__transfers__send_stagenet_coinbase) root.put("sec_viewKey_string", "9ef8e116d2c774b207a2dd6a234dab8f5d54becc04aa26ccbd6f1f67e8427308"); root.put("sec_spendKey_string", "4acde2a96d5085423fcc8713c878448b35e45900f4e9cf2c0b643eb4268e140e"); root.put("fee_per_b", "166333"); + root.put("fee_mask", "10000"); root.put("unlock_time", "0"); root.put("priority", "1"); root.add_child("mix_outs", mix_outs);