Compare commits

...

39 Commits

Author SHA1 Message Date
luigi1111 b089f9ee69 Merge pull request #9434
7cb69fa epee: string_tools: keep full path in cut_off_extension (tobtoht)
c7d4bf4 epee: string_tools: remove dot from get_extension (tobtoht)
2024-08-14 14:19:55 -04:00
tobtoht 7cb69fa6bc epee: string_tools: keep full path in cut_off_extension 2024-08-14 19:50:06 +02:00
tobtoht c7d4bf491e epee: string_tools: remove dot from get_extension
Fixes a regression introduced in #9254. Previously it did not
include the dot.
2024-08-14 16:57:49 +02:00
luigi1111 c6d17a0b39 Merge pull request #9345
956d55c build: prepare v0.18.3.4 (selsta)
2024-08-13 12:33:21 -04:00
luigi1111 753e4683af Merge pull request #9430
dffa676 device: add ledger flex support (tobtoht)
2024-08-13 12:30:11 -04:00
luigi1111 2676e5ae85 Merge pull request #9426
1f733fb Make wallet2::estimate_fee static (Lee Clagett)
2024-08-13 12:29:10 -04:00
luigi1111 bedfa83ea0 Merge pull request #9385
c5ad937 Fix ZMQ DaemonInfo: (Lee *!* Clagett)
2024-08-13 12:15:57 -04:00
tobtoht dffa6766e7 device: add ledger flex support
See: https://github.com/LedgerHQ/ledger-live/blob/bd1b09970f2f5a27eb08352a67a73dfa2fce29f6/libs/ledgerjs/packages/devices/src/index.ts#L111
2024-08-09 10:33:55 +02:00
Lee Clagett 1f733fb868 Make wallet2::estimate_fee static 2024-08-07 17:43:03 -04:00
selsta 956d55c35f build: prepare v0.18.3.4 2024-07-22 14:23:40 +02:00
luigi1111 76feeb64b7 Merge pull request #9396
b9fddc0 epee: fix mlog filename compare bug. (0xFFFC0000)
2024-07-16 19:03:10 -04:00
luigi1111 61db6497f7 Merge pull request #9377
e875a58 Fix ZMQ Tx Pruning (Lee Clagett)
2024-07-16 18:57:35 -04:00
luigi1111 6664e3e3b1 Merge pull request #9374
8c254e4 wallet: fetch pool txs in pruned form [RELEASE] (jeffro256)
2024-07-16 18:57:12 -04:00
luigi1111 ebe3fdaff3 Merge pull request #9355
8dbc361 cryptonote_protocol: prevent duplicate txs in fluff queue (0xFFFC0000)
2024-07-16 18:51:56 -04:00
luigi1111 886595b540 Merge pull request #9347
738f503 contrib: fix compilation error for boost 1.85 (0xFFFC0000)
2024-07-16 18:50:09 -04:00
0xFFFC0000 b9fddc08b2 epee: fix mlog filename compare bug.
When using a relative path for the log filename,
since the iteration on files adds "./" to the beginning of the filename
monero-wallet-rpc and monero-wallet-cli	cannot find already written
log files and therefore rotate indefinitely.
2024-07-14 19:23:07 +03:30
Lee *!* Clagett c5ad937cc1 Fix ZMQ DaemonInfo:
* top_block_hash was never set in handler
  * wide_difficulty was never sent in JSON
  * wide_cumulative_difficulty was never sent in JSON
2024-06-24 20:06:33 -04:00
Lee Clagett e875a587e2 Fix ZMQ Tx Pruning 2024-06-21 21:37:31 -04:00
jeffro256 8c254e42e3 wallet: fetch pool txs in pruned form [RELEASE] 2024-06-21 08:15:26 -05:00
0xFFFC0000 8dbc361e98 cryptonote_protocol: prevent duplicate txs in fluff queue
1. Fix duplicate transaction #9335
2. Add test for cases where there are duplicate transaction in fluff

Co-authored-by: Boog900 <boog900@tutanota.com>
2024-06-06 17:33:17 +03:30
0xFFFC0000 738f5038bf contrib: fix compilation error for boost 1.85 2024-05-29 16:02:15 +02:00
luigi1111 24ccaba6ef Merge pull request #9323
1123ae9 net_node: update seed nodes (selsta)
2024-05-20 23:45:36 -05:00
luigi1111 1ec7eae036 Merge pull request #9311
dd47d03 Enforce Tx unlock_time is Zero by Relay Rule [RELEASE] (jeffro256)
2024-05-20 23:42:54 -05:00
luigi1111 2f0503d7f3 Merge pull request #9309
4634b8b wallet2: fix stagenet get_approximate_blockchain_height (selsta)
2024-05-20 23:40:31 -05:00
luigi1111 b13e597e8e Merge pull request #9306
755dddd common: support boost filesystem copy_options. Co-authored-by: selsta <selsta@sent.at> (0xFFFC0000)
2024-05-20 23:39:01 -05:00
luigi1111 19fa7dceac Merge pull request #9292
100a7d0 Add drop_and_recreate in privatefile class. When creating a private file we need to delete the file if exist. (0xFFFC0000)
2024-05-20 23:37:41 -05:00
luigi1111 f48fc72fb6 Merge pull request #9291
7156788 build: force Trezor for depends builds (tobtoht)
2024-05-20 23:37:11 -05:00
luigi1111 5930557a94 Merge pull request #9267
7686af7 Skip privacy networks (on tx sends) that don't have outgoing connections (Lee *!* Clagett)
2024-05-20 23:34:08 -05:00
luigi1111 b85f320738 Merge pull request #9260
8703b8a wallet2: ensure transfers and sweeps use same fee calc logic rnd2 (j-berman)
2024-05-20 23:33:31 -05:00
luigi1111 026be65bf5 Merge pull request #9254
d6b35e9 Cleanup string_tools. 1. Use boost::filesystem for already available operations. 2. Use boost::string for already available operations. (0xFFFC0000)
2024-05-20 23:30:18 -05:00
selsta 1123ae9043 net_node: update seed nodes
Also remove port for I2P seed nodes
2024-05-12 15:24:41 +02:00
0xFFFC0000 755dddd2bc common: support boost filesystem copy_options.
Co-authored-by: selsta <selsta@sent.at>
2024-05-01 02:51:08 +03:30
jeffro256 dd47d03cf2 Enforce Tx unlock_time is Zero by Relay Rule [RELEASE]
Related to https://github.com/monero-project/research-lab/issues/78

