Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| e69437ca6a | |||
| 50075e04c3 | |||
| 7f3dba49a7 | |||
| 9c098ae1fb | |||
| 078fa00bc5 | |||
| 9dc1c429f7 |
@@ -36,6 +36,7 @@
|
||||
#include "warnings.h"
|
||||
#include "misc_log_ex.h"
|
||||
|
||||
#include <boost/numeric/conversion/bounds.hpp>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <typeinfo>
|
||||
#include <iomanip>
|
||||
|
||||
@@ -847,7 +847,7 @@ int BlockchainLMDB::get_yield_tx_info(const uint64_t height, std::vector<yield_t
|
||||
while (1)
|
||||
{
|
||||
int ret = mdb_cursor_get(m_cur_yield_txs, &k, &v, op);
|
||||
op = MDB_NEXT;
|
||||
op = MDB_NEXT_DUP;
|
||||
if (ret == MDB_NOTFOUND)
|
||||
break;
|
||||
if (ret)
|
||||
@@ -1249,9 +1249,28 @@ uint64_t BlockchainLMDB::add_transaction_data(const crypto::hash& blk_hash, cons
|
||||
throw0(DB_ERROR("tx.vout is wrong size (needed to create yield data for the PROTOCOL_TX)"));
|
||||
if (!cryptonote::get_output_public_key(tx.vout[0], yield_data.P_change))
|
||||
throw0(DB_ERROR("failed to get P_change from tx.vout[0] (needed to create yield data for the PROTOCOL_TX)"));
|
||||
|
||||
// Because LMDB is shockingly bad at handling duplicates, we have resorted to using a counter of elements
|
||||
// in the first element of the struct.
|
||||
MDB_val data;
|
||||
MDB_val_set(val_height, m_height);
|
||||
result = mdb_cursor_get(m_cur_yield_txs, &val_height, &data, MDB_SET);
|
||||
if (!result)
|
||||
{
|
||||
mdb_size_t num_elems = 0;
|
||||
result = mdb_cursor_count(m_cur_yield_txs, &num_elems);
|
||||
if (result)
|
||||
throw0(DB_ERROR(std::string("Failed to get number of yield TXs for height: ").append(mdb_strerror(result)).c_str()));
|
||||
yield_data.block_height = num_elems;
|
||||
}
|
||||
else if (result != MDB_NOTFOUND)
|
||||
throw0(DB_ERROR(lmdb_error("Failed to get output amount in db transaction: ", result).c_str()));
|
||||
else
|
||||
yield_data.block_height = 0;
|
||||
|
||||
// Now we know how many there are, write out the data to the DB
|
||||
MDB_val_set(val_yield_tx_data, yield_data);
|
||||
result = mdb_cursor_put(m_cur_yield_txs, &val_height, &val_yield_tx_data, MDB_APPEND);
|
||||
result = mdb_cursor_put(m_cur_yield_txs, &val_height, &val_yield_tx_data, MDB_APPENDDUP);
|
||||
if (result)
|
||||
throw0(DB_ERROR( lmdb_error("Failed to add tx yield data to db transaction: ", result).c_str() ));
|
||||
}
|
||||
|
||||
@@ -110,7 +110,8 @@ namespace tools
|
||||
catch(...)
|
||||
{
|
||||
// if failed, try reading in unportable mode
|
||||
boost::filesystem::copy_file(file_path, file_path + ".unportable", boost::filesystem::copy_option::overwrite_if_exists);
|
||||
//boost::filesystem::copy_file(file_path, file_path + ".unportable", boost::filesystem::copy_option::overwrite_if_exists);
|
||||
tools::copy_file(file_path, file_path + ".unportable");
|
||||
data_file.close();
|
||||
data_file.open( file_path, std::ios_base::binary | std::ios_base::in);
|
||||
if(data_file.fail())
|
||||
|
||||
@@ -115,6 +115,24 @@ static int flock_exnb(int fd)
|
||||
|
||||
namespace tools
|
||||
{
|
||||
|
||||
void copy_file(const std::string& from, const std::string& to)
|
||||
{
|
||||
using boost::filesystem::path;
|
||||
#if BOOST_VERSION < 107400
|
||||
// Remove this preprocessor if/else when we are bumping the boost version.
|
||||
boost::filesystem::copy_file(
|
||||
path(from),
|
||||
path(to),
|
||||
boost::filesystem::copy_option::overwrite_if_exists);
|
||||
#else
|
||||
boost::filesystem::copy_file(
|
||||
path(from),
|
||||
path(to),
|
||||
boost::filesystem::copy_options::overwrite_existing);
|
||||
#endif
|
||||
}
|
||||
|
||||
std::function<void(int)> signal_handler::m_handler;
|
||||
|
||||
private_file::private_file() noexcept : m_handle(), m_filename() {}
|
||||
|
||||
@@ -67,6 +67,8 @@ namespace tools
|
||||
}
|
||||
};
|
||||
|
||||
void copy_file(const std::string& from, const std::string& to);
|
||||
|
||||
//! A file restricted to process owner AND process. Deletes file on destruction.
|
||||
class private_file {
|
||||
std::unique_ptr<std::FILE, close_file> m_handle;
|
||||
|
||||
@@ -399,8 +399,12 @@ namespace cryptonote
|
||||
// SRCG: This is a confusing one - for some reason I was using the line below, and it _seemed_ to work...
|
||||
// ... but I think it was luck! the "od.output_index" would only work for the TD_ORIGIN data, of course...
|
||||
//hwdev.derive_subaddress_public_key(out_key, recv_derivation, od.output_index, P_change);
|
||||
hwdev.derive_subaddress_public_key(out_key, recv_derivation, real_output_index, P_change);
|
||||
|
||||
if (od.tx_type == cryptonote::transaction_type::CONVERT || od.tx_type == cryptonote::transaction_type::STAKE) {
|
||||
hwdev.derive_subaddress_public_key(out_key, recv_derivation, 0, P_change);
|
||||
} else {
|
||||
hwdev.derive_subaddress_public_key(out_key, recv_derivation, real_output_index, P_change);
|
||||
}
|
||||
|
||||
// 2. Obtain a separate key_derivation for the _original_ P_change output
|
||||
// (using the TX public key from the CONVERT TX and the sender's private view key)
|
||||
crypto::key_derivation derivation_P_change_tx = AUTO_VAL_INIT(derivation_P_change_tx);
|
||||
@@ -416,9 +420,11 @@ namespace cryptonote
|
||||
CHECK_AND_ASSERT_MES(P_change == change_pk, false, "derived P_change public key does not match P_change");
|
||||
|
||||
// 5. Calculate the secret spend key "x_return"
|
||||
// SRCG: And another confusing one - luck again?!?!?
|
||||
// CHECK_AND_ASSERT_MES(hwdev.derive_secret_key(recv_derivation, od.output_index, sk_spend, scalar_step1), false, "Failed to derive one-time output secret key 'x_return'");
|
||||
CHECK_AND_ASSERT_MES(hwdev.derive_secret_key(recv_derivation, real_output_index, sk_spend, scalar_step1), false, "Failed to derive one-time output secret key 'x_return'");
|
||||
if (od.tx_type == cryptonote::transaction_type::CONVERT || od.tx_type == cryptonote::transaction_type::STAKE) {
|
||||
CHECK_AND_ASSERT_MES(hwdev.derive_secret_key(recv_derivation, 0, sk_spend, scalar_step1), false, "Failed to derive one-time output secret key 'x_return'");
|
||||
} else {
|
||||
CHECK_AND_ASSERT_MES(hwdev.derive_secret_key(recv_derivation, real_output_index, sk_spend, scalar_step1), false, "Failed to derive one-time output secret key 'x_return'");
|
||||
}
|
||||
in_ephemeral.sec = scalar_step1;
|
||||
CHECK_AND_ASSERT_MES(hwdev.secret_key_to_public_key(in_ephemeral.sec, in_ephemeral.pub), false, "Failed to derive one-time output public key 'P_return'");
|
||||
CHECK_AND_ASSERT_MES(in_ephemeral.pub == out_key,
|
||||
|
||||
@@ -1491,15 +1491,6 @@ bool Blockchain::validate_protocol_transaction(const block& b, uint64_t height,
|
||||
return true;
|
||||
}
|
||||
|
||||
key_images_container keys;
|
||||
|
||||
uint64_t fee_summary = 0;
|
||||
uint64_t t_checktx = 0;
|
||||
uint64_t t_exists = 0;
|
||||
uint64_t t_pool = 0;
|
||||
uint64_t t_dblspnd = 0;
|
||||
uint64_t n_pruned = 0;
|
||||
|
||||
// Build a map of outputs from the protocol_tx
|
||||
std::map<crypto::public_key, std::tuple<std::string, uint64_t, uint64_t>> outputs;
|
||||
for (auto& o : b.protocol_tx.vout) {
|
||||
@@ -1514,6 +1505,9 @@ bool Blockchain::validate_protocol_transaction(const block& b, uint64_t height,
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Maintain a count of outputs that we have verified
|
||||
std::vector<crypto::public_key> outputs_verified;
|
||||
|
||||
size_t tx_index = 0;
|
||||
// Iterate over the block's transaction hashes, grabbing each
|
||||
@@ -1530,69 +1524,119 @@ bool Blockchain::validate_protocol_transaction(const block& b, uint64_t height,
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check to see if the TX is a conversion or not
|
||||
if (tx->type != cryptonote::transaction_type::CONVERT) {
|
||||
// Only conversion (and failed conversion, aka refund) TXs need to be verified - skip this TX
|
||||
continue;
|
||||
}
|
||||
/*
|
||||
// Verify that the TX has an output in the protocol_tx to verify
|
||||
if (outputs.count(tx->return_address) != 1) {
|
||||
LOG_ERROR("Failed to locate output for conversion TX id " << tx->hash << " - rejecting block");
|
||||
return false;
|
||||
}
|
||||
if (hf_version >= HF_VERSION_ENABLE_CONVERT) {
|
||||
|
||||
// Check to see if the TX is a conversion or not
|
||||
if (tx->type != cryptonote::transaction_type::CONVERT) {
|
||||
// Only conversion (and failed conversion, aka refund) TXs need to be verified - skip this TX
|
||||
continue;
|
||||
}
|
||||
|
||||
// Get the output information
|
||||
std::string output_asset_type;
|
||||
uint64_t output_amount;
|
||||
uint64_t output_unlock_time;
|
||||
std::tie(output_asset_type, output_amount, output_unlock_time) = outputs[tx->return_address];
|
||||
|
||||
// Verify the asset_type
|
||||
if (tx->source_asset_type == output_asset_type) {
|
||||
// Check the amount for REFUND
|
||||
if (tx->amount_burnt != output_amount) {
|
||||
LOG_ERROR("Output amount does not match amount_burnt for refunded TX id " << tx->hash << " - rejecting block");
|
||||
// Verify that the TX has an output in the protocol_tx to verify
|
||||
if (outputs.count(tx->return_address) != 1) {
|
||||
LOG_ERROR("Block at height: " << height << " - Failed to locate output for conversion TX id " << tx->hash << " - rejecting block");
|
||||
return false;
|
||||
}
|
||||
} else if (tx->destination_asset_type == output_asset_type) {
|
||||
// Check the amount for CONVERT
|
||||
|
||||
// Verify the amount of the conversion
|
||||
uint64_t amount_minted_check = 0, amount_slippage_check = 0;
|
||||
bool ok = cryptonote::calculate_conversion(tx->source_asset_type, tx->destination_asset_type, tx->amount_burnt, tx->amount_slippage_limit, amount_minted_check, amount_slippage_check, circ_supply, b.pricing_record, hf_version);
|
||||
if (!ok) {
|
||||
LOG_ERROR("Failed to calculate conversion for TX id " << tx->hash << " - rejecting block");
|
||||
// Get the output information
|
||||
std::string output_asset_type;
|
||||
uint64_t output_amount;
|
||||
uint64_t output_unlock_time;
|
||||
std::tie(output_asset_type, output_amount, output_unlock_time) = outputs[tx->return_address];
|
||||
|
||||
// Verify the asset_type
|
||||
if (tx->source_asset_type == output_asset_type) {
|
||||
// Check the amount for REFUND
|
||||
if (tx->amount_burnt != output_amount) {
|
||||
LOG_ERROR("Block at height: " << height << " - Output amount does not match amount_burnt for refunded TX id " << tx->hash << " - rejecting block");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Verified the refund successfully
|
||||
outputs_verified.push_back(tx->return_address);
|
||||
|
||||
} else if (tx->destination_asset_type == output_asset_type) {
|
||||
// Check the amount for CONVERT
|
||||
|
||||
// Verify the amount of the conversion
|
||||
uint64_t amount_minted_check = 0, amount_slippage_check = 0;
|
||||
bool ok = cryptonote::calculate_conversion(tx->source_asset_type, tx->destination_asset_type, tx->amount_burnt, tx->amount_slippage_limit, amount_minted_check, amount_slippage_check, circ_supply, b.pricing_record, hf_version);
|
||||
if (!ok) {
|
||||
LOG_ERROR("Block at height: " << height << " - Failed to calculate conversion for TX id " << tx->hash << " - rejecting block");
|
||||
return false;
|
||||
}
|
||||
if (amount_minted_check != output_amount) {
|
||||
LOG_ERROR("Block at height: " << height << " - Output amount does not match amount_burnt for refunded TX id " << tx->hash << " - rejecting block");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Verified the conversion successfully
|
||||
outputs_verified.push_back(tx->return_address);
|
||||
|
||||
} else {
|
||||
LOG_ERROR("Block at height: " << height << " - Output asset type incorrect: source " << tx->source_asset_type << ", dest " << tx->destination_asset_type << ", got " << output_asset_type << " - rejecting block");
|
||||
return false;
|
||||
}
|
||||
if (amount_minted_check != output_amount) {
|
||||
LOG_ERROR("Output amount does not match amount_burnt for refunded TX id " << tx->hash << " - rejecting block");
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
LOG_ERROR("Output asset type incorrect: source " << tx->source_asset_type << ", dest " << tx->destination_asset_type << ", got " << output_asset_type << " - rejecting block");
|
||||
return false;
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
// Now consider the payouts from matured YIELD transactions
|
||||
|
||||
// Get the data for the block that matured this time
|
||||
cryptonote::yield_block_info ybi_matured;
|
||||
// Can we have matured STAKE transactions yet?
|
||||
uint64_t lock_period = get_config(m_nettype).STAKE_LOCK_PERIOD;
|
||||
uint64_t start_height = (height > lock_period) ? height - lock_period - 1 : 0;
|
||||
bool ok = get_ybi_entry(start_height, ybi_matured);
|
||||
if (ok && ybi_matured.locked_coins_this_block > 0) {
|
||||
|
||||
// Iterate over the cached data for block yield, calculating the yield payouts due
|
||||
std::vector<std::pair<yield_tx_info, uint64_t>> yield_payouts;
|
||||
if (!calculate_yield_payouts(start_height, yield_payouts)) {
|
||||
LOG_ERROR("Failed to obtain yield payout information - aborting");
|
||||
return false;
|
||||
if (height > lock_period) {
|
||||
|
||||
// Yes - Get the staking data for the block that matured this time
|
||||
cryptonote::yield_block_info ybi_matured;
|
||||
uint64_t matured_height = height - lock_period - 1;
|
||||
bool ok = get_ybi_entry(matured_height, ybi_matured);
|
||||
if (ok && ybi_matured.locked_coins_this_block > 0) {
|
||||
|
||||
// Iterate over the cached data for block yield, calculating the yield payouts due
|
||||
std::vector<std::pair<yield_tx_info, uint64_t>> yield_payouts;
|
||||
if (!calculate_yield_payouts(matured_height, yield_payouts)) {
|
||||
LOG_ERROR("Block at height: " << height << " - Failed to obtain yield payout information - aborting");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Iterate the yield payouts, verifying as we go
|
||||
for (const auto& payout: yield_payouts) {
|
||||
|
||||
// Do we have a singular matching output in tx.vout?
|
||||
if (outputs.count(payout.first.return_address) != 1) {
|
||||
LOG_ERROR("Block at height: " << height << " - Failed to locate output for matured TX id " << payout.first.tx_hash << " - rejecting block");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get the output information
|
||||
std::string output_asset_type;
|
||||
uint64_t output_amount;
|
||||
uint64_t output_unlock_time;
|
||||
std::tie(output_asset_type, output_amount, output_unlock_time) = outputs[payout.first.return_address];
|
||||
|
||||
// Verify the asset type - must be SAL
|
||||
if (output_asset_type != "SAL") {
|
||||
LOG_ERROR("Block at height: " << height << " - Incorrect output asset type for matured TX id " << payout.first.tx_hash << " - rejecting block");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Verify the amount
|
||||
if (output_amount != payout.second) {
|
||||
LOG_ERROR("Block at height: " << height << " - Incorrect output amount for matured TX id " << payout.first.tx_hash << " - rejecting block");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Amount and return_address match our expectation
|
||||
outputs_verified.push_back(payout.first.return_address);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// All candidates have been evaluated - make sure there are no other outputs that have not been catered for
|
||||
if (outputs.size() != outputs_verified.size()) {
|
||||
LOG_ERROR("Block at height: " << height << " - Incorrect number of outputs - expected " << outputs_verified.size() << " but received " << outputs.size() << " - rejecting block");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Everything checks out
|
||||
return true;
|
||||
}
|
||||
//------------------------------------------------------------------
|
||||
@@ -4944,7 +4988,7 @@ leave:
|
||||
return false;
|
||||
}
|
||||
|
||||
MINFO("+++++ BLOCK SUCCESSFULLY ADDED" << std::endl << "id:\t" << id << std::endl << "PoW:\t" << proof_of_work << std::endl << "HEIGHT " << new_height-1 << ", difficulty:\t" << current_diffic << std::endl << "block reward: " << print_money(fee_summary + base_reward) << "(" << print_money(base_reward) << " + " << print_money(fee_summary) << "), coinbase_weight: " << coinbase_weight << ", cumulative weight: " << cumulative_block_weight << ", " << block_processing_time << "(" << target_calculating_time << "/" << longhash_calculating_time << ")ms");
|
||||
MINFO("+++++ BLOCK SUCCESSFULLY ADDED" << std::endl << "id:\t" << id << std::endl << "PoW:\t" << proof_of_work << std::endl << "HEIGHT " << new_height-1 << ", difficulty:\t" << current_diffic << std::endl << "block reward: " << print_money(fee_summary + base_reward - bl.miner_tx.amount_burnt) << "(" << print_money(base_reward - bl.miner_tx.amount_burnt) << " reward + " << print_money(fee_summary) << " fees), coinbase_weight: " << coinbase_weight << ", cumulative weight: " << cumulative_block_weight << ", " << block_processing_time << "(" << target_calculating_time << "/" << longhash_calculating_time << ")ms");
|
||||
if(m_show_time_stats)
|
||||
{
|
||||
MINFO("Height: " << new_height << " coinbase weight: " << coinbase_weight << " cumm: "
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
#include <boost/serialization/version.hpp>
|
||||
|
||||
#include "net_peerlist_boost_serialization.h"
|
||||
|
||||
#include "common/util.h"
|
||||
|
||||
namespace nodetool
|
||||
{
|
||||
@@ -200,7 +200,8 @@ namespace nodetool
|
||||
if (!out)
|
||||
{
|
||||
// if failed, try reading in unportable mode
|
||||
boost::filesystem::copy_file(path, path + ".unportable", boost::filesystem::copy_option::overwrite_if_exists);
|
||||
//boost::filesystem::copy_file(path, path + ".unportable", boost::filesystem::copy_option::overwrite_if_exists);
|
||||
tools::copy_file(path, path + ".unportable");
|
||||
src_file.close();
|
||||
src_file.open( path , std::ios_base::binary | std::ios_base::in);
|
||||
if(src_file.fail())
|
||||
|
||||
@@ -3178,6 +3178,25 @@ bool simple_wallet::set_enable_multisig(const std::vector<std::string> &args/* =
|
||||
return true;
|
||||
}
|
||||
|
||||
bool simple_wallet::set_freeze_incoming_payments(const std::vector<std::string> &args/* = std::vector<std::string>()*/)
|
||||
{
|
||||
if (args.size() < 2)
|
||||
{
|
||||
fail_msg_writer() << tr("Value not specified");
|
||||
return true;
|
||||
}
|
||||
|
||||
const auto pwd_container = get_and_verify_password();
|
||||
if (pwd_container)
|
||||
{
|
||||
parse_bool_and_use(args[1], [&](bool r) {
|
||||
m_wallet->freeze_incoming_payments(r);
|
||||
m_wallet->rewrite(m_wallet_file, pwd_container->password());
|
||||
});
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool simple_wallet::help(const std::vector<std::string> &args/* = std::vector<std::string>()*/)
|
||||
{
|
||||
if(args.empty())
|
||||
@@ -3533,7 +3552,9 @@ simple_wallet::simple_wallet()
|
||||
"enable-multisig-experimental <1|0>\n "
|
||||
" Set this to allow multisig commands. Multisig may currently be exploitable if parties do not trust each other.\n "
|
||||
"inactivity-lock-timeout <unsigned int>\n "
|
||||
" How many seconds to wait before locking the wallet (0 to disable)."));
|
||||
" How many seconds to wait before locking the wallet (0 to disable).\n"
|
||||
"freeze-incoming-payments <1|0>\n "
|
||||
" Whether to have incoming payments automatically frozen, so they cannot be spent erroneously."));
|
||||
m_cmd_binder.set_handler("encrypted_seed",
|
||||
boost::bind(&simple_wallet::on_command, this, &simple_wallet::encrypted_seed, _1),
|
||||
tr("Display the encrypted Electrum-style mnemonic seed."));
|
||||
@@ -3948,6 +3969,7 @@ bool simple_wallet::set_variable(const std::vector<std::string> &args)
|
||||
success_msg_writer() << "credits-target = " << m_wallet->credits_target();
|
||||
success_msg_writer() << "load-deprecated-formats = " << m_wallet->load_deprecated_formats();
|
||||
success_msg_writer() << "enable-multisig-experimental = " << m_wallet->is_multisig_enabled();
|
||||
success_msg_writer() << "freeze-incoming-payments = " << m_wallet->is_freeze_incoming_payments_enabled();
|
||||
return true;
|
||||
}
|
||||
else
|
||||
@@ -4015,6 +4037,7 @@ bool simple_wallet::set_variable(const std::vector<std::string> &args)
|
||||
CHECK_SIMPLE_VARIABLE("auto-mine-for-rpc-payment-threshold", set_auto_mine_for_rpc_payment_threshold, tr("floating point >= 0"));
|
||||
CHECK_SIMPLE_VARIABLE("credits-target", set_credits_target, tr("unsigned integer"));
|
||||
CHECK_SIMPLE_VARIABLE("enable-multisig-experimental", set_enable_multisig, tr("0 or 1"));
|
||||
CHECK_SIMPLE_VARIABLE("freeze-incoming-payments", set_freeze_incoming_payments, tr("0 or 1"));
|
||||
}
|
||||
fail_msg_writer() << tr("set: unrecognized argument(s)");
|
||||
return true;
|
||||
|
||||
@@ -154,6 +154,7 @@ namespace cryptonote
|
||||
bool set_export_format(const std::vector<std::string> &args = std::vector<std::string>());
|
||||
bool set_load_deprecated_formats(const std::vector<std::string> &args = std::vector<std::string>());
|
||||
bool set_enable_multisig(const std::vector<std::string> &args = std::vector<std::string>());
|
||||
bool set_freeze_incoming_payments(const std::vector<std::string> &args = std::vector<std::string>());
|
||||
bool set_persistent_rpc_client_id(const std::vector<std::string> &args = std::vector<std::string>());
|
||||
bool set_auto_mine_for_rpc_payment_threshold(const std::vector<std::string> &args = std::vector<std::string>());
|
||||
bool set_credits_target(const std::vector<std::string> &args = std::vector<std::string>());
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
#define DEF_SALVIUM_VERSION_TAG "7f6b8da"
|
||||
#define DEF_SALVIUM_VERSION "0.2.0"
|
||||
#define DEF_SALVIUM_VERSION "0.2.3"
|
||||
#define DEF_MONERO_VERSION_TAG "@VERSIONTAG@"
|
||||
#define DEF_MONERO_VERSION "0.18.3.3"
|
||||
#define DEF_MONERO_RELEASE_NAME "Zero"
|
||||
|
||||
+26
-8
@@ -1240,6 +1240,7 @@ wallet2::wallet2(network_type nettype, uint64_t kdf_rounds, bool unattended, std
|
||||
m_load_deprecated_formats(false),
|
||||
m_credits_target(0),
|
||||
m_enable_multisig(false),
|
||||
m_freeze_incoming_payments(false),
|
||||
m_pool_info_query_time(0),
|
||||
m_has_ever_refreshed_from_node(false),
|
||||
m_allow_mismatched_daemon_version(false)
|
||||
@@ -2178,9 +2179,15 @@ void wallet2::scan_output(const cryptonote::transaction &tx, bool miner_tx, cons
|
||||
|
||||
// Calculate the subaddress public_key (P_change)
|
||||
crypto::public_key pk_change = crypto::null_pkey;
|
||||
bool ok = m_account.get_device().derive_subaddress_public_key(output_public_key, tx_scan_info.received->derivation, i, pk_change);
|
||||
THROW_WALLET_EXCEPTION_IF(!ok, error::wallet_internal_error, "Failed to derive subaddress public key for CONVERT/YIELD/RETURN TX");
|
||||
|
||||
if (tx.type == cryptonote::transaction_type::PROTOCOL) {
|
||||
// Force the output index to be 0 in all cases, despite where it appears in this TX
|
||||
bool ok = m_account.get_device().derive_subaddress_public_key(output_public_key, tx_scan_info.received->derivation, 0, pk_change);
|
||||
THROW_WALLET_EXCEPTION_IF(!ok, error::wallet_internal_error, "Failed to derive subaddress public key for CONVERT/YIELD TX");
|
||||
} else {
|
||||
bool ok = m_account.get_device().derive_subaddress_public_key(output_public_key, tx_scan_info.received->derivation, i, pk_change);
|
||||
THROW_WALLET_EXCEPTION_IF(!ok, error::wallet_internal_error, "Failed to derive subaddress public key for RETURN TX");
|
||||
}
|
||||
|
||||
// Flag to indicate this is a TX that uses a return_address
|
||||
bool use_od = false;
|
||||
cryptonote::origin_data od = AUTO_VAL_INIT(od);
|
||||
@@ -2193,6 +2200,7 @@ void wallet2::scan_output(const cryptonote::transaction &tx, bool miner_tx, cons
|
||||
use_od = true;
|
||||
od.tx_pub_key = get_tx_pub_key_from_extra(td_origin.m_tx);
|
||||
od.output_index = td_origin.m_internal_output_index;
|
||||
od.tx_type = td_origin.m_tx.type;
|
||||
}
|
||||
|
||||
if (m_multisig)
|
||||
@@ -2214,12 +2222,14 @@ void wallet2::scan_output(const cryptonote::transaction &tx, bool miner_tx, cons
|
||||
{
|
||||
tx_scan_info.money_transfered = tools::decodeRct(tx.rct_signatures, tx_scan_info.received->derivation, i, tx_scan_info.mask, m_account.get_device());
|
||||
}
|
||||
/*
|
||||
if (tx_scan_info.money_transfered == 0)
|
||||
{
|
||||
MERROR("Invalid output amount, skipping");
|
||||
tx_scan_info.error = true;
|
||||
return;
|
||||
}
|
||||
*/
|
||||
outs.push_back(i);
|
||||
THROW_WALLET_EXCEPTION_IF(tx_money_got_in_outs[tx_scan_info.received->index][tx_scan_info.asset_type] >= std::numeric_limits<uint64_t>::max() - tx_scan_info.money_transfered,
|
||||
error::wallet_internal_error, "Overflow in received amounts");
|
||||
@@ -2642,7 +2652,7 @@ void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote
|
||||
td.m_mask = rct::identity();
|
||||
td.m_rct = false;
|
||||
}
|
||||
td.m_frozen = false;
|
||||
td.m_frozen = m_freeze_incoming_payments;
|
||||
set_unspent(m_transfers.size()-1);
|
||||
if (td.m_key_image_known)
|
||||
m_key_images[td.m_key_image] = m_transfers.size()-1;
|
||||
@@ -2992,7 +3002,7 @@ void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote
|
||||
if (tx.type == cryptonote::transaction_type::PROTOCOL) {
|
||||
if (td_origin_idx != ((uint64_t)-1)) {
|
||||
// Get the origin TD information
|
||||
payment.m_amount = payment.m_amounts[0];
|
||||
payment.m_amount = payment.m_amounts.empty() ? 0 : payment.m_amounts[0];
|
||||
payment.m_tx_type = m_transfers[td_origin_idx].m_tx.type;
|
||||
payment.m_fee = m_transfers[td_origin_idx].m_tx.amount_burnt;
|
||||
} else {
|
||||
@@ -4856,6 +4866,9 @@ boost::optional<wallet2::keys_file_data> wallet2::get_keys_file_data(const epee:
|
||||
value2.SetInt(m_enable_multisig ? 1 : 0);
|
||||
json.AddMember("enable_multisig", value2, json.GetAllocator());
|
||||
|
||||
value2.SetInt(m_freeze_incoming_payments ? 1 : 0);
|
||||
json.AddMember("freeze_incoming_payments", value2, json.GetAllocator());
|
||||
|
||||
// Serialize the JSON object
|
||||
rapidjson::StringBuffer buffer;
|
||||
rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
|
||||
@@ -5002,6 +5015,7 @@ bool wallet2::load_keys_buf(const std::string& keys_buf, const epee::wipeable_st
|
||||
m_auto_mine_for_rpc_payment_threshold = -1.0f;
|
||||
m_credits_target = 0;
|
||||
m_enable_multisig = false;
|
||||
m_freeze_incoming_payments = false;
|
||||
m_allow_mismatched_daemon_version = false;
|
||||
}
|
||||
else if(json.IsObject())
|
||||
@@ -5239,6 +5253,8 @@ bool wallet2::load_keys_buf(const std::string& keys_buf, const epee::wipeable_st
|
||||
m_credits_target = field_credits_target;
|
||||
GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, enable_multisig, int, Int, false, false);
|
||||
m_enable_multisig = field_enable_multisig;
|
||||
GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, freeze_incoming_payments, int, Int, false, false);
|
||||
m_freeze_incoming_payments = field_freeze_incoming_payments;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -6425,8 +6441,9 @@ void wallet2::load(const std::string& wallet_, const epee::wipeable_string& pass
|
||||
catch (...)
|
||||
{
|
||||
LOG_PRINT_L0("Failed to open portable binary, trying unportable");
|
||||
if (use_fs) boost::filesystem::copy_file(m_wallet_file, m_wallet_file + ".unportable", boost::filesystem::copy_option::overwrite_if_exists);
|
||||
std::stringstream iss;
|
||||
//if (use_fs) boost::filesystem::copy_file(m_wallet_file, m_wallet_file + ".unportable", boost::filesystem::copy_option::overwrite_if_exists);
|
||||
if (use_fs) tools::copy_file(m_wallet_file, m_wallet_file + ".unportable");
|
||||
std::stringstream iss;
|
||||
iss.str("");
|
||||
iss << cache_data;
|
||||
boost::archive::binary_iarchive ar(iss);
|
||||
@@ -6447,7 +6464,8 @@ void wallet2::load(const std::string& wallet_, const epee::wipeable_string& pass
|
||||
catch (...)
|
||||
{
|
||||
LOG_PRINT_L0("Failed to open portable binary, trying unportable");
|
||||
if (use_fs) boost::filesystem::copy_file(m_wallet_file, m_wallet_file + ".unportable", boost::filesystem::copy_option::overwrite_if_exists);
|
||||
//if (use_fs) boost::filesystem::copy_file(m_wallet_file, m_wallet_file + ".unportable", boost::filesystem::copy_option::overwrite_if_exists);
|
||||
if (use_fs) tools::copy_file(m_wallet_file, m_wallet_file + ".unportable");
|
||||
std::stringstream iss;
|
||||
iss.str("");
|
||||
iss << cache_file_buf;
|
||||
|
||||
@@ -1450,6 +1450,8 @@ private:
|
||||
void credits_target(uint64_t threshold) { m_credits_target = threshold; }
|
||||
bool is_multisig_enabled() const { return m_enable_multisig; }
|
||||
void enable_multisig(bool enable) { m_enable_multisig = enable; }
|
||||
bool is_freeze_incoming_payments_enabled() const { return m_freeze_incoming_payments; }
|
||||
void freeze_incoming_payments(bool enable) { m_freeze_incoming_payments = enable; }
|
||||
bool is_mismatched_daemon_version_allowed() const { return m_allow_mismatched_daemon_version; }
|
||||
void allow_mismatched_daemon_version(bool allow_mismatch) { m_allow_mismatched_daemon_version = allow_mismatch; }
|
||||
|
||||
@@ -1991,6 +1993,7 @@ private:
|
||||
rpc_payment_state_t m_rpc_payment_state;
|
||||
uint64_t m_credits_target;
|
||||
bool m_enable_multisig;
|
||||
bool m_freeze_incoming_payments;
|
||||
bool m_allow_mismatched_daemon_version;
|
||||
|
||||
// Aux transaction data from device
|
||||
|
||||
Reference in New Issue
Block a user