Compare commits
39 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| b089f9ee69 | |||
| 7cb69fa6bc | |||
| c7d4bf491e | |||
| c6d17a0b39 | |||
| 753e4683af | |||
| 2676e5ae85 | |||
| bedfa83ea0 | |||
| dffa6766e7 | |||
| 1f733fb868 | |||
| 956d55c35f | |||
| 76feeb64b7 | |||
| 61db6497f7 | |||
| 6664e3e3b1 | |||
| ebe3fdaff3 | |||
| 886595b540 | |||
| b9fddc08b2 | |||
| c5ad937cc1 | |||
| e875a587e2 | |||
| 8c254e42e3 | |||
| 8dbc361e98 | |||
| 738f5038bf | |||
| 24ccaba6ef | |||
| 1ec7eae036 | |||
| 2f0503d7f3 | |||
| b13e597e8e | |||
| 19fa7dceac | |||
| f48fc72fb6 | |||
| 5930557a94 | |||
| b85f320738 | |||
| 026be65bf5 | |||
| 1123ae9043 | |||
| 755dddd2bc | |||
| dd47d03cf2 | |||
| 4634b8b539 | |||
| 100a7d06ee | |||
| 71567885e6 | |||
| 7686af7acf | |||
| 8703b8a4cb | |||
| d6b35e97be |
@@ -48,7 +48,7 @@ all: release-all
|
||||
|
||||
depends:
|
||||
cd contrib/depends && $(MAKE) HOST=$(target) && cd ../.. && mkdir -p build/$(target)/release
|
||||
cd build/$(target)/release && cmake -DCMAKE_TOOLCHAIN_FILE=$(CURDIR)/contrib/depends/$(target)/share/toolchain.cmake ../../.. && $(MAKE)
|
||||
cd build/$(target)/release && USE_DEVICE_TREZOR_MANDATORY=1 cmake -DCMAKE_TOOLCHAIN_FILE=$(CURDIR)/contrib/depends/$(target)/share/toolchain.cmake ../../.. && $(MAKE)
|
||||
|
||||
cmake-debug:
|
||||
mkdir -p $(builddir)/debug
|
||||
|
||||
@@ -138,8 +138,8 @@ Dates are provided in the format YYYY-MM-DD.
|
||||
| 1978433 | 2019-11-30 | v12 | v0.15.0.0 | v0.16.0.0 | New PoW based on RandomX, only allow >= 2 outputs, change to the block median used to calculate penalty, v1 coinbases are forbidden, rct sigs in coinbase forbidden, 10 block lock time for incoming outputs
|
||||
| 2210000 | 2020-10-17 | v13 | v0.17.0.0 | v0.17.3.2 | New CLSAG transaction format
|
||||
| 2210720 | 2020-10-18 | v14 | v0.17.1.1 | v0.17.3.2 | forbid old MLSAG transaction format
|
||||
| 2688888 | 2022-08-13 | v15 | v0.18.0.0 | v0.18.3.3 | ringsize = 16, bulletproofs+, view tags, adjusted dynamic block weight algorithm
|
||||
| 2689608 | 2022-08-14 | v16 | v0.18.0.0 | v0.18.3.3 | forbid old v14 transaction format
|
||||
| 2688888 | 2022-08-13 | v15 | v0.18.0.0 | v0.18.3.4 | ringsize = 16, bulletproofs+, view tags, adjusted dynamic block weight algorithm
|
||||
| 2689608 | 2022-08-14 | v16 | v0.18.0.0 | v0.18.3.4 | forbid old v14 transaction format
|
||||
| XXXXXXX | XXX-XX-XX | XXX | vX.XX.X.X | vX.XX.X.X | XXX |
|
||||
|
||||
X's indicate that these details have not been determined as of commit date.
|
||||
@@ -344,7 +344,7 @@ Tested on a Raspberry Pi Zero with a clean install of minimal Raspbian Stretch (
|
||||
```bash
|
||||
git clone https://github.com/monero-project/monero.git
|
||||
cd monero
|
||||
git checkout v0.18.3.3
|
||||
git checkout v0.18.3.4
|
||||
```
|
||||
|
||||
* Build:
|
||||
@@ -463,10 +463,10 @@ application.
|
||||
cd monero
|
||||
```
|
||||
|
||||
* If you would like a specific [version/tag](https://github.com/monero-project/monero/tags), do a git checkout for that version. eg. 'v0.18.3.3'. If you don't care about the version and just want binaries from master, skip this step:
|
||||
* If you would like a specific [version/tag](https://github.com/monero-project/monero/tags), do a git checkout for that version. eg. 'v0.18.3.4'. If you don't care about the version and just want binaries from master, skip this step:
|
||||
|
||||
```bash
|
||||
git checkout v0.18.3.3
|
||||
git checkout v0.18.3.4
|
||||
```
|
||||
|
||||
* If you are on a 64-bit system, run:
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
#include "misc_log_ex.h"
|
||||
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <boost/numeric/conversion/bounds.hpp>
|
||||
#include <typeinfo>
|
||||
#include <iomanip>
|
||||
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
#include "mlocker.h"
|
||||
|
||||
#include <boost/utility/string_ref.hpp>
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <cstdint>
|
||||
@@ -69,23 +70,19 @@ namespace string_tools
|
||||
#ifdef _WIN32
|
||||
std::string get_current_module_path();
|
||||
#endif
|
||||
bool set_module_name_and_folder(const std::string& path_to_process_);
|
||||
bool trim_left(std::string& str);
|
||||
bool trim_right(std::string& str);
|
||||
void set_module_name_and_folder(const std::string& path_to_process_);
|
||||
void trim_left(std::string& str);
|
||||
void trim_right(std::string& str);
|
||||
//----------------------------------------------------------------------------
|
||||
inline std::string& trim(std::string& str)
|
||||
{
|
||||
trim_left(str);
|
||||
trim_right(str);
|
||||
boost::trim(str);
|
||||
return str;
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
inline std::string trim(const std::string& str_)
|
||||
inline std::string trim(const std::string& str)
|
||||
{
|
||||
std::string str = str_;
|
||||
trim_left(str);
|
||||
trim_right(str);
|
||||
return str;
|
||||
return boost::trim_copy(str);
|
||||
}
|
||||
std::string pad_string(std::string s, size_t n, char c = ' ', bool prepend = false);
|
||||
|
||||
|
||||
@@ -176,11 +176,12 @@ void mlog_configure(const std::string &filename_base, bool console, const std::s
|
||||
std::vector<boost::filesystem::path> found_files;
|
||||
const boost::filesystem::directory_iterator end_itr;
|
||||
const boost::filesystem::path filename_base_path(filename_base);
|
||||
const std::string filename_base_name = filename_base_path.filename().string();
|
||||
const boost::filesystem::path parent_path = filename_base_path.has_parent_path() ? filename_base_path.parent_path() : ".";
|
||||
for (boost::filesystem::directory_iterator iter(parent_path); iter != end_itr; ++iter)
|
||||
{
|
||||
const std::string filename = iter->path().string();
|
||||
if (filename.size() >= filename_base.size() && std::memcmp(filename.data(), filename_base.data(), filename_base.size()) == 0)
|
||||
const std::string filename = iter->path().filename().string();
|
||||
if (filename.size() >= filename_base_name.size() && std::memcmp(filename.data(), filename_base_name.data(), filename_base_name.size()) == 0)
|
||||
{
|
||||
found_files.push_back(iter->path());
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include "readline_buffer.h"
|
||||
#include "string_tools.h"
|
||||
#include <readline/readline.h>
|
||||
#include <readline/history.h>
|
||||
#include <iostream>
|
||||
@@ -173,7 +174,7 @@ static void handle_line(char* line)
|
||||
line_stat = rdln::full;
|
||||
the_line = line;
|
||||
std::string test_line = line;
|
||||
boost::trim_right(test_line);
|
||||
epee::string_tools::trim_right(test_line);
|
||||
if(!test_line.empty())
|
||||
{
|
||||
if (!same_as_last_line(test_line))
|
||||
|
||||
@@ -38,9 +38,12 @@
|
||||
#include <cstdlib>
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
#include <system_error>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include <boost/algorithm/string/predicate.hpp>
|
||||
#include <boost/utility/string_ref.hpp>
|
||||
#include <boost/filesystem.hpp>
|
||||
#include "misc_log_ex.h"
|
||||
#include "storages/parserse_base_utils.h"
|
||||
#include "hex.h"
|
||||
@@ -157,46 +160,33 @@ namespace string_tools
|
||||
return pname;
|
||||
}
|
||||
#endif
|
||||
|
||||
bool set_module_name_and_folder(const std::string& path_to_process_)
|
||||
{
|
||||
std::string path_to_process = path_to_process_;
|
||||
|
||||
void set_module_name_and_folder(const std::string& path_to_process_)
|
||||
{
|
||||
boost::filesystem::path path_to_process = path_to_process_;
|
||||
|
||||
#ifdef _WIN32
|
||||
path_to_process = get_current_module_path();
|
||||
#endif
|
||||
std::string::size_type a = path_to_process.rfind( '\\' );
|
||||
if(a == std::string::npos )
|
||||
{
|
||||
a = path_to_process.rfind( '/' );
|
||||
}
|
||||
if ( a != std::string::npos )
|
||||
{
|
||||
get_current_module_name() = path_to_process.substr(a+1, path_to_process.size());
|
||||
get_current_module_folder() = path_to_process.substr(0, a);
|
||||
return true;
|
||||
}else
|
||||
return false;
|
||||
|
||||
}
|
||||
get_current_module_name() = path_to_process.filename().string();
|
||||
get_current_module_folder() = path_to_process.parent_path().string();
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool trim_left(std::string& str)
|
||||
{
|
||||
for(std::string::iterator it = str.begin(); it!= str.end() && isspace(static_cast<unsigned char>(*it));)
|
||||
str.erase(str.begin());
|
||||
|
||||
return true;
|
||||
}
|
||||
void trim_left(std::string& str)
|
||||
{
|
||||
boost::trim_left(str);
|
||||
return;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool trim_right(std::string& str)
|
||||
{
|
||||
void trim_right(std::string& str)
|
||||
{
|
||||
boost::trim_right(str);
|
||||
return;
|
||||
}
|
||||
|
||||
for(std::string::reverse_iterator it = str.rbegin(); it!= str.rend() && isspace(static_cast<unsigned char>(*it));)
|
||||
str.erase( --((it++).base()));
|
||||
|
||||
return true;
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
std::string pad_string(std::string s, size_t n, char c, bool prepend)
|
||||
{
|
||||
if (s.size() < n)
|
||||
@@ -209,28 +199,22 @@ namespace string_tools
|
||||
return s;
|
||||
}
|
||||
|
||||
std::string get_extension(const std::string& str)
|
||||
{
|
||||
std::string res;
|
||||
std::string::size_type pos = str.rfind('.');
|
||||
if(std::string::npos == pos)
|
||||
return res;
|
||||
|
||||
res = str.substr(pos+1, str.size()-pos);
|
||||
return res;
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
std::string cut_off_extension(const std::string& str)
|
||||
{
|
||||
std::string res;
|
||||
std::string::size_type pos = str.rfind('.');
|
||||
if(std::string::npos == pos)
|
||||
return str;
|
||||
std::string get_extension(const std::string& str)
|
||||
{
|
||||
std::string ext_with_dot = boost::filesystem::path(str).extension().string();
|
||||
|
||||
if (ext_with_dot.empty())
|
||||
return {};
|
||||
|
||||
return ext_with_dot.erase(0, 1);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
std::string cut_off_extension(const std::string& str)
|
||||
{
|
||||
return boost::filesystem::path(str).replace_extension("").string();
|
||||
}
|
||||
|
||||
res = str.substr(0, pos);
|
||||
return res;
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
#ifdef _WIN32
|
||||
std::wstring utf8_to_utf16(const std::string& str)
|
||||
{
|
||||
|
||||
@@ -57,7 +57,7 @@ The dockrun.sh script will do everything to build the binaries. Just specify the
|
||||
version to build as its only argument, e.g.
|
||||
|
||||
```bash
|
||||
VERSION=v0.18.3.3
|
||||
VERSION=v0.18.3.4
|
||||
./dockrun.sh $VERSION
|
||||
```
|
||||
|
||||
|
||||
@@ -133,7 +133,7 @@ Common setup part:
|
||||
su - gitianuser
|
||||
|
||||
GH_USER=YOUR_GITHUB_USER_NAME
|
||||
VERSION=v0.18.3.3
|
||||
VERSION=v0.18.3.4
|
||||
```
|
||||
|
||||
Where `GH_USER` is your GitHub user name and `VERSION` is the version tag you want to build.
|
||||
|
||||
Binary file not shown.
@@ -250,6 +250,7 @@ namespace cryptonote
|
||||
ADD_CHECKPOINT2(2985000, "08f5e6b7301c1b6ed88268a28f8677a06e8ff943b3f9e48d3080f71f9c134bfb", "0x444b7b42a633c96");
|
||||
ADD_CHECKPOINT2(3088000, "bddf8ca09110d33d6d497f13a113630c2b6af1c84d4f3a6f35cb1446f2604ade", "0x4aed3615c2f8c3e");
|
||||
ADD_CHECKPOINT2(3102800, "083f4a34f9490403b564286e7f13fd1ed45c52c86fa47195f151594e5bc87504", "0x4bbed52d4da5dfb");
|
||||
ADD_CHECKPOINT2(3198000, "1d685b39be51e4e84e0af69fa78e023c7cb21de7d33acd012d0371d5f78712d5", "0x517d415fee3a816");
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
#include <boost/archive/portable_binary_iarchive.hpp>
|
||||
#include <boost/filesystem/operations.hpp>
|
||||
|
||||
#include "common/util.h"
|
||||
|
||||
namespace tools
|
||||
{
|
||||
@@ -110,7 +111,7 @@ 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);
|
||||
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())
|
||||
|
||||
+38
-3
@@ -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() {}
|
||||
@@ -122,7 +140,7 @@ namespace tools
|
||||
private_file::private_file(std::FILE* handle, std::string&& filename) noexcept
|
||||
: m_handle(handle), m_filename(std::move(filename)) {}
|
||||
|
||||
private_file private_file::create(std::string name)
|
||||
private_file private_file::create(std::string name, uint32_t extra_flags)
|
||||
{
|
||||
#ifdef WIN32
|
||||
struct close_handle
|
||||
@@ -175,7 +193,7 @@ namespace tools
|
||||
name.c_str(),
|
||||
GENERIC_WRITE, FILE_SHARE_READ,
|
||||
std::addressof(attributes),
|
||||
CREATE_NEW, (FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE),
|
||||
CREATE_NEW, (FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE | extra_flags),
|
||||
nullptr
|
||||
)
|
||||
};
|
||||
@@ -194,7 +212,7 @@ namespace tools
|
||||
}
|
||||
}
|
||||
#else
|
||||
const int fdr = open(name.c_str(), (O_RDONLY | O_CREAT), S_IRUSR);
|
||||
const int fdr = open(name.c_str(), (O_RDONLY | O_CREAT | extra_flags), S_IRUSR);
|
||||
if (0 <= fdr)
|
||||
{
|
||||
struct stat rstats = {};
|
||||
@@ -225,6 +243,23 @@ namespace tools
|
||||
return {};
|
||||
}
|
||||
|
||||
private_file private_file::drop_and_recreate(std::string filename)
|
||||
{
|
||||
if (epee::file_io_utils::is_file_exist(filename)) {
|
||||
boost::system::error_code ec{};
|
||||
boost::filesystem::remove(filename, ec);
|
||||
if (ec) {
|
||||
MERROR("Failed to remove " << filename << ": " << ec.message());
|
||||
return {};
|
||||
}
|
||||
}
|
||||
#ifdef WIN32
|
||||
return create(filename);
|
||||
#else
|
||||
return create(filename, O_EXCL);
|
||||
#endif
|
||||
}
|
||||
|
||||
private_file::~private_file() noexcept
|
||||
{
|
||||
try
|
||||
|
||||
+7
-1
@@ -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;
|
||||
@@ -80,7 +82,11 @@ namespace tools
|
||||
|
||||
/*! \return File only readable by owner and only used by this process
|
||||
OR `private_file{}` on error. */
|
||||
static private_file create(std::string filename);
|
||||
static private_file create(std::string filename, uint32_t extra_flags = 0);
|
||||
|
||||
/*! \return Drop and create file only readable by owner and only used
|
||||
by this process OR `private_file{}` on error. */
|
||||
static private_file drop_and_recreate(std::string filename);
|
||||
|
||||
private_file(private_file&&) = default;
|
||||
private_file& operator=(private_file&&) = default;
|
||||
|
||||
@@ -59,6 +59,7 @@ namespace cryptonote
|
||||
bool m_fee_too_low;
|
||||
bool m_too_few_outputs;
|
||||
bool m_tx_extra_too_big;
|
||||
bool m_nonzero_unlock_time;
|
||||
};
|
||||
|
||||
struct block_verification_context
|
||||
|
||||
@@ -5552,7 +5552,7 @@ void Blockchain::cancel()
|
||||
}
|
||||
|
||||
#if defined(PER_BLOCK_CHECKPOINT)
|
||||
static const char expected_block_hashes_hash[] = "0046a0019beb6e697e27d834d6127851425f7ee09bfb8e9f8df7b1420131aca8";
|
||||
static const char expected_block_hashes_hash[] = "8ada865350270fd008397684d978dac75ea4029a8a1ffcaa9975c43be119ec19";
|
||||
void Blockchain::load_compiled_in_block_hashes(const GetCheckpointsCallback& get_checkpoints)
|
||||
{
|
||||
if (get_checkpoints == nullptr || !m_fast_sync)
|
||||
|
||||
@@ -203,7 +203,7 @@ namespace cryptonote
|
||||
return addr.m_view_public_key;
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
bool construct_tx_with_tx_key(const account_keys& sender_account_keys, const std::unordered_map<crypto::public_key, subaddress_index>& subaddresses, std::vector<tx_source_entry>& sources, std::vector<tx_destination_entry>& destinations, const boost::optional<cryptonote::account_public_address>& change_addr, const std::vector<uint8_t> &extra, transaction& tx, uint64_t unlock_time, const crypto::secret_key &tx_key, const std::vector<crypto::secret_key> &additional_tx_keys, bool rct, const rct::RCTConfig &rct_config, bool shuffle_outs, bool use_view_tags)
|
||||
bool construct_tx_with_tx_key(const account_keys& sender_account_keys, const std::unordered_map<crypto::public_key, subaddress_index>& subaddresses, std::vector<tx_source_entry>& sources, std::vector<tx_destination_entry>& destinations, const boost::optional<cryptonote::account_public_address>& change_addr, const std::vector<uint8_t> &extra, transaction& tx, const crypto::secret_key &tx_key, const std::vector<crypto::secret_key> &additional_tx_keys, bool rct, const rct::RCTConfig &rct_config, bool shuffle_outs, bool use_view_tags)
|
||||
{
|
||||
hw::device &hwdev = sender_account_keys.get_device();
|
||||
|
||||
@@ -218,7 +218,7 @@ namespace cryptonote
|
||||
amount_keys.clear();
|
||||
|
||||
tx.version = rct ? 2 : 1;
|
||||
tx.unlock_time = unlock_time;
|
||||
tx.unlock_time = 0;
|
||||
|
||||
tx.extra = extra;
|
||||
crypto::public_key txkey_pub;
|
||||
@@ -606,7 +606,7 @@ namespace cryptonote
|
||||
return true;
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
bool construct_tx_and_get_tx_key(const account_keys& sender_account_keys, const std::unordered_map<crypto::public_key, subaddress_index>& subaddresses, std::vector<tx_source_entry>& sources, std::vector<tx_destination_entry>& destinations, const boost::optional<cryptonote::account_public_address>& change_addr, const std::vector<uint8_t> &extra, transaction& tx, uint64_t unlock_time, crypto::secret_key &tx_key, std::vector<crypto::secret_key> &additional_tx_keys, bool rct, const rct::RCTConfig &rct_config, bool use_view_tags)
|
||||
bool construct_tx_and_get_tx_key(const account_keys& sender_account_keys, const std::unordered_map<crypto::public_key, subaddress_index>& subaddresses, std::vector<tx_source_entry>& sources, std::vector<tx_destination_entry>& destinations, const boost::optional<cryptonote::account_public_address>& change_addr, const std::vector<uint8_t> &extra, transaction& tx, crypto::secret_key &tx_key, std::vector<crypto::secret_key> &additional_tx_keys, bool rct, const rct::RCTConfig &rct_config, bool use_view_tags)
|
||||
{
|
||||
hw::device &hwdev = sender_account_keys.get_device();
|
||||
hwdev.open_tx(tx_key);
|
||||
@@ -627,7 +627,7 @@ namespace cryptonote
|
||||
}
|
||||
|
||||
bool shuffle_outs = true;
|
||||
bool r = construct_tx_with_tx_key(sender_account_keys, subaddresses, sources, destinations, change_addr, extra, tx, unlock_time, tx_key, additional_tx_keys, rct, rct_config, shuffle_outs, use_view_tags);
|
||||
bool r = construct_tx_with_tx_key(sender_account_keys, subaddresses, sources, destinations, change_addr, extra, tx, tx_key, additional_tx_keys, rct, rct_config, shuffle_outs, use_view_tags);
|
||||
hwdev.close_tx();
|
||||
return r;
|
||||
} catch(...) {
|
||||
@@ -636,14 +636,14 @@ namespace cryptonote
|
||||
}
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
bool construct_tx(const account_keys& sender_account_keys, std::vector<tx_source_entry>& sources, const std::vector<tx_destination_entry>& destinations, const boost::optional<cryptonote::account_public_address>& change_addr, const std::vector<uint8_t> &extra, transaction& tx, uint64_t unlock_time)
|
||||
bool construct_tx(const account_keys& sender_account_keys, std::vector<tx_source_entry>& sources, const std::vector<tx_destination_entry>& destinations, const boost::optional<cryptonote::account_public_address>& change_addr, const std::vector<uint8_t> &extra, transaction& tx)
|
||||
{
|
||||
std::unordered_map<crypto::public_key, cryptonote::subaddress_index> subaddresses;
|
||||
subaddresses[sender_account_keys.m_account_address.m_spend_public_key] = {0,0};
|
||||
crypto::secret_key tx_key;
|
||||
std::vector<crypto::secret_key> additional_tx_keys;
|
||||
std::vector<tx_destination_entry> destinations_copy = destinations;
|
||||
return construct_tx_and_get_tx_key(sender_account_keys, subaddresses, sources, destinations_copy, change_addr, extra, tx, unlock_time, tx_key, additional_tx_keys, false, { rct::RangeProofBorromean, 0});
|
||||
return construct_tx_and_get_tx_key(sender_account_keys, subaddresses, sources, destinations_copy, change_addr, extra, tx, tx_key, additional_tx_keys, false, { rct::RangeProofBorromean, 0});
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
bool generate_genesis_block(
|
||||
|
||||
@@ -118,9 +118,9 @@ namespace cryptonote
|
||||
|
||||
//---------------------------------------------------------------
|
||||
crypto::public_key get_destination_view_key_pub(const std::vector<tx_destination_entry> &destinations, const boost::optional<cryptonote::account_public_address>& change_addr);
|
||||
bool construct_tx(const account_keys& sender_account_keys, std::vector<tx_source_entry> &sources, const std::vector<tx_destination_entry>& destinations, const boost::optional<cryptonote::account_public_address>& change_addr, const std::vector<uint8_t> &extra, transaction& tx, uint64_t unlock_time);
|
||||
bool construct_tx_with_tx_key(const account_keys& sender_account_keys, const std::unordered_map<crypto::public_key, subaddress_index>& subaddresses, std::vector<tx_source_entry>& sources, std::vector<tx_destination_entry>& destinations, const boost::optional<cryptonote::account_public_address>& change_addr, const std::vector<uint8_t> &extra, transaction& tx, uint64_t unlock_time, const crypto::secret_key &tx_key, const std::vector<crypto::secret_key> &additional_tx_keys, bool rct = false, const rct::RCTConfig &rct_config = { rct::RangeProofBorromean, 0 }, bool shuffle_outs = true, bool use_view_tags = false);
|
||||
bool construct_tx_and_get_tx_key(const account_keys& sender_account_keys, const std::unordered_map<crypto::public_key, subaddress_index>& subaddresses, std::vector<tx_source_entry>& sources, std::vector<tx_destination_entry>& destinations, const boost::optional<cryptonote::account_public_address>& change_addr, const std::vector<uint8_t> &extra, transaction& tx, uint64_t unlock_time, crypto::secret_key &tx_key, std::vector<crypto::secret_key> &additional_tx_keys, bool rct = false, const rct::RCTConfig &rct_config = { rct::RangeProofBorromean, 0 }, bool use_view_tags = false);
|
||||
bool construct_tx(const account_keys& sender_account_keys, std::vector<tx_source_entry> &sources, const std::vector<tx_destination_entry>& destinations, const boost::optional<cryptonote::account_public_address>& change_addr, const std::vector<uint8_t> &extra, transaction& tx);
|
||||
bool construct_tx_with_tx_key(const account_keys& sender_account_keys, const std::unordered_map<crypto::public_key, subaddress_index>& subaddresses, std::vector<tx_source_entry>& sources, std::vector<tx_destination_entry>& destinations, const boost::optional<cryptonote::account_public_address>& change_addr, const std::vector<uint8_t> &extra, transaction& tx, const crypto::secret_key &tx_key, const std::vector<crypto::secret_key> &additional_tx_keys, bool rct = false, const rct::RCTConfig &rct_config = { rct::RangeProofBorromean, 0 }, bool shuffle_outs = true, bool use_view_tags = false);
|
||||
bool construct_tx_and_get_tx_key(const account_keys& sender_account_keys, const std::unordered_map<crypto::public_key, subaddress_index>& subaddresses, std::vector<tx_source_entry>& sources, std::vector<tx_destination_entry>& destinations, const boost::optional<cryptonote::account_public_address>& change_addr, const std::vector<uint8_t> &extra, transaction& tx, crypto::secret_key &tx_key, std::vector<crypto::secret_key> &additional_tx_keys, bool rct = false, const rct::RCTConfig &rct_config = { rct::RangeProofBorromean, 0 }, bool use_view_tags = false);
|
||||
bool generate_output_ephemeral_keys(const size_t tx_version, const cryptonote::account_keys &sender_account_keys, const crypto::public_key &txkey_pub, const crypto::secret_key &tx_key,
|
||||
const cryptonote::tx_destination_entry &dst_entr, const boost::optional<cryptonote::account_public_address> &change_addr, const size_t output_index,
|
||||
const bool &need_additional_txkeys, const std::vector<crypto::secret_key> &additional_tx_keys,
|
||||
|
||||
@@ -236,6 +236,15 @@ namespace cryptonote
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!kept_by_block && tx.unlock_time)
|
||||
{
|
||||
LOG_PRINT_L1("transaction unlock time is not zero: " << tx.unlock_time);
|
||||
tvc.m_verifivation_failed = true;
|
||||
tvc.m_nonzero_unlock_time = true;
|
||||
tvc.m_no_drop_offense = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
// if the transaction came from a block popped from the chain,
|
||||
// don't check if we have its key images as spent.
|
||||
// TODO: Investigate why not?
|
||||
|
||||
@@ -396,6 +396,8 @@ namespace levin
|
||||
for (auto& connection : connections)
|
||||
{
|
||||
std::sort(connection.first.begin(), connection.first.end()); // don't leak receive order
|
||||
connection.first.erase(std::unique(connection.first.begin(), connection.first.end()),
|
||||
connection.first.end());
|
||||
make_payload_send_txs(*zone_->p2p, std::move(connection.first), connection.second, zone_->pad_txs, true);
|
||||
}
|
||||
|
||||
@@ -741,9 +743,14 @@ namespace levin
|
||||
notify::status notify::get_status() const noexcept
|
||||
{
|
||||
if (!zone_)
|
||||
return {false, false};
|
||||
return {false, false, false};
|
||||
|
||||
return {!zone_->noise.empty(), CRYPTONOTE_NOISE_CHANNELS <= zone_->connection_count};
|
||||
// `connection_count` is only set when `!noise.empty()`.
|
||||
const std::size_t connection_count = zone_->connection_count;
|
||||
bool has_outgoing = connection_count;
|
||||
if (zone_->noise.empty())
|
||||
has_outgoing = zone_->p2p->get_out_connections_count();
|
||||
return {!zone_->noise.empty(), CRYPTONOTE_NOISE_CHANNELS <= connection_count, has_outgoing};
|
||||
}
|
||||
|
||||
void notify::new_out_connection()
|
||||
|
||||
@@ -75,7 +75,8 @@ namespace levin
|
||||
struct status
|
||||
{
|
||||
bool has_noise;
|
||||
bool connections_filled;
|
||||
bool connections_filled; //!< True when has zone has `CRYPTONOTE_NOISE_CHANNELS` outgoing noise channels
|
||||
bool has_outgoing; //!< True when zone has outgoing connections
|
||||
};
|
||||
|
||||
//! Construct an instance that cannot notify.
|
||||
|
||||
@@ -527,6 +527,7 @@ namespace hw {
|
||||
{0x2c97, 0x0004, 0, 0xffa0},
|
||||
{0x2c97, 0x0005, 0, 0xffa0},
|
||||
{0x2c97, 0x0006, 0, 0xffa0},
|
||||
{0x2c97, 0x0007, 0, 0xffa0},
|
||||
};
|
||||
|
||||
bool device_ledger::connect(void) {
|
||||
|
||||
@@ -820,7 +820,6 @@ tx_builder_ringct_t::~tx_builder_ringct_t()
|
||||
bool tx_builder_ringct_t::init(
|
||||
const cryptonote::account_keys& account_keys,
|
||||
const std::vector<std::uint8_t>& extra,
|
||||
const std::uint64_t unlock_time,
|
||||
const std::uint32_t subaddr_account,
|
||||
const std::set<std::uint32_t>& subaddr_minor_indices,
|
||||
std::vector<cryptonote::tx_source_entry>& sources,
|
||||
@@ -854,7 +853,7 @@ bool tx_builder_ringct_t::init(
|
||||
|
||||
// misc. fields
|
||||
unsigned_tx.version = 2; //rct = 2
|
||||
unsigned_tx.unlock_time = unlock_time;
|
||||
unsigned_tx.unlock_time = 0;
|
||||
|
||||
// sort inputs
|
||||
sort_sources(sources);
|
||||
|
||||
@@ -71,7 +71,6 @@ public:
|
||||
bool init(
|
||||
const cryptonote::account_keys& account_keys,
|
||||
const std::vector<std::uint8_t>& extra,
|
||||
const std::uint64_t unlock_time,
|
||||
const std::uint32_t subaddr_account,
|
||||
const std::set<std::uint32_t>& subaddr_minor_indices,
|
||||
std::vector<cryptonote::tx_source_entry>& sources,
|
||||
|
||||
+11
-11
@@ -706,18 +706,18 @@ namespace nodetool
|
||||
if (m_nettype == cryptonote::TESTNET)
|
||||
{
|
||||
full_addrs.insert("176.9.0.187:28080");
|
||||
full_addrs.insert("88.99.173.38:28080");
|
||||
full_addrs.insert("51.79.173.165:28080");
|
||||
full_addrs.insert("192.99.8.110:28080");
|
||||
full_addrs.insert("37.187.74.171:28080");
|
||||
full_addrs.insert("77.172.183.193:28080");
|
||||
}
|
||||
else if (m_nettype == cryptonote::STAGENET)
|
||||
{
|
||||
full_addrs.insert("176.9.0.187:38080");
|
||||
full_addrs.insert("88.99.173.38:38080");
|
||||
full_addrs.insert("51.79.173.165:38080");
|
||||
full_addrs.insert("192.99.8.110:38080");
|
||||
full_addrs.insert("37.187.74.171:38080");
|
||||
full_addrs.insert("77.172.183.193:38080");
|
||||
}
|
||||
else if (m_nettype == cryptonote::FAKECHAIN)
|
||||
{
|
||||
@@ -727,10 +727,10 @@ namespace nodetool
|
||||
full_addrs.insert("176.9.0.187:18080");
|
||||
full_addrs.insert("88.198.163.90:18080");
|
||||
full_addrs.insert("66.85.74.134:18080");
|
||||
full_addrs.insert("88.99.173.38:18080");
|
||||
full_addrs.insert("51.79.173.165:18080");
|
||||
full_addrs.insert("192.99.8.110:18080");
|
||||
full_addrs.insert("37.187.74.171:18080");
|
||||
full_addrs.insert("77.172.183.193:18080");
|
||||
}
|
||||
return full_addrs;
|
||||
}
|
||||
@@ -861,12 +861,12 @@ namespace nodetool
|
||||
if (m_nettype == cryptonote::MAINNET)
|
||||
{
|
||||
return {
|
||||
"xwvz3ekocr3dkyxfkmgm2hvbpzx2ysqmaxgter7znnqrhoicygkfswid.onion:18083",
|
||||
"4pixvbejrvihnkxmduo2agsnmc3rrulrqc7s3cbwwrep6h6hrzsibeqd.onion:18083",
|
||||
"zbjkbsxc5munw3qusl7j2hpcmikhqocdf4pqhnhtpzw5nt5jrmofptid.onion:18083",
|
||||
"qz43zul2x56jexzoqgkx2trzwcfnr6l3hbtfcfx54g4r3eahy3bssjyd.onion:18083",
|
||||
"plowsof3t5hogddwabaeiyrno25efmzfxyro2vligremt7sxpsclfaid.onion:18083",
|
||||
"plowsoffjexmxalw73tkjmf422gq6575fc7vicuu4javzn2ynnte6tyd.onion:18083",
|
||||
"plowsofe6cleftfmk2raiw5h2x66atrik3nja4bfd3zrfa2hdlgworad.onion:18083",
|
||||
"aclc4e2jhhtr44guufbnwk5bzwhaecinax4yip4wr4tjn27sjsfg6zqd.onion:18083",
|
||||
};
|
||||
}
|
||||
return {};
|
||||
@@ -874,10 +874,9 @@ namespace nodetool
|
||||
if (m_nettype == cryptonote::MAINNET)
|
||||
{
|
||||
return {
|
||||
"s3l6ke4ed3df466khuebb4poienoingwof7oxtbo6j4n56sghe3a.b32.i2p:18080",
|
||||
"sel36x6fibfzujwvt4hf5gxolz6kd3jpvbjqg6o3ud2xtionyl2q.b32.i2p:18080",
|
||||
"uqj3aphckqtjsitz7kxx5flqpwjlq5ppr3chazfued7xucv3nheq.b32.i2p:18080",
|
||||
"vdmnehdjkpkg57nthgnjfuaqgku673r5bpbqg56ix6fyqoywgqrq.b32.i2p:18080",
|
||||
"uqj3aphckqtjsitz7kxx5flqpwjlq5ppr3chazfued7xucv3nheq.b32.i2p",
|
||||
"vdmnehdjkpkg57nthgnjfuaqgku673r5bpbqg56ix6fyqoywgqrq.b32.i2p",
|
||||
"ugnlcdciyhghh2zert7c3kl4biwkirc43ke33jiy5slnd3mv2trq.b32.i2p",
|
||||
};
|
||||
}
|
||||
return {};
|
||||
@@ -2300,11 +2299,12 @@ namespace nodetool
|
||||
if (enet::zone::tor < network->first)
|
||||
break; // unknown network
|
||||
|
||||
if (network->second.m_connect)
|
||||
const auto status = network->second.m_notifier.get_status();
|
||||
if (network->second.m_connect && status.has_outgoing)
|
||||
return send(*network);
|
||||
}
|
||||
|
||||
// configuration should not allow this scenario
|
||||
MWARNING("Unable to send " << txs.size() << " transaction(s): anonymity networks had no outgoing connections");
|
||||
return enet::zone::invalid;
|
||||
}
|
||||
//-----------------------------------------------------------------------------------
|
||||
|
||||
@@ -42,6 +42,7 @@
|
||||
#include <boost/serialization/version.hpp>
|
||||
|
||||
#include "net_peerlist_boost_serialization.h"
|
||||
#include "common/util.h"
|
||||
|
||||
|
||||
namespace nodetool
|
||||
@@ -200,7 +201,7 @@ 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);
|
||||
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())
|
||||
|
||||
@@ -1340,6 +1340,8 @@ namespace cryptonote
|
||||
add_reason(reason, "too few outputs");
|
||||
if ((res.tx_extra_too_big = tvc.m_tx_extra_too_big))
|
||||
add_reason(reason, "tx-extra too big");
|
||||
if ((res.nonzero_unlock_time = tvc.m_nonzero_unlock_time))
|
||||
add_reason(reason, "tx unlock time is not zero");
|
||||
const std::string punctuation = reason.empty() ? "" : ": ";
|
||||
if (tvc.m_verifivation_failed)
|
||||
{
|
||||
|
||||
@@ -88,7 +88,7 @@ namespace cryptonote
|
||||
// advance which version they will stop working with
|
||||
// Don't go over 32767 for any of these
|
||||
#define CORE_RPC_VERSION_MAJOR 3
|
||||
#define CORE_RPC_VERSION_MINOR 13
|
||||
#define CORE_RPC_VERSION_MINOR 14
|
||||
#define MAKE_CORE_RPC_VERSION(major,minor) (((major)<<16)|(minor))
|
||||
#define CORE_RPC_VERSION MAKE_CORE_RPC_VERSION(CORE_RPC_VERSION_MAJOR, CORE_RPC_VERSION_MINOR)
|
||||
|
||||
@@ -640,6 +640,7 @@ namespace cryptonote
|
||||
bool too_few_outputs;
|
||||
bool sanity_check_failed;
|
||||
bool tx_extra_too_big;
|
||||
bool nonzero_unlock_time;
|
||||
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE_PARENT(rpc_access_response_base)
|
||||
@@ -655,6 +656,7 @@ namespace cryptonote
|
||||
KV_SERIALIZE(too_few_outputs)
|
||||
KV_SERIALIZE(sanity_check_failed)
|
||||
KV_SERIALIZE(tx_extra_too_big)
|
||||
KV_SERIALIZE(nonzero_unlock_time)
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
typedef epee::misc_utils::struct_init<response_t> response;
|
||||
|
||||
@@ -422,6 +422,16 @@ namespace rpc
|
||||
if (!res.error_details.empty()) res.error_details += " and ";
|
||||
res.error_details += "too few outputs";
|
||||
}
|
||||
if (tvc.m_tx_extra_too_big)
|
||||
{
|
||||
if (!res.error_details.empty()) res.error_details += " and ";
|
||||
res.error_details += "tx_extra too long";
|
||||
}
|
||||
if (tvc.m_nonzero_unlock_time)
|
||||
{
|
||||
if (!res.error_details.empty()) res.error_details += " and ";
|
||||
res.error_details += "non-zero unlock time";
|
||||
}
|
||||
if (res.error_details.empty())
|
||||
{
|
||||
res.error_details = "an unknown issue was found with the transaction";
|
||||
@@ -510,6 +520,8 @@ namespace rpc
|
||||
res.info.target_height = res.info.height;
|
||||
}
|
||||
|
||||
m_core.get_blockchain_top(res.info.top_block_height, res.info.top_block_hash);
|
||||
|
||||
auto& chain = m_core.get_blockchain_storage();
|
||||
|
||||
res.info.wide_difficulty = chain.get_difficulty_for_next_block();
|
||||
|
||||
@@ -176,6 +176,7 @@ namespace rpc
|
||||
{
|
||||
uint64_t height;
|
||||
uint64_t target_height;
|
||||
uint64_t top_block_height;
|
||||
cryptonote::difficulty_type wide_difficulty;
|
||||
uint64_t difficulty;
|
||||
uint64_t target;
|
||||
|
||||
@@ -273,7 +273,10 @@ void toJsonValue(rapidjson::Writer<epee::byte_stream>& dest, const cryptonote::t
|
||||
{
|
||||
INSERT_INTO_JSON_OBJECT(dest, signatures, tx.signatures);
|
||||
}
|
||||
INSERT_INTO_JSON_OBJECT(dest, ringct, tx.rct_signatures);
|
||||
{
|
||||
dest.Key("ringct");
|
||||
toJsonValue(dest, tx.rct_signatures, tx.pruned);
|
||||
}
|
||||
|
||||
dest.EndObject();
|
||||
}
|
||||
@@ -1111,7 +1114,7 @@ void fromJsonValue(const rapidjson::Value& val, cryptonote::rpc::BlockHeaderResp
|
||||
GET_FROM_JSON_OBJECT(val, response.reward, reward);
|
||||
}
|
||||
|
||||
void toJsonValue(rapidjson::Writer<epee::byte_stream>& dest, const rct::rctSig& sig)
|
||||
void toJsonValue(rapidjson::Writer<epee::byte_stream>& dest, const rct::rctSig& sig, const bool prune)
|
||||
{
|
||||
using boost::adaptors::transform;
|
||||
|
||||
@@ -1131,7 +1134,7 @@ void toJsonValue(rapidjson::Writer<epee::byte_stream>& dest, const rct::rctSig&
|
||||
}
|
||||
|
||||
// prunable
|
||||
if (!sig.p.bulletproofs.empty() || !sig.p.bulletproofs_plus.empty() || !sig.p.rangeSigs.empty() || !sig.p.MGs.empty() || !sig.get_pseudo_outs().empty())
|
||||
if (!prune && (!sig.p.bulletproofs.empty() || !sig.p.bulletproofs_plus.empty() || !sig.p.rangeSigs.empty() || !sig.p.MGs.empty() || !sig.get_pseudo_outs().empty()))
|
||||
{
|
||||
dest.Key("prunable");
|
||||
dest.StartObject();
|
||||
@@ -1423,9 +1426,14 @@ void toJsonValue(rapidjson::Writer<epee::byte_stream>& dest, const cryptonote::r
|
||||
{
|
||||
dest.StartObject();
|
||||
|
||||
const uint64_t difficulty_top64 = (info.wide_difficulty >> 64).convert_to<std::uint64_t>();
|
||||
const uint64_t cumulative_difficulty_top64 = (info.wide_cumulative_difficulty >> 64).convert_to<std::uint64_t>();
|
||||
|
||||
INSERT_INTO_JSON_OBJECT(dest, height, info.height);
|
||||
INSERT_INTO_JSON_OBJECT(dest, target_height, info.target_height);
|
||||
INSERT_INTO_JSON_OBJECT(dest, top_block_height, info.top_block_height);
|
||||
INSERT_INTO_JSON_OBJECT(dest, difficulty, info.difficulty);
|
||||
INSERT_INTO_JSON_OBJECT(dest, difficulty_top64, difficulty_top64);
|
||||
INSERT_INTO_JSON_OBJECT(dest, target, info.target);
|
||||
INSERT_INTO_JSON_OBJECT(dest, tx_count, info.tx_count);
|
||||
INSERT_INTO_JSON_OBJECT(dest, tx_pool_size, info.tx_pool_size);
|
||||
@@ -1440,12 +1448,14 @@ void toJsonValue(rapidjson::Writer<epee::byte_stream>& dest, const cryptonote::r
|
||||
INSERT_INTO_JSON_OBJECT(dest, nettype, info.nettype);
|
||||
INSERT_INTO_JSON_OBJECT(dest, top_block_hash, info.top_block_hash);
|
||||
INSERT_INTO_JSON_OBJECT(dest, cumulative_difficulty, info.cumulative_difficulty);
|
||||
INSERT_INTO_JSON_OBJECT(dest, cumulative_difficulty_top64, cumulative_difficulty_top64);
|
||||
INSERT_INTO_JSON_OBJECT(dest, block_size_limit, info.block_size_limit);
|
||||
INSERT_INTO_JSON_OBJECT(dest, block_weight_limit, info.block_weight_limit);
|
||||
INSERT_INTO_JSON_OBJECT(dest, block_size_median, info.block_size_median);
|
||||
INSERT_INTO_JSON_OBJECT(dest, block_weight_median, info.block_weight_median);
|
||||
INSERT_INTO_JSON_OBJECT(dest, adjusted_time, info.adjusted_time);
|
||||
INSERT_INTO_JSON_OBJECT(dest, start_time, info.start_time);
|
||||
INSERT_INTO_JSON_OBJECT(dest, version, info.version);
|
||||
|
||||
dest.EndObject();
|
||||
}
|
||||
@@ -1457,9 +1467,14 @@ void fromJsonValue(const rapidjson::Value& val, cryptonote::rpc::DaemonInfo& inf
|
||||
throw WRONG_TYPE("json object");
|
||||
}
|
||||
|
||||
uint64_t difficulty_top64 = 0;
|
||||
uint64_t cumulative_difficulty_top64 = 0;
|
||||
|
||||
GET_FROM_JSON_OBJECT(val, info.height, height);
|
||||
GET_FROM_JSON_OBJECT(val, info.target_height, target_height);
|
||||
GET_FROM_JSON_OBJECT(val, info.top_block_height, top_block_height);
|
||||
GET_FROM_JSON_OBJECT(val, info.difficulty, difficulty);
|
||||
GET_FROM_JSON_OBJECT(val, difficulty_top64, difficulty_top64);
|
||||
GET_FROM_JSON_OBJECT(val, info.target, target);
|
||||
GET_FROM_JSON_OBJECT(val, info.tx_count, tx_count);
|
||||
GET_FROM_JSON_OBJECT(val, info.tx_pool_size, tx_pool_size);
|
||||
@@ -1474,12 +1489,22 @@ void fromJsonValue(const rapidjson::Value& val, cryptonote::rpc::DaemonInfo& inf
|
||||
GET_FROM_JSON_OBJECT(val, info.nettype, nettype);
|
||||
GET_FROM_JSON_OBJECT(val, info.top_block_hash, top_block_hash);
|
||||
GET_FROM_JSON_OBJECT(val, info.cumulative_difficulty, cumulative_difficulty);
|
||||
GET_FROM_JSON_OBJECT(val, cumulative_difficulty_top64, cumulative_difficulty_top64);
|
||||
GET_FROM_JSON_OBJECT(val, info.block_size_limit, block_size_limit);
|
||||
GET_FROM_JSON_OBJECT(val, info.block_weight_limit, block_weight_limit);
|
||||
GET_FROM_JSON_OBJECT(val, info.block_size_median, block_size_median);
|
||||
GET_FROM_JSON_OBJECT(val, info.block_weight_median, block_weight_median);
|
||||
GET_FROM_JSON_OBJECT(val, info.adjusted_time, adjusted_time);
|
||||
GET_FROM_JSON_OBJECT(val, info.start_time, start_time);
|
||||
GET_FROM_JSON_OBJECT(val, info.version, version);
|
||||
|
||||
info.wide_difficulty = difficulty_top64;
|
||||
info.wide_difficulty <<= 64;
|
||||
info.wide_difficulty += info.difficulty;
|
||||
|
||||
info.wide_cumulative_difficulty = cumulative_difficulty_top64;
|
||||
info.wide_cumulative_difficulty <<= 64;
|
||||
info.wide_cumulative_difficulty += info.cumulative_difficulty;
|
||||
}
|
||||
|
||||
void toJsonValue(rapidjson::Writer<epee::byte_stream>& dest, const cryptonote::rpc::output_distribution& dist)
|
||||
|
||||
@@ -281,7 +281,7 @@ void fromJsonValue(const rapidjson::Value& val, cryptonote::rpc::error& error);
|
||||
void toJsonValue(rapidjson::Writer<epee::byte_stream>& dest, const cryptonote::rpc::BlockHeaderResponse& response);
|
||||
void fromJsonValue(const rapidjson::Value& val, cryptonote::rpc::BlockHeaderResponse& response);
|
||||
|
||||
void toJsonValue(rapidjson::Writer<epee::byte_stream>& dest, const rct::rctSig& i);
|
||||
void toJsonValue(rapidjson::Writer<epee::byte_stream>& dest, const rct::rctSig& sig, bool prune);
|
||||
void fromJsonValue(const rapidjson::Value& val, rct::rctSig& sig);
|
||||
|
||||
void fromJsonValue(const rapidjson::Value& val, rct::ctkey& key);
|
||||
|
||||
@@ -155,11 +155,6 @@ typedef cryptonote::simple_wallet sw;
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
enum TransferType {
|
||||
Transfer,
|
||||
TransferLocked,
|
||||
};
|
||||
|
||||
static std::string get_human_readable_timespan(std::chrono::seconds seconds);
|
||||
static std::string get_human_readable_timespan(uint64_t seconds);
|
||||
|
||||
@@ -197,8 +192,6 @@ namespace
|
||||
const char* USAGE_PAYMENTS("payments <PID_1> [<PID_2> ... <PID_N>]");
|
||||
const char* USAGE_PAYMENT_ID("payment_id");
|
||||
const char* USAGE_TRANSFER("transfer [index=<N1>[,<N2>,...]] [<priority>] [<ring_size>] (<URI> | <address> <amount>) [subtractfeefrom=<D0>[,<D1>,all,...]] [<payment_id>]");
|
||||
const char* USAGE_LOCKED_TRANSFER("locked_transfer [index=<N1>[,<N2>,...]] [<priority>] [<ring_size>] (<URI> | <addr> <amount>) <lockblocks> [<payment_id (obsolete)>]");
|
||||
const char* USAGE_LOCKED_SWEEP_ALL("locked_sweep_all [index=<N1>[,<N2>,...] | index=all] [<priority>] [<ring_size>] <address> <lockblocks> [<payment_id (obsolete)>]");
|
||||
const char* USAGE_SWEEP_ALL("sweep_all [index=<N1>[,<N2>,...] | index=all] [<priority>] [<ring_size>] [outputs=<N>] <address> [<payment_id (obsolete)>]");
|
||||
const char* USAGE_SWEEP_ACCOUNT("sweep_account <account> [index=<N1>[,<N2>,...] | index=all] [<priority>] [<ring_size>] [outputs=<N>] <address> [<payment_id (obsolete)>]");
|
||||
const char* USAGE_SWEEP_BELOW("sweep_below <amount_threshold> [index=<N1>[,<N2>,...]] [<priority>] [<ring_size>] <address> [<payment_id (obsolete)>]");
|
||||
@@ -3336,14 +3329,6 @@ simple_wallet::simple_wallet()
|
||||
m_cmd_binder.set_handler("transfer", boost::bind(&simple_wallet::on_command, this, &simple_wallet::transfer, _1),
|
||||
tr(USAGE_TRANSFER),
|
||||
tr("Transfer <amount> to <address>. If the parameter \"index=<N1>[,<N2>,...]\" is specified, the wallet uses outputs received by addresses of those indices. If omitted, the wallet randomly chooses address indices to be used. In any case, it tries its best not to combine outputs across multiple addresses. <priority> is the priority of the transaction. The higher the priority, the higher the transaction fee. Valid values in priority order (from lowest to highest) are: unimportant, normal, elevated, priority. If omitted, the default value (see the command \"set priority\") is used. <ring_size> is the number of inputs to include for untraceability. Multiple payments can be made at once by adding URI_2 or <address_2> <amount_2> etcetera (before the payment ID, if it's included). The \"subtractfeefrom=\" list allows you to choose which destinations to fund the tx fee from instead of the change output. The fee will be split across the chosen destinations proportionally equally. For example, to make 3 transfers where the fee is taken from the first and third destinations, one could do: \"transfer <addr1> 3 <addr2> 0.5 <addr3> 1 subtractfeefrom=0,2\". Let's say the tx fee is 0.1. The balance would drop by exactly 4.5 XMR including fees, and addr1 & addr3 would receive 2.925 & 0.975 XMR, respectively. Use \"subtractfeefrom=all\" to spread the fee across all destinations."));
|
||||
m_cmd_binder.set_handler("locked_transfer",
|
||||
boost::bind(&simple_wallet::on_command, this, &simple_wallet::locked_transfer,_1),
|
||||
tr(USAGE_LOCKED_TRANSFER),
|
||||
tr("Transfer <amount> to <address> and lock it for <lockblocks> (max. 1000000). If the parameter \"index=<N1>[,<N2>,...]\" is specified, the wallet uses outputs received by addresses of those indices. If omitted, the wallet randomly chooses address indices to be used. In any case, it tries its best not to combine outputs across multiple addresses. <priority> is the priority of the transaction. The higher the priority, the higher the transaction fee. Valid values in priority order (from lowest to highest) are: unimportant, normal, elevated, priority. If omitted, the default value (see the command \"set priority\") is used. <ring_size> is the number of inputs to include for untraceability. Multiple payments can be made at once by adding URI_2 or <address_2> <amount_2> etcetera (before the payment ID, if it's included)"));
|
||||
m_cmd_binder.set_handler("locked_sweep_all",
|
||||
boost::bind(&simple_wallet::on_command, this, &simple_wallet::locked_sweep_all,_1),
|
||||
tr(USAGE_LOCKED_SWEEP_ALL),
|
||||
tr("Send all unlocked balance to an address and lock it for <lockblocks> (max. 1000000). If the parameter \"index=<N1>[,<N2>,...]\" or \"index=all\" is specified, the wallet sweeps outputs received by those or all address indices, respectively. If omitted, the wallet randomly chooses an address index to be used. <priority> is the priority of the sweep. The higher the priority, the higher the transaction fee. Valid values in priority order (from lowest to highest) are: unimportant, normal, elevated, priority. If omitted, the default value (see the command \"set priority\") is used. <ring_size> is the number of inputs to include for untraceability."));
|
||||
m_cmd_binder.set_handler("sweep_unmixable",
|
||||
boost::bind(&simple_wallet::on_command, this, &simple_wallet::sweep_unmixable, _1),
|
||||
tr("Send all unmixable outputs to yourself with ring_size 1"));
|
||||
@@ -6588,7 +6573,7 @@ bool simple_wallet::on_command(bool (simple_wallet::*cmd)(const std::vector<std:
|
||||
return (this->*cmd)(args);
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
bool simple_wallet::transfer_main(int transfer_type, const std::vector<std::string> &args_, bool called_by_mms)
|
||||
bool simple_wallet::transfer_main(const std::vector<std::string> &args_, bool called_by_mms)
|
||||
{
|
||||
// "transfer [index=<N1>[,<N2>,...]] [<priority>] [<ring_size>] <address> <amount> [<payment_id>]"
|
||||
if (!try_connect_to_daemon())
|
||||
@@ -6640,7 +6625,7 @@ bool simple_wallet::transfer_main(int transfer_type, const std::vector<std::stri
|
||||
return false;
|
||||
}
|
||||
|
||||
const size_t min_args = (transfer_type == TransferLocked) ? 2 : 1;
|
||||
const size_t min_args = 1;
|
||||
if(local_args.size() < min_args)
|
||||
{
|
||||
fail_msg_writer() << tr("wrong number of arguments");
|
||||
@@ -6665,26 +6650,6 @@ bool simple_wallet::transfer_main(int transfer_type, const std::vector<std::stri
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t locked_blocks = 0;
|
||||
if (transfer_type == TransferLocked)
|
||||
{
|
||||
try
|
||||
{
|
||||
locked_blocks = boost::lexical_cast<uint64_t>(local_args.back());
|
||||
}
|
||||
catch (const std::exception &e)
|
||||
{
|
||||
fail_msg_writer() << tr("bad locked_blocks parameter:") << " " << local_args.back();
|
||||
return false;
|
||||
}
|
||||
if (locked_blocks > 1000000)
|
||||
{
|
||||
fail_msg_writer() << tr("Locked blocks too high, max 1000000 (˜4 yrs)");
|
||||
return false;
|
||||
}
|
||||
local_args.pop_back();
|
||||
}
|
||||
|
||||
// Parse subtractfeefrom destination list
|
||||
tools::wallet2::unique_index_container subtract_fee_from_outputs;
|
||||
bool subtract_fee_from_all = false;
|
||||
@@ -6814,28 +6779,8 @@ bool simple_wallet::transfer_main(int transfer_type, const std::vector<std::stri
|
||||
try
|
||||
{
|
||||
// figure out what tx will be necessary
|
||||
std::vector<tools::wallet2::pending_tx> ptx_vector;
|
||||
uint64_t bc_height, unlock_block = 0;
|
||||
std::string err;
|
||||
switch (transfer_type)
|
||||
{
|
||||
case TransferLocked:
|
||||
bc_height = get_daemon_blockchain_height(err);
|
||||
if (!err.empty())
|
||||
{
|
||||
fail_msg_writer() << tr("failed to get blockchain height: ") << err;
|
||||
return false;
|
||||
}
|
||||
unlock_block = bc_height + locked_blocks;
|
||||
ptx_vector = m_wallet->create_transactions_2(dsts, fake_outs_count, unlock_block /* unlock_time */, priority, extra, m_current_subaddress_account, subaddr_indices, subtract_fee_from_outputs);
|
||||
break;
|
||||
default:
|
||||
LOG_ERROR("Unknown transfer method, using default");
|
||||
/* FALLTHRU */
|
||||
case Transfer:
|
||||
ptx_vector = m_wallet->create_transactions_2(dsts, fake_outs_count, 0 /* unlock_time */, priority, extra, m_current_subaddress_account, subaddr_indices, subtract_fee_from_outputs);
|
||||
break;
|
||||
}
|
||||
auto ptx_vector = m_wallet->create_transactions_2(dsts, fake_outs_count, priority, extra,
|
||||
m_current_subaddress_account, subaddr_indices, subtract_fee_from_outputs);
|
||||
|
||||
if (ptx_vector.empty())
|
||||
{
|
||||
@@ -6945,11 +6890,6 @@ bool simple_wallet::transfer_main(int transfer_type, const std::vector<std::stri
|
||||
if (dust_in_fee != 0) prompt << boost::format(tr(", of which %s is dust from change")) % print_money(dust_in_fee);
|
||||
if (dust_not_in_fee != 0) prompt << tr(".") << ENDL << boost::format(tr("A total of %s from dust change will be sent to dust address"))
|
||||
% print_money(dust_not_in_fee);
|
||||
if (transfer_type == TransferLocked)
|
||||
{
|
||||
float days = locked_blocks / 720.0f;
|
||||
prompt << boost::format(tr(".\nThis transaction (including %s change) will unlock on block %llu, in approximately %s days (assuming 2 minutes per block)")) % cryptonote::print_money(change) % ((unsigned long long)unlock_block) % days;
|
||||
}
|
||||
if (!process_ring_members(ptx_vector, prompt, m_wallet->print_ring_members()))
|
||||
return false;
|
||||
bool default_ring_size = true;
|
||||
@@ -7069,29 +7009,7 @@ bool simple_wallet::transfer(const std::vector<std::string> &args_)
|
||||
PRINT_USAGE(USAGE_TRANSFER);
|
||||
return true;
|
||||
}
|
||||
transfer_main(Transfer, args_, false);
|
||||
return true;
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
bool simple_wallet::locked_transfer(const std::vector<std::string> &args_)
|
||||
{
|
||||
if (args_.size() < 1)
|
||||
{
|
||||
PRINT_USAGE(USAGE_LOCKED_TRANSFER);
|
||||
return true;
|
||||
}
|
||||
transfer_main(TransferLocked, args_, false);
|
||||
return true;
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
bool simple_wallet::locked_sweep_all(const std::vector<std::string> &args_)
|
||||
{
|
||||
if (args_.size() < 1)
|
||||
{
|
||||
PRINT_USAGE(USAGE_LOCKED_SWEEP_ALL);
|
||||
return true;
|
||||
}
|
||||
sweep_main(m_current_subaddress_account, 0, true, args_);
|
||||
transfer_main(args_, false);
|
||||
return true;
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
@@ -7203,7 +7121,7 @@ bool simple_wallet::sweep_unmixable(const std::vector<std::string> &args_)
|
||||
return true;
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
bool simple_wallet::sweep_main(uint32_t account, uint64_t below, bool locked, const std::vector<std::string> &args_)
|
||||
bool simple_wallet::sweep_main(uint32_t account, uint64_t below, const std::vector<std::string> &args_)
|
||||
{
|
||||
auto print_usage = [this, account, below]()
|
||||
{
|
||||
@@ -7283,41 +7201,6 @@ bool simple_wallet::sweep_main(uint32_t account, uint64_t below, bool locked, co
|
||||
return true;
|
||||
}
|
||||
|
||||
uint64_t unlock_block = 0;
|
||||
if (locked) {
|
||||
uint64_t locked_blocks = 0;
|
||||
|
||||
if (local_args.size() < 2) {
|
||||
fail_msg_writer() << tr("missing lockedblocks parameter");
|
||||
return true;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
locked_blocks = boost::lexical_cast<uint64_t>(local_args[1]);
|
||||
}
|
||||
catch (const std::exception &e)
|
||||
{
|
||||
fail_msg_writer() << tr("bad locked_blocks parameter");
|
||||
return true;
|
||||
}
|
||||
if (locked_blocks > 1000000)
|
||||
{
|
||||
fail_msg_writer() << tr("Locked blocks too high, max 1000000 (˜4 yrs)");
|
||||
return true;
|
||||
}
|
||||
std::string err;
|
||||
uint64_t bc_height = get_daemon_blockchain_height(err);
|
||||
if (!err.empty())
|
||||
{
|
||||
fail_msg_writer() << tr("failed to get blockchain height: ") << err;
|
||||
return true;
|
||||
}
|
||||
unlock_block = bc_height + locked_blocks;
|
||||
|
||||
local_args.erase(local_args.begin() + 1);
|
||||
}
|
||||
|
||||
size_t outputs = 1;
|
||||
if (local_args.size() > 0 && local_args[0].substr(0, 8) == "outputs=")
|
||||
{
|
||||
@@ -7392,7 +7275,7 @@ bool simple_wallet::sweep_main(uint32_t account, uint64_t below, bool locked, co
|
||||
try
|
||||
{
|
||||
// figure out what tx will be necessary
|
||||
auto ptx_vector = m_wallet->create_transactions_all(below, info.address, info.is_subaddress, outputs, fake_outs_count, unlock_block /* unlock_time */, priority, extra, account, subaddr_indices);
|
||||
auto ptx_vector = m_wallet->create_transactions_all(below, info.address, info.is_subaddress, outputs, fake_outs_count, priority, extra, account, subaddr_indices);
|
||||
|
||||
if (ptx_vector.empty())
|
||||
{
|
||||
@@ -7649,7 +7532,7 @@ bool simple_wallet::sweep_single(const std::vector<std::string> &args_)
|
||||
try
|
||||
{
|
||||
// figure out what tx will be necessary
|
||||
auto ptx_vector = m_wallet->create_transactions_single(ki, info.address, info.is_subaddress, outputs, fake_outs_count, 0 /* unlock_time */, priority, extra);
|
||||
auto ptx_vector = m_wallet->create_transactions_single(ki, info.address, info.is_subaddress, outputs, fake_outs_count, priority, extra);
|
||||
|
||||
if (ptx_vector.empty())
|
||||
{
|
||||
@@ -7759,7 +7642,7 @@ bool simple_wallet::sweep_single(const std::vector<std::string> &args_)
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
bool simple_wallet::sweep_all(const std::vector<std::string> &args_)
|
||||
{
|
||||
sweep_main(m_current_subaddress_account, 0, false, args_);
|
||||
sweep_main(m_current_subaddress_account, 0, args_);
|
||||
return true;
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
@@ -7779,7 +7662,7 @@ bool simple_wallet::sweep_account(const std::vector<std::string> &args_)
|
||||
}
|
||||
local_args.erase(local_args.begin());
|
||||
|
||||
sweep_main(account, 0, false, local_args);
|
||||
sweep_main(account, 0, local_args);
|
||||
return true;
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
@@ -7797,7 +7680,7 @@ bool simple_wallet::sweep_below(const std::vector<std::string> &args_)
|
||||
fail_msg_writer() << tr("invalid amount threshold");
|
||||
return true;
|
||||
}
|
||||
sweep_main(m_current_subaddress_account, below, false, std::vector<std::string>(++args_.begin(), args_.end()));
|
||||
sweep_main(m_current_subaddress_account, below, std::vector<std::string>(++args_.begin(), args_.end()));
|
||||
return true;
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
@@ -11399,7 +11282,7 @@ void simple_wallet::mms_sync(const std::vector<std::string> &args)
|
||||
void simple_wallet::mms_transfer(const std::vector<std::string> &args)
|
||||
{
|
||||
// It's too complicated to check any arguments here, just let 'transfer_main' do the whole job
|
||||
transfer_main(Transfer, args, true);
|
||||
transfer_main(args, true);
|
||||
}
|
||||
|
||||
void simple_wallet::mms_delete(const std::vector<std::string> &args)
|
||||
|
||||
@@ -170,11 +170,9 @@ namespace cryptonote
|
||||
bool show_incoming_transfers(const std::vector<std::string> &args);
|
||||
bool show_payments(const std::vector<std::string> &args);
|
||||
bool show_blockchain_height(const std::vector<std::string> &args);
|
||||
bool transfer_main(int transfer_type, const std::vector<std::string> &args, bool called_by_mms);
|
||||
bool transfer_main(const std::vector<std::string> &args, bool called_by_mms);
|
||||
bool transfer(const std::vector<std::string> &args);
|
||||
bool locked_transfer(const std::vector<std::string> &args);
|
||||
bool locked_sweep_all(const std::vector<std::string> &args);
|
||||
bool sweep_main(uint32_t account, uint64_t below, bool locked, const std::vector<std::string> &args);
|
||||
bool sweep_main(uint32_t account, uint64_t below, const std::vector<std::string> &args);
|
||||
bool sweep_all(const std::vector<std::string> &args);
|
||||
bool sweep_account(const std::vector<std::string> &args);
|
||||
bool sweep_below(const std::vector<std::string> &args);
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
#define DEF_MONERO_VERSION_TAG "@VERSIONTAG@"
|
||||
#define DEF_MONERO_VERSION "0.18.3.3"
|
||||
#define DEF_MONERO_VERSION "0.18.3.4"
|
||||
#define DEF_MONERO_RELEASE_NAME "Fluorine Fermi"
|
||||
#define DEF_MONERO_VERSION_FULL DEF_MONERO_VERSION "-" DEF_MONERO_VERSION_TAG
|
||||
#define DEF_MONERO_VERSION_IS_RELEASE @VERSION_IS_RELEASE@
|
||||
|
||||
@@ -1588,11 +1588,11 @@ PendingTransaction *WalletImpl::createTransactionMultDest(const std::vector<stri
|
||||
fake_outs_count = m_wallet->adjust_mixin(mixin_count);
|
||||
|
||||
if (amount) {
|
||||
transaction->m_pending_tx = m_wallet->create_transactions_2(dsts, fake_outs_count, 0 /* unlock_time */,
|
||||
transaction->m_pending_tx = m_wallet->create_transactions_2(dsts, fake_outs_count,
|
||||
adjusted_priority,
|
||||
extra, subaddr_account, subaddr_indices);
|
||||
} else {
|
||||
transaction->m_pending_tx = m_wallet->create_transactions_all(0, info.address, info.is_subaddress, 1, fake_outs_count, 0 /* unlock_time */,
|
||||
transaction->m_pending_tx = m_wallet->create_transactions_all(0, info.address, info.is_subaddress, 1, fake_outs_count,
|
||||
adjusted_priority,
|
||||
extra, subaddr_account, subaddr_indices);
|
||||
}
|
||||
|
||||
+36
-38
@@ -3606,6 +3606,7 @@ void wallet2::update_pool_state(std::vector<std::tuple<cryptonote::transaction,
|
||||
|
||||
req.requested_info = COMMAND_RPC_GET_BLOCKS_FAST::POOL_ONLY;
|
||||
req.pool_info_since = m_pool_info_query_time;
|
||||
req.prune = true;
|
||||
|
||||
{
|
||||
const boost::lock_guard<boost::recursive_mutex> lock{m_daemon_rpc_mutex};
|
||||
@@ -6208,7 +6209,7 @@ 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) tools::copy_file(m_wallet_file, m_wallet_file + ".unportable");
|
||||
std::stringstream iss;
|
||||
iss.str("");
|
||||
iss << cache_data;
|
||||
@@ -6230,7 +6231,7 @@ 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) tools::copy_file(m_wallet_file, m_wallet_file + ".unportable");
|
||||
std::stringstream iss;
|
||||
iss.str("");
|
||||
iss << cache_file_buf;
|
||||
@@ -7333,14 +7334,15 @@ bool wallet2::sign_tx(unsigned_tx_set &exported_txs, std::vector<wallet2::pendin
|
||||
{
|
||||
tools::wallet2::tx_construction_data &sd = exported_txs.txes[n];
|
||||
THROW_WALLET_EXCEPTION_IF(sd.sources.empty(), error::wallet_internal_error, "Empty sources");
|
||||
THROW_WALLET_EXCEPTION_IF(sd.unlock_time, error::nonzero_unlock_time);
|
||||
LOG_PRINT_L1(" " << (n+1) << ": " << sd.sources.size() << " inputs, ring size " << sd.sources[0].outputs.size());
|
||||
signed_txes.ptx.push_back(pending_tx());
|
||||
tools::wallet2::pending_tx &ptx = signed_txes.ptx.back();
|
||||
rct::RCTConfig rct_config = sd.rct_config;
|
||||
crypto::secret_key tx_key;
|
||||
std::vector<crypto::secret_key> additional_tx_keys;
|
||||
bool r = cryptonote::construct_tx_and_get_tx_key(m_account.get_keys(), m_subaddresses, sd.sources, sd.splitted_dsts, sd.change_dts.addr, sd.extra, ptx.tx, sd.unlock_time, tx_key, additional_tx_keys, sd.use_rct, rct_config, sd.use_view_tags);
|
||||
THROW_WALLET_EXCEPTION_IF(!r, error::tx_not_constructed, sd.sources, sd.splitted_dsts, sd.unlock_time, m_nettype);
|
||||
bool r = cryptonote::construct_tx_and_get_tx_key(m_account.get_keys(), m_subaddresses, sd.sources, sd.splitted_dsts, sd.change_dts.addr, sd.extra, ptx.tx, tx_key, additional_tx_keys, sd.use_rct, rct_config, sd.use_view_tags);
|
||||
THROW_WALLET_EXCEPTION_IF(!r, error::tx_not_constructed, sd.sources, sd.splitted_dsts, m_nettype);
|
||||
// we don't test tx size, because we don't know the current limit, due to not having a blockchain,
|
||||
// and it's a bit pointless to fail there anyway, since it'd be a (good) guess only. We sign anyway,
|
||||
// and if we really go over limit, the daemon will reject when it gets submitted. Chances are it's
|
||||
@@ -7870,7 +7872,6 @@ bool wallet2::sign_multisig_tx(multisig_tx_set &exported_txs, std::vector<crypto
|
||||
not multisig_tx_builder.init(
|
||||
m_account.get_keys(),
|
||||
ptx.construction_data.extra,
|
||||
ptx.construction_data.unlock_time,
|
||||
ptx.construction_data.subaddr_account,
|
||||
ptx.construction_data.subaddr_indices,
|
||||
ptx.construction_data.sources,
|
||||
@@ -8006,7 +8007,7 @@ bool wallet2::sign_multisig_tx_from_file(const std::string &filename, std::vecto
|
||||
return sign_multisig_tx_to_file(exported_txs, filename, txids);
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
uint64_t wallet2::estimate_fee(bool use_per_byte_fee, bool use_rct, int n_inputs, int mixin, int n_outputs, size_t extra_size, bool bulletproof, bool clsag, bool bulletproof_plus, bool use_view_tags, uint64_t base_fee, uint64_t fee_quantization_mask) const
|
||||
uint64_t wallet2::estimate_fee(bool use_per_byte_fee, bool use_rct, int n_inputs, int mixin, int n_outputs, size_t extra_size, bool bulletproof, bool clsag, bool bulletproof_plus, bool use_view_tags, uint64_t base_fee, uint64_t fee_quantization_mask)
|
||||
{
|
||||
if (use_per_byte_fee)
|
||||
{
|
||||
@@ -9422,7 +9423,7 @@ void wallet2::get_outs(std::vector<std::vector<tools::wallet2::get_outs_entry>>
|
||||
template<typename T>
|
||||
void wallet2::transfer_selected(const std::vector<cryptonote::tx_destination_entry>& dsts, const std::vector<size_t>& selected_transfers, size_t fake_outputs_count,
|
||||
std::vector<std::vector<tools::wallet2::get_outs_entry>> &outs, std::unordered_set<crypto::public_key> &valid_public_keys_cache,
|
||||
uint64_t unlock_time, uint64_t fee, const std::vector<uint8_t>& extra, T destination_split_strategy, const tx_dust_policy& dust_policy, cryptonote::transaction& tx, pending_tx &ptx,
|
||||
uint64_t fee, const std::vector<uint8_t>& extra, T destination_split_strategy, const tx_dust_policy& dust_policy, cryptonote::transaction& tx, pending_tx &ptx,
|
||||
bool use_view_tags)
|
||||
{
|
||||
using namespace cryptonote;
|
||||
@@ -9533,9 +9534,9 @@ void wallet2::transfer_selected(const std::vector<cryptonote::tx_destination_ent
|
||||
crypto::secret_key tx_key;
|
||||
std::vector<crypto::secret_key> additional_tx_keys;
|
||||
LOG_PRINT_L2("constructing tx");
|
||||
bool r = cryptonote::construct_tx_and_get_tx_key(m_account.get_keys(), m_subaddresses, sources, splitted_dsts, change_dts.addr, extra, tx, unlock_time, tx_key, additional_tx_keys, false, {}, use_view_tags);
|
||||
bool r = cryptonote::construct_tx_and_get_tx_key(m_account.get_keys(), m_subaddresses, sources, splitted_dsts, change_dts.addr, extra, tx, tx_key, additional_tx_keys, false, {}, use_view_tags);
|
||||
LOG_PRINT_L2("constructed tx, r="<<r);
|
||||
THROW_WALLET_EXCEPTION_IF(!r, error::tx_not_constructed, sources, splitted_dsts, unlock_time, m_nettype);
|
||||
THROW_WALLET_EXCEPTION_IF(!r, error::tx_not_constructed, sources, splitted_dsts, m_nettype);
|
||||
THROW_WALLET_EXCEPTION_IF(upper_transaction_weight_limit <= get_transaction_weight(tx), error::tx_too_big, tx, upper_transaction_weight_limit);
|
||||
|
||||
std::string key_images;
|
||||
@@ -9568,7 +9569,7 @@ void wallet2::transfer_selected(const std::vector<cryptonote::tx_destination_ent
|
||||
ptx.construction_data.splitted_dsts = splitted_dsts;
|
||||
ptx.construction_data.selected_transfers = selected_transfers;
|
||||
ptx.construction_data.extra = tx.extra;
|
||||
ptx.construction_data.unlock_time = unlock_time;
|
||||
ptx.construction_data.unlock_time = 0;
|
||||
ptx.construction_data.use_rct = false;
|
||||
ptx.construction_data.rct_config = { rct::RangeProofBorromean, 0 };
|
||||
ptx.construction_data.use_view_tags = use_view_tags;
|
||||
@@ -9583,7 +9584,7 @@ void wallet2::transfer_selected(const std::vector<cryptonote::tx_destination_ent
|
||||
|
||||
void wallet2::transfer_selected_rct(std::vector<cryptonote::tx_destination_entry> dsts, const std::vector<size_t>& selected_transfers, size_t fake_outputs_count,
|
||||
std::vector<std::vector<tools::wallet2::get_outs_entry>> &outs, std::unordered_set<crypto::public_key> &valid_public_keys_cache,
|
||||
uint64_t unlock_time, uint64_t fee, const std::vector<uint8_t>& extra, cryptonote::transaction& tx, pending_tx &ptx, const rct::RCTConfig &rct_config, bool use_view_tags)
|
||||
uint64_t fee, const std::vector<uint8_t>& extra, cryptonote::transaction& tx, pending_tx &ptx, const rct::RCTConfig &rct_config, bool use_view_tags)
|
||||
{
|
||||
using namespace cryptonote;
|
||||
// throw if attempting a transaction with no destinations
|
||||
@@ -9779,7 +9780,6 @@ void wallet2::transfer_selected_rct(std::vector<cryptonote::tx_destination_entry
|
||||
THROW_WALLET_EXCEPTION_IF(
|
||||
not multisig_tx_builder.init(m_account.get_keys(),
|
||||
extra,
|
||||
unlock_time,
|
||||
subaddr_account,
|
||||
subaddr_minor_indices,
|
||||
sources,
|
||||
@@ -9799,9 +9799,9 @@ void wallet2::transfer_selected_rct(std::vector<cryptonote::tx_destination_entry
|
||||
}
|
||||
else {
|
||||
// make a normal tx
|
||||
bool r = cryptonote::construct_tx_and_get_tx_key(m_account.get_keys(), m_subaddresses, sources, splitted_dsts, change_dts.addr, extra, tx, unlock_time, tx_key, additional_tx_keys, true, rct_config, use_view_tags);
|
||||
bool r = cryptonote::construct_tx_and_get_tx_key(m_account.get_keys(), m_subaddresses, sources, splitted_dsts, change_dts.addr, extra, tx, tx_key, additional_tx_keys, true, rct_config, use_view_tags);
|
||||
LOG_PRINT_L2("constructed tx, r="<<r);
|
||||
THROW_WALLET_EXCEPTION_IF(!r, error::tx_not_constructed, sources, dsts, unlock_time, m_nettype);
|
||||
THROW_WALLET_EXCEPTION_IF(!r, error::tx_not_constructed, sources, dsts, m_nettype);
|
||||
}
|
||||
THROW_WALLET_EXCEPTION_IF(upper_transaction_weight_limit <= get_transaction_weight(tx), error::tx_too_big, tx, upper_transaction_weight_limit);
|
||||
|
||||
@@ -9923,7 +9923,7 @@ void wallet2::transfer_selected_rct(std::vector<cryptonote::tx_destination_entry
|
||||
ptx.construction_data.splitted_dsts = splitted_dsts;
|
||||
ptx.construction_data.selected_transfers = ptx.selected_transfers;
|
||||
ptx.construction_data.extra = tx.extra;
|
||||
ptx.construction_data.unlock_time = unlock_time;
|
||||
ptx.construction_data.unlock_time = 0;
|
||||
ptx.construction_data.use_rct = true;
|
||||
ptx.construction_data.rct_config = {
|
||||
rct::RangeProofPaddedBulletproof,
|
||||
@@ -10553,7 +10553,7 @@ bool wallet2::light_wallet_key_image_is_ours(const crypto::key_image& key_image,
|
||||
// This system allows for sending (almost) the entire balance, since it does
|
||||
// not generate spurious change in all txes, thus decreasing the instantaneous
|
||||
// usable balance.
|
||||
std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryptonote::tx_destination_entry> dsts, const size_t fake_outs_count, const uint64_t unlock_time, uint32_t priority, const std::vector<uint8_t>& extra, uint32_t subaddr_account, std::set<uint32_t> subaddr_indices, const unique_index_container& subtract_fee_from_outputs)
|
||||
std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryptonote::tx_destination_entry> dsts, const size_t fake_outs_count, uint32_t priority, const std::vector<uint8_t>& extra, uint32_t subaddr_account, std::set<uint32_t> subaddr_indices, const unique_index_container& subtract_fee_from_outputs)
|
||||
{
|
||||
//ensure device is let in NONE mode in any case
|
||||
hw::device &hwdev = m_account.get_device();
|
||||
@@ -11080,10 +11080,10 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryp
|
||||
tx.selected_transfers.size() << " inputs");
|
||||
auto tx_dsts = tx.get_adjusted_dsts(needed_fee);
|
||||
if (use_rct)
|
||||
transfer_selected_rct(tx_dsts, tx.selected_transfers, fake_outs_count, outs, valid_public_keys_cache, unlock_time, needed_fee, extra,
|
||||
transfer_selected_rct(tx_dsts, tx.selected_transfers, fake_outs_count, outs, valid_public_keys_cache, needed_fee, extra,
|
||||
test_tx, test_ptx, rct_config, use_view_tags);
|
||||
else
|
||||
transfer_selected(tx_dsts, tx.selected_transfers, fake_outs_count, outs, valid_public_keys_cache, unlock_time, needed_fee, extra,
|
||||
transfer_selected(tx_dsts, tx.selected_transfers, fake_outs_count, outs, valid_public_keys_cache, needed_fee, extra,
|
||||
detail::digit_split_strategy, tx_dust_policy(::config::DEFAULT_DUST_THRESHOLD), test_tx, test_ptx, use_view_tags);
|
||||
auto txBlob = t_serializable_object_to_blob(test_ptx.tx);
|
||||
needed_fee = calculate_fee(use_per_byte_fee, test_ptx.tx, txBlob.size(), base_fee, fee_quantization_mask);
|
||||
@@ -11119,21 +11119,21 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryp
|
||||
else
|
||||
{
|
||||
LOG_PRINT_L2("We made a tx, adjusting fee and saving it, we need " << print_money(needed_fee) << " and we have " << print_money(test_ptx.fee));
|
||||
size_t fee_tries;
|
||||
for (fee_tries = 0; fee_tries < 10 && needed_fee > test_ptx.fee; ++fee_tries) {
|
||||
size_t fee_tries = 0;
|
||||
do {
|
||||
tx_dsts = tx.get_adjusted_dsts(needed_fee);
|
||||
|
||||
if (use_rct)
|
||||
transfer_selected_rct(tx_dsts, tx.selected_transfers, fake_outs_count, outs, valid_public_keys_cache, unlock_time, needed_fee, extra,
|
||||
transfer_selected_rct(tx_dsts, tx.selected_transfers, fake_outs_count, outs, valid_public_keys_cache, needed_fee, extra,
|
||||
test_tx, test_ptx, rct_config, use_view_tags);
|
||||
else
|
||||
transfer_selected(tx_dsts, tx.selected_transfers, fake_outs_count, outs, valid_public_keys_cache, unlock_time, needed_fee, extra,
|
||||
transfer_selected(tx_dsts, tx.selected_transfers, fake_outs_count, outs, valid_public_keys_cache, needed_fee, extra,
|
||||
detail::digit_split_strategy, tx_dust_policy(::config::DEFAULT_DUST_THRESHOLD), test_tx, test_ptx, use_view_tags);
|
||||
txBlob = t_serializable_object_to_blob(test_ptx.tx);
|
||||
needed_fee = calculate_fee(use_per_byte_fee, test_ptx.tx, txBlob.size(), base_fee, fee_quantization_mask);
|
||||
LOG_PRINT_L2("Made an attempt at a final " << get_weight_string(test_ptx.tx, txBlob.size()) << " tx, with " << print_money(test_ptx.fee) <<
|
||||
" fee and " << print_money(test_ptx.change_dts.amount) << " change");
|
||||
};
|
||||
} while (needed_fee > test_ptx.fee && ++fee_tries < 10);
|
||||
|
||||
THROW_WALLET_EXCEPTION_IF(fee_tries == 10, error::wallet_internal_error,
|
||||
"Too many attempts to raise pending tx fee to level of needed fee");
|
||||
@@ -11200,7 +11200,6 @@ skip_tx:
|
||||
fake_outs_count, /* CONST size_t fake_outputs_count, */
|
||||
tx.outs, /* MOD std::vector<std::vector<tools::wallet2::get_outs_entry>> &outs, */
|
||||
valid_public_keys_cache,
|
||||
unlock_time, /* CONST uint64_t unlock_time, */
|
||||
tx.needed_fee, /* CONST uint64_t fee, */
|
||||
extra, /* const std::vector<uint8_t>& extra, */
|
||||
test_tx, /* OUT cryptonote::transaction& tx, */
|
||||
@@ -11213,7 +11212,6 @@ skip_tx:
|
||||
fake_outs_count,
|
||||
tx.outs,
|
||||
valid_public_keys_cache,
|
||||
unlock_time,
|
||||
tx.needed_fee,
|
||||
extra,
|
||||
detail::digit_split_strategy,
|
||||
@@ -11327,7 +11325,7 @@ bool wallet2::sanity_check(const std::vector<wallet2::pending_tx> &ptx_vector, c
|
||||
return true;
|
||||
}
|
||||
|
||||
std::vector<wallet2::pending_tx> wallet2::create_transactions_all(uint64_t below, const cryptonote::account_public_address &address, bool is_subaddress, const size_t outputs, const size_t fake_outs_count, const uint64_t unlock_time, uint32_t priority, const std::vector<uint8_t>& extra, uint32_t subaddr_account, std::set<uint32_t> subaddr_indices)
|
||||
std::vector<wallet2::pending_tx> wallet2::create_transactions_all(uint64_t below, const cryptonote::account_public_address &address, bool is_subaddress, const size_t outputs, const size_t fake_outs_count, uint32_t priority, const std::vector<uint8_t>& extra, uint32_t subaddr_account, std::set<uint32_t> subaddr_indices)
|
||||
{
|
||||
std::vector<size_t> unused_transfers_indices;
|
||||
std::vector<size_t> unused_dust_indices;
|
||||
@@ -11397,10 +11395,10 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_all(uint64_t below
|
||||
}
|
||||
}
|
||||
|
||||
return create_transactions_from(address, is_subaddress, outputs, unused_transfers_indices, unused_dust_indices, fake_outs_count, unlock_time, priority, extra);
|
||||
return create_transactions_from(address, is_subaddress, outputs, unused_transfers_indices, unused_dust_indices, fake_outs_count, priority, extra);
|
||||
}
|
||||
|
||||
std::vector<wallet2::pending_tx> wallet2::create_transactions_single(const crypto::key_image &ki, const cryptonote::account_public_address &address, bool is_subaddress, const size_t outputs, const size_t fake_outs_count, const uint64_t unlock_time, uint32_t priority, const std::vector<uint8_t>& extra)
|
||||
std::vector<wallet2::pending_tx> wallet2::create_transactions_single(const crypto::key_image &ki, const cryptonote::account_public_address &address, bool is_subaddress, const size_t outputs, const size_t fake_outs_count, uint32_t priority, const std::vector<uint8_t>& extra)
|
||||
{
|
||||
std::vector<size_t> unused_transfers_indices;
|
||||
std::vector<size_t> unused_dust_indices;
|
||||
@@ -11418,10 +11416,10 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_single(const crypt
|
||||
break;
|
||||
}
|
||||
}
|
||||
return create_transactions_from(address, is_subaddress, outputs, unused_transfers_indices, unused_dust_indices, fake_outs_count, unlock_time, priority, extra);
|
||||
return create_transactions_from(address, is_subaddress, outputs, unused_transfers_indices, unused_dust_indices, fake_outs_count, priority, extra);
|
||||
}
|
||||
|
||||
std::vector<wallet2::pending_tx> wallet2::create_transactions_from(const cryptonote::account_public_address &address, bool is_subaddress, const size_t outputs, std::vector<size_t> unused_transfers_indices, std::vector<size_t> unused_dust_indices, const size_t fake_outs_count, const uint64_t unlock_time, uint32_t priority, const std::vector<uint8_t>& extra)
|
||||
std::vector<wallet2::pending_tx> wallet2::create_transactions_from(const cryptonote::account_public_address &address, bool is_subaddress, const size_t outputs, std::vector<size_t> unused_transfers_indices, std::vector<size_t> unused_dust_indices, const size_t fake_outs_count, uint32_t priority, const std::vector<uint8_t>& extra)
|
||||
{
|
||||
//ensure device is let in NONE mode in any case
|
||||
hw::device &hwdev = m_account.get_device();
|
||||
@@ -11530,10 +11528,10 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_from(const crypton
|
||||
LOG_PRINT_L2("Trying to create a tx now, with " << tx.dsts.size() << " destinations and " <<
|
||||
tx.selected_transfers.size() << " outputs");
|
||||
if (use_rct)
|
||||
transfer_selected_rct(tx.dsts, tx.selected_transfers, fake_outs_count, outs, valid_public_keys_cache, unlock_time, needed_fee, extra,
|
||||
transfer_selected_rct(tx.dsts, tx.selected_transfers, fake_outs_count, outs, valid_public_keys_cache, needed_fee, extra,
|
||||
test_tx, test_ptx, rct_config, use_view_tags);
|
||||
else
|
||||
transfer_selected(tx.dsts, tx.selected_transfers, fake_outs_count, outs, valid_public_keys_cache, unlock_time, needed_fee, extra,
|
||||
transfer_selected(tx.dsts, tx.selected_transfers, fake_outs_count, outs, valid_public_keys_cache, needed_fee, extra,
|
||||
detail::digit_split_strategy, tx_dust_policy(::config::DEFAULT_DUST_THRESHOLD), test_tx, test_ptx, use_view_tags);
|
||||
auto txBlob = t_serializable_object_to_blob(test_ptx.tx);
|
||||
needed_fee = calculate_fee(use_per_byte_fee, test_ptx.tx, txBlob.size(), base_fee, fee_quantization_mask);
|
||||
@@ -11567,10 +11565,10 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_from(const crypton
|
||||
dt.amount = dt_amount + dt_residue;
|
||||
}
|
||||
if (use_rct)
|
||||
transfer_selected_rct(tx.dsts, tx.selected_transfers, fake_outs_count, outs, valid_public_keys_cache, unlock_time, needed_fee, extra,
|
||||
transfer_selected_rct(tx.dsts, tx.selected_transfers, fake_outs_count, outs, valid_public_keys_cache, needed_fee, extra,
|
||||
test_tx, test_ptx, rct_config, use_view_tags);
|
||||
else
|
||||
transfer_selected(tx.dsts, tx.selected_transfers, fake_outs_count, outs, valid_public_keys_cache, unlock_time, needed_fee, extra,
|
||||
transfer_selected(tx.dsts, tx.selected_transfers, fake_outs_count, outs, valid_public_keys_cache, needed_fee, extra,
|
||||
detail::digit_split_strategy, tx_dust_policy(::config::DEFAULT_DUST_THRESHOLD), test_tx, test_ptx, use_view_tags);
|
||||
txBlob = t_serializable_object_to_blob(test_ptx.tx);
|
||||
needed_fee = calculate_fee(use_per_byte_fee, test_ptx.tx, txBlob.size(), base_fee, fee_quantization_mask);
|
||||
@@ -11606,10 +11604,10 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_from(const crypton
|
||||
cryptonote::transaction test_tx;
|
||||
pending_tx test_ptx;
|
||||
if (use_rct) {
|
||||
transfer_selected_rct(tx.dsts, tx.selected_transfers, fake_outs_count, tx.outs, valid_public_keys_cache, unlock_time, tx.needed_fee, extra,
|
||||
transfer_selected_rct(tx.dsts, tx.selected_transfers, fake_outs_count, tx.outs, valid_public_keys_cache, tx.needed_fee, extra,
|
||||
test_tx, test_ptx, rct_config, use_view_tags);
|
||||
} else {
|
||||
transfer_selected(tx.dsts, tx.selected_transfers, fake_outs_count, tx.outs, valid_public_keys_cache, unlock_time, tx.needed_fee, extra,
|
||||
transfer_selected(tx.dsts, tx.selected_transfers, fake_outs_count, tx.outs, valid_public_keys_cache, tx.needed_fee, extra,
|
||||
detail::digit_split_strategy, tx_dust_policy(::config::DEFAULT_DUST_THRESHOLD), test_tx, test_ptx, use_view_tags);
|
||||
}
|
||||
auto txBlob = t_serializable_object_to_blob(test_ptx.tx);
|
||||
@@ -11921,7 +11919,7 @@ std::vector<wallet2::pending_tx> wallet2::create_unmixable_sweep_transactions()
|
||||
unmixable_transfer_outputs.push_back(n);
|
||||
}
|
||||
|
||||
return create_transactions_from(m_account_public_address, false, 1, unmixable_transfer_outputs, unmixable_dust_outputs, 0 /*fake_outs_count */, 0 /* unlock_time */, 1 /*priority */, std::vector<uint8_t>());
|
||||
return create_transactions_from(m_account_public_address, false, 1, unmixable_transfer_outputs, unmixable_dust_outputs, 0 /*fake_outs_count */, 1 /*priority */, std::vector<uint8_t>());
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
void wallet2::discard_unmixable_outputs()
|
||||
@@ -13146,7 +13144,7 @@ uint64_t wallet2::get_approximate_blockchain_height() const
|
||||
// Calculated blockchain height
|
||||
uint64_t approx_blockchain_height = fork_block + (time(NULL) - fork_time)/seconds_per_block;
|
||||
// testnet and stagenet got some huge rollbacks, so the estimation is way off
|
||||
static const uint64_t approximate_rolled_back_blocks = m_nettype == TESTNET ? 342100 : 30000;
|
||||
static const uint64_t approximate_rolled_back_blocks = m_nettype == TESTNET ? 342100 : m_nettype == STAGENET ? 60000 : 30000;
|
||||
if ((m_nettype == TESTNET || m_nettype == STAGENET) && approx_blockchain_height > approximate_rolled_back_blocks)
|
||||
approx_blockchain_height -= approximate_rolled_back_blocks;
|
||||
LOG_PRINT_L2("Calculated blockchain height: " << approx_blockchain_height);
|
||||
|
||||
@@ -1088,10 +1088,10 @@ private:
|
||||
template<typename T>
|
||||
void transfer_selected(const std::vector<cryptonote::tx_destination_entry>& dsts, const std::vector<size_t>& selected_transfers, size_t fake_outputs_count,
|
||||
std::vector<std::vector<tools::wallet2::get_outs_entry>> &outs, std::unordered_set<crypto::public_key> &valid_public_keys_cache,
|
||||
uint64_t unlock_time, uint64_t fee, const std::vector<uint8_t>& extra, T destination_split_strategy, const tx_dust_policy& dust_policy, cryptonote::transaction& tx, pending_tx &ptx, const bool use_view_tags);
|
||||
uint64_t fee, const std::vector<uint8_t>& extra, T destination_split_strategy, const tx_dust_policy& dust_policy, cryptonote::transaction& tx, pending_tx &ptx, const bool use_view_tags);
|
||||
void transfer_selected_rct(std::vector<cryptonote::tx_destination_entry> dsts, const std::vector<size_t>& selected_transfers, size_t fake_outputs_count,
|
||||
std::vector<std::vector<tools::wallet2::get_outs_entry>> &outs, std::unordered_set<crypto::public_key> &valid_public_keys_cache,
|
||||
uint64_t unlock_time, uint64_t fee, const std::vector<uint8_t>& extra, cryptonote::transaction& tx, pending_tx &ptx, const rct::RCTConfig &rct_config, const bool use_view_tags);
|
||||
uint64_t fee, const std::vector<uint8_t>& extra, cryptonote::transaction& tx, pending_tx &ptx, const rct::RCTConfig &rct_config, const bool use_view_tags);
|
||||
|
||||
void commit_tx(pending_tx& ptx_vector);
|
||||
void commit_tx(std::vector<pending_tx>& ptx_vector);
|
||||
@@ -1113,10 +1113,10 @@ private:
|
||||
bool parse_unsigned_tx_from_str(const std::string &unsigned_tx_st, unsigned_tx_set &exported_txs) const;
|
||||
bool load_tx(const std::string &signed_filename, std::vector<tools::wallet2::pending_tx> &ptx, std::function<bool(const signed_tx_set&)> accept_func = NULL);
|
||||
bool parse_tx_from_str(const std::string &signed_tx_st, std::vector<tools::wallet2::pending_tx> &ptx, std::function<bool(const signed_tx_set &)> accept_func);
|
||||
std::vector<wallet2::pending_tx> create_transactions_2(std::vector<cryptonote::tx_destination_entry> dsts, const size_t fake_outs_count, const uint64_t unlock_time, uint32_t priority, const std::vector<uint8_t>& extra, uint32_t subaddr_account, std::set<uint32_t> subaddr_indices, const unique_index_container& subtract_fee_from_outputs = {}); // pass subaddr_indices by value on purpose
|
||||
std::vector<wallet2::pending_tx> create_transactions_all(uint64_t below, const cryptonote::account_public_address &address, bool is_subaddress, const size_t outputs, const size_t fake_outs_count, const uint64_t unlock_time, uint32_t priority, const std::vector<uint8_t>& extra, uint32_t subaddr_account, std::set<uint32_t> subaddr_indices);
|
||||
std::vector<wallet2::pending_tx> create_transactions_single(const crypto::key_image &ki, const cryptonote::account_public_address &address, bool is_subaddress, const size_t outputs, const size_t fake_outs_count, const uint64_t unlock_time, uint32_t priority, const std::vector<uint8_t>& extra);
|
||||
std::vector<wallet2::pending_tx> create_transactions_from(const cryptonote::account_public_address &address, bool is_subaddress, const size_t outputs, std::vector<size_t> unused_transfers_indices, std::vector<size_t> unused_dust_indices, const size_t fake_outs_count, const uint64_t unlock_time, uint32_t priority, const std::vector<uint8_t>& extra);
|
||||
std::vector<wallet2::pending_tx> create_transactions_2(std::vector<cryptonote::tx_destination_entry> dsts, const size_t fake_outs_count, uint32_t priority, const std::vector<uint8_t>& extra, uint32_t subaddr_account, std::set<uint32_t> subaddr_indices, const unique_index_container& subtract_fee_from_outputs = {}); // pass subaddr_indices by value on purpose
|
||||
std::vector<wallet2::pending_tx> create_transactions_all(uint64_t below, const cryptonote::account_public_address &address, bool is_subaddress, const size_t outputs, const size_t fake_outs_count, uint32_t priority, const std::vector<uint8_t>& extra, uint32_t subaddr_account, std::set<uint32_t> subaddr_indices);
|
||||
std::vector<wallet2::pending_tx> create_transactions_single(const crypto::key_image &ki, const cryptonote::account_public_address &address, bool is_subaddress, const size_t outputs, const size_t fake_outs_count, uint32_t priority, const std::vector<uint8_t>& extra);
|
||||
std::vector<wallet2::pending_tx> create_transactions_from(const cryptonote::account_public_address &address, bool is_subaddress, const size_t outputs, std::vector<size_t> unused_transfers_indices, std::vector<size_t> unused_dust_indices, const size_t fake_outs_count, uint32_t priority, const std::vector<uint8_t>& extra);
|
||||
bool sanity_check(const std::vector<wallet2::pending_tx> &ptx_vector, const std::vector<cryptonote::tx_destination_entry>& dsts, const unique_index_container& subtract_fee_from_outputs = {}) const;
|
||||
void cold_tx_aux_import(const std::vector<pending_tx>& ptx, const std::vector<std::string>& tx_device_aux);
|
||||
void cold_sign_tx(const std::vector<pending_tx>& ptx_vector, signed_tx_set &exported_txs, std::vector<cryptonote::address_parse_info> &dsts_info, std::vector<std::string> & tx_device_aux);
|
||||
@@ -1565,7 +1565,7 @@ private:
|
||||
std::vector<std::pair<uint64_t, uint64_t>> estimate_backlog(const std::vector<std::pair<double, double>> &fee_levels);
|
||||
std::vector<std::pair<uint64_t, uint64_t>> estimate_backlog(uint64_t min_tx_weight, uint64_t max_tx_weight, const std::vector<uint64_t> &fees);
|
||||
|
||||
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, bool clsag, bool bulletproof_plus, bool use_view_tags, uint64_t base_fee, uint64_t fee_quantization_mask) const;
|
||||
static 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, bool clsag, bool bulletproof_plus, bool use_view_tags, uint64_t base_fee, uint64_t fee_quantization_mask);
|
||||
uint64_t get_fee_multiplier(uint32_t priority, int fee_algorithm = -1);
|
||||
uint64_t get_base_fee(uint32_t priority);
|
||||
uint64_t get_base_fee();
|
||||
|
||||
@@ -86,6 +86,7 @@ namespace tools
|
||||
// zero_amount
|
||||
// zero_destination
|
||||
// subtract_fee_from_bad_index
|
||||
// nonzero_unlock_time
|
||||
// wallet_rpc_error *
|
||||
// daemon_busy
|
||||
// no_connection_to_daemon
|
||||
@@ -592,20 +593,17 @@ namespace tools
|
||||
std::string && loc
|
||||
, sources_t const & sources
|
||||
, destinations_t const & destinations
|
||||
, uint64_t unlock_time
|
||||
, cryptonote::network_type nettype
|
||||
)
|
||||
: transfer_error(std::move(loc), "transaction was not constructed")
|
||||
, m_sources(sources)
|
||||
, m_destinations(destinations)
|
||||
, m_unlock_time(unlock_time)
|
||||
, m_nettype(nettype)
|
||||
{
|
||||
}
|
||||
|
||||
const sources_t& sources() const { return m_sources; }
|
||||
const destinations_t& destinations() const { return m_destinations; }
|
||||
uint64_t unlock_time() const { return m_unlock_time; }
|
||||
|
||||
std::string to_string() const
|
||||
{
|
||||
@@ -637,15 +635,12 @@ namespace tools
|
||||
cryptonote::print_money(dst.amount);
|
||||
}
|
||||
|
||||
ss << "\nunlock_time: " << m_unlock_time;
|
||||
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
private:
|
||||
sources_t m_sources;
|
||||
destinations_t m_destinations;
|
||||
uint64_t m_unlock_time;
|
||||
cryptonote::network_type m_nettype;
|
||||
};
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
@@ -789,6 +784,14 @@ namespace tools
|
||||
}
|
||||
};
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
struct nonzero_unlock_time : public transfer_error
|
||||
{
|
||||
explicit nonzero_unlock_time(std::string&& loc)
|
||||
: transfer_error(std::move(loc), "transaction cannot have non-zero unlock time")
|
||||
{
|
||||
}
|
||||
};
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
struct wallet_rpc_error : public wallet_logic_error
|
||||
{
|
||||
const std::string& request() const { return m_request; }
|
||||
|
||||
@@ -245,7 +245,7 @@ namespace tools
|
||||
);
|
||||
|
||||
std::string temp = "monero-wallet-rpc." + bind_port + ".login";
|
||||
rpc_login_file = tools::private_file::create(temp);
|
||||
rpc_login_file = tools::private_file::drop_and_recreate(temp);
|
||||
if (!rpc_login_file.handle())
|
||||
{
|
||||
LOG_ERROR(tr("Failed to create file ") << temp << tr(". Check permissions or remove file"));
|
||||
@@ -1080,6 +1080,12 @@ namespace tools
|
||||
er.message = "Command unavailable in restricted mode.";
|
||||
return false;
|
||||
}
|
||||
else if (req.unlock_time)
|
||||
{
|
||||
er.code = WALLET_RPC_ERROR_CODE_NONZERO_UNLOCK_TIME;
|
||||
er.message = "Transaction cannot have non-zero unlock time";
|
||||
return false;
|
||||
}
|
||||
|
||||
CHECK_MULTISIG_ENABLED();
|
||||
|
||||
@@ -1093,7 +1099,7 @@ namespace tools
|
||||
{
|
||||
uint64_t mixin = m_wallet->adjust_mixin(req.ring_size ? req.ring_size - 1 : 0);
|
||||
uint32_t priority = m_wallet->adjust_priority(req.priority);
|
||||
std::vector<wallet2::pending_tx> ptx_vector = m_wallet->create_transactions_2(dsts, mixin, req.unlock_time, priority, extra, req.account_index, req.subaddr_indices, req.subtract_fee_from_outputs);
|
||||
std::vector<wallet2::pending_tx> ptx_vector = m_wallet->create_transactions_2(dsts, mixin, priority, extra, req.account_index, req.subaddr_indices, req.subtract_fee_from_outputs);
|
||||
|
||||
if (ptx_vector.empty())
|
||||
{
|
||||
@@ -1134,6 +1140,12 @@ namespace tools
|
||||
er.message = "Command unavailable in restricted mode.";
|
||||
return false;
|
||||
}
|
||||
else if (req.unlock_time)
|
||||
{
|
||||
er.code = WALLET_RPC_ERROR_CODE_NONZERO_UNLOCK_TIME;
|
||||
er.message = "Transaction cannot have non-zero unlock time";
|
||||
return false;
|
||||
}
|
||||
|
||||
CHECK_MULTISIG_ENABLED();
|
||||
|
||||
@@ -1148,7 +1160,7 @@ namespace tools
|
||||
uint64_t mixin = m_wallet->adjust_mixin(req.ring_size ? req.ring_size - 1 : 0);
|
||||
uint32_t priority = m_wallet->adjust_priority(req.priority);
|
||||
LOG_PRINT_L2("on_transfer_split calling create_transactions_2");
|
||||
std::vector<wallet2::pending_tx> ptx_vector = m_wallet->create_transactions_2(dsts, mixin, req.unlock_time, priority, extra, req.account_index, req.subaddr_indices);
|
||||
std::vector<wallet2::pending_tx> ptx_vector = m_wallet->create_transactions_2(dsts, mixin, priority, extra, req.account_index, req.subaddr_indices);
|
||||
LOG_PRINT_L2("on_transfer_split called create_transactions_2");
|
||||
|
||||
if (ptx_vector.empty())
|
||||
@@ -1570,6 +1582,12 @@ namespace tools
|
||||
er.message = "Command unavailable in restricted mode.";
|
||||
return false;
|
||||
}
|
||||
else if (req.unlock_time)
|
||||
{
|
||||
er.code = WALLET_RPC_ERROR_CODE_NONZERO_UNLOCK_TIME;
|
||||
er.message = "Transaction cannot have non-zero unlock time";
|
||||
return false;
|
||||
}
|
||||
|
||||
CHECK_MULTISIG_ENABLED();
|
||||
|
||||
@@ -1605,7 +1623,7 @@ namespace tools
|
||||
{
|
||||
uint64_t mixin = m_wallet->adjust_mixin(req.ring_size ? req.ring_size - 1 : 0);
|
||||
uint32_t priority = m_wallet->adjust_priority(req.priority);
|
||||
std::vector<wallet2::pending_tx> ptx_vector = m_wallet->create_transactions_all(req.below_amount, dsts[0].addr, dsts[0].is_subaddress, req.outputs, mixin, req.unlock_time, priority, extra, req.account_index, subaddr_indices);
|
||||
std::vector<wallet2::pending_tx> ptx_vector = m_wallet->create_transactions_all(req.below_amount, dsts[0].addr, dsts[0].is_subaddress, req.outputs, mixin, priority, extra, req.account_index, subaddr_indices);
|
||||
|
||||
return fill_response(ptx_vector, req.get_tx_keys, res.tx_key_list, res.amount_list, res.amounts_by_dest_list, res.fee_list, res.weight_list, res.multisig_txset, res.unsigned_txset, req.do_not_relay,
|
||||
res.tx_hash_list, req.get_tx_hex, res.tx_blob_list, req.get_tx_metadata, res.tx_metadata_list, res.spent_key_images_list, er);
|
||||
@@ -1630,6 +1648,12 @@ namespace tools
|
||||
er.message = "Command unavailable in restricted mode.";
|
||||
return false;
|
||||
}
|
||||
else if (req.unlock_time)
|
||||
{
|
||||
er.code = WALLET_RPC_ERROR_CODE_NONZERO_UNLOCK_TIME;
|
||||
er.message = "Transaction cannot have non-zero unlock time";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (req.outputs < 1)
|
||||
{
|
||||
@@ -1662,7 +1686,7 @@ namespace tools
|
||||
{
|
||||
uint64_t mixin = m_wallet->adjust_mixin(req.ring_size ? req.ring_size - 1 : 0);
|
||||
uint32_t priority = m_wallet->adjust_priority(req.priority);
|
||||
std::vector<wallet2::pending_tx> ptx_vector = m_wallet->create_transactions_single(ki, dsts[0].addr, dsts[0].is_subaddress, req.outputs, mixin, req.unlock_time, priority, extra);
|
||||
std::vector<wallet2::pending_tx> ptx_vector = m_wallet->create_transactions_single(ki, dsts[0].addr, dsts[0].is_subaddress, req.outputs, mixin, priority, extra);
|
||||
|
||||
if (ptx_vector.empty())
|
||||
{
|
||||
|
||||
@@ -79,3 +79,5 @@
|
||||
#define WALLET_RPC_ERROR_CODE_ZERO_AMOUNT -46
|
||||
#define WALLET_RPC_ERROR_CODE_INVALID_SIGNATURE_TYPE -47
|
||||
#define WALLET_RPC_ERROR_CODE_DISABLED -48
|
||||
#define WALLET_RPC_ERROR_CODE_PROXY_ALREADY_DEFINED -49
|
||||
#define WALLET_RPC_ERROR_CODE_NONZERO_UNLOCK_TIME -50
|
||||
|
||||
@@ -350,7 +350,7 @@ bool gen_block_miner_tx_has_2_in::generate(std::vector<test_event_entry>& events
|
||||
destinations.push_back(de);
|
||||
|
||||
transaction tmp_tx;
|
||||
if (!construct_tx(miner_account.get_keys(), sources, destinations, boost::none, std::vector<uint8_t>(), tmp_tx, 0))
|
||||
if (!construct_tx(miner_account.get_keys(), sources, destinations, boost::none, std::vector<uint8_t>(), tmp_tx))
|
||||
return false;
|
||||
|
||||
MAKE_MINER_TX_MANUALLY(miner_tx, blk_0);
|
||||
@@ -393,7 +393,7 @@ bool gen_block_miner_tx_with_txin_to_key::generate(std::vector<test_event_entry>
|
||||
destinations.push_back(de);
|
||||
|
||||
transaction tmp_tx;
|
||||
if (!construct_tx(miner_account.get_keys(), sources, destinations, boost::none, std::vector<uint8_t>(), tmp_tx, 0))
|
||||
if (!construct_tx(miner_account.get_keys(), sources, destinations, boost::none, std::vector<uint8_t>(), tmp_tx))
|
||||
return false;
|
||||
|
||||
MAKE_MINER_TX_MANUALLY(miner_tx, blk_1);
|
||||
|
||||
@@ -136,7 +136,7 @@ bool gen_bpp_tx_validation_base::generate_with(std::vector<test_event_entry>& ev
|
||||
std::unordered_map<crypto::public_key, cryptonote::subaddress_index> subaddresses;
|
||||
subaddresses[miner_accounts[n].get_keys().m_account_address.m_spend_public_key] = {0,0};
|
||||
rct_txes.resize(rct_txes.size() + 1);
|
||||
bool r = construct_tx_and_get_tx_key(miner_accounts[n].get_keys(), subaddresses, sources, destinations, cryptonote::account_public_address{}, std::vector<uint8_t>(), rct_txes.back(), 0, tx_key, additional_tx_keys, true, rct_config[n]);
|
||||
bool r = construct_tx_and_get_tx_key(miner_accounts[n].get_keys(), subaddresses, sources, destinations, cryptonote::account_public_address{}, std::vector<uint8_t>(), rct_txes.back(), tx_key, additional_tx_keys, true, rct_config[n]);
|
||||
CHECK_AND_ASSERT_MES(r, false, "failed to construct transaction");
|
||||
|
||||
if (post_tx && !post_tx(rct_txes.back(), n))
|
||||
|
||||
@@ -136,7 +136,7 @@ bool gen_bp_tx_validation_base::generate_with(std::vector<test_event_entry>& eve
|
||||
std::unordered_map<crypto::public_key, cryptonote::subaddress_index> subaddresses;
|
||||
subaddresses[miner_accounts[n].get_keys().m_account_address.m_spend_public_key] = {0,0};
|
||||
rct_txes.resize(rct_txes.size() + 1);
|
||||
bool r = construct_tx_and_get_tx_key(miner_accounts[n].get_keys(), subaddresses, sources, destinations, cryptonote::account_public_address{}, std::vector<uint8_t>(), rct_txes.back(), 0, tx_key, additional_tx_keys, true, rct_config[n]);
|
||||
bool r = construct_tx_and_get_tx_key(miner_accounts[n].get_keys(), subaddresses, sources, destinations, cryptonote::account_public_address{}, std::vector<uint8_t>(), rct_txes.back(), tx_key, additional_tx_keys, true, rct_config[n]);
|
||||
CHECK_AND_ASSERT_MES(r, false, "failed to construct transaction");
|
||||
|
||||
if (post_tx && !post_tx(rct_txes.back(), n))
|
||||
|
||||
@@ -1028,7 +1028,7 @@ bool construct_tx_to_key(const std::vector<test_event_entry>& events, cryptonote
|
||||
vector<tx_destination_entry> destinations;
|
||||
fill_tx_sources_and_destinations(events, blk_head, from, get_address(to), amount, fee, nmix, sources, destinations);
|
||||
|
||||
return construct_tx_rct(from.get_keys(), sources, destinations, from.get_keys().m_account_address, std::vector<uint8_t>(), tx, 0, rct, range_proof_type, bp_version);
|
||||
return construct_tx_rct(from.get_keys(), sources, destinations, from.get_keys().m_account_address, std::vector<uint8_t>(), tx, rct, range_proof_type, bp_version);
|
||||
}
|
||||
|
||||
bool construct_tx_to_key(const std::vector<test_event_entry>& events, cryptonote::transaction& tx, const cryptonote::block& blk_head,
|
||||
@@ -1044,7 +1044,7 @@ bool construct_tx_to_key(const std::vector<test_event_entry>& events, cryptonote
|
||||
|
||||
fill_tx_destinations(from, destinations, fee, sources, destinations_all, false);
|
||||
|
||||
return construct_tx_rct(from.get_keys(), sources, destinations_all, get_address(from), std::vector<uint8_t>(), tx, 0, rct, range_proof_type, bp_version);
|
||||
return construct_tx_rct(from.get_keys(), sources, destinations_all, get_address(from), std::vector<uint8_t>(), tx, rct, range_proof_type, bp_version);
|
||||
}
|
||||
|
||||
bool construct_tx_to_key(cryptonote::transaction& tx,
|
||||
@@ -1054,7 +1054,7 @@ bool construct_tx_to_key(cryptonote::transaction& tx,
|
||||
{
|
||||
vector<tx_destination_entry> destinations;
|
||||
fill_tx_destinations(from, get_address(to), amount, fee, sources, destinations, rct);
|
||||
return construct_tx_rct(from.get_keys(), sources, destinations, get_address(from), std::vector<uint8_t>(), tx, 0, rct, range_proof_type, bp_version);
|
||||
return construct_tx_rct(from.get_keys(), sources, destinations, get_address(from), std::vector<uint8_t>(), tx, rct, range_proof_type, bp_version);
|
||||
}
|
||||
|
||||
bool construct_tx_to_key(cryptonote::transaction& tx,
|
||||
@@ -1065,10 +1065,10 @@ bool construct_tx_to_key(cryptonote::transaction& tx,
|
||||
{
|
||||
vector<tx_destination_entry> all_destinations;
|
||||
fill_tx_destinations(from, destinations, fee, sources, all_destinations, rct);
|
||||
return construct_tx_rct(from.get_keys(), sources, all_destinations, get_address(from), std::vector<uint8_t>(), tx, 0, rct, range_proof_type, bp_version);
|
||||
return construct_tx_rct(from.get_keys(), sources, all_destinations, get_address(from), std::vector<uint8_t>(), tx, rct, range_proof_type, bp_version);
|
||||
}
|
||||
|
||||
bool construct_tx_rct(const cryptonote::account_keys& sender_account_keys, std::vector<cryptonote::tx_source_entry>& sources, const std::vector<cryptonote::tx_destination_entry>& destinations, const boost::optional<cryptonote::account_public_address>& change_addr, std::vector<uint8_t> extra, cryptonote::transaction& tx, uint64_t unlock_time, bool rct, rct::RangeProofType range_proof_type, int bp_version)
|
||||
bool construct_tx_rct(const cryptonote::account_keys& sender_account_keys, std::vector<cryptonote::tx_source_entry>& sources, const std::vector<cryptonote::tx_destination_entry>& destinations, const boost::optional<cryptonote::account_public_address>& change_addr, std::vector<uint8_t> extra, cryptonote::transaction& tx, bool rct, rct::RangeProofType range_proof_type, int bp_version)
|
||||
{
|
||||
std::unordered_map<crypto::public_key, cryptonote::subaddress_index> subaddresses;
|
||||
subaddresses[sender_account_keys.m_account_address.m_spend_public_key] = {0, 0};
|
||||
@@ -1076,7 +1076,7 @@ bool construct_tx_rct(const cryptonote::account_keys& sender_account_keys, std::
|
||||
std::vector<crypto::secret_key> additional_tx_keys;
|
||||
std::vector<tx_destination_entry> destinations_copy = destinations;
|
||||
rct::RCTConfig rct_config = {range_proof_type, bp_version};
|
||||
return construct_tx_and_get_tx_key(sender_account_keys, subaddresses, sources, destinations_copy, change_addr, extra, tx, unlock_time, tx_key, additional_tx_keys, rct, rct_config);
|
||||
return construct_tx_and_get_tx_key(sender_account_keys, subaddresses, sources, destinations_copy, change_addr, extra, tx, tx_key, additional_tx_keys, rct, rct_config);
|
||||
}
|
||||
|
||||
transaction construct_tx_with_fee(std::vector<test_event_entry>& events, const block& blk_head,
|
||||
|
||||
@@ -450,7 +450,7 @@ bool construct_tx_rct(const cryptonote::account_keys& sender_account_keys,
|
||||
std::vector<cryptonote::tx_source_entry>& sources,
|
||||
const std::vector<cryptonote::tx_destination_entry>& destinations,
|
||||
const boost::optional<cryptonote::account_public_address>& change_addr,
|
||||
std::vector<uint8_t> extra, cryptonote::transaction& tx, uint64_t unlock_time,
|
||||
std::vector<uint8_t> extra, cryptonote::transaction& tx,
|
||||
bool rct=false, rct::RangeProofType range_proof_type=rct::RangeProofBorromean, int bp_version = 0);
|
||||
|
||||
|
||||
|
||||
@@ -144,7 +144,7 @@ bool gen_double_spend_in_tx<txs_keeped_by_block>::generate(std::vector<test_even
|
||||
destinations.push_back(de);
|
||||
|
||||
cryptonote::transaction tx_1;
|
||||
if (!construct_tx(bob_account.get_keys(), sources, destinations, boost::none, std::vector<uint8_t>(), tx_1, 0))
|
||||
if (!construct_tx(bob_account.get_keys(), sources, destinations, boost::none, std::vector<uint8_t>(), tx_1))
|
||||
return false;
|
||||
|
||||
SET_EVENT_VISITOR_SETT(events, txs_keeped_by_block ? event_visitor_settings::set_txs_keeped_by_block : 0);
|
||||
|
||||
@@ -174,7 +174,7 @@ bool gen_uint_overflow_2::generate(std::vector<test_event_entry>& events) const
|
||||
destinations.push_back(tx_destination_entry(sources.front().amount - MONEY_SUPPLY - MONEY_SUPPLY + 1 - TESTS_DEFAULT_FEE, bob_addr, false));
|
||||
|
||||
cryptonote::transaction tx_1;
|
||||
if (!construct_tx(miner_account.get_keys(), sources, destinations, boost::none, std::vector<uint8_t>(), tx_1, 0))
|
||||
if (!construct_tx(miner_account.get_keys(), sources, destinations, boost::none, std::vector<uint8_t>(), tx_1))
|
||||
return false;
|
||||
events.push_back(tx_1);
|
||||
|
||||
@@ -200,7 +200,7 @@ bool gen_uint_overflow_2::generate(std::vector<test_event_entry>& events) const
|
||||
destinations.push_back(de);
|
||||
|
||||
cryptonote::transaction tx_2;
|
||||
if (!construct_tx(bob_account.get_keys(), sources, destinations, boost::none, std::vector<uint8_t>(), tx_2, 0))
|
||||
if (!construct_tx(bob_account.get_keys(), sources, destinations, boost::none, std::vector<uint8_t>(), tx_2))
|
||||
return false;
|
||||
events.push_back(tx_2);
|
||||
|
||||
|
||||
@@ -310,7 +310,7 @@ bool gen_multisig_tx_validation_base::generate_with(std::vector<test_event_entry
|
||||
crypto::secret_key multisig_tx_key_entropy;
|
||||
auto sources_copy = sources;
|
||||
multisig::signing::tx_builder_ringct_t tx_builder;
|
||||
CHECK_AND_ASSERT_MES(tx_builder.init(miner_account[creator].get_keys(), {}, 0, 0, {0}, sources, destinations, {}, {rct::RangeProofPaddedBulletproof, 4}, true, false, tx_key, additional_tx_secret_keys, multisig_tx_key_entropy, tx), false, "error: multisig::signing::tx_builder_ringct_t::init");
|
||||
CHECK_AND_ASSERT_MES(tx_builder.init(miner_account[creator].get_keys(), {}, 0, {0}, sources, destinations, {}, {rct::RangeProofPaddedBulletproof, 4}, true, false, tx_key, additional_tx_secret_keys, multisig_tx_key_entropy, tx), false, "error: multisig::signing::tx_builder_ringct_t::init");
|
||||
|
||||
// work out the permutation done on sources
|
||||
std::vector<size_t> ins_order;
|
||||
@@ -399,7 +399,7 @@ bool gen_multisig_tx_validation_base::generate_with(std::vector<test_event_entry
|
||||
}
|
||||
tools::apply_permutation(ins_order, k);
|
||||
multisig::signing::tx_builder_ringct_t signer_tx_builder;
|
||||
CHECK_AND_ASSERT_MES(signer_tx_builder.init(miner_account[signer].get_keys(), {}, 0, 0, {0}, sources, destinations, {}, {rct::RangeProofPaddedBulletproof, 4}, true, true, tx_key, additional_tx_secret_keys, multisig_tx_key_entropy, tx), false, "error: multisig::signing::tx_builder_ringct_t::init");
|
||||
CHECK_AND_ASSERT_MES(signer_tx_builder.init(miner_account[signer].get_keys(), {}, 0, {0}, sources, destinations, {}, {rct::RangeProofPaddedBulletproof, 4}, true, true, tx_key, additional_tx_secret_keys, multisig_tx_key_entropy, tx), false, "error: multisig::signing::tx_builder_ringct_t::init");
|
||||
|
||||
MDEBUG("signing with k size " << k.size());
|
||||
for (size_t n = 0; n < multisig::signing::kAlphaComponents; ++n)
|
||||
|
||||
@@ -122,7 +122,7 @@ bool gen_rct_tx_validation_base::generate_with_full(std::vector<test_event_entry
|
||||
std::vector<crypto::secret_key> additional_tx_keys;
|
||||
std::unordered_map<crypto::public_key, cryptonote::subaddress_index> subaddresses;
|
||||
subaddresses[miner_accounts[n].get_keys().m_account_address.m_spend_public_key] = {0,0};
|
||||
bool r = construct_tx_and_get_tx_key(miner_accounts[n].get_keys(), subaddresses, sources, destinations, cryptonote::account_public_address{}, std::vector<uint8_t>(), rct_txes[n], 0, tx_key, additional_tx_keys, true);
|
||||
bool r = construct_tx_and_get_tx_key(miner_accounts[n].get_keys(), subaddresses, sources, destinations, cryptonote::account_public_address{}, std::vector<uint8_t>(), rct_txes[n], tx_key, additional_tx_keys, true);
|
||||
CHECK_AND_ASSERT_MES(r, false, "failed to construct transaction");
|
||||
events.push_back(rct_txes[n]);
|
||||
starting_rct_tx_hashes.push_back(get_transaction_hash(rct_txes[n]));
|
||||
@@ -229,7 +229,7 @@ bool gen_rct_tx_validation_base::generate_with_full(std::vector<test_event_entry
|
||||
std::vector<crypto::secret_key> additional_tx_keys;
|
||||
std::unordered_map<crypto::public_key, cryptonote::subaddress_index> subaddresses;
|
||||
subaddresses[miner_accounts[0].get_keys().m_account_address.m_spend_public_key] = {0,0};
|
||||
bool r = construct_tx_and_get_tx_key(miner_accounts[0].get_keys(), subaddresses, sources, destinations, cryptonote::account_public_address{}, std::vector<uint8_t>(), tx, 0, tx_key, additional_tx_keys, true, rct_config, use_view_tags);
|
||||
bool r = construct_tx_and_get_tx_key(miner_accounts[0].get_keys(), subaddresses, sources, destinations, cryptonote::account_public_address{}, std::vector<uint8_t>(), tx, tx_key, additional_tx_keys, true, rct_config, use_view_tags);
|
||||
CHECK_AND_ASSERT_MES(r, false, "failed to construct transaction");
|
||||
|
||||
if (post_tx)
|
||||
|
||||
@@ -136,7 +136,7 @@ bool gen_rct2_tx_validation_base::generate_with(std::vector<test_event_entry>& e
|
||||
std::unordered_map<crypto::public_key, cryptonote::subaddress_index> subaddresses;
|
||||
subaddresses[miner_accounts[n].get_keys().m_account_address.m_spend_public_key] = {0,0};
|
||||
rct_txes.resize(rct_txes.size() + 1);
|
||||
bool r = construct_tx_and_get_tx_key(miner_accounts[n].get_keys(), subaddresses, sources, destinations, cryptonote::account_public_address{}, std::vector<uint8_t>(), rct_txes.back(), 0, tx_key, additional_tx_keys, true, rct_config[n]);
|
||||
bool r = construct_tx_and_get_tx_key(miner_accounts[n].get_keys(), subaddresses, sources, destinations, cryptonote::account_public_address{}, std::vector<uint8_t>(), rct_txes.back(), tx_key, additional_tx_keys, true, rct_config[n]);
|
||||
CHECK_AND_ASSERT_MES(r, false, "failed to construct transaction");
|
||||
|
||||
if (post_tx && !post_tx(rct_txes.back(), n))
|
||||
|
||||
@@ -102,7 +102,7 @@ bool test_transaction_generation_and_ring_signature()
|
||||
destinations.push_back(td);
|
||||
|
||||
transaction tx_rc1;
|
||||
bool r = construct_tx(miner_acc2.get_keys(), sources, destinations, boost::none, std::vector<uint8_t>(), tx_rc1, 0);
|
||||
bool r = construct_tx(miner_acc2.get_keys(), sources, destinations, boost::none, std::vector<uint8_t>(), tx_rc1);
|
||||
CHECK_AND_ASSERT_MES(r, false, "failed to construct transaction");
|
||||
|
||||
crypto::hash pref_hash = get_transaction_prefix_hash(tx_rc1);
|
||||
|
||||
@@ -212,7 +212,7 @@ bool gen_tx_unlock_time::generate(std::vector<test_event_entry>& events) const
|
||||
|
||||
GENERATE_ACCOUNT(miner_account);
|
||||
MAKE_GENESIS_BLOCK(events, blk_0, miner_account, ts_start);
|
||||
REWIND_BLOCKS_N(events, blk_1, blk_0, miner_account, 10);
|
||||
REWIND_BLOCKS_N(events, blk_1, blk_0, miner_account, 20);
|
||||
REWIND_BLOCKS(events, blk_1r, blk_1, miner_account);
|
||||
|
||||
auto make_tx_with_unlock_time = [&](uint64_t unlock_time) -> transaction
|
||||
@@ -222,9 +222,34 @@ bool gen_tx_unlock_time::generate(std::vector<test_event_entry>& events) const
|
||||
|
||||
std::list<transaction> txs_0;
|
||||
|
||||
// Let's make sure that non-zero unlock times fail with a normal relay method
|
||||
SET_EVENT_VISITOR_SETT(events, 0); // set relay_method::fluff
|
||||
|
||||
txs_0.push_back(make_tx_with_unlock_time(0));
|
||||
events.push_back(txs_0.back());
|
||||
|
||||
DO_CALLBACK(events, "mark_invalid_tx");
|
||||
events.push_back(make_tx_with_unlock_time(get_block_height(blk_1r) - 1));
|
||||
|
||||
DO_CALLBACK(events, "mark_invalid_tx");
|
||||
events.push_back(make_tx_with_unlock_time(get_block_height(blk_1r)));
|
||||
|
||||
DO_CALLBACK(events, "mark_invalid_tx");
|
||||
events.push_back(make_tx_with_unlock_time(get_block_height(blk_1r) + 1));
|
||||
|
||||
DO_CALLBACK(events, "mark_invalid_tx");
|
||||
events.push_back(make_tx_with_unlock_time(get_block_height(blk_1r) + 2));
|
||||
|
||||
DO_CALLBACK(events, "mark_invalid_tx");
|
||||
events.push_back(make_tx_with_unlock_time(ts_start - 1));
|
||||
|
||||
DO_CALLBACK(events, "mark_invalid_tx");
|
||||
events.push_back(make_tx_with_unlock_time(time(0) + 60 * 60));
|
||||
|
||||
// We want to try adding these transactions with non-zero unlock times to the pool, but relay
|
||||
// rules enforce otherwise, so we set the relay method to block
|
||||
SET_EVENT_VISITOR_SETT(events, event_visitor_settings::set_txs_keeped_by_block); // set relay_method::block
|
||||
|
||||
txs_0.push_back(make_tx_with_unlock_time(get_block_height(blk_1r) - 1));
|
||||
events.push_back(txs_0.back());
|
||||
|
||||
@@ -596,6 +621,7 @@ bool gen_tx_check_input_unlock_time::generate(std::vector<test_event_entry>& eve
|
||||
events.push_back(txs_0.back());
|
||||
};
|
||||
|
||||
SET_EVENT_VISITOR_SETT(events, event_visitor_settings::set_txs_keeped_by_block); // set relay_method::block
|
||||
uint64_t blk_3_height = get_block_height(blk_1r) + 2;
|
||||
make_tx_to_acc(0, 0);
|
||||
make_tx_to_acc(1, blk_3_height - 1);
|
||||
@@ -604,6 +630,7 @@ bool gen_tx_check_input_unlock_time::generate(std::vector<test_event_entry>& eve
|
||||
make_tx_to_acc(4, time(0) - 1);
|
||||
make_tx_to_acc(5, time(0) + 60 * 60);
|
||||
MAKE_NEXT_BLOCK_TX_LIST(events, blk_2, blk_1r, miner_account, txs_0);
|
||||
SET_EVENT_VISITOR_SETT(events, 0); // set relay_method::fluff
|
||||
|
||||
std::list<transaction> txs_1;
|
||||
auto make_tx_from_acc = [&](size_t acc_idx, bool invalid)
|
||||
|
||||
@@ -107,7 +107,7 @@ bool gen_v2_tx_validation_base::generate_with(std::vector<test_event_entry>& eve
|
||||
destinations.push_back(td);
|
||||
|
||||
transaction tx;
|
||||
bool r = construct_tx(miner_accounts[0].get_keys(), sources, destinations, boost::none, std::vector<uint8_t>(), tx, 0);
|
||||
bool r = construct_tx(miner_accounts[0].get_keys(), sources, destinations, boost::none, std::vector<uint8_t>(), tx);
|
||||
CHECK_AND_ASSERT_MES(r, false, "failed to construct transaction");
|
||||
if (!valid)
|
||||
DO_CALLBACK(events, "mark_invalid_tx");
|
||||
|
||||
@@ -259,7 +259,7 @@ bool construct_tx_to_key(cryptonote::transaction& tx,
|
||||
{
|
||||
vector<tx_destination_entry> destinations;
|
||||
fill_tx_destinations(sender_wallet->get_account(), get_address(to), amount, fee, sources, destinations, rct);
|
||||
return construct_tx_rct(sender_wallet, sources, destinations, get_address(sender_wallet), std::vector<uint8_t>(), tx, 0, rct, range_proof_type, bp_version);
|
||||
return construct_tx_rct(sender_wallet, sources, destinations, get_address(sender_wallet), std::vector<uint8_t>(), tx, rct, range_proof_type, bp_version);
|
||||
}
|
||||
|
||||
bool construct_tx_to_key(cryptonote::transaction& tx,
|
||||
@@ -270,15 +270,15 @@ bool construct_tx_to_key(cryptonote::transaction& tx,
|
||||
{
|
||||
vector<tx_destination_entry> all_destinations;
|
||||
fill_tx_destinations(sender_wallet->get_account(), destinations, fee, sources, all_destinations, rct);
|
||||
return construct_tx_rct(sender_wallet, sources, all_destinations, get_address(sender_wallet), std::vector<uint8_t>(), tx, 0, rct, range_proof_type, bp_version);
|
||||
return construct_tx_rct(sender_wallet, sources, all_destinations, get_address(sender_wallet), std::vector<uint8_t>(), tx, rct, range_proof_type, bp_version);
|
||||
}
|
||||
|
||||
bool construct_tx_rct(tools::wallet2 * sender_wallet, std::vector<cryptonote::tx_source_entry>& sources, const std::vector<cryptonote::tx_destination_entry>& destinations, const boost::optional<cryptonote::account_public_address>& change_addr, std::vector<uint8_t> extra, cryptonote::transaction& tx, uint64_t unlock_time, bool rct, rct::RangeProofType range_proof_type, int bp_version)
|
||||
bool construct_tx_rct(tools::wallet2 * sender_wallet, std::vector<cryptonote::tx_source_entry>& sources, const std::vector<cryptonote::tx_destination_entry>& destinations, const boost::optional<cryptonote::account_public_address>& change_addr, std::vector<uint8_t> extra, cryptonote::transaction& tx, bool rct, rct::RangeProofType range_proof_type, int bp_version)
|
||||
{
|
||||
subaddresses_t & subaddresses = wallet_accessor_test::get_subaddresses(sender_wallet);
|
||||
crypto::secret_key tx_key;
|
||||
std::vector<crypto::secret_key> additional_tx_keys;
|
||||
std::vector<tx_destination_entry> destinations_copy = destinations;
|
||||
rct::RCTConfig rct_config = {range_proof_type, bp_version};
|
||||
return construct_tx_and_get_tx_key(sender_wallet->get_account().get_keys(), subaddresses, sources, destinations_copy, change_addr, extra, tx, unlock_time, tx_key, additional_tx_keys, rct, rct_config);
|
||||
return construct_tx_and_get_tx_key(sender_wallet->get_account().get_keys(), subaddresses, sources, destinations_copy, change_addr, extra, tx, tx_key, additional_tx_keys, rct, rct_config);
|
||||
}
|
||||
|
||||
@@ -82,5 +82,5 @@ bool construct_tx_rct(tools::wallet2 * sender_wallet,
|
||||
std::vector<cryptonote::tx_source_entry>& sources,
|
||||
const std::vector<cryptonote::tx_destination_entry>& destinations,
|
||||
const boost::optional<cryptonote::account_public_address>& change_addr,
|
||||
std::vector<uint8_t> extra, cryptonote::transaction& tx, uint64_t unlock_time,
|
||||
std::vector<uint8_t> extra, cryptonote::transaction& tx,
|
||||
bool rct=false, rct::RangeProofType range_proof_type=rct::RangeProofBorromean, int bp_version = 0);
|
||||
|
||||
@@ -85,7 +85,7 @@ bool do_send_money(tools::wallet2& w1, tools::wallet2& w2, size_t mix_in_factor,
|
||||
try
|
||||
{
|
||||
std::vector<tools::wallet2::pending_tx> ptx;
|
||||
ptx = w1.create_transactions_2(dsts, mix_in_factor, 0, 0, std::vector<uint8_t>(), 0, {});
|
||||
ptx = w1.create_transactions_2(dsts, mix_in_factor, 0, std::vector<uint8_t>(), 0, {});
|
||||
for (auto &p: ptx)
|
||||
w1.commit_tx(p);
|
||||
return true;
|
||||
|
||||
@@ -72,7 +72,7 @@ public:
|
||||
std::unordered_map<crypto::public_key, cryptonote::subaddress_index> subaddresses;
|
||||
subaddresses[this->m_miners[this->real_source_idx].get_keys().m_account_address.m_spend_public_key] = {0,0};
|
||||
rct::RCTConfig rct_config{range_proof_type, bp_version};
|
||||
if (!construct_tx_and_get_tx_key(this->m_miners[this->real_source_idx].get_keys(), subaddresses, this->m_sources, destinations, cryptonote::account_public_address{}, std::vector<uint8_t>(), m_tx, 0, tx_key, additional_tx_keys, rct, rct_config))
|
||||
if (!construct_tx_and_get_tx_key(this->m_miners[this->real_source_idx].get_keys(), subaddresses, this->m_sources, destinations, cryptonote::account_public_address{}, std::vector<uint8_t>(), m_tx, tx_key, additional_tx_keys, rct, rct_config))
|
||||
return false;
|
||||
|
||||
get_transaction_prefix_hash(m_tx, m_tx_prefix_hash);
|
||||
@@ -136,7 +136,7 @@ public:
|
||||
m_txes.resize(a_num_txes + (extra_outs > 0 ? 1 : 0));
|
||||
for (size_t n = 0; n < a_num_txes; ++n)
|
||||
{
|
||||
if (!construct_tx_and_get_tx_key(this->m_miners[this->real_source_idx].get_keys(), subaddresses, this->m_sources, destinations, cryptonote::account_public_address{}, std::vector<uint8_t>(), m_txes[n], 0, tx_key, additional_tx_keys, true, {rct::RangeProofPaddedBulletproof, 2}))
|
||||
if (!construct_tx_and_get_tx_key(this->m_miners[this->real_source_idx].get_keys(), subaddresses, this->m_sources, destinations, cryptonote::account_public_address{}, std::vector<uint8_t>(), m_txes[n], tx_key, additional_tx_keys, true, {rct::RangeProofPaddedBulletproof, 2}))
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -147,7 +147,7 @@ public:
|
||||
for (size_t n = 1; n < extra_outs; ++n)
|
||||
destinations.push_back(tx_destination_entry(1, m_alice.get_keys().m_account_address, false));
|
||||
|
||||
if (!construct_tx_and_get_tx_key(this->m_miners[this->real_source_idx].get_keys(), subaddresses, this->m_sources, destinations, cryptonote::account_public_address{}, std::vector<uint8_t>(), m_txes.back(), 0, tx_key, additional_tx_keys, true, {rct::RangeProofMultiOutputBulletproof, 2}))
|
||||
if (!construct_tx_and_get_tx_key(this->m_miners[this->real_source_idx].get_keys(), subaddresses, this->m_sources, destinations, cryptonote::account_public_address{}, std::vector<uint8_t>(), m_txes.back(), tx_key, additional_tx_keys, true, {rct::RangeProofMultiOutputBulletproof, 2}))
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -74,7 +74,7 @@ public:
|
||||
std::unordered_map<crypto::public_key, cryptonote::subaddress_index> subaddresses;
|
||||
subaddresses[this->m_miners[this->real_source_idx].get_keys().m_account_address.m_spend_public_key] = {0,0};
|
||||
rct::RCTConfig rct_config{range_proof_type, bp_version};
|
||||
return cryptonote::construct_tx_and_get_tx_key(this->m_miners[this->real_source_idx].get_keys(), subaddresses, this->m_sources, m_destinations, cryptonote::account_public_address{}, std::vector<uint8_t>(), m_tx, 0, tx_key, additional_tx_keys, rct, rct_config);
|
||||
return cryptonote::construct_tx_and_get_tx_key(this->m_miners[this->real_source_idx].get_keys(), subaddresses, this->m_sources, m_destinations, cryptonote::account_public_address{}, std::vector<uint8_t>(), m_tx, tx_key, additional_tx_keys, rct, rct_config);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
@@ -57,7 +57,7 @@ public:
|
||||
std::vector<tx_destination_entry> destinations;
|
||||
destinations.push_back(tx_destination_entry(1, m_alice.get_keys().m_account_address, false));
|
||||
|
||||
if (!construct_tx(this->m_miners[this->real_source_idx].get_keys(), this->m_sources, destinations, boost::none, std::vector<uint8_t>(), m_tx, 0))
|
||||
if (!construct_tx(this->m_miners[this->real_source_idx].get_keys(), this->m_sources, destinations, boost::none, std::vector<uint8_t>(), m_tx))
|
||||
return false;
|
||||
|
||||
const cryptonote::txin_to_key& txin = boost::get<cryptonote::txin_to_key>(m_tx.vin[0]);
|
||||
|
||||
@@ -57,7 +57,7 @@ public:
|
||||
std::vector<tx_destination_entry> destinations;
|
||||
destinations.push_back(tx_destination_entry(1, m_alice.get_keys().m_account_address, false));
|
||||
|
||||
if (!construct_tx(this->m_miners[this->real_source_idx].get_keys(), this->m_sources, destinations, boost::none, std::vector<uint8_t>(), m_tx, 0))
|
||||
if (!construct_tx(this->m_miners[this->real_source_idx].get_keys(), this->m_sources, destinations, boost::none, std::vector<uint8_t>(), m_tx))
|
||||
return false;
|
||||
|
||||
const cryptonote::txin_to_key& txin = boost::get<cryptonote::txin_to_key>(m_tx.vin[0]);
|
||||
|
||||
@@ -1427,6 +1427,21 @@ TEST(StringTools, GetIpInt32)
|
||||
EXPECT_EQ(htonl(0xff0aff00), ip);
|
||||
}
|
||||
|
||||
TEST(StringTools, GetExtension)
|
||||
{
|
||||
EXPECT_EQ(std::string{}, epee::string_tools::get_extension(""));
|
||||
EXPECT_EQ(std::string{}, epee::string_tools::get_extension("."));
|
||||
EXPECT_EQ(std::string{"keys"}, epee::string_tools::get_extension("wallet.keys"));
|
||||
EXPECT_EQ(std::string{"3"}, epee::string_tools::get_extension("1.2.3"));
|
||||
}
|
||||
|
||||
TEST(StringTools, CutOffExtension)
|
||||
{
|
||||
EXPECT_EQ(std::string{}, epee::string_tools::cut_off_extension(""));
|
||||
EXPECT_EQ(std::string{"/home/user/Monero/wallets/wallet"}, epee::string_tools::cut_off_extension("/home/user/Monero/wallets/wallet"));
|
||||
EXPECT_EQ(std::string{"/home/user/Monero/wallets/wallet"}, epee::string_tools::cut_off_extension("/home/user/Monero/wallets/wallet.keys"));
|
||||
}
|
||||
|
||||
TEST(NetUtils, IPv4NetworkAddress)
|
||||
{
|
||||
static_assert(epee::net_utils::ipv4_network_address::get_type_id() == epee::net_utils::address_type::ipv4, "bad ipv4 type id");
|
||||
|
||||
@@ -78,7 +78,7 @@ namespace test
|
||||
std::unordered_map<crypto::public_key, cryptonote::subaddress_index> subaddresses;
|
||||
subaddresses[from.m_account_address.m_spend_public_key] = {0,0};
|
||||
|
||||
if (!cryptonote::construct_tx_and_get_tx_key(from, subaddresses, actual_sources, to, boost::none, {}, tx, 0, tx_key, extra_keys, rct, { bulletproof ? rct::RangeProofBulletproof : rct::RangeProofBorromean, bulletproof ? 2 : 0 }))
|
||||
if (!cryptonote::construct_tx_and_get_tx_key(from, subaddresses, actual_sources, to, boost::none, {}, tx, tx_key, extra_keys, rct, { bulletproof ? rct::RangeProofBulletproof : rct::RangeProofBorromean, bulletproof ? 2 : 0 }))
|
||||
throw std::runtime_error{"transaction construction error"};
|
||||
|
||||
return tx;
|
||||
@@ -124,6 +124,68 @@ TEST(JsonSerialization, InvalidVectorBytes)
|
||||
EXPECT_THROW(cryptonote::json::fromJsonValue(doc, out), cryptonote::json::BAD_INPUT);
|
||||
}
|
||||
|
||||
TEST(JsonSerialization, DaemonInfo)
|
||||
{
|
||||
cryptonote::rpc::DaemonInfo info{};
|
||||
info.height = 154544;
|
||||
info.target_height = 15345435;
|
||||
info.top_block_height = 2344;
|
||||
info.wide_difficulty = cryptonote::difficulty_type{"100000000000000000005443"};
|
||||
info.difficulty = 200376420520695107;
|
||||
info.target = 7657567;
|
||||
info.tx_count = 355;
|
||||
info.tx_pool_size = 45435;
|
||||
info.alt_blocks_count = 43535;
|
||||
info.outgoing_connections_count = 1444;
|
||||
info.incoming_connections_count = 1444;
|
||||
info.white_peerlist_size = 14550;
|
||||
info.grey_peerlist_size = 34324;
|
||||
info.mainnet = true;
|
||||
info.testnet = true;
|
||||
info.stagenet = true;
|
||||
info.nettype = "main";
|
||||
info.top_block_hash = crypto::hash{1};
|
||||
info.wide_cumulative_difficulty = cryptonote::difficulty_type{"200000000000000000005543"};
|
||||
info.cumulative_difficulty = 400752841041384871;
|
||||
info.block_size_limit = 4324234;
|
||||
info.block_weight_limit = 3434;
|
||||
info.block_size_median = 3434;
|
||||
info.adjusted_time = 4535;
|
||||
info.block_weight_median = 43535;
|
||||
info.start_time = 34535;
|
||||
info.version = "1.0";
|
||||
|
||||
const auto info_copy = test_json(info);
|
||||
|
||||
EXPECT_EQ(info.height, info_copy.height);
|
||||
EXPECT_EQ(info.target_height, info_copy.target_height);
|
||||
EXPECT_EQ(info.top_block_height, info_copy.top_block_height);
|
||||
EXPECT_EQ(info.wide_difficulty, info_copy.wide_difficulty);
|
||||
EXPECT_EQ(info.difficulty, info_copy.difficulty);
|
||||
EXPECT_EQ(info.target, info_copy.target);
|
||||
EXPECT_EQ(info.tx_count, info_copy.tx_count);
|
||||
EXPECT_EQ(info.tx_pool_size, info_copy.tx_pool_size);
|
||||
EXPECT_EQ(info.alt_blocks_count, info_copy.alt_blocks_count);
|
||||
EXPECT_EQ(info.outgoing_connections_count, info_copy.outgoing_connections_count);
|
||||
EXPECT_EQ(info.incoming_connections_count, info_copy.incoming_connections_count);
|
||||
EXPECT_EQ(info.white_peerlist_size, info_copy.white_peerlist_size);
|
||||
EXPECT_EQ(info.grey_peerlist_size, info_copy.grey_peerlist_size);
|
||||
EXPECT_EQ(info.mainnet, info_copy.mainnet);
|
||||
EXPECT_EQ(info.testnet, info_copy.testnet);
|
||||
EXPECT_EQ(info.stagenet, info_copy.stagenet);
|
||||
EXPECT_EQ(info.nettype, info_copy.nettype);
|
||||
EXPECT_EQ(info.top_block_hash, info_copy.top_block_hash);
|
||||
EXPECT_EQ(info.wide_cumulative_difficulty, info_copy.wide_cumulative_difficulty);
|
||||
EXPECT_EQ(info.cumulative_difficulty, info_copy.cumulative_difficulty);
|
||||
EXPECT_EQ(info.block_size_limit, info_copy.block_size_limit);
|
||||
EXPECT_EQ(info.block_weight_limit, info_copy.block_weight_limit);
|
||||
EXPECT_EQ(info.block_size_median, info_copy.block_size_median);
|
||||
EXPECT_EQ(info.adjusted_time, info_copy.adjusted_time);
|
||||
EXPECT_EQ(info.block_weight_median, info_copy.block_weight_median);
|
||||
EXPECT_EQ(info.start_time, info_copy.start_time);
|
||||
EXPECT_EQ(info.version, info_copy.version);
|
||||
}
|
||||
|
||||
TEST(JsonSerialization, MinerTransaction)
|
||||
{
|
||||
cryptonote::account_base acct;
|
||||
|
||||
@@ -591,6 +591,7 @@ TEST_F(levin_notify, defaulted)
|
||||
const auto status = notifier.get_status();
|
||||
EXPECT_FALSE(status.has_noise);
|
||||
EXPECT_FALSE(status.connections_filled);
|
||||
EXPECT_FALSE(status.has_outgoing);
|
||||
}
|
||||
EXPECT_TRUE(notifier.send_txs({}, random_generator_(), cryptonote::relay_method::local));
|
||||
|
||||
@@ -611,6 +612,7 @@ TEST_F(levin_notify, fluff_without_padding)
|
||||
const auto status = notifier.get_status();
|
||||
EXPECT_FALSE(status.has_noise);
|
||||
EXPECT_FALSE(status.connections_filled);
|
||||
EXPECT_TRUE(status.has_outgoing);
|
||||
}
|
||||
notifier.new_out_connection();
|
||||
io_service_.poll();
|
||||
@@ -658,6 +660,7 @@ TEST_F(levin_notify, stem_without_padding)
|
||||
const auto status = notifier.get_status();
|
||||
EXPECT_FALSE(status.has_noise);
|
||||
EXPECT_FALSE(status.connections_filled);
|
||||
EXPECT_TRUE(status.has_outgoing);
|
||||
}
|
||||
notifier.new_out_connection();
|
||||
io_service_.poll();
|
||||
@@ -731,6 +734,7 @@ TEST_F(levin_notify, stem_no_outs_without_padding)
|
||||
const auto status = notifier.get_status();
|
||||
EXPECT_FALSE(status.has_noise);
|
||||
EXPECT_FALSE(status.connections_filled);
|
||||
EXPECT_FALSE(status.has_outgoing);
|
||||
}
|
||||
notifier.new_out_connection();
|
||||
io_service_.poll();
|
||||
@@ -788,6 +792,7 @@ TEST_F(levin_notify, local_without_padding)
|
||||
const auto status = notifier.get_status();
|
||||
EXPECT_FALSE(status.has_noise);
|
||||
EXPECT_FALSE(status.connections_filled);
|
||||
EXPECT_TRUE(status.has_outgoing);
|
||||
}
|
||||
notifier.new_out_connection();
|
||||
io_service_.poll();
|
||||
@@ -897,6 +902,7 @@ TEST_F(levin_notify, forward_without_padding)
|
||||
const auto status = notifier.get_status();
|
||||
EXPECT_FALSE(status.has_noise);
|
||||
EXPECT_FALSE(status.connections_filled);
|
||||
EXPECT_TRUE(status.has_outgoing);
|
||||
}
|
||||
notifier.new_out_connection();
|
||||
io_service_.poll();
|
||||
@@ -970,6 +976,7 @@ TEST_F(levin_notify, block_without_padding)
|
||||
const auto status = notifier.get_status();
|
||||
EXPECT_FALSE(status.has_noise);
|
||||
EXPECT_FALSE(status.connections_filled);
|
||||
EXPECT_TRUE(status.has_outgoing);
|
||||
}
|
||||
notifier.new_out_connection();
|
||||
io_service_.poll();
|
||||
@@ -1000,6 +1007,7 @@ TEST_F(levin_notify, none_without_padding)
|
||||
const auto status = notifier.get_status();
|
||||
EXPECT_FALSE(status.has_noise);
|
||||
EXPECT_FALSE(status.connections_filled);
|
||||
EXPECT_TRUE(status.has_outgoing);
|
||||
}
|
||||
notifier.new_out_connection();
|
||||
io_service_.poll();
|
||||
@@ -1030,6 +1038,7 @@ TEST_F(levin_notify, fluff_with_padding)
|
||||
const auto status = notifier.get_status();
|
||||
EXPECT_FALSE(status.has_noise);
|
||||
EXPECT_FALSE(status.connections_filled);
|
||||
EXPECT_TRUE(status.has_outgoing);
|
||||
}
|
||||
notifier.new_out_connection();
|
||||
io_service_.poll();
|
||||
@@ -1077,6 +1086,7 @@ TEST_F(levin_notify, stem_with_padding)
|
||||
const auto status = notifier.get_status();
|
||||
EXPECT_FALSE(status.has_noise);
|
||||
EXPECT_FALSE(status.connections_filled);
|
||||
EXPECT_TRUE(status.has_outgoing);
|
||||
}
|
||||
notifier.new_out_connection();
|
||||
io_service_.poll();
|
||||
@@ -1145,6 +1155,7 @@ TEST_F(levin_notify, stem_no_outs_with_padding)
|
||||
const auto status = notifier.get_status();
|
||||
EXPECT_FALSE(status.has_noise);
|
||||
EXPECT_FALSE(status.connections_filled);
|
||||
EXPECT_FALSE(status.has_outgoing);
|
||||
}
|
||||
notifier.new_out_connection();
|
||||
io_service_.poll();
|
||||
@@ -1202,6 +1213,7 @@ TEST_F(levin_notify, local_with_padding)
|
||||
const auto status = notifier.get_status();
|
||||
EXPECT_FALSE(status.has_noise);
|
||||
EXPECT_FALSE(status.connections_filled);
|
||||
EXPECT_TRUE(status.has_outgoing);
|
||||
}
|
||||
notifier.new_out_connection();
|
||||
io_service_.poll();
|
||||
@@ -1303,6 +1315,7 @@ TEST_F(levin_notify, forward_with_padding)
|
||||
const auto status = notifier.get_status();
|
||||
EXPECT_FALSE(status.has_noise);
|
||||
EXPECT_FALSE(status.connections_filled);
|
||||
EXPECT_TRUE(status.has_outgoing);
|
||||
}
|
||||
notifier.new_out_connection();
|
||||
io_service_.poll();
|
||||
@@ -1371,6 +1384,7 @@ TEST_F(levin_notify, block_with_padding)
|
||||
const auto status = notifier.get_status();
|
||||
EXPECT_FALSE(status.has_noise);
|
||||
EXPECT_FALSE(status.connections_filled);
|
||||
EXPECT_TRUE(status.has_outgoing);
|
||||
}
|
||||
notifier.new_out_connection();
|
||||
io_service_.poll();
|
||||
@@ -1401,6 +1415,7 @@ TEST_F(levin_notify, none_with_padding)
|
||||
const auto status = notifier.get_status();
|
||||
EXPECT_FALSE(status.has_noise);
|
||||
EXPECT_FALSE(status.connections_filled);
|
||||
EXPECT_TRUE(status.has_outgoing);
|
||||
}
|
||||
notifier.new_out_connection();
|
||||
io_service_.poll();
|
||||
@@ -1431,6 +1446,7 @@ TEST_F(levin_notify, private_fluff_without_padding)
|
||||
const auto status = notifier.get_status();
|
||||
EXPECT_FALSE(status.has_noise);
|
||||
EXPECT_FALSE(status.connections_filled);
|
||||
EXPECT_TRUE(status.has_outgoing);
|
||||
}
|
||||
notifier.new_out_connection();
|
||||
io_service_.poll();
|
||||
@@ -1483,6 +1499,7 @@ TEST_F(levin_notify, private_stem_without_padding)
|
||||
const auto status = notifier.get_status();
|
||||
EXPECT_FALSE(status.has_noise);
|
||||
EXPECT_FALSE(status.connections_filled);
|
||||
EXPECT_TRUE(status.has_outgoing);
|
||||
}
|
||||
notifier.new_out_connection();
|
||||
io_service_.poll();
|
||||
@@ -1535,6 +1552,7 @@ TEST_F(levin_notify, private_local_without_padding)
|
||||
const auto status = notifier.get_status();
|
||||
EXPECT_FALSE(status.has_noise);
|
||||
EXPECT_FALSE(status.connections_filled);
|
||||
EXPECT_TRUE(status.has_outgoing);
|
||||
}
|
||||
notifier.new_out_connection();
|
||||
io_service_.poll();
|
||||
@@ -1587,6 +1605,7 @@ TEST_F(levin_notify, private_forward_without_padding)
|
||||
const auto status = notifier.get_status();
|
||||
EXPECT_FALSE(status.has_noise);
|
||||
EXPECT_FALSE(status.connections_filled);
|
||||
EXPECT_TRUE(status.has_outgoing);
|
||||
}
|
||||
notifier.new_out_connection();
|
||||
io_service_.poll();
|
||||
@@ -1639,6 +1658,7 @@ TEST_F(levin_notify, private_block_without_padding)
|
||||
const auto status = notifier.get_status();
|
||||
EXPECT_FALSE(status.has_noise);
|
||||
EXPECT_FALSE(status.connections_filled);
|
||||
EXPECT_TRUE(status.has_outgoing);
|
||||
}
|
||||
notifier.new_out_connection();
|
||||
io_service_.poll();
|
||||
@@ -1670,6 +1690,7 @@ TEST_F(levin_notify, private_none_without_padding)
|
||||
const auto status = notifier.get_status();
|
||||
EXPECT_FALSE(status.has_noise);
|
||||
EXPECT_FALSE(status.connections_filled);
|
||||
EXPECT_TRUE(status.has_outgoing);
|
||||
}
|
||||
notifier.new_out_connection();
|
||||
io_service_.poll();
|
||||
@@ -1700,6 +1721,7 @@ TEST_F(levin_notify, private_fluff_with_padding)
|
||||
const auto status = notifier.get_status();
|
||||
EXPECT_FALSE(status.has_noise);
|
||||
EXPECT_FALSE(status.connections_filled);
|
||||
EXPECT_TRUE(status.has_outgoing);
|
||||
}
|
||||
notifier.new_out_connection();
|
||||
io_service_.poll();
|
||||
@@ -1751,6 +1773,7 @@ TEST_F(levin_notify, private_stem_with_padding)
|
||||
const auto status = notifier.get_status();
|
||||
EXPECT_FALSE(status.has_noise);
|
||||
EXPECT_FALSE(status.connections_filled);
|
||||
EXPECT_TRUE(status.has_outgoing);
|
||||
}
|
||||
notifier.new_out_connection();
|
||||
io_service_.poll();
|
||||
@@ -1802,6 +1825,7 @@ TEST_F(levin_notify, private_local_with_padding)
|
||||
const auto status = notifier.get_status();
|
||||
EXPECT_FALSE(status.has_noise);
|
||||
EXPECT_FALSE(status.connections_filled);
|
||||
EXPECT_TRUE(status.has_outgoing);
|
||||
}
|
||||
notifier.new_out_connection();
|
||||
io_service_.poll();
|
||||
@@ -1853,6 +1877,7 @@ TEST_F(levin_notify, private_forward_with_padding)
|
||||
const auto status = notifier.get_status();
|
||||
EXPECT_FALSE(status.has_noise);
|
||||
EXPECT_FALSE(status.connections_filled);
|
||||
EXPECT_TRUE(status.has_outgoing);
|
||||
}
|
||||
notifier.new_out_connection();
|
||||
io_service_.poll();
|
||||
@@ -1904,6 +1929,7 @@ TEST_F(levin_notify, private_block_with_padding)
|
||||
const auto status = notifier.get_status();
|
||||
EXPECT_FALSE(status.has_noise);
|
||||
EXPECT_FALSE(status.connections_filled);
|
||||
EXPECT_TRUE(status.has_outgoing);
|
||||
}
|
||||
notifier.new_out_connection();
|
||||
io_service_.poll();
|
||||
@@ -1934,6 +1960,7 @@ TEST_F(levin_notify, private_none_with_padding)
|
||||
const auto status = notifier.get_status();
|
||||
EXPECT_FALSE(status.has_noise);
|
||||
EXPECT_FALSE(status.connections_filled);
|
||||
EXPECT_TRUE(status.has_outgoing);
|
||||
}
|
||||
notifier.new_out_connection();
|
||||
io_service_.poll();
|
||||
@@ -1966,6 +1993,7 @@ TEST_F(levin_notify, stem_mappings)
|
||||
const auto status = notifier.get_status();
|
||||
EXPECT_FALSE(status.has_noise);
|
||||
EXPECT_FALSE(status.connections_filled);
|
||||
EXPECT_TRUE(status.has_outgoing);
|
||||
}
|
||||
notifier.new_out_connection();
|
||||
io_service_.poll();
|
||||
@@ -2090,6 +2118,7 @@ TEST_F(levin_notify, fluff_multiple)
|
||||
const auto status = notifier.get_status();
|
||||
EXPECT_FALSE(status.has_noise);
|
||||
EXPECT_FALSE(status.connections_filled);
|
||||
EXPECT_TRUE(status.has_outgoing);
|
||||
}
|
||||
notifier.new_out_connection();
|
||||
io_service_.poll();
|
||||
@@ -2190,6 +2219,63 @@ TEST_F(levin_notify, fluff_multiple)
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(levin_notify, fluff_with_duplicate)
|
||||
{
|
||||
std::shared_ptr<cryptonote::levin::notify> notifier_ptr = make_notifier(0, true, false);
|
||||
auto ¬ifier = *notifier_ptr;
|
||||
|
||||
for (unsigned count = 0; count < 10; ++count)
|
||||
add_connection(count % 2 == 0);
|
||||
|
||||
{
|
||||
const auto status = notifier.get_status();
|
||||
EXPECT_FALSE(status.has_noise);
|
||||
EXPECT_FALSE(status.connections_filled);
|
||||
EXPECT_TRUE(status.has_outgoing);
|
||||
}
|
||||
notifier.new_out_connection();
|
||||
io_service_.poll();
|
||||
|
||||
std::vector<cryptonote::blobdata> txs(9);
|
||||
txs[0].resize(100, 'e');
|
||||
txs[1].resize(100, 'e');
|
||||
txs[2].resize(100, 'e');
|
||||
txs[3].resize(100, 'e');
|
||||
txs[4].resize(200, 'f');
|
||||
txs[5].resize(200, 'f');
|
||||
txs[6].resize(200, 'f');
|
||||
txs[7].resize(200, 'f');
|
||||
txs[8].resize(200, 'f');
|
||||
|
||||
ASSERT_EQ(10u, contexts_.size());
|
||||
{
|
||||
auto context = contexts_.begin();
|
||||
EXPECT_TRUE(notifier.send_txs(txs, context->get_id(), cryptonote::relay_method::fluff));
|
||||
|
||||
io_service_.reset();
|
||||
ASSERT_LT(0u, io_service_.poll());
|
||||
notifier.run_fluff();
|
||||
ASSERT_LT(0u, io_service_.poll());
|
||||
|
||||
EXPECT_EQ(0u, context->process_send_queue());
|
||||
for (++context; context != contexts_.end(); ++context)
|
||||
EXPECT_EQ(1u, context->process_send_queue());
|
||||
|
||||
EXPECT_EQ(txs, events_.take_relayed(cryptonote::relay_method::fluff));
|
||||
std::sort(txs.begin(), txs.end());
|
||||
ASSERT_EQ(9u, receiver_.notified_size());
|
||||
for (unsigned count = 0; count < 9; ++count)
|
||||
{
|
||||
auto notification = receiver_.get_notification<cryptonote::NOTIFY_NEW_TRANSACTIONS>().second;
|
||||
EXPECT_NE(txs, notification.txs);
|
||||
EXPECT_EQ(notification.txs.size(), 2);
|
||||
EXPECT_TRUE(notification._.empty());
|
||||
EXPECT_TRUE(notification.dandelionpp_fluff);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
TEST_F(levin_notify, noise)
|
||||
{
|
||||
for (unsigned count = 0; count < 10; ++count)
|
||||
@@ -2206,12 +2292,14 @@ TEST_F(levin_notify, noise)
|
||||
const auto status = notifier.get_status();
|
||||
EXPECT_TRUE(status.has_noise);
|
||||
EXPECT_FALSE(status.connections_filled);
|
||||
EXPECT_FALSE(status.has_outgoing);
|
||||
}
|
||||
ASSERT_LT(0u, io_service_.poll());
|
||||
{
|
||||
const auto status = notifier.get_status();
|
||||
EXPECT_TRUE(status.has_noise);
|
||||
EXPECT_TRUE(status.connections_filled);
|
||||
EXPECT_TRUE(status.has_outgoing);
|
||||
}
|
||||
|
||||
notifier.run_stems();
|
||||
@@ -2298,12 +2386,14 @@ TEST_F(levin_notify, noise_stem)
|
||||
const auto status = notifier.get_status();
|
||||
EXPECT_TRUE(status.has_noise);
|
||||
EXPECT_FALSE(status.connections_filled);
|
||||
EXPECT_FALSE(status.has_outgoing);
|
||||
}
|
||||
ASSERT_LT(0u, io_service_.poll());
|
||||
{
|
||||
const auto status = notifier.get_status();
|
||||
EXPECT_TRUE(status.has_noise);
|
||||
EXPECT_TRUE(status.connections_filled);
|
||||
EXPECT_TRUE(status.has_outgoing);
|
||||
}
|
||||
|
||||
notifier.run_stems();
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
|
||||
#include "file_io_utils.h"
|
||||
#include "wallet/wallet2.h"
|
||||
#include "common/util.h"
|
||||
|
||||
using namespace boost::filesystem;
|
||||
using namespace epee::file_io_utils;
|
||||
@@ -47,8 +48,8 @@ TEST(wallet_storage, store_to_file2file)
|
||||
ASSERT_TRUE(is_file_exist(source_wallet_file.string()));
|
||||
ASSERT_TRUE(is_file_exist(source_wallet_file.string() + ".keys"));
|
||||
|
||||
copy_file(source_wallet_file, interm_wallet_file, copy_option::overwrite_if_exists);
|
||||
copy_file(source_wallet_file.string() + ".keys", interm_wallet_file.string() + ".keys", copy_option::overwrite_if_exists);
|
||||
tools::copy_file(source_wallet_file.string(), interm_wallet_file.string());
|
||||
tools::copy_file(source_wallet_file.string() + ".keys", interm_wallet_file.string() + ".keys");
|
||||
|
||||
ASSERT_TRUE(is_file_exist(interm_wallet_file.string()));
|
||||
ASSERT_TRUE(is_file_exist(interm_wallet_file.string() + ".keys"));
|
||||
@@ -138,8 +139,8 @@ TEST(wallet_storage, change_password_same_file)
|
||||
ASSERT_TRUE(is_file_exist(source_wallet_file.string()));
|
||||
ASSERT_TRUE(is_file_exist(source_wallet_file.string() + ".keys"));
|
||||
|
||||
copy_file(source_wallet_file, interm_wallet_file, copy_option::overwrite_if_exists);
|
||||
copy_file(source_wallet_file.string() + ".keys", interm_wallet_file.string() + ".keys", copy_option::overwrite_if_exists);
|
||||
tools::copy_file(source_wallet_file.string(), interm_wallet_file.string());
|
||||
tools::copy_file(source_wallet_file.string() + ".keys", interm_wallet_file.string() + ".keys");
|
||||
|
||||
ASSERT_TRUE(is_file_exist(interm_wallet_file.string()));
|
||||
ASSERT_TRUE(is_file_exist(interm_wallet_file.string() + ".keys"));
|
||||
@@ -177,8 +178,8 @@ TEST(wallet_storage, change_password_different_file)
|
||||
ASSERT_TRUE(is_file_exist(source_wallet_file.string()));
|
||||
ASSERT_TRUE(is_file_exist(source_wallet_file.string() + ".keys"));
|
||||
|
||||
copy_file(source_wallet_file, interm_wallet_file, copy_option::overwrite_if_exists);
|
||||
copy_file(source_wallet_file.string() + ".keys", interm_wallet_file.string() + ".keys", copy_option::overwrite_if_exists);
|
||||
tools::copy_file(source_wallet_file.string(), interm_wallet_file.string());
|
||||
tools::copy_file(source_wallet_file.string() + ".keys", interm_wallet_file.string() + ".keys");
|
||||
|
||||
ASSERT_TRUE(is_file_exist(interm_wallet_file.string()));
|
||||
ASSERT_TRUE(is_file_exist(interm_wallet_file.string() + ".keys"));
|
||||
|
||||
Reference in New Issue
Block a user