mirror of
https://github.com/wownero/wownero-cpp.git
synced 2026-10-19 16:18:40 +02:00
move reconcile() utils from monero_utils to gen_utils
This commit is contained in:
@@ -228,6 +228,7 @@ set_target_properties(version PROPERTIES IMPORTED_LOCATION
|
||||
|
||||
set(
|
||||
LIBRARY_SRC_FILES
|
||||
src/utils/gen_utils.cpp
|
||||
src/utils/monero_utils.cpp
|
||||
src/daemon/monero_daemon_model.cpp
|
||||
src/daemon/monero_daemon.cpp
|
||||
|
||||
@@ -52,6 +52,7 @@
|
||||
|
||||
#include "monero_daemon_model.h"
|
||||
|
||||
#include "utils/gen_utils.h"
|
||||
#include "utils/monero_utils.h"
|
||||
#include "include_base_utils.h"
|
||||
#include "common/util.h"
|
||||
@@ -111,24 +112,24 @@ namespace monero {
|
||||
void monero_block_header::merge(const shared_ptr<monero_block_header>& self, const shared_ptr<monero_block_header>& other) {
|
||||
if (this != self.get()) throw runtime_error("this != self");
|
||||
if (self == other) return;
|
||||
m_id = monero_utils::reconcile(m_id, other->m_id);
|
||||
m_height = monero_utils::reconcile(m_height, other->m_height, boost::none, boost::none, true, "block height"); // height can increase
|
||||
m_timestamp = monero_utils::reconcile(m_timestamp, other->m_timestamp, boost::none, boost::none, true, "block header timestamp"); // timestamp can increase
|
||||
m_size = monero_utils::reconcile(m_size, other->m_size, "block header size");
|
||||
m_weight = monero_utils::reconcile(m_weight, other->m_weight, "block header weight");
|
||||
m_long_term_weight = monero_utils::reconcile(m_long_term_weight, other->m_long_term_weight, "block header long term weight");
|
||||
m_depth = monero_utils::reconcile(m_depth, other->m_depth, "block header depth");
|
||||
m_difficulty = monero_utils::reconcile(m_difficulty, other->m_difficulty, "difficulty");
|
||||
m_cumulative_difficulty = monero_utils::reconcile(m_cumulative_difficulty, other->m_cumulative_difficulty, "m_cumulative_difficulty");
|
||||
m_major_version = monero_utils::reconcile(m_major_version, other->m_major_version, "m_major_version");
|
||||
m_minor_version = monero_utils::reconcile(m_minor_version, other->m_minor_version, "m_minor_version");
|
||||
m_nonce = monero_utils::reconcile(m_nonce, other->m_nonce, "m_nonce");
|
||||
m_miner_tx_id = monero_utils::reconcile(m_miner_tx_id, other->m_miner_tx_id);
|
||||
m_num_txs = monero_utils::reconcile(m_num_txs, other->m_num_txs, "block header m_num_txs");
|
||||
m_orphan_status = monero_utils::reconcile(m_orphan_status, other->m_orphan_status);
|
||||
m_prev_id = monero_utils::reconcile(m_prev_id, other->m_prev_id);
|
||||
m_reward = monero_utils::reconcile(m_reward, other->m_reward, "block header m_reward");
|
||||
m_pow_hash = monero_utils::reconcile(m_pow_hash, other->m_pow_hash);
|
||||
m_id = gen_utils::reconcile(m_id, other->m_id);
|
||||
m_height = gen_utils::reconcile(m_height, other->m_height, boost::none, boost::none, true, "block height"); // height can increase
|
||||
m_timestamp = gen_utils::reconcile(m_timestamp, other->m_timestamp, boost::none, boost::none, true, "block header timestamp"); // timestamp can increase
|
||||
m_size = gen_utils::reconcile(m_size, other->m_size, "block header size");
|
||||
m_weight = gen_utils::reconcile(m_weight, other->m_weight, "block header weight");
|
||||
m_long_term_weight = gen_utils::reconcile(m_long_term_weight, other->m_long_term_weight, "block header long term weight");
|
||||
m_depth = gen_utils::reconcile(m_depth, other->m_depth, "block header depth");
|
||||
m_difficulty = gen_utils::reconcile(m_difficulty, other->m_difficulty, "difficulty");
|
||||
m_cumulative_difficulty = gen_utils::reconcile(m_cumulative_difficulty, other->m_cumulative_difficulty, "m_cumulative_difficulty");
|
||||
m_major_version = gen_utils::reconcile(m_major_version, other->m_major_version, "m_major_version");
|
||||
m_minor_version = gen_utils::reconcile(m_minor_version, other->m_minor_version, "m_minor_version");
|
||||
m_nonce = gen_utils::reconcile(m_nonce, other->m_nonce, "m_nonce");
|
||||
m_miner_tx_id = gen_utils::reconcile(m_miner_tx_id, other->m_miner_tx_id);
|
||||
m_num_txs = gen_utils::reconcile(m_num_txs, other->m_num_txs, "block header m_num_txs");
|
||||
m_orphan_status = gen_utils::reconcile(m_orphan_status, other->m_orphan_status);
|
||||
m_prev_id = gen_utils::reconcile(m_prev_id, other->m_prev_id);
|
||||
m_reward = gen_utils::reconcile(m_reward, other->m_reward, "block header m_reward");
|
||||
m_pow_hash = gen_utils::reconcile(m_pow_hash, other->m_pow_hash);
|
||||
}
|
||||
|
||||
// ----------------------------- MONERO BLOCK -------------------------------
|
||||
@@ -154,8 +155,8 @@ namespace monero {
|
||||
monero_block_header::merge(self, other);
|
||||
|
||||
// merge reconcilable block extensions
|
||||
m_hex = monero_utils::reconcile(m_hex, other->m_hex);
|
||||
m_tx_ids = monero_utils::reconcile(m_tx_ids, other->m_tx_ids);
|
||||
m_hex = gen_utils::reconcile(m_hex, other->m_hex);
|
||||
m_tx_ids = gen_utils::reconcile(m_tx_ids, other->m_tx_ids);
|
||||
|
||||
// merge miner tx
|
||||
if (m_miner_tx == boost::none) m_miner_tx = other->m_miner_tx;
|
||||
@@ -299,37 +300,37 @@ namespace monero {
|
||||
}
|
||||
|
||||
// otherwise merge tx fields
|
||||
m_id = monero_utils::reconcile(m_id, other->m_id);
|
||||
m_version = monero_utils::reconcile(m_version, other->m_version);
|
||||
m_payment_id = monero_utils::reconcile(m_payment_id, other->m_payment_id);
|
||||
m_fee = monero_utils::reconcile(m_fee, other->m_fee, "tx fee");
|
||||
m_mixin = monero_utils::reconcile(m_mixin, other->m_mixin, "tx m_mixin");
|
||||
m_is_confirmed = monero_utils::reconcile(m_is_confirmed, other->m_is_confirmed);
|
||||
m_do_not_relay = monero_utils::reconcile(m_do_not_relay, other->m_do_not_relay);
|
||||
m_is_relayed = monero_utils::reconcile(m_is_relayed, other->m_is_relayed);
|
||||
m_is_double_spend_seen = monero_utils::reconcile(m_is_double_spend_seen, other->m_is_double_spend_seen);
|
||||
m_key = monero_utils::reconcile(m_key, other->m_key);
|
||||
m_full_hex = monero_utils::reconcile(m_full_hex, other->m_full_hex);
|
||||
m_pruned_hex = monero_utils::reconcile(m_pruned_hex, other->m_pruned_hex);
|
||||
m_prunable_hex = monero_utils::reconcile(m_prunable_hex, other->m_prunable_hex);
|
||||
m_prunable_hash = monero_utils::reconcile(m_prunable_hash, other->m_prunable_hash);
|
||||
m_size = monero_utils::reconcile(m_size, other->m_size, "tx size");
|
||||
m_weight = monero_utils::reconcile(m_weight, other->m_weight, "tx weight");
|
||||
//m_output_indices = monero_utils::reconcile(m_output_indices, other->m_output_indices); // TODO
|
||||
m_metadata = monero_utils::reconcile(m_metadata, other->m_metadata);
|
||||
m_common_tx_sets = monero_utils::reconcile(m_common_tx_sets, other->m_common_tx_sets);
|
||||
//m_extra = monero_utils::reconcile(m_extra, other->m_extra); // TODO
|
||||
m_rct_signatures = monero_utils::reconcile(m_rct_signatures, other->m_rct_signatures);
|
||||
m_rct_sig_prunable = monero_utils::reconcile(m_rct_sig_prunable, other->m_rct_sig_prunable);
|
||||
m_is_kept_by_block = monero_utils::reconcile(m_is_kept_by_block, other->m_is_kept_by_block);
|
||||
m_is_failed = monero_utils::reconcile(m_is_failed, other->m_is_failed);
|
||||
m_last_failed_height = monero_utils::reconcile(m_last_failed_height, other->m_last_failed_height, "m_last_failed_height");
|
||||
m_last_failed_id = monero_utils::reconcile(m_last_failed_id, other->m_last_failed_id);
|
||||
m_max_used_block_height = monero_utils::reconcile(m_max_used_block_height, other->m_max_used_block_height, "max_used_block_height");
|
||||
m_max_used_block_id = monero_utils::reconcile(m_max_used_block_id, other->m_max_used_block_id);
|
||||
//m_signatures = monero_utils::reconcile(m_signatures, other->m_signatures); // TODO
|
||||
m_unlock_time = monero_utils::reconcile(m_unlock_time, other->m_unlock_time, "m_unlock_time");
|
||||
m_num_confirmations = monero_utils::reconcile(m_num_confirmations, other->m_num_confirmations, "m_num_confirmations");
|
||||
m_id = gen_utils::reconcile(m_id, other->m_id);
|
||||
m_version = gen_utils::reconcile(m_version, other->m_version);
|
||||
m_payment_id = gen_utils::reconcile(m_payment_id, other->m_payment_id);
|
||||
m_fee = gen_utils::reconcile(m_fee, other->m_fee, "tx fee");
|
||||
m_mixin = gen_utils::reconcile(m_mixin, other->m_mixin, "tx m_mixin");
|
||||
m_is_confirmed = gen_utils::reconcile(m_is_confirmed, other->m_is_confirmed);
|
||||
m_do_not_relay = gen_utils::reconcile(m_do_not_relay, other->m_do_not_relay);
|
||||
m_is_relayed = gen_utils::reconcile(m_is_relayed, other->m_is_relayed);
|
||||
m_is_double_spend_seen = gen_utils::reconcile(m_is_double_spend_seen, other->m_is_double_spend_seen);
|
||||
m_key = gen_utils::reconcile(m_key, other->m_key);
|
||||
m_full_hex = gen_utils::reconcile(m_full_hex, other->m_full_hex);
|
||||
m_pruned_hex = gen_utils::reconcile(m_pruned_hex, other->m_pruned_hex);
|
||||
m_prunable_hex = gen_utils::reconcile(m_prunable_hex, other->m_prunable_hex);
|
||||
m_prunable_hash = gen_utils::reconcile(m_prunable_hash, other->m_prunable_hash);
|
||||
m_size = gen_utils::reconcile(m_size, other->m_size, "tx size");
|
||||
m_weight = gen_utils::reconcile(m_weight, other->m_weight, "tx weight");
|
||||
//m_output_indices = gen_utils::reconcile(m_output_indices, other->m_output_indices); // TODO
|
||||
m_metadata = gen_utils::reconcile(m_metadata, other->m_metadata);
|
||||
m_common_tx_sets = gen_utils::reconcile(m_common_tx_sets, other->m_common_tx_sets);
|
||||
//m_extra = gen_utils::reconcile(m_extra, other->m_extra); // TODO
|
||||
m_rct_signatures = gen_utils::reconcile(m_rct_signatures, other->m_rct_signatures);
|
||||
m_rct_sig_prunable = gen_utils::reconcile(m_rct_sig_prunable, other->m_rct_sig_prunable);
|
||||
m_is_kept_by_block = gen_utils::reconcile(m_is_kept_by_block, other->m_is_kept_by_block);
|
||||
m_is_failed = gen_utils::reconcile(m_is_failed, other->m_is_failed);
|
||||
m_last_failed_height = gen_utils::reconcile(m_last_failed_height, other->m_last_failed_height, "m_last_failed_height");
|
||||
m_last_failed_id = gen_utils::reconcile(m_last_failed_id, other->m_last_failed_id);
|
||||
m_max_used_block_height = gen_utils::reconcile(m_max_used_block_height, other->m_max_used_block_height, "max_used_block_height");
|
||||
m_max_used_block_id = gen_utils::reconcile(m_max_used_block_id, other->m_max_used_block_id);
|
||||
//m_signatures = gen_utils::reconcile(m_signatures, other->m_signatures); // TODO
|
||||
m_unlock_time = gen_utils::reconcile(m_unlock_time, other->m_unlock_time, "m_unlock_time");
|
||||
m_num_confirmations = gen_utils::reconcile(m_num_confirmations, other->m_num_confirmations, "m_num_confirmations");
|
||||
|
||||
// merge vins
|
||||
if (!other->m_vins.empty()) {
|
||||
@@ -426,9 +427,9 @@ namespace monero {
|
||||
m_received_timestamp = boost::none;
|
||||
m_last_relayed_timestamp = boost::none;
|
||||
} else {
|
||||
m_in_tx_pool = monero_utils::reconcile(m_in_tx_pool, other->m_in_tx_pool, boost::none, true, boost::none); // unrelayed -> tx pool
|
||||
m_received_timestamp = monero_utils::reconcile(m_received_timestamp, other->m_received_timestamp, boost::none, boost::none, false, "m_received_timestamp"); // take earliest receive time
|
||||
m_last_relayed_timestamp = monero_utils::reconcile(m_last_relayed_timestamp, other->m_last_relayed_timestamp, boost::none, boost::none, true, "m_last_relayed_timestamp"); // take latest relay time
|
||||
m_in_tx_pool = gen_utils::reconcile(m_in_tx_pool, other->m_in_tx_pool, boost::none, true, boost::none); // unrelayed -> tx pool
|
||||
m_received_timestamp = gen_utils::reconcile(m_received_timestamp, other->m_received_timestamp, boost::none, boost::none, false, "m_received_timestamp"); // take earliest receive time
|
||||
m_last_relayed_timestamp = gen_utils::reconcile(m_last_relayed_timestamp, other->m_last_relayed_timestamp, boost::none, boost::none, true, "m_last_relayed_timestamp"); // take latest relay time
|
||||
}
|
||||
}
|
||||
|
||||
@@ -488,7 +489,7 @@ namespace monero {
|
||||
// otherwise merge output fields
|
||||
if (m_key_image == boost::none) m_key_image = other->m_key_image;
|
||||
else if (other->m_key_image != boost::none) m_key_image.get()->merge(m_key_image.get(), other->m_key_image.get());
|
||||
m_amount = monero_utils::reconcile(m_amount, other->m_amount, "output amount");
|
||||
m_index = monero_utils::reconcile(m_index, other->m_index, "output index");
|
||||
m_amount = gen_utils::reconcile(m_amount, other->m_amount, "output amount");
|
||||
m_index = gen_utils::reconcile(m_index, other->m_index, "output index");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
/**
|
||||
* Copyright (c) 2017-2019 woodser
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Parts of this file are originally copyright (c) 2014-2019, The Monero Project
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers
|
||||
*/
|
||||
|
||||
#include "gen_utils.h"
|
||||
|
||||
using namespace std;
|
||||
@@ -0,0 +1,151 @@
|
||||
/**
|
||||
* Copyright (c) 2017-2019 woodser
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Parts of this file are originally copyright (c) 2014-2019, The Monero Project
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#ifndef gen_utils_h
|
||||
#define gen_utils_h
|
||||
|
||||
#include "wallet/monero_wallet.h"
|
||||
|
||||
/**
|
||||
* Collection of utilities for working with Monero's binary portable storage format.
|
||||
*/
|
||||
namespace gen_utils
|
||||
{
|
||||
using namespace std;
|
||||
|
||||
// ------------------------- VALUE RECONCILATION- ---------------------------
|
||||
|
||||
// TODO: refactor common template code
|
||||
template <class T, typename std::enable_if<std::is_same<T, string>::value, T>::type* = nullptr>
|
||||
boost::optional<T> reconcile(const boost::optional<T>& val1, const boost::optional<T>& val2, boost::optional<bool> resolve_defined, boost::optional<bool> resolve_true, boost::optional<bool> resolve_max, const string& err_msg = "") {
|
||||
|
||||
// check for equality
|
||||
if (val1 == val2) return val1;
|
||||
|
||||
// resolve one value none
|
||||
if (val1 == boost::none || val2 == boost::none) {
|
||||
if (resolve_defined != boost::none && *resolve_defined == false) return boost::none;
|
||||
else return val1 == boost::none ? val2 : val1;
|
||||
}
|
||||
|
||||
throw runtime_error(string("Cannot reconcile strings: ") + to_string(val1) + string(" vs ") + to_string(val2) + (!err_msg.empty() ? string(". ") + err_msg : string("")));
|
||||
}
|
||||
template <class T, typename std::enable_if<std::is_same<T, string>::value, T>::type* = nullptr>
|
||||
boost::optional<T> reconcile(const boost::optional<T>& val1, const boost::optional<T>& val2, const string& err_msg = "") {
|
||||
return reconcile(val1, val2, boost::none, boost::none, boost::none, err_msg);
|
||||
}
|
||||
|
||||
template <class T, typename std::enable_if<std::is_integral<T>::value, T>::type* = nullptr>
|
||||
boost::optional<T> reconcile(const boost::optional<T>& val1, const boost::optional<T>& val2, boost::optional<bool> resolve_defined, boost::optional<bool> resolve_true, boost::optional<bool> resolve_max, const string& err_msg = "") {
|
||||
|
||||
// check for equality
|
||||
if (val1 == val2) return val1;
|
||||
|
||||
// resolve one value none
|
||||
if (val1 == boost::none || val2 == boost::none) {
|
||||
if (resolve_defined != boost::none && *resolve_defined == false) return boost::none;
|
||||
else return val1 == boost::none ? val2 : val1;
|
||||
}
|
||||
|
||||
// resolve different numbers
|
||||
if (resolve_max != boost::none) {
|
||||
return *resolve_max ? max(*val1, *val2) : min(*val1, *val2);
|
||||
}
|
||||
|
||||
// throw runtime_error("Cannot reconcile values " + val1 + " and " + val2 + " with config: [" + resolve_defined + ", " + resolve_true + ", " + resolve_max + "]", val1, val2);
|
||||
throw runtime_error(string("Cannot reconcile integrals: ") + to_string(val1) + string(" vs ") + to_string(val2) + (!err_msg.empty() ? string(". ") + err_msg : string("")));
|
||||
}
|
||||
template <class T, typename std::enable_if<std::is_integral<T>::value, T>::type* = nullptr>
|
||||
boost::optional<T> reconcile(const boost::optional<T>& val1, const boost::optional<T>& val2, const string& err_msg = "") {
|
||||
return reconcile(val1, val2, boost::none, boost::none, boost::none, err_msg);
|
||||
}
|
||||
|
||||
template <class T, typename std::enable_if<std::is_same<T, bool>::value, T>::type>
|
||||
boost::optional<T> reconcile(const boost::optional<T>& val1, const boost::optional<T>& val2, boost::optional<bool> resolve_defined, boost::optional<bool> resolve_true, boost::optional<bool> resolve_max, const string& err_msg = "") {
|
||||
|
||||
// check for equality
|
||||
if (val1 == val2) return val1;
|
||||
|
||||
// resolve one value none
|
||||
if (val1 == boost::none || val2 == boost::none) {
|
||||
if (resolve_defined != boost::none && *resolve_defined == false) return boost::none;
|
||||
else return val1 == boost::none ? val2 : val1;
|
||||
}
|
||||
|
||||
// resolve different booleans
|
||||
if (resolve_true != boost::none) {
|
||||
return val1 == resolve_true ? val1 : val2; // if resolve true, return true, else return false
|
||||
} else {
|
||||
throw runtime_error(string("Cannot reconcile booleans: ") + to_string(val1) + string(" vs ") + to_string(val2) + (!err_msg.empty() ? string(". ") + err_msg : string("")));
|
||||
}
|
||||
}
|
||||
template <class T, typename std::enable_if<std::is_same<T, bool>::value, T>::type>
|
||||
boost::optional<T> reconcile(const boost::optional<T>& val1, const boost::optional<T>& val2, const string& err_msg = "") {
|
||||
return reconcile(val1, val2, boost::none, boost::none, boost::none, err_msg);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
vector<T> reconcile(const vector<T>& v1, const vector<T>& v2, const string& err_msg = "") {
|
||||
|
||||
// check for equality
|
||||
if (v1 == v2) return v1;
|
||||
|
||||
// resolve one vector empty
|
||||
if (v1.empty()) return v2;
|
||||
if (v2.empty()) return v1;
|
||||
|
||||
// otherwise cannot reconcile
|
||||
throw runtime_error("Cannot reconcile vectors" + (!err_msg.empty() ? string(". ") + err_msg : string("")));
|
||||
}
|
||||
}
|
||||
#endif /* gen_utils_h */
|
||||
@@ -92,7 +92,6 @@ namespace monero_utils
|
||||
*/
|
||||
shared_ptr<monero_block> cn_block_to_block(const cryptonote::block& cn_block);
|
||||
|
||||
|
||||
/**
|
||||
* Convert a Monero Core crpytonote::transaction to a transaction in this library's
|
||||
* native model.
|
||||
@@ -140,95 +139,5 @@ namespace monero_utils
|
||||
boost::property_tree::ptree to_property_tree(const vector<uint8_t>& nums);
|
||||
boost::property_tree::ptree to_property_tree(const vector<uint32_t>& nums);
|
||||
boost::property_tree::ptree to_property_tree(const vector<uint64_t>& nums);
|
||||
|
||||
// ------------------------- VALUE RECONCILATION- ---------------------------
|
||||
|
||||
// TODO: refactor common template code
|
||||
template <class T, typename std::enable_if<std::is_same<T, string>::value, T>::type* = nullptr>
|
||||
boost::optional<T> reconcile(const boost::optional<T>& val1, const boost::optional<T>& val2, boost::optional<bool> resolve_defined, boost::optional<bool> resolve_true, boost::optional<bool> resolve_max, const string& err_msg = "") {
|
||||
|
||||
// check for equality
|
||||
if (val1 == val2) return val1;
|
||||
|
||||
// resolve one value none
|
||||
if (val1 == boost::none || val2 == boost::none) {
|
||||
if (resolve_defined != boost::none && *resolve_defined == false) return boost::none;
|
||||
else return val1 == boost::none ? val2 : val1;
|
||||
}
|
||||
|
||||
throw runtime_error(string("Cannot reconcile strings: ") + to_string(val1) + string(" vs ") + to_string(val2) + (!err_msg.empty() ? string(". ") + err_msg : string("")));
|
||||
}
|
||||
template <class T, typename std::enable_if<std::is_same<T, string>::value, T>::type* = nullptr>
|
||||
boost::optional<T> reconcile(const boost::optional<T>& val1, const boost::optional<T>& val2, const string& err_msg = "") {
|
||||
return reconcile(val1, val2, boost::none, boost::none, boost::none, err_msg);
|
||||
}
|
||||
|
||||
template <class T, typename std::enable_if<std::is_integral<T>::value, T>::type* = nullptr>
|
||||
boost::optional<T> reconcile(const boost::optional<T>& val1, const boost::optional<T>& val2, boost::optional<bool> resolve_defined, boost::optional<bool> resolve_true, boost::optional<bool> resolve_max, const string& err_msg = "") {
|
||||
|
||||
// check for equality
|
||||
if (val1 == val2) return val1;
|
||||
|
||||
// resolve one value none
|
||||
if (val1 == boost::none || val2 == boost::none) {
|
||||
if (resolve_defined != boost::none && *resolve_defined == false) return boost::none;
|
||||
else return val1 == boost::none ? val2 : val1;
|
||||
}
|
||||
|
||||
// resolve different numbers
|
||||
if (resolve_max != boost::none) {
|
||||
return *resolve_max ? max(*val1, *val2) : min(*val1, *val2);
|
||||
}
|
||||
|
||||
// throw runtime_error("Cannot reconcile values " + val1 + " and " + val2 + " with config: [" + resolve_defined + ", " + resolve_true + ", " + resolve_max + "]", val1, val2);
|
||||
throw runtime_error(string("Cannot reconcile integrals: ") + to_string(val1) + string(" vs ") + to_string(val2) + (!err_msg.empty() ? string(". ") + err_msg : string("")));
|
||||
}
|
||||
template <class T, typename std::enable_if<std::is_integral<T>::value, T>::type* = nullptr>
|
||||
boost::optional<T> reconcile(const boost::optional<T>& val1, const boost::optional<T>& val2, const string& err_msg = "") {
|
||||
return reconcile(val1, val2, boost::none, boost::none, boost::none, err_msg);
|
||||
}
|
||||
|
||||
template <class T, typename std::enable_if<std::is_same<T, bool>::value, T>::type>
|
||||
boost::optional<T> reconcile(const boost::optional<T>& val1, const boost::optional<T>& val2, boost::optional<bool> resolve_defined, boost::optional<bool> resolve_true, boost::optional<bool> resolve_max, const string& err_msg = "") {
|
||||
|
||||
// check for equality
|
||||
if (val1 == val2) return val1;
|
||||
|
||||
// resolve one value none
|
||||
if (val1 == boost::none || val2 == boost::none) {
|
||||
if (resolve_defined != boost::none && *resolve_defined == false) return boost::none;
|
||||
else return val1 == boost::none ? val2 : val1;
|
||||
}
|
||||
|
||||
// resolve different booleans
|
||||
if (resolve_true != boost::none) {
|
||||
return val1 == resolve_true ? val1 : val2; // if resolve true, return true, else return false
|
||||
} else {
|
||||
throw runtime_error(string("Cannot reconcile booleans: ") + to_string(val1) + string(" vs ") + to_string(val2) + (!err_msg.empty() ? string(". ") + err_msg : string("")));
|
||||
}
|
||||
}
|
||||
template <class T, typename std::enable_if<std::is_same<T, bool>::value, T>::type>
|
||||
boost::optional<T> reconcile(const boost::optional<T>& val1, const boost::optional<T>& val2, const string& err_msg = "") {
|
||||
return reconcile(val1, val2, boost::none, boost::none, boost::none, err_msg);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
vector<T> reconcile(const vector<T>& v1, const vector<T>& v2, const string& err_msg = "") {
|
||||
|
||||
// check for equality
|
||||
if (v1 == v2) return v1;
|
||||
|
||||
// resolve one vector empty
|
||||
if (v1.empty()) return v2;
|
||||
if (v2.empty()) return v1;
|
||||
|
||||
// otherwise cannot reconcile
|
||||
throw runtime_error("Cannot reconcile vectors" + (!err_msg.empty() ? string(". ") + err_msg : string("")));
|
||||
}
|
||||
|
||||
// template <class T>
|
||||
// boost::optional<T> reconcile(const boost::optional<T>& val1, const boost::optional<T>& val2) {
|
||||
// return reconcile(val1, val2, boost::none, boost::none, boost::none);
|
||||
// }
|
||||
}
|
||||
#endif /* monero_utils_h */
|
||||
|
||||
@@ -52,6 +52,7 @@
|
||||
|
||||
#include "monero_wallet.h"
|
||||
|
||||
#include "utils/gen_utils.h"
|
||||
#include "utils/monero_utils.h"
|
||||
#include <stdio.h>
|
||||
#include <iostream>
|
||||
@@ -164,7 +165,7 @@ namespace monero {
|
||||
monero_tx::merge(self, other);
|
||||
|
||||
// merge wallet extensions
|
||||
m_note = monero_utils::reconcile(m_note, other->m_note);
|
||||
m_note = gen_utils::reconcile(m_note, other->m_note);
|
||||
|
||||
// merge incoming transfers
|
||||
if (!other->m_incoming_transfers.empty()) {
|
||||
@@ -352,16 +353,16 @@ namespace monero {
|
||||
}
|
||||
|
||||
// otherwise merge transfer fields
|
||||
m_account_index = monero_utils::reconcile(m_account_index, other->m_account_index, "acountIndex");
|
||||
m_account_index = gen_utils::reconcile(m_account_index, other->m_account_index, "acountIndex");
|
||||
|
||||
// TODO monero core: failed m_tx in pool (after testUpdateLockedDifferentAccounts()) causes non-originating saved wallets to return duplicate incoming transfers but one has amount/m_num_suggested_confirmations of 0
|
||||
if (m_amount != boost::none && other->m_amount != boost::none && *m_amount != *other->m_amount && (*m_amount == 0 || *other->m_amount == 0)) {
|
||||
m_account_index = monero_utils::reconcile(m_account_index, other->m_account_index, boost::none, boost::none, true, "acountIndex");
|
||||
m_num_suggested_confirmations = monero_utils::reconcile(m_num_suggested_confirmations, other->m_num_suggested_confirmations, boost::none, boost::none, true, "m_num_suggested_confirmations");
|
||||
m_account_index = gen_utils::reconcile(m_account_index, other->m_account_index, boost::none, boost::none, true, "acountIndex");
|
||||
m_num_suggested_confirmations = gen_utils::reconcile(m_num_suggested_confirmations, other->m_num_suggested_confirmations, boost::none, boost::none, true, "m_num_suggested_confirmations");
|
||||
MWARNING("WARNING: failed tx in pool causes non-originating wallets to return duplicate incoming transfers but with one amount/m_num_suggested_confirmations of 0");
|
||||
} else {
|
||||
m_amount = monero_utils::reconcile(m_amount, other->m_amount, "transfer amount");
|
||||
m_num_suggested_confirmations = monero_utils::reconcile(m_num_suggested_confirmations, other->m_num_suggested_confirmations, boost::none, boost::none, false, "m_num_suggested_confirmations");
|
||||
m_amount = gen_utils::reconcile(m_amount, other->m_amount, "transfer amount");
|
||||
m_num_suggested_confirmations = gen_utils::reconcile(m_num_suggested_confirmations, other->m_num_suggested_confirmations, boost::none, boost::none, false, "m_num_suggested_confirmations");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -391,8 +392,8 @@ namespace monero {
|
||||
void monero_incoming_transfer::merge(const shared_ptr<monero_incoming_transfer>& self, const shared_ptr<monero_incoming_transfer>& other) {
|
||||
if (self == other) return;
|
||||
monero_transfer::merge(self, other);
|
||||
m_subaddress_index = monero_utils::reconcile(m_subaddress_index, other->m_subaddress_index, "incoming transfer m_subaddress_index");
|
||||
m_address = monero_utils::reconcile(m_address, other->m_address);
|
||||
m_subaddress_index = gen_utils::reconcile(m_subaddress_index, other->m_subaddress_index, "incoming transfer m_subaddress_index");
|
||||
m_address = gen_utils::reconcile(m_address, other->m_address);
|
||||
}
|
||||
|
||||
// ----------------------- MONERO OUTGOING TRANSFER -------------------------
|
||||
@@ -422,9 +423,9 @@ namespace monero {
|
||||
void monero_outgoing_transfer::merge(const shared_ptr<monero_outgoing_transfer>& self, const shared_ptr<monero_outgoing_transfer>& other) {
|
||||
if (self == other) return;
|
||||
monero_transfer::merge(self, other);
|
||||
m_subaddress_indices = monero_utils::reconcile(m_subaddress_indices, other->m_subaddress_indices);
|
||||
m_addresses = monero_utils::reconcile(m_addresses, other->m_addresses);
|
||||
m_destinations = monero_utils::reconcile(m_destinations, other->m_destinations);
|
||||
m_subaddress_indices = gen_utils::reconcile(m_subaddress_indices, other->m_subaddress_indices);
|
||||
m_addresses = gen_utils::reconcile(m_addresses, other->m_addresses);
|
||||
m_destinations = gen_utils::reconcile(m_destinations, other->m_destinations);
|
||||
}
|
||||
|
||||
// ----------------------- MONERO TRANSFER REQUEST --------------------------
|
||||
@@ -588,9 +589,9 @@ namespace monero {
|
||||
monero_output::merge(self, other);
|
||||
|
||||
// merge output wallet extensions
|
||||
m_account_index = monero_utils::reconcile(m_account_index, other->m_account_index);
|
||||
m_subaddress_index = monero_utils::reconcile(m_subaddress_index, other->m_subaddress_index);
|
||||
m_is_spent = monero_utils::reconcile(m_is_spent, other->m_is_spent);
|
||||
m_account_index = gen_utils::reconcile(m_account_index, other->m_account_index);
|
||||
m_subaddress_index = gen_utils::reconcile(m_subaddress_index, other->m_subaddress_index);
|
||||
m_is_spent = gen_utils::reconcile(m_is_spent, other->m_is_spent);
|
||||
}
|
||||
|
||||
// ------------------------ MONERO OUTPUT REQUEST ---------------------------
|
||||
|
||||
Reference in New Issue
Block a user