diff --git a/CMakeLists.txt b/CMakeLists.txt index e08679e..1063195 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -75,6 +75,8 @@ set( src/monero_key_image_utils.cpp src/monero_transfer_utils.hpp src/monero_transfer_utils.cpp + src/monero_fork_rules.hpp + src/monero_fork_rules.cpp src/monero_wallet_utils.hpp src/monero_wallet_utils.cpp src/tools__ret_vals.hpp diff --git a/src/monero_fork_rules.cpp b/src/monero_fork_rules.cpp new file mode 100644 index 0000000..bbe38f3 --- /dev/null +++ b/src/monero_fork_rules.cpp @@ -0,0 +1,53 @@ +// +// monero_fork_rules.cpp +// MyMonero +// +// Created by Paul Shapiro on 1/9/18. +// Copyright (c) 2014-2018, MyMonero.com +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without modification, are +// permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of +// conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list +// of conditions and the following disclaimer in the documentation and/or other +// materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be +// used to endorse or promote products derived from this software without specific +// prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF +// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// +// +#include "monero_fork_rules.hpp" +// +using namespace monero_fork_rules; +// +uint8_t monero_fork_rules::get_bulletproof_fork() +{ + return 8; +} +// +bool monero_fork_rules::lightwallet_hardcoded__use_fork_rules(uint8_t version, int64_t early_blocks) +{ + bool bulletproof = false; // This is temporary (and true only because it's not time for the fork yet) until we have the fork rules supplied by the server + if (version >= monero_fork_rules::get_bulletproof_fork()) { + return bulletproof; + } + return true; +} + diff --git a/src/monero_fork_rules.hpp b/src/monero_fork_rules.hpp new file mode 100644 index 0000000..1cea5e9 --- /dev/null +++ b/src/monero_fork_rules.hpp @@ -0,0 +1,51 @@ +// +// monero_fork_rules.hpp +// MyMonero +// +// Created by Paul Shapiro on 1/9/18. +// Copyright (c) 2014-2018, MyMonero.com +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without modification, are +// permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of +// conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list +// of conditions and the following disclaimer in the documentation and/or other +// materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be +// used to endorse or promote products derived from this software without specific +// prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF +// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// + +#ifndef monero_fork_rules_hpp +#define monero_fork_rules_hpp + +#include "crypto.h" + +namespace monero_fork_rules +{ + typedef std::function use_fork_rules_fn_type; + // + uint8_t get_bulletproof_fork(); + // + // + bool lightwallet_hardcoded__use_fork_rules(uint8_t version, int64_t early_blocks); // convenience +} + +#endif /* monero_fork_rules */ diff --git a/src/monero_transfer_utils.cpp b/src/monero_transfer_utils.cpp index f7bc111..3988a8a 100644 --- a/src/monero_transfer_utils.cpp +++ b/src/monero_transfer_utils.cpp @@ -32,7 +32,6 @@ // // #include "monero_transfer_utils.hpp" -//#include "monero_fork_rules.hpp" #include "wallet_errors.h" // //using namespace std; @@ -41,12 +40,12 @@ using namespace cryptonote; //using namespace tools; // for error:: using namespace monero_transfer_utils; -//using namespace monero_fork_rules; +using namespace monero_fork_rules; // // Protocol / Defaults uint32_t monero_transfer_utils::fixed_ringsize() { - return 7; // TODO/FIXME: temporary…… for lightwallet code! + return 7; // best practice is to conform to fixed ring size } uint32_t monero_transfer_utils::fixed_mixinsize() { @@ -58,8 +57,24 @@ uint32_t monero_transfer_utils::default_priority() } // // Fee estimation -uint64_t monero_transfer_utils::get_upper_transaction_size_limit(uint64_t upper_transaction_size_limit__or_0_for_default, use_fork_rules_fn_type use_fork_rules_fn) -{ +uint64_t monero_transfer_utils::estimated_tx_network_fee( + uint64_t fee_per_kb, + uint32_t priority, + network_type nettype, + use_fork_rules_fn_type use_fork_rules_fn +) { + bool bulletproof = use_fork_rules_fn(get_bulletproof_fork(), 0); + uint64_t fee_multiplier = get_fee_multiplier(priority, default_priority(), get_fee_algorithm(use_fork_rules_fn), use_fork_rules_fn); + std::vector extra; // blank extra + size_t est_tx_size = estimate_rct_tx_size(2, fixed_mixinsize(), 2, extra.size(), bulletproof); // typically ~14kb post-rct, pre-bulletproofs + uint64_t estimated_fee = calculate_fee(fee_per_kb, est_tx_size, fee_multiplier); + // + return estimated_fee; +} +uint64_t monero_transfer_utils::get_upper_transaction_size_limit( + uint64_t upper_transaction_size_limit__or_0_for_default, + use_fork_rules_fn_type use_fork_rules_fn +) { if (upper_transaction_size_limit__or_0_for_default > 0) return upper_transaction_size_limit__or_0_for_default; uint64_t full_reward_zone = use_fork_rules_fn(5, 10) ? CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V5 : use_fork_rules_fn(2, 10) ? CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V2 : CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V1; @@ -105,7 +120,6 @@ uint64_t monero_transfer_utils::get_fee_multiplier( THROW_WALLET_EXCEPTION_IF (false, error::invalid_priority); return 1; } -// int monero_transfer_utils::get_fee_algorithm(use_fork_rules_fn_type use_fork_rules_fn) { // changes at v3 and v5 @@ -115,7 +129,6 @@ int monero_transfer_utils::get_fee_algorithm(use_fork_rules_fn_type use_fork_rul return 1; return 0; } -// size_t monero_transfer_utils::estimate_rct_tx_size(int n_inputs, int mixin, int n_outputs, size_t extra_size, bool bulletproof) { size_t size = 0; diff --git a/src/monero_transfer_utils.hpp b/src/monero_transfer_utils.hpp index 0f0deac..3687ea4 100644 --- a/src/monero_transfer_utils.hpp +++ b/src/monero_transfer_utils.hpp @@ -37,6 +37,7 @@ #include "cryptonote_basic.h" #include "cryptonote_format_utils.h" #include "cryptonote_tx_utils.h" +#include "monero_fork_rules.hpp" // using namespace tools; #include "tools__ret_vals.hpp" @@ -47,17 +48,21 @@ using namespace tools; namespace monero_transfer_utils { // - typedef std::function use_fork_rules_fn_type; - // - uint64_t get_upper_transaction_size_limit(uint64_t upper_transaction_size_limit__or_0_for_default, use_fork_rules_fn_type use_fork_rules_fn); - 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_upper_transaction_size_limit(uint64_t upper_transaction_size_limit__or_0_for_default, monero_fork_rules::use_fork_rules_fn_type use_fork_rules_fn); + uint64_t get_fee_multiplier(uint32_t priority, uint32_t default_priority, int fee_algorithm, monero_fork_rules::use_fork_rules_fn_type use_fork_rules_fn); + int get_fee_algorithm(monero_fork_rules::use_fork_rules_fn_type use_fork_rules_fn); // uint64_t calculate_fee(uint64_t fee_per_kb, size_t bytes, uint64_t fee_multiplier); uint64_t calculate_fee(uint64_t fee_per_kb, const cryptonote::blobdata &blob, uint64_t fee_multiplier); // size_t estimate_rct_tx_size(int n_inputs, int mixin, int n_outputs, size_t extra_size, bool bulletproof); size_t estimate_tx_size(bool use_rct, int n_inputs, int mixin, int n_outputs, size_t extra_size, bool bulletproof); + uint64_t estimated_tx_network_fee( // convenience function for size + calc + uint64_t fee_per_kb, + uint32_t priority, // when priority=0, falls back to monero_transfer_utils::default_priority() + cryptonote::network_type nettype, + monero_fork_rules::use_fork_rules_fn_type use_fork_rules_fn // this is extracted to a function so that implementations can optionally query the daemon (although this presently implies that such a call remains blocking) + ); // bool is_transfer_unlocked(uint64_t unlock_time, uint64_t block_height, uint64_t blockchain_size, cryptonote::network_type nettype = cryptonote::MAINNET); bool is_tx_spendtime_unlocked(uint64_t unlock_time, uint64_t block_height, uint64_t blockchain_size, cryptonote::network_type nettype = cryptonote::MAINNET); diff --git a/test/test_all.cpp b/test/test_all.cpp index 8034b61..3dc6ddf 100644 --- a/test/test_all.cpp +++ b/test/test_all.cpp @@ -90,3 +90,19 @@ BOOST_AUTO_TEST_CASE(keyImage) BOOST_AUTO_TEST_CASE(wallet) { } +// +// +#include "../src/monero_transfer_utils.hpp" +#include "../src/monero_fork_rules.hpp" +BOOST_AUTO_TEST_CASE(transfers__fee) +{ + monero_fork_rules::use_fork_rules_fn_type use_fork_rules_fn = [] (uint8_t version, int64_t early_blocks) -> bool + { + return monero_fork_rules::lightwallet_hardcoded__use_fork_rules(version, early_blocks); + }; + uint64_t fee_per_kb = 9000000; + uint32_t priority = 2; + uint64_t est_fee = monero_transfer_utils::estimated_tx_network_fee(fee_per_kb, priority, cryptonote::MAINNET, use_fork_rules_fn); + std::cout << "est_fee with fee_per_kb " << fee_per_kb << ": " << est_fee << std::endl; + BOOST_REQUIRE(est_fee > 0); +}