Added a relay rule that enforces the `unlock_time` field is equal to 0 for non-coinbase transactions.

UIs changed:
* Removed `locked_transfer` and `locked_sweep_all` commands from `monero-wallet-cli`

APIs changed:
* Removed `unlock_time` parameters from `wallet2` transfer methods
* Wallet RPC transfer endpoints send error codes when requested unlock time is not 0
* Removed `unlock_time` parameters from `construct_tx*` cryptonote core functions

@tobtoht: undo rebase changes tx.dsts -> tx_dsts
2024-04-29 00:08:53 -05:00
selsta 4634b8b539 wallet2: fix stagenet get_approximate_blockchain_height 2024-04-28 21:16:14 +02:00
0xFFFC0000 100a7d06ee Add drop_and_recreate in privatefile class.
When creating a private file we need to delete the file if exist.
2024-04-23 11:52:45 +03:30
tobtoht 71567885e6 build: force Trezor for depends builds 2024-04-15 17:25:52 +02:00
Lee *!* Clagett 7686af7acf Skip privacy networks (on tx sends) that don't have outgoing connections 2024-03-29 15:30:14 -04:00
j-berman 8703b8a4cb wallet2: ensure transfers and sweeps use same fee calc logic rnd2
Looks like the logic from #8882 was accidentally removed in #8861
(regressing to the behavior noted in the #8882 description).
This commit brings that logic back.
2024-03-22 14:09:47 -07:00
0xFFFC0000 d6b35e97be Cleanup string_tools.
1. Use boost::filesystem for already available operations.
2. Use boost::string for already available operations.
2024-03-15 19:19:39 +03:30
65 changed files with 535 additions and 345 deletions
+1 -1
View File
@@ -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
+5 -5
View File
@@ -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>
+7 -10
View File
@@ -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);
+3 -2
View File
@@ -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());
}
+2 -1
View File
@@ -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))
+37 -53
View File
@@ -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)
{
+1 -1
View File
@@ -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
```
+1 -1
View File
@@ -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.
+1
View File
@@ -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;
}
+2 -1
View File
@@ -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
View File
@@ -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
View File
@@ -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
+1 -1
View File
@@ -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)
+6 -6
View File
@@ -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(
+3 -3
View File
@@ -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,
+9
View File
@@ -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?
+9 -2
View File
@@ -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()
+2 -1
View File
@@ -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.
+1
View File
@@ -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) {
+1 -2
View File
@@ -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
View File
@@ -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;
}
//-----------------------------------------------------------------------------------
+2 -1
View File
@@ -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())
+2
View File
@@ -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)
{
+3 -1
View File
@@ -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;
+12
View File
@@ -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();
+1
View File
@@ -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;
+28 -3
View File
@@ -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)
+1 -1
View File
@@ -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);
+12 -129
View File
@@ -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)
+2 -4
View File
@@ -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
View File
@@ -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@
+2 -2
View File
@@ -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
View File
@@ -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);
+7 -7
View File
@@ -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();
+9 -6
View File
@@ -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; }
+29 -5
View File
@@ -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
+2 -2
View File
@@ -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);
+1 -1
View File
@@ -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))
+1 -1
View File
@@ -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))
+6 -6
View File
@@ -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,
+1 -1
View File
@@ -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);
+1 -1
View File
@@ -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);
+2 -2
View File
@@ -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);
+2 -2
View File
@@ -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)
+2 -2
View File
@@ -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)
+1 -1
View File
@@ -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))
+1 -1
View File
@@ -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);
+28 -1
View File
@@ -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)
+1 -1
View File
@@ -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");
+4 -4
View File
@@ -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);
}
+1 -1
View File
@@ -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;
+3 -3
View File
@@ -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;
}
+1 -1
View File
@@ -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]);
+1 -1
View File
@@ -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]);
+15
View File
@@ -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");
+63 -1
View File
@@ -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;
+90
View File
@@ -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 &notifier = *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();
+7 -6
View File
@@ -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"));