aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt9
-rw-r--r--Makefile7
-rw-r--r--README.md4
-rw-r--r--contrib/epee/include/serialization/keyvalue_serialization_overloads.h6
-rw-r--r--contrib/epee/include/storages/parserse_base_utils.h9
-rw-r--r--src/blockchain_db/lmdb/db_lmdb.cpp15
-rw-r--r--src/common/util.cpp1
-rw-r--r--src/crypto/keccak.c74
-rw-r--r--src/crypto/keccak.h14
-rw-r--r--src/cryptonote_core/cryptonote_tx_utils.cpp3
-rw-r--r--src/cryptonote_core/tx_pool.cpp8
-rw-r--r--src/cryptonote_protocol/block_queue.cpp39
-rw-r--r--src/cryptonote_protocol/block_queue.h6
-rw-r--r--src/multisig/multisig.cpp5
-rw-r--r--src/ringct/rctSigs.cpp8
-rw-r--r--src/simplewallet/simplewallet.cpp121
-rw-r--r--src/simplewallet/simplewallet.h2
-rw-r--r--src/wallet/api/wallet.cpp11
-rw-r--r--src/wallet/api/wallet.h1
-rw-r--r--src/wallet/wallet2.cpp114
-rw-r--r--src/wallet/wallet2.h44
-rw-r--r--src/wallet/wallet_rpc_server.cpp67
-rw-r--r--src/wallet/wallet_rpc_server.h3
-rw-r--r--src/wallet/wallet_rpc_server_commands_defs.h23
-rw-r--r--tests/functional_tests/transactions_flow_test.cpp2
-rw-r--r--tests/fuzz/signature.cpp1
-rw-r--r--tests/unit_tests/CMakeLists.txt1
-rw-r--r--tests/unit_tests/keccak.cpp150
-rw-r--r--tests/unit_tests/serialization.cpp2
-rw-r--r--translations/CMakeLists.txt17
-rw-r--r--utils/build_scripts/android32.Dockerfile119
-rw-r--r--utils/build_scripts/android64.Dockerfile95
32 files changed, 635 insertions, 346 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index cab853581..8f2bdc78a 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -436,11 +436,7 @@ add_definition_if_function_found(strptime HAVE_STRPTIME)
add_definitions(-DAUTO_INITIALIZE_EASYLOGGINGPP)
# Generate header for embedded translations
-include(ExternalProject)
-ExternalProject_Add(generate_translations_header
- SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/translations"
- BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/translations"
- INSTALL_COMMAND cmake -E echo "")
+add_subdirectory(translations)
include_directories("${CMAKE_CURRENT_BINARY_DIR}/translations")
add_subdirectory(external)
@@ -814,7 +810,7 @@ endif()
include_directories(SYSTEM ${Boost_INCLUDE_DIRS})
if(MINGW)
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Wa,-mbig-obj")
- set(EXTRA_LIBRARIES mswsock;ws2_32;iphlpapi)
+ set(EXTRA_LIBRARIES mswsock;ws2_32;iphlpapi;crypt32)
set(ICU_LIBRARIES ${Boost_LOCALE_LIBRARY} icuio icuin icuuc icudt icutu iconv)
elseif(APPLE OR OPENBSD OR ANDROID)
set(EXTRA_LIBRARIES "")
@@ -847,6 +843,7 @@ endif()
if(ANDROID)
set(ATOMIC libatomic.a)
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-error=user-defined-warnings")
endif()
if(CMAKE_C_COMPILER_ID STREQUAL "Clang" AND ARCH_WIDTH EQUAL "32" AND NOT IOS AND NOT FREEBSD)
find_library(ATOMIC atomic)
diff --git a/Makefile b/Makefile
index 41e8805d4..9f328434c 100644
--- a/Makefile
+++ b/Makefile
@@ -26,6 +26,8 @@
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
# THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ANDROID_STANDALONE_TOOLCHAIN_PATH ?= /usr/local/toolchain
+
all: release-all
cmake-debug:
@@ -91,8 +93,9 @@ release-static-linux-armv7:
cd build/release && cmake -D BUILD_TESTS=OFF -D ARCH="armv7-a" -D STATIC=ON -D BUILD_64=OFF -D CMAKE_BUILD_TYPE=release -D BUILD_TAG="linux-armv7" ../.. && $(MAKE)
release-static-android:
- mkdir -p build/release
- cd build/release && cmake -D BUILD_TESTS=OFF -D ARCH="armv7-a" -D STATIC=ON -D BUILD_64=OFF -D CMAKE_BUILD_TYPE=release -D ANDROID=true -D INSTALL_VENDORED_LIBUNBOUND=ON -D BUILD_TAG="android" ../.. && $(MAKE)
+ mkdir -p build/release/translations
+ cd build/release/translations && cmake ../../../translations && $(MAKE)
+ cd build/release && CC=arm-linux-androideabi-clang CXX=arm-linux-androideabi-clang++ cmake -D BUILD_TESTS=OFF -D ARCH="armv7-a" -D STATIC=ON -D BUILD_64=OFF -D CMAKE_BUILD_TYPE=release -D ANDROID=true -D INSTALL_VENDORED_LIBUNBOUND=ON -D BUILD_TAG="android" -D CMAKE_SYSTEM_NAME="Android" -D CMAKE_ANDROID_STANDALONE_TOOLCHAIN="${ANDROID_STANDALONE_TOOLCHAIN_PATH}" -D CMAKE_ANDROID_ARM_MODE=ON -D CMAKE_ANDROID_ARCH_ABI="armeabi-v7a" ../.. && $(MAKE)
release-static-linux-armv8:
mkdir -p build/release
diff --git a/README.md b/README.md
index ee7c112e7..637be8ed7 100644
--- a/README.md
+++ b/README.md
@@ -470,8 +470,8 @@ Then you can run make as usual.
### On Linux for Android (using docker):
- # Build image (select android64.Dockerfile for aarch64)
- cd utils/build_scripts/ && docker build -f android32.Dockerfile -t monero-android .
+ # Build image
+ docker build -f utils/build_scripts/android32.Dockerfile -t monero-android .
# Create container
docker create -it --name monero-android monero-android bash
# Get binaries
diff --git a/contrib/epee/include/serialization/keyvalue_serialization_overloads.h b/contrib/epee/include/serialization/keyvalue_serialization_overloads.h
index 09087f785..15c95f07a 100644
--- a/contrib/epee/include/serialization/keyvalue_serialization_overloads.h
+++ b/contrib/epee/include/serialization/keyvalue_serialization_overloads.h
@@ -35,6 +35,11 @@
namespace epee
{
+ namespace
+ {
+ template<class C> void hint_resize(C &container, size_t size) {}
+ template<class C> void hint_resize(std::vector<C> &container, size_t size) { container.reserve(size); }
+ }
namespace serialization
{
@@ -158,6 +163,7 @@ namespace epee
false,
"size in blob " << loaded_size << " not have not zero modulo for sizeof(value_type) = " << sizeof(typename stl_container::value_type) << ", type " << typeid(typename stl_container::value_type).name());
size_t count = (loaded_size/sizeof(typename stl_container::value_type));
+ hint_resize(container, count);
for(size_t i = 0; i < count; i++)
container.insert(container.end(), *(pelem++));
}
diff --git a/contrib/epee/include/storages/parserse_base_utils.h b/contrib/epee/include/storages/parserse_base_utils.h
index c809392f4..8c6c1a64d 100644
--- a/contrib/epee/include/storages/parserse_base_utils.h
+++ b/contrib/epee/include/storages/parserse_base_utils.h
@@ -28,6 +28,8 @@
#pragma once
+#include <algorithm>
+
namespace epee
{
namespace misc_utils
@@ -36,8 +38,12 @@ namespace misc_utils
{
inline std::string transform_to_escape_sequence(const std::string& src)
{
- //std::stringstream res;
+ static const char escaped[] = "\b\f\n\r\t\v\"\\/";
+ if (std::find_first_of(src.begin(), src.end(), escaped, escaped + sizeof(escaped)) == src.end())
+ return src;
+
std::string res;
+ res.reserve(2 * src.size());
for(std::string::const_iterator it = src.begin(); it!=src.end(); ++it)
{
switch(*it)
@@ -84,6 +90,7 @@ namespace misc_utils
inline void match_string2(std::string::const_iterator& star_end_string, std::string::const_iterator buf_end, std::string& val)
{
val.clear();
+ val.reserve(std::distance(star_end_string, buf_end));
bool escape_mode = false;
std::string::const_iterator it = star_end_string;
++it;
diff --git a/src/blockchain_db/lmdb/db_lmdb.cpp b/src/blockchain_db/lmdb/db_lmdb.cpp
index 983a0168a..32ed0e9a2 100644
--- a/src/blockchain_db/lmdb/db_lmdb.cpp
+++ b/src/blockchain_db/lmdb/db_lmdb.cpp
@@ -1971,14 +1971,25 @@ std::vector<uint64_t> BlockchainLMDB::get_block_cumulative_rct_outputs(const std
MDB_val v;
+ uint64_t prev_height = heights[0];
for (uint64_t height: heights)
{
- MDB_val_set(v, height);
- result = mdb_cursor_get(m_cur_block_info, (MDB_val *)&zerokval, &v, MDB_GET_BOTH);
+ if (height == prev_height + 1)
+ {
+ MDB_val k2;
+ result = mdb_cursor_get(m_cur_block_info, &k2, &v, MDB_NEXT);
+ }
+ else
+ {
+ v.mv_size = sizeof(uint64_t);
+ v.mv_data = (void*)&height;
+ result = mdb_cursor_get(m_cur_block_info, (MDB_val *)&zerokval, &v, MDB_GET_BOTH);
+ }
if (result)
throw0(DB_ERROR(lmdb_error("Error attempting to retrieve rct distribution from the db: ", result).c_str()));
const mdb_block_info *bi = (const mdb_block_info *)v.mv_data;
res.push_back(bi->bi_cum_rct);
+ prev_height = height;
}
TXN_POSTFIX_RDONLY();
diff --git a/src/common/util.cpp b/src/common/util.cpp
index 5e0d2726e..25312bdda 100644
--- a/src/common/util.cpp
+++ b/src/common/util.cpp
@@ -38,7 +38,6 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/resource.h>
-#include <ustat.h>
#include <unistd.h>
#include <dirent.h>
#include <string.h>
diff --git a/src/crypto/keccak.c b/src/crypto/keccak.c
index de8e2a5b3..8fcd2138e 100644
--- a/src/crypto/keccak.c
+++ b/src/crypto/keccak.c
@@ -132,3 +132,77 @@ void keccak1600(const uint8_t *in, size_t inlen, uint8_t *md)
{
keccak(in, inlen, md, sizeof(state_t));
}
+
+#define KECCAK_FINALIZED 0x80000000
+#define KECCAK_BLOCKLEN 136
+#define KECCAK_WORDS 17
+#define KECCAK_DIGESTSIZE 32
+#define IS_ALIGNED_64(p) (0 == (7 & ((const char*)(p) - (const char*)0)))
+#define KECCAK_PROCESS_BLOCK(st, block) { \
+ for (int i_ = 0; i_ < KECCAK_WORDS; i_++){ \
+ ((st))[i_] ^= ((block))[i_]; \
+ }; \
+ keccakf(st, KECCAK_ROUNDS); }
+
+
+void keccak_init(KECCAK_CTX * ctx){
+ memset(ctx, 0, sizeof(KECCAK_CTX));
+}
+
+void keccak_update(KECCAK_CTX * ctx, const uint8_t *in, size_t inlen){
+ if (ctx->rest & KECCAK_FINALIZED) {
+ local_abort("Bad keccak use");
+ }
+
+ const size_t idx = ctx->rest;
+ ctx->rest = (ctx->rest + inlen) % KECCAK_BLOCKLEN;
+
+ // fill partial block
+ if (idx) {
+ size_t left = KECCAK_BLOCKLEN - idx;
+ memcpy((char*)ctx->message + idx, in, (inlen < left ? inlen : left));
+ if (inlen < left) return;
+
+ KECCAK_PROCESS_BLOCK(ctx->hash, ctx->message);
+
+ in += left;
+ inlen -= left;
+ }
+
+ const bool is_aligned = IS_ALIGNED_64(in);
+ while (inlen >= KECCAK_BLOCKLEN) {
+ const uint64_t* aligned_message_block;
+ if (is_aligned) {
+ aligned_message_block = (uint64_t*)in;
+ } else {
+ memcpy(ctx->message, in, KECCAK_BLOCKLEN);
+ aligned_message_block = ctx->message;
+ }
+
+ KECCAK_PROCESS_BLOCK(ctx->hash, aligned_message_block);
+ in += KECCAK_BLOCKLEN;
+ inlen -= KECCAK_BLOCKLEN;
+ }
+ if (inlen) {
+ memcpy(ctx->message, in, inlen);
+ }
+}
+
+void keccak_finish(KECCAK_CTX * ctx, uint8_t *md){
+ if (!(ctx->rest & KECCAK_FINALIZED))
+ {
+ // clear the rest of the data queue
+ memset((char*)ctx->message + ctx->rest, 0, KECCAK_BLOCKLEN - ctx->rest);
+ ((char*)ctx->message)[ctx->rest] |= 0x01;
+ ((char*)ctx->message)[KECCAK_BLOCKLEN - 1] |= 0x80;
+
+ // process final block
+ KECCAK_PROCESS_BLOCK(ctx->hash, ctx->message);
+ ctx->rest = KECCAK_FINALIZED; // mark context as finalized
+ }
+
+ static_assert(KECCAK_BLOCKLEN > KECCAK_DIGESTSIZE, "");
+ if (md) {
+ memcpy(md, ctx->hash, KECCAK_DIGESTSIZE);
+ }
+}
diff --git a/src/crypto/keccak.h b/src/crypto/keccak.h
index fb9d8bd04..9123c7a3b 100644
--- a/src/crypto/keccak.h
+++ b/src/crypto/keccak.h
@@ -15,6 +15,17 @@
#define ROTL64(x, y) (((x) << (y)) | ((x) >> (64 - (y))))
#endif
+// SHA3 Algorithm context.
+typedef struct KECCAK_CTX
+{
+ // 1600 bits algorithm hashing state
+ uint64_t hash[25];
+ // 1088-bit buffer for leftovers, block size = 136 B for 256-bit keccak
+ uint64_t message[17];
+ // count of bytes in the message[] buffer
+ size_t rest;
+} KECCAK_CTX;
+
// compute a keccak hash (md) of given byte length from "in"
void keccak(const uint8_t *in, size_t inlen, uint8_t *md, int mdlen);
@@ -23,4 +34,7 @@ void keccakf(uint64_t st[25], int norounds);
void keccak1600(const uint8_t *in, size_t inlen, uint8_t *md);
+void keccak_init(KECCAK_CTX * ctx);
+void keccak_update(KECCAK_CTX * ctx, const uint8_t *in, size_t inlen);
+void keccak_finish(KECCAK_CTX * ctx, uint8_t *md);
#endif
diff --git a/src/cryptonote_core/cryptonote_tx_utils.cpp b/src/cryptonote_core/cryptonote_tx_utils.cpp
index 071ce591e..1581f3088 100644
--- a/src/cryptonote_core/cryptonote_tx_utils.cpp
+++ b/src/cryptonote_core/cryptonote_tx_utils.cpp
@@ -516,6 +516,7 @@ namespace cryptonote
uint64_t amount_in = 0, amount_out = 0;
rct::ctkeyV inSk;
+ inSk.reserve(sources.size());
// mixRing indexing is done the other way round for simple
rct::ctkeyM mixRing(use_simple_rct ? sources.size() : n_total_outs);
rct::keyV destinations;
@@ -532,6 +533,7 @@ namespace cryptonote
ctkey.dest = rct::sk2rct(in_contexts[i].in_ephemeral.sec);
ctkey.mask = sources[i].mask;
inSk.push_back(ctkey);
+ memwipe(&ctkey, sizeof(rct::ctkey));
// inPk: (public key, commitment)
// will be done when filling in mixRing
if (msout)
@@ -590,6 +592,7 @@ namespace cryptonote
tx.rct_signatures = rct::genRctSimple(rct::hash2rct(tx_prefix_hash), inSk, destinations, inamounts, outamounts, amount_in - amount_out, mixRing, amount_keys, msout ? &kLRki : NULL, msout, index, outSk, bulletproof, hwdev);
else
tx.rct_signatures = rct::genRct(rct::hash2rct(tx_prefix_hash), inSk, destinations, outamounts, mixRing, amount_keys, msout ? &kLRki[0] : NULL, msout, sources[0].real_output, outSk, bulletproof, hwdev); // same index assumption
+ memwipe(inSk.data(), inSk.size() * sizeof(rct::ctkey));
CHECK_AND_ASSERT_MES(tx.vout.size() == outSk.size(), false, "outSk size does not match vout");
diff --git a/src/cryptonote_core/tx_pool.cpp b/src/cryptonote_core/tx_pool.cpp
index 5807867d9..41c58fcb6 100644
--- a/src/cryptonote_core/tx_pool.cpp
+++ b/src/cryptonote_core/tx_pool.cpp
@@ -1154,7 +1154,7 @@ namespace cryptonote
LockedTXN lock(m_blockchain);
auto sorted_it = m_txs_by_fee_and_receive_time.begin();
- while (sorted_it != m_txs_by_fee_and_receive_time.end())
+ for (; sorted_it != m_txs_by_fee_and_receive_time.end(); ++sorted_it)
{
txpool_tx_meta_t meta;
if (!m_blockchain.get_txpool_tx_meta(sorted_it->second, meta))
@@ -1168,7 +1168,6 @@ namespace cryptonote
if (max_total_size < total_size + meta.blob_size)
{
LOG_PRINT_L2(" would exceed maximum block size");
- sorted_it++;
continue;
}
@@ -1181,14 +1180,12 @@ namespace cryptonote
if(!get_block_reward(median_size, total_size + meta.blob_size, already_generated_coins, block_reward, version))
{
LOG_PRINT_L2(" would exceed maximum block size");
- sorted_it++;
continue;
}
coinbase = block_reward + fee + meta.fee;
if (coinbase < template_accept_threshold(best_coinbase))
{
LOG_PRINT_L2(" would decrease coinbase to " << print_money(coinbase));
- sorted_it++;
continue;
}
}
@@ -1235,13 +1232,11 @@ namespace cryptonote
if (!ready)
{
LOG_PRINT_L2(" not ready to go");
- sorted_it++;
continue;
}
if (have_key_images(k_images, tx))
{
LOG_PRINT_L2(" key images already seen");
- sorted_it++;
continue;
}
@@ -1250,7 +1245,6 @@ namespace cryptonote
fee += meta.fee;
best_coinbase = coinbase;
append_key_images(k_images, tx);
- sorted_it++;
LOG_PRINT_L2(" added, new block size " << total_size << "/" << max_total_size << ", coinbase " << print_money(best_coinbase));
}
diff --git a/src/cryptonote_protocol/block_queue.cpp b/src/cryptonote_protocol/block_queue.cpp
index c39d67ceb..05f4189fb 100644
--- a/src/cryptonote_protocol/block_queue.cpp
+++ b/src/cryptonote_protocol/block_queue.cpp
@@ -57,7 +57,11 @@ void block_queue::add_blocks(uint64_t height, std::vector<cryptonote::block_comp
bool has_hashes = remove_span(height, &hashes);
blocks.insert(span(height, std::move(bcel), connection_id, rate, size));
if (has_hashes)
+ {
+ for (const crypto::hash &h: hashes)
+ requested_hashes.insert(h);
set_span_hashes(height, connection_id, hashes);
+ }
}
void block_queue::add_blocks(uint64_t height, uint64_t nblocks, const boost::uuids::uuid &connection_id, boost::posix_time::ptime time)
@@ -76,11 +80,19 @@ void block_queue::flush_spans(const boost::uuids::uuid &connection_id, bool all)
block_map::iterator j = i++;
if (j->connection_id == connection_id && (all || j->blocks.size() == 0))
{
- blocks.erase(j);
+ erase_block(j);
}
}
}
+void block_queue::erase_block(block_map::iterator j)
+{
+ CHECK_AND_ASSERT_THROW_MES(j != blocks.end(), "Invalid iterator");
+ for (const crypto::hash &h: j->hashes)
+ requested_hashes.erase(h);
+ blocks.erase(j);
+}
+
void block_queue::flush_stale_spans(const std::set<boost::uuids::uuid> &live_connections)
{
boost::unique_lock<boost::recursive_mutex> lock(mutex);
@@ -92,7 +104,7 @@ void block_queue::flush_stale_spans(const std::set<boost::uuids::uuid> &live_con
block_map::iterator j = i++;
if (live_connections.find(j->connection_id) == live_connections.end() && j->blocks.size() == 0)
{
- blocks.erase(j);
+ erase_block(j);
}
}
}
@@ -106,7 +118,7 @@ bool block_queue::remove_span(uint64_t start_block_height, std::vector<crypto::h
{
if (hashes)
*hashes = std::move(i->hashes);
- blocks.erase(i);
+ erase_block(i);
return true;
}
}
@@ -121,7 +133,7 @@ void block_queue::remove_spans(const boost::uuids::uuid &connection_id, uint64_t
block_map::iterator j = i++;
if (j->connection_id == connection_id && j->start_block_height <= start_block_height)
{
- blocks.erase(j);
+ erase_block(j);
}
}
}
@@ -160,16 +172,15 @@ std::string block_queue::get_overview() const
return s;
}
+inline bool block_queue::requested_internal(const crypto::hash &hash) const
+{
+ return requested_hashes.find(hash) != requested_hashes.end();
+}
+
bool block_queue::requested(const crypto::hash &hash) const
{
boost::unique_lock<boost::recursive_mutex> lock(mutex);
- for (const auto &span: blocks)
- {
- for (const auto &h: span.hashes)
- if (h == hash)
- return true;
- }
- return false;
+ return requested_internal(hash);
}
std::pair<uint64_t, uint64_t> block_queue::reserve_span(uint64_t first_block_height, uint64_t last_block_height, uint64_t max_blocks, const boost::uuids::uuid &connection_id, const std::vector<crypto::hash> &block_hashes, boost::posix_time::ptime time)
@@ -184,7 +195,7 @@ std::pair<uint64_t, uint64_t> block_queue::reserve_span(uint64_t first_block_hei
uint64_t span_start_height = last_block_height - block_hashes.size() + 1;
std::vector<crypto::hash>::const_iterator i = block_hashes.begin();
- while (i != block_hashes.end() && requested(*i))
+ while (i != block_hashes.end() && requested_internal(*i))
{
++i;
++span_start_height;
@@ -256,8 +267,10 @@ void block_queue::set_span_hashes(uint64_t start_height, const boost::uuids::uui
if (i->start_block_height == start_height && i->connection_id == connection_id)
{
span s = *i;
- blocks.erase(i);
+ erase_block(i);
s.hashes = std::move(hashes);
+ for (const crypto::hash &h: s.hashes)
+ requested_hashes.insert(h);
blocks.insert(s);
return;
}
diff --git a/src/cryptonote_protocol/block_queue.h b/src/cryptonote_protocol/block_queue.h
index 9059e89ac..9cce95075 100644
--- a/src/cryptonote_protocol/block_queue.h
+++ b/src/cryptonote_protocol/block_queue.h
@@ -33,6 +33,7 @@
#include <string>
#include <vector>
#include <set>
+#include <unordered_set>
#include <boost/thread/recursive_mutex.hpp>
#include <boost/uuid/uuid.hpp>
@@ -93,7 +94,12 @@ namespace cryptonote
bool requested(const crypto::hash &hash) const;
private:
+ void erase_block(block_map::iterator j);
+ inline bool requested_internal(const crypto::hash &hash) const;
+
+ private:
block_map blocks;
mutable boost::recursive_mutex mutex;
+ std::unordered_set<crypto::hash> requested_hashes;
};
}
diff --git a/src/multisig/multisig.cpp b/src/multisig/multisig.cpp
index d85c47772..a0a788b7d 100644
--- a/src/multisig/multisig.cpp
+++ b/src/multisig/multisig.cpp
@@ -47,9 +47,12 @@ namespace cryptonote
crypto::secret_key get_multisig_blinded_secret_key(const crypto::secret_key &key)
{
rct::keyV data;
+ data.reserve(2);
data.push_back(rct::sk2rct(key));
data.push_back(multisig_salt);
- return rct::rct2sk(rct::hash_to_scalar(data));
+ crypto::secret_key result = rct::rct2sk(rct::hash_to_scalar(data));
+ memwipe(&data[0], sizeof(rct::key));
+ return result;
}
//-----------------------------------------------------------------
void generate_multisig_N_N(const account_keys &keys, const std::vector<crypto::public_key> &spend_keys, std::vector<crypto::secret_key> &multisig_keys, rct::key &spend_skey, rct::key &spend_pkey)
diff --git a/src/ringct/rctSigs.cpp b/src/ringct/rctSigs.cpp
index f74216ed4..cc966c44b 100644
--- a/src/ringct/rctSigs.cpp
+++ b/src/ringct/rctSigs.cpp
@@ -492,7 +492,9 @@ namespace rct {
for (size_t j = 0; j < outPk.size(); j++) {
sc_sub(sk[rows].bytes, sk[rows].bytes, outSk[j].mask.bytes); //subtract output masks in last row..
}
- return MLSAG_Gen(message, M, sk, kLRki, mscout, index, rows, hwdev);
+ mgSig result = MLSAG_Gen(message, M, sk, kLRki, mscout, index, rows, hwdev);
+ memwipe(sk.data(), sk.size() * sizeof(key));
+ return result;
}
@@ -521,7 +523,9 @@ namespace rct {
M[i][0] = pubs[i].dest;
subKeys(M[i][1], pubs[i].mask, Cout);
}
- return MLSAG_Gen(message, M, sk, kLRki, mscout, index, rows, hwdev);
+ mgSig result = MLSAG_Gen(message, M, sk, kLRki, mscout, index, rows, hwdev);
+ memwipe(&sk[0], sizeof(key));
+ return result;
}
diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp
index bdf4212ce..f5aeabded 100644
--- a/src/simplewallet/simplewallet.cpp
+++ b/src/simplewallet/simplewallet.cpp
@@ -129,8 +129,6 @@ namespace
const command_line::arg_descriptor<bool> arg_restore_deterministic_wallet = {"restore-deterministic-wallet", sw::tr("Recover wallet using Electrum-style mnemonic seed"), false};
const command_line::arg_descriptor<bool> arg_restore_multisig_wallet = {"restore-multisig-wallet", sw::tr("Recover multisig wallet using Electrum-style mnemonic seed"), false};
const command_line::arg_descriptor<bool> arg_non_deterministic = {"non-deterministic", sw::tr("Generate non-deterministic view and spend keys"), false};
- const command_line::arg_descriptor<bool> arg_trusted_daemon = {"trusted-daemon", sw::tr("Enable commands which rely on a trusted daemon"), false};
- const command_line::arg_descriptor<bool> arg_untrusted_daemon = {"untrusted-daemon", sw::tr("Disable commands which rely on a trusted daemon"), false};
const command_line::arg_descriptor<bool> arg_allow_mismatched_daemon_version = {"allow-mismatched-daemon-version", sw::tr("Allow communicating with a daemon that uses a different RPC version"), false};
const command_line::arg_descriptor<uint64_t> arg_restore_height = {"restore-height", sw::tr("Restore from specific blockchain height"), 0};
const command_line::arg_descriptor<bool> arg_do_not_relay = {"do-not-relay", sw::tr("The newly created transaction will not be relayed to the monero network"), false};
@@ -581,6 +579,18 @@ bool parse_priority(const std::string& arg, uint32_t& priority)
return false;
}
+std::string join_priority_strings(const char *delimiter)
+{
+ std::string s;
+ for (size_t n = 0; n < allowed_priority_strings.size(); ++n)
+ {
+ if (!s.empty())
+ s += delimiter;
+ s += allowed_priority_strings[n];
+ }
+ return s;
+}
+
std::string simple_wallet::get_commands_str()
{
std::stringstream ss;
@@ -1137,7 +1147,7 @@ bool simple_wallet::import_multisig(const std::vector<std::string> &args)
fail_msg_writer() << tr("Failed to import multisig info: ") << e.what();
return true;
}
- if (is_daemon_trusted())
+ if (m_wallet->is_trusted_daemon())
{
try
{
@@ -1291,7 +1301,7 @@ bool simple_wallet::submit_multisig(const std::vector<std::string> &args)
}
catch (const std::exception &e)
{
- handle_transfer_exception(std::current_exception(), is_daemon_trusted());
+ handle_transfer_exception(std::current_exception(), m_wallet->is_trusted_daemon());
}
catch (...)
{
@@ -1852,12 +1862,12 @@ bool simple_wallet::set_default_ring_size(const std::vector<std::string> &args/*
bool simple_wallet::set_default_priority(const std::vector<std::string> &args/* = std::vector<std::string>()*/)
{
- int priority = 0;
+ uint32_t priority = 0;
try
{
if (strchr(args[1].c_str(), '-'))
{
- fail_msg_writer() << tr("priority must be 0, 1, 2, 3, or 4 ");
+ fail_msg_writer() << tr("priority must be either 0, 1, 2, 3, or 4, or one of: ") << join_priority_strings(", ");
return true;
}
if (args[1] == "0")
@@ -1866,11 +1876,23 @@ bool simple_wallet::set_default_priority(const std::vector<std::string> &args/*
}
else
{
- priority = boost::lexical_cast<int>(args[1]);
- if (priority < 1 || priority > 4)
+ bool found = false;
+ for (size_t n = 0; n < allowed_priority_strings.size(); ++n)
{
- fail_msg_writer() << tr("priority must be 0, 1, 2, 3, or 4");
- return true;
+ if (allowed_priority_strings[n] == args[1])
+ {
+ found = true;
+ priority = n;
+ }
+ }
+ if (!found)
+ {
+ priority = boost::lexical_cast<int>(args[1]);
+ if (priority < 1 || priority > 4)
+ {
+ fail_msg_writer() << tr("priority must be either 0, 1, 2, 3, or 4, or one of: ") << join_priority_strings(", ");
+ return true;
+ }
}
}
@@ -1884,7 +1906,7 @@ bool simple_wallet::set_default_priority(const std::vector<std::string> &args/*
}
catch(const boost::bad_lexical_cast &)
{
- fail_msg_writer() << tr("priority must be 0, 1, 2, 3, or 4");
+ fail_msg_writer() << tr("priority must be either 0, 1, 2, 3, or 4, or one of: ") << join_priority_strings(", ");
return true;
}
catch(...)
@@ -2559,6 +2581,10 @@ bool simple_wallet::set_variable(const std::vector<std::string> &args)
std::string seed_language = m_wallet->get_seed_language();
if (m_use_english_language_names)
seed_language = crypto::ElectrumWords::get_english_name_for(seed_language);
+ std::string priority_string = "invalid";
+ uint32_t priority = m_wallet->get_default_priority();
+ if (priority < allowed_priority_strings.size())
+ priority_string = allowed_priority_strings[priority];
success_msg_writer() << "seed = " << seed_language;
success_msg_writer() << "always-confirm-transfers = " << m_wallet->always_confirm_transfers();
success_msg_writer() << "print-ring-members = " << m_wallet->print_ring_members();
@@ -2566,7 +2592,7 @@ bool simple_wallet::set_variable(const std::vector<std::string> &args)
success_msg_writer() << "default-ring-size = " << (m_wallet->default_mixin() ? m_wallet->default_mixin() + 1 : 0);
success_msg_writer() << "auto-refresh = " << m_wallet->auto_refresh();
success_msg_writer() << "refresh-type = " << get_refresh_type_name(m_wallet->get_refresh_type());
- success_msg_writer() << "priority = " << m_wallet->get_default_priority();
+ success_msg_writer() << "priority = " << priority<< " (" << priority_string << ")";
success_msg_writer() << "confirm-missing-payment-id = " << m_wallet->confirm_missing_payment_id();
success_msg_writer() << "ask-password = " << m_wallet->ask_password();
success_msg_writer() << "unit = " << cryptonote::get_unit(cryptonote::get_default_decimal_point());
@@ -2622,7 +2648,7 @@ bool simple_wallet::set_variable(const std::vector<std::string> &args)
CHECK_SIMPLE_VARIABLE("default-ring-size", set_default_ring_size, tr("integer >= ") << MIN_RING_SIZE);
CHECK_SIMPLE_VARIABLE("auto-refresh", set_auto_refresh, tr("0 or 1"));
CHECK_SIMPLE_VARIABLE("refresh-type", set_refresh_type, tr("full (slowest, no assumptions); optimize-coinbase (fast, assumes the whole coinbase is paid to a single address); no-coinbase (fastest, assumes we receive no coinbase transaction), default (same as optimize-coinbase)"));
- CHECK_SIMPLE_VARIABLE("priority", set_default_priority, tr("0, 1, 2, 3, or 4"));
+ CHECK_SIMPLE_VARIABLE("priority", set_default_priority, tr("0, 1, 2, 3, or 4, or one of ") << join_priority_strings(", "));
CHECK_SIMPLE_VARIABLE("confirm-missing-payment-id", set_confirm_missing_payment_id, tr("0 or 1"));
CHECK_SIMPLE_VARIABLE("ask-password", set_ask_password, tr("0 or 1"));
CHECK_SIMPLE_VARIABLE("unit", set_unit, tr("monero, millinero, micronero, nanonero, piconero"));
@@ -3363,22 +3389,7 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm)
return false;
}
- // set --trusted-daemon if local and not overridden
- if (!m_trusted_daemon)
- {
- try
- {
- m_trusted_daemon = false;
- if (tools::is_local_address(m_wallet->get_daemon_address()))
- {
- MINFO(tr("Daemon is local, assuming trusted"));
- m_trusted_daemon = true;
- }
- }
- catch (const std::exception &e) { }
- }
-
- if (!is_daemon_trusted())
+ if (!m_wallet->is_trusted_daemon())
message_writer() << (boost::format(tr("Warning: using an untrusted daemon at %s, privacy will be lessened")) % m_wallet->get_daemon_address()).str();
if (m_wallet->get_ring_database().empty())
@@ -3412,10 +3423,6 @@ bool simple_wallet::handle_command_line(const boost::program_options::variables_
m_restore_deterministic_wallet = command_line::get_arg(vm, arg_restore_deterministic_wallet);
m_restore_multisig_wallet = command_line::get_arg(vm, arg_restore_multisig_wallet);
m_non_deterministic = command_line::get_arg(vm, arg_non_deterministic);
- if (!command_line::is_arg_defaulted(vm, arg_trusted_daemon) || !command_line::is_arg_defaulted(vm, arg_untrusted_daemon))
- m_trusted_daemon = command_line::get_arg(vm, arg_trusted_daemon) && !command_line::get_arg(vm, arg_untrusted_daemon);
- if (!command_line::is_arg_defaulted(vm, arg_trusted_daemon) && !command_line::is_arg_defaulted(vm, arg_untrusted_daemon))
- message_writer() << tr("--trusted-daemon and --untrusted-daemon are both seen, assuming untrusted");
m_allow_mismatched_daemon_version = command_line::get_arg(vm, arg_allow_mismatched_daemon_version);
m_restore_height = command_line::get_arg(vm, arg_restore_height);
m_do_not_relay = command_line::get_arg(vm, arg_do_not_relay);
@@ -3927,7 +3934,7 @@ bool simple_wallet::save_watch_only(const std::vector<std::string> &args/* = std
//----------------------------------------------------------------------------------------------------
bool simple_wallet::start_mining(const std::vector<std::string>& args)
{
- if (!is_daemon_trusted())
+ if (!m_wallet->is_trusted_daemon())
{
fail_msg_writer() << tr("this command requires a trusted daemon. Enable with --trusted-daemon");
return true;
@@ -4040,29 +4047,29 @@ bool simple_wallet::set_daemon(const std::vector<std::string>& args)
if (args.size() == 2)
{
if (args[1] == "trusted")
- m_trusted_daemon = true;
+ m_wallet->set_trusted_daemon(true);
else if (args[1] == "untrusted")
- m_trusted_daemon = false;
+ m_wallet->set_trusted_daemon(false);
else
{
fail_msg_writer() << tr("Expected trusted or untrusted, got ") << args[1] << ": assuming untrusted";
- m_trusted_daemon = false;
+ m_wallet->set_trusted_daemon(false);
}
}
else
{
- m_trusted_daemon = false;
+ m_wallet->set_trusted_daemon(false);
try
{
if (tools::is_local_address(m_wallet->get_daemon_address()))
{
MINFO(tr("Daemon is local, assuming trusted"));
- m_trusted_daemon = true;
+ m_wallet->set_trusted_daemon(true);
}
}
catch (const std::exception &e) { }
}
- success_msg_writer() << boost::format("Daemon set to %s, %s") % daemon_url % (*m_trusted_daemon ? tr("trusted") : tr("untrusted"));
+ success_msg_writer() << boost::format("Daemon set to %s, %s") % daemon_url % (m_wallet->is_trusted_daemon() ? tr("trusted") : tr("untrusted"));
} else {
fail_msg_writer() << tr("This does not seem to be a valid daemon URL.");
}
@@ -4198,7 +4205,7 @@ bool simple_wallet::refresh_main(uint64_t start_height, bool reset, bool is_init
{
m_in_manual_refresh.store(true, std::memory_order_relaxed);
epee::misc_utils::auto_scope_leave_caller scope_exit_handler = epee::misc_utils::create_scope_leave_handler([&](){m_in_manual_refresh.store(false, std::memory_order_relaxed);});
- m_wallet->refresh(is_daemon_trusted(), start_height, fetched_blocks);
+ m_wallet->refresh(m_wallet->is_trusted_daemon(), start_height, fetched_blocks);
ok = true;
// Clear line "Height xxx of xxx"
std::cout << "\r \r";
@@ -4489,7 +4496,7 @@ bool simple_wallet::show_blockchain_height(const std::vector<std::string>& args)
//----------------------------------------------------------------------------------------------------
bool simple_wallet::rescan_spent(const std::vector<std::string> &args)
{
- if (!is_daemon_trusted())
+ if (!m_wallet->is_trusted_daemon())
{
fail_msg_writer() << tr("this command requires a trusted daemon. Enable with --trusted-daemon");
return true;
@@ -4837,16 +4844,16 @@ bool simple_wallet::transfer_main(int transfer_type, const std::vector<std::stri
return true;
}
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, is_daemon_trusted());
+ ptx_vector = m_wallet->create_transactions_2(dsts, fake_outs_count, unlock_block /* unlock_time */, priority, extra, m_current_subaddress_account, subaddr_indices);
break;
case TransferNew:
- ptx_vector = m_wallet->create_transactions_2(dsts, fake_outs_count, 0 /* unlock_time */, priority, extra, m_current_subaddress_account, subaddr_indices, is_daemon_trusted());
+ ptx_vector = m_wallet->create_transactions_2(dsts, fake_outs_count, 0 /* unlock_time */, priority, extra, m_current_subaddress_account, subaddr_indices);
break;
default:
LOG_ERROR("Unknown transfer method, using original");
/* FALLTHRU */
case TransferOriginal:
- ptx_vector = m_wallet->create_transactions(dsts, fake_outs_count, 0 /* unlock_time */, priority, extra, is_daemon_trusted());
+ ptx_vector = m_wallet->create_transactions(dsts, fake_outs_count, 0 /* unlock_time */, priority, extra);
break;
}
@@ -5022,7 +5029,7 @@ bool simple_wallet::transfer_main(int transfer_type, const std::vector<std::stri
}
catch (const std::exception &e)
{
- handle_transfer_exception(std::current_exception(), is_daemon_trusted());
+ handle_transfer_exception(std::current_exception(), m_wallet->is_trusted_daemon());
}
catch (...)
{
@@ -5064,7 +5071,7 @@ bool simple_wallet::sweep_unmixable(const std::vector<std::string> &args_)
try
{
// figure out what tx will be necessary
- auto ptx_vector = m_wallet->create_unmixable_sweep_transactions(is_daemon_trusted());
+ auto ptx_vector = m_wallet->create_unmixable_sweep_transactions();
if (ptx_vector.empty())
{
@@ -5143,13 +5150,13 @@ bool simple_wallet::sweep_unmixable(const std::vector<std::string> &args_)
{
try
{
- m_wallet->discard_unmixable_outputs(is_daemon_trusted());
+ m_wallet->discard_unmixable_outputs();
} catch (...) {}
}
}
catch (const std::exception &e)
{
- handle_transfer_exception(std::current_exception(), is_daemon_trusted());
+ handle_transfer_exception(std::current_exception(), m_wallet->is_trusted_daemon());
}
catch (...)
{
@@ -5341,7 +5348,7 @@ bool simple_wallet::sweep_main(uint64_t below, bool locked, const std::vector<st
try
{
// figure out what tx will be necessary
- auto ptx_vector = m_wallet->create_transactions_all(below, info.address, info.is_subaddress, fake_outs_count, unlock_block /* unlock_time */, priority, extra, m_current_subaddress_account, subaddr_indices, is_daemon_trusted());
+ auto ptx_vector = m_wallet->create_transactions_all(below, info.address, info.is_subaddress, fake_outs_count, unlock_block /* unlock_time */, priority, extra, m_current_subaddress_account, subaddr_indices);
if (ptx_vector.empty())
{
@@ -5425,7 +5432,7 @@ bool simple_wallet::sweep_main(uint64_t below, bool locked, const std::vector<st
}
catch (const std::exception& e)
{
- handle_transfer_exception(std::current_exception(), is_daemon_trusted());
+ handle_transfer_exception(std::current_exception(), m_wallet->is_trusted_daemon());
}
catch (...)
{
@@ -5554,7 +5561,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, fake_outs_count, 0 /* unlock_time */, priority, extra, is_daemon_trusted());
+ auto ptx_vector = m_wallet->create_transactions_single(ki, info.address, info.is_subaddress, fake_outs_count, 0 /* unlock_time */, priority, extra);
if (ptx_vector.empty())
{
@@ -5624,7 +5631,7 @@ bool simple_wallet::sweep_single(const std::vector<std::string> &args_)
}
catch (const std::exception& e)
{
- handle_transfer_exception(std::current_exception(), is_daemon_trusted());
+ handle_transfer_exception(std::current_exception(), m_wallet->is_trusted_daemon());
}
catch (...)
{
@@ -5930,7 +5937,7 @@ bool simple_wallet::submit_transfer(const std::vector<std::string> &args_)
}
catch (const std::exception& e)
{
- handle_transfer_exception(std::current_exception(), is_daemon_trusted());
+ handle_transfer_exception(std::current_exception(), m_wallet->is_trusted_daemon());
}
catch (...)
{
@@ -6843,7 +6850,7 @@ void simple_wallet::wallet_idle_thread()
{
uint64_t fetched_blocks;
if (try_connect_to_daemon(true))
- m_wallet->refresh(is_daemon_trusted(), 0, fetched_blocks);
+ m_wallet->refresh(m_wallet->is_trusted_daemon(), 0, fetched_blocks);
}
catch(...) {}
m_auto_refresh_refreshing = false;
@@ -7591,7 +7598,7 @@ bool simple_wallet::import_key_images(const std::vector<std::string> &args)
fail_msg_writer() << tr("command not supported by HW wallet");
return true;
}
- if (!is_daemon_trusted())
+ if (!m_wallet->is_trusted_daemon())
{
fail_msg_writer() << tr("this command requires a trusted daemon. Enable with --trusted-daemon");
return true;
@@ -7922,8 +7929,6 @@ int main(int argc, char* argv[])
command_line::add_arg(desc_params, arg_restore_multisig_wallet );
command_line::add_arg(desc_params, arg_non_deterministic );
command_line::add_arg(desc_params, arg_electrum_seed );
- command_line::add_arg(desc_params, arg_trusted_daemon);
- command_line::add_arg(desc_params, arg_untrusted_daemon);
command_line::add_arg(desc_params, arg_allow_mismatched_daemon_version);
command_line::add_arg(desc_params, arg_restore_height);
command_line::add_arg(desc_params, arg_do_not_relay);
diff --git a/src/simplewallet/simplewallet.h b/src/simplewallet/simplewallet.h
index 99fc19c00..bfbe633ac 100644
--- a/src/simplewallet/simplewallet.h
+++ b/src/simplewallet/simplewallet.h
@@ -233,7 +233,6 @@ namespace cryptonote
bool print_ring_members(const std::vector<tools::wallet2::pending_tx>& ptx_vector, std::ostream& ostr);
std::string get_prompt() const;
bool print_seed(bool encrypted);
- bool is_daemon_trusted() const { return *m_trusted_daemon; }
/*!
* \brief Prints the seed with a nice message
@@ -337,7 +336,6 @@ namespace cryptonote
bool m_restore_deterministic_wallet; // recover flag
bool m_restore_multisig_wallet; // recover flag
bool m_non_deterministic; // old 2-random generation
- boost::optional<bool> m_trusted_daemon;
bool m_allow_mismatched_daemon_version;
bool m_restoring; // are we restoring, by whatever method?
uint64_t m_restore_height; // optional
diff --git a/src/wallet/api/wallet.cpp b/src/wallet/api/wallet.cpp
index bfd0e4aff..7b4ad27e4 100644
--- a/src/wallet/api/wallet.cpp
+++ b/src/wallet/api/wallet.cpp
@@ -369,7 +369,6 @@ void Wallet::error(const std::string &category, const std::string &str) {
WalletImpl::WalletImpl(NetworkType nettype, uint64_t kdf_rounds)
:m_wallet(nullptr)
, m_status(Wallet::Status_Ok)
- , m_trustedDaemon(false)
, m_wallet2Callback(nullptr)
, m_recoveringFromSeed(false)
, m_recoveringFromDevice(false)
@@ -1358,7 +1357,7 @@ PendingTransaction *WalletImpl::createTransaction(const string &dst_addr, const
dsts.push_back(de);
transaction->m_pending_tx = m_wallet->create_transactions_2(dsts, fake_outs_count, 0 /* unlock_time */,
adjusted_priority,
- extra, subaddr_account, subaddr_indices, m_trustedDaemon);
+ extra, subaddr_account, subaddr_indices);
} else {
// for the GUI, sweep_all (i.e. amount set as "(all)") will always sweep all the funds in all the addresses
if (subaddr_indices.empty())
@@ -1368,7 +1367,7 @@ PendingTransaction *WalletImpl::createTransaction(const string &dst_addr, const
}
transaction->m_pending_tx = m_wallet->create_transactions_all(0, info.address, info.is_subaddress, fake_outs_count, 0 /* unlock_time */,
adjusted_priority,
- extra, subaddr_account, subaddr_indices, m_trustedDaemon);
+ extra, subaddr_account, subaddr_indices);
}
if (multisig().isMultisig) {
@@ -1454,7 +1453,7 @@ PendingTransaction *WalletImpl::createSweepUnmixableTransaction()
do {
try {
- transaction->m_pending_tx = m_wallet->create_unmixable_sweep_transactions(m_trustedDaemon);
+ transaction->m_pending_tx = m_wallet->create_unmixable_sweep_transactions();
} catch (const tools::error::daemon_busy&) {
// TODO: make it translatable with "tr"?
@@ -1891,12 +1890,12 @@ Wallet::ConnectionStatus WalletImpl::connected() const
void WalletImpl::setTrustedDaemon(bool arg)
{
- m_trustedDaemon = arg;
+ m_wallet->set_trusted_daemon(arg);
}
bool WalletImpl::trustedDaemon() const
{
- return m_trustedDaemon;
+ return m_wallet->is_trusted_daemon();
}
bool WalletImpl::watchOnly() const
diff --git a/src/wallet/api/wallet.h b/src/wallet/api/wallet.h
index 9218d3ad5..0f3b1ce04 100644
--- a/src/wallet/api/wallet.h
+++ b/src/wallet/api/wallet.h
@@ -219,7 +219,6 @@ private:
mutable std::string m_errorString;
std::string m_password;
TransactionHistoryImpl * m_history;
- bool m_trustedDaemon;
Wallet2CallbackImpl * m_wallet2Callback;
AddressBookImpl * m_addressBook;
SubaddressImpl * m_subaddress;
diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp
index 96b77a7a6..a2e36706e 100644
--- a/src/wallet/wallet2.cpp
+++ b/src/wallet/wallet2.cpp
@@ -140,6 +140,8 @@ namespace
struct options {
const command_line::arg_descriptor<std::string> daemon_address = {"daemon-address", tools::wallet2::tr("Use daemon instance at <host>:<port>"), ""};
const command_line::arg_descriptor<std::string> daemon_host = {"daemon-host", tools::wallet2::tr("Use daemon instance at host <arg> instead of localhost"), ""};
+ const command_line::arg_descriptor<bool> trusted_daemon = {"trusted-daemon", tools::wallet2::tr("Enable commands which rely on a trusted daemon"), false};
+ const command_line::arg_descriptor<bool> untrusted_daemon = {"untrusted-daemon", tools::wallet2::tr("Disable commands which rely on a trusted daemon"), false};
const command_line::arg_descriptor<std::string> password = {"password", tools::wallet2::tr("Wallet password (escape/quote as needed)"), "", true};
const command_line::arg_descriptor<std::string> password_file = {"password-file", tools::wallet2::tr("Wallet password file"), "", true};
const command_line::arg_descriptor<int> daemon_port = {"daemon-port", tools::wallet2::tr("Use daemon instance at port <arg> instead of 18081"), 0};
@@ -236,8 +238,29 @@ std::unique_ptr<tools::wallet2> make_basic(const boost::program_options::variabl
if (daemon_address.empty())
daemon_address = std::string("http://") + daemon_host + ":" + std::to_string(daemon_port);
+ boost::optional<bool> trusted_daemon;
+ if (!command_line::is_arg_defaulted(vm, opts.trusted_daemon) || !command_line::is_arg_defaulted(vm, opts.untrusted_daemon))
+ trusted_daemon = command_line::get_arg(vm, opts.trusted_daemon) && !command_line::get_arg(vm, opts.untrusted_daemon);
+ THROW_WALLET_EXCEPTION_IF(!command_line::is_arg_defaulted(vm, opts.trusted_daemon) && !command_line::is_arg_defaulted(vm, opts.untrusted_daemon),
+ tools::error::wallet_internal_error, tools::wallet2::tr("--trusted-daemon and --untrusted-daemon are both seen, assuming untrusted"));
+
+ // set --trusted-daemon if local and not overridden
+ if (!trusted_daemon)
+ {
+ try
+ {
+ trusted_daemon = false;
+ if (tools::is_local_address(daemon_address))
+ {
+ MINFO(tr("Daemon is local, assuming trusted"));
+ trusted_daemon = true;
+ }
+ }
+ catch (const std::exception &e) { }
+ }
+
std::unique_ptr<tools::wallet2> wallet(new tools::wallet2(nettype, kdf_rounds));
- wallet->init(rpc, std::move(daemon_address), std::move(login));
+ wallet->init(rpc, std::move(daemon_address), std::move(login), 0, false, *trusted_daemon);
boost::filesystem::path ringdb_path = command_line::get_arg(vm, opts.shared_ringdb_dir);
wallet->set_ring_database(ringdb_path.string());
return wallet;
@@ -680,6 +703,7 @@ wallet2::wallet2(network_type nettype, uint64_t kdf_rounds):
m_multisig_rescan_k(NULL),
m_run(true),
m_callback(0),
+ m_trusted_daemon(false),
m_nettype(nettype),
m_always_confirm_transfers(true),
m_print_ring_members(false),
@@ -745,6 +769,8 @@ void wallet2::init_options(boost::program_options::options_description& desc_par
const options opts{};
command_line::add_arg(desc_params, opts.daemon_address);
command_line::add_arg(desc_params, opts.daemon_host);
+ command_line::add_arg(desc_params, opts.trusted_daemon);
+ command_line::add_arg(desc_params, opts.untrusted_daemon);
command_line::add_arg(desc_params, opts.password);
command_line::add_arg(desc_params, opts.password_file);
command_line::add_arg(desc_params, opts.daemon_port);
@@ -796,7 +822,7 @@ std::unique_ptr<wallet2> wallet2::make_dummy(const boost::program_options::varia
}
//----------------------------------------------------------------------------------------------------
-bool wallet2::init(bool rpc, std::string daemon_address, boost::optional<epee::net_utils::http::login> daemon_login, uint64_t upper_transaction_size_limit, bool ssl)
+bool wallet2::init(bool rpc, std::string daemon_address, boost::optional<epee::net_utils::http::login> daemon_login, uint64_t upper_transaction_size_limit, bool ssl, bool trusted_daemon)
{
m_rpc = rpc;
m_checkpoints.init_default_checkpoints(m_nettype);
@@ -806,6 +832,7 @@ bool wallet2::init(bool rpc, std::string daemon_address, boost::optional<epee::n
m_upper_transaction_size_limit = upper_transaction_size_limit;
m_daemon_address = std::move(daemon_address);
m_daemon_login = std::move(daemon_login);
+ m_trusted_daemon = trusted_daemon;
// When switching from light wallet to full wallet, we need to reset the height we got from lw node.
return m_http_client.set_server(get_daemon_address(), get_daemon_login(), ssl);
}
@@ -1808,34 +1835,7 @@ void wallet2::pull_blocks(uint64_t start_height, uint64_t &blocks_start_height,
cryptonote::COMMAND_RPC_GET_BLOCKS_FAST::response res = AUTO_VAL_INIT(res);
req.block_ids = short_chain_history;
- uint32_t rpc_version;
- boost::optional<std::string> result = m_node_rpc_proxy.get_rpc_version(rpc_version);
- // no error
- if (!!result)
- {
- // empty string -> not connection
- THROW_WALLET_EXCEPTION_IF(result->empty(), tools::error::no_connection_to_daemon, "getversion");
- THROW_WALLET_EXCEPTION_IF(*result == CORE_RPC_STATUS_BUSY, tools::error::daemon_busy, "getversion");
- if (*result != CORE_RPC_STATUS_OK)
- {
- MDEBUG("Cannot determine daemon RPC version, not asking for pruned blocks");
- req.prune = false; // old daemon
- }
- }
- else
- {
- if (rpc_version >= MAKE_CORE_RPC_VERSION(1, 7))
- {
- MDEBUG("Daemon is recent enough, asking for pruned blocks");
- req.prune = true;
- }
- else
- {
- MDEBUG("Daemon is too old, not asking for pruned blocks");
- req.prune = false;
- }
- }
-
+ req.prune = true;
req.start_height = start_height;
req.no_miner_tx = m_refresh_type == RefreshNoCoinbase;
m_daemon_rpc_mutex.lock();
@@ -2656,6 +2656,7 @@ bool wallet2::get_rct_distribution(uint64_t &start_height, std::vector<uint64_t>
req.amounts.push_back(0);
req.from_height = 0;
req.cumulative = true;
+ req.binary = true;
m_daemon_rpc_mutex.lock();
bool r = net_utils::invoke_http_json_rpc("/json_rpc", "get_output_distribution", req, res, m_http_client, rpc_timeout);
m_daemon_rpc_mutex.unlock();
@@ -3388,6 +3389,7 @@ void wallet2::generate(const std::string& wallet_, const epee::wipeable_string&
for (const auto &msk: multisig_keys)
sc_add(skey.bytes, skey.bytes, rct::sk2rct(msk).bytes);
THROW_WALLET_EXCEPTION_IF(!(rct::rct2sk(skey) == spend_secret_key), error::invalid_multisig_seed);
+ memwipe(&skey, sizeof(rct::key));
m_account.make_multisig(view_secret_key, spend_secret_key, spend_public_key, multisig_keys);
m_account.finalize_multisig(spend_public_key);
@@ -3750,6 +3752,7 @@ std::string wallet2::make_multisig(const epee::wipeable_string &password,
MINFO("Creating multisig address...");
CHECK_AND_ASSERT_THROW_MES(m_account.make_multisig(view_skey, rct::rct2sk(spend_skey), rct::rct2pk(spend_pkey), multisig_keys),
"Failed to create multisig wallet due to bad keys");
+ memwipe(&spend_skey, sizeof(rct::key));
m_account_public_address = m_account.get_keys().m_account_address;
m_watch_only = false;
@@ -4901,7 +4904,7 @@ size_t wallet2::pop_best_value(std::vector<size_t> &unused_indices, const std::v
// returns:
// direct return: amount of money found
// modified reference: selected_transfers, a list of iterators/indices of input sources
-uint64_t wallet2::select_transfers(uint64_t needed_money, std::vector<size_t> unused_transfers_indices, std::vector<size_t>& selected_transfers, bool trusted_daemon) const
+uint64_t wallet2::select_transfers(uint64_t needed_money, std::vector<size_t> unused_transfers_indices, std::vector<size_t>& selected_transfers) const
{
uint64_t found_money = 0;
selected_transfers.reserve(unused_transfers_indices.size());
@@ -4945,17 +4948,17 @@ void wallet2::add_unconfirmed_tx(const cryptonote::transaction& tx, uint64_t amo
//----------------------------------------------------------------------------------------------------
void wallet2::transfer(const std::vector<cryptonote::tx_destination_entry>& dsts, const size_t fake_outs_count, const std::vector<size_t> &unused_transfers_indices,
- uint64_t unlock_time, uint64_t fee, const std::vector<uint8_t>& extra, cryptonote::transaction& tx, pending_tx& ptx, bool trusted_daemon)
+ uint64_t unlock_time, uint64_t fee, const std::vector<uint8_t>& extra, cryptonote::transaction& tx, pending_tx& ptx)
{
- transfer(dsts, fake_outs_count, unused_transfers_indices, unlock_time, fee, extra, detail::digit_split_strategy, tx_dust_policy(::config::DEFAULT_DUST_THRESHOLD), tx, ptx, trusted_daemon);
+ transfer(dsts, fake_outs_count, unused_transfers_indices, unlock_time, fee, extra, detail::digit_split_strategy, tx_dust_policy(::config::DEFAULT_DUST_THRESHOLD), tx, ptx);
}
//----------------------------------------------------------------------------------------------------
void wallet2::transfer(const std::vector<cryptonote::tx_destination_entry>& dsts, const size_t fake_outs_count, const std::vector<size_t> &unused_transfers_indices,
- uint64_t unlock_time, uint64_t fee, const std::vector<uint8_t>& extra, bool trusted_daemon)
+ uint64_t unlock_time, uint64_t fee, const std::vector<uint8_t>& extra)
{
cryptonote::transaction tx;
pending_tx ptx;
- transfer(dsts, fake_outs_count, unused_transfers_indices, unlock_time, fee, extra, tx, ptx, trusted_daemon);
+ transfer(dsts, fake_outs_count, unused_transfers_indices, unlock_time, fee, extra, tx, ptx);
}
namespace {
@@ -5941,9 +5944,9 @@ uint32_t wallet2::adjust_priority(uint32_t priority)
//
// this function will make multiple calls to wallet2::transfer if multiple
// transactions will be required
-std::vector<wallet2::pending_tx> wallet2::create_transactions(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, bool trusted_daemon)
+std::vector<wallet2::pending_tx> wallet2::create_transactions(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)
{
- const std::vector<size_t> unused_transfers_indices = select_available_outputs_from_histogram(fake_outs_count + 1, true, true, true, trusted_daemon);
+ const std::vector<size_t> unused_transfers_indices = select_available_outputs_from_histogram(fake_outs_count + 1, true, true, true);
const uint64_t fee_per_kb = get_per_kb_fee();
const uint64_t fee_multiplier = get_fee_multiplier(priority, get_fee_algorithm());
@@ -5977,7 +5980,7 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions(std::vector<crypto
uint64_t needed_fee = calculate_fee(fee_per_kb, estimated_tx_size, fee_multiplier);
do
{
- transfer(dst_vector, fake_outs_count, unused_transfers_indices, unlock_time, needed_fee, extra, tx, ptx, trusted_daemon);
+ transfer(dst_vector, fake_outs_count, unused_transfers_indices, unlock_time, needed_fee, extra, tx, ptx);
auto txBlob = t_serializable_object_to_blob(ptx.tx);
needed_fee = calculate_fee(fee_per_kb, txBlob, fee_multiplier);
} while (ptx.fee < needed_fee);
@@ -6476,6 +6479,7 @@ void wallet2::get_outs(std::vector<std::vector<tools::wallet2::get_outs_entry>>
req_t.from_height = std::max<uint64_t>(segregation_fork_height, RECENT_OUTPUT_BLOCKS) - RECENT_OUTPUT_BLOCKS;
req_t.to_height = segregation_fork_height + 1;
req_t.cumulative = true;
+ req_t.binary = true;
m_daemon_rpc_mutex.lock();
bool r = net_utils::invoke_http_json_rpc("/json_rpc", "get_output_distribution", req_t, resp_t, m_http_client, rpc_timeout * 1000);
m_daemon_rpc_mutex.unlock();
@@ -7951,7 +7955,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, bool trusted_daemon)
+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)
{
//ensure device is let in NONE mode in any case
hw::device &hwdev = m_account.get_device();
@@ -8476,7 +8480,7 @@ skip_tx:
return ptx_vector;
}
-std::vector<wallet2::pending_tx> wallet2::create_transactions_all(uint64_t below, const cryptonote::account_public_address &address, bool is_subaddress, 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, bool trusted_daemon)
+std::vector<wallet2::pending_tx> wallet2::create_transactions_all(uint64_t below, const cryptonote::account_public_address &address, bool is_subaddress, 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<size_t> unused_transfers_indices;
std::vector<size_t> unused_dust_indices;
@@ -8527,10 +8531,10 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_all(uint64_t below
}
}
- return create_transactions_from(address, is_subaddress, unused_transfers_indices, unused_dust_indices, fake_outs_count, unlock_time, priority, extra, trusted_daemon);
+ return create_transactions_from(address, is_subaddress, unused_transfers_indices, unused_dust_indices, fake_outs_count, unlock_time, 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 fake_outs_count, const uint64_t unlock_time, uint32_t priority, const std::vector<uint8_t>& extra, bool trusted_daemon)
+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 fake_outs_count, const uint64_t unlock_time, uint32_t priority, const std::vector<uint8_t>& extra)
{
std::vector<size_t> unused_transfers_indices;
std::vector<size_t> unused_dust_indices;
@@ -8548,10 +8552,10 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_single(const crypt
break;
}
}
- return create_transactions_from(address, is_subaddress, unused_transfers_indices, unused_dust_indices, fake_outs_count, unlock_time, priority, extra, trusted_daemon);
+ return create_transactions_from(address, is_subaddress, unused_transfers_indices, unused_dust_indices, fake_outs_count, unlock_time, priority, extra);
}
-std::vector<wallet2::pending_tx> wallet2::create_transactions_from(const cryptonote::account_public_address &address, bool is_subaddress, 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, bool trusted_daemon)
+std::vector<wallet2::pending_tx> wallet2::create_transactions_from(const cryptonote::account_public_address &address, bool is_subaddress, 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)
{
//ensure device is let in NONE mode in any case
hw::device &hwdev = m_account.get_device();
@@ -8785,12 +8789,12 @@ std::vector<uint64_t> wallet2::get_unspent_amounts_vector() const
return vector;
}
//----------------------------------------------------------------------------------------------------
-std::vector<size_t> wallet2::select_available_outputs_from_histogram(uint64_t count, bool atleast, bool unlocked, bool allow_rct, bool trusted_daemon)
+std::vector<size_t> wallet2::select_available_outputs_from_histogram(uint64_t count, bool atleast, bool unlocked, bool allow_rct)
{
cryptonote::COMMAND_RPC_GET_OUTPUT_HISTOGRAM::request req_t = AUTO_VAL_INIT(req_t);
cryptonote::COMMAND_RPC_GET_OUTPUT_HISTOGRAM::response resp_t = AUTO_VAL_INIT(resp_t);
m_daemon_rpc_mutex.lock();
- if (trusted_daemon)
+ if (is_trusted_daemon())
req_t.amounts = get_unspent_amounts_vector();
req_t.min_count = count;
req_t.max_count = 0;
@@ -8851,21 +8855,21 @@ const wallet2::transfer_details &wallet2::get_transfer_details(size_t idx) const
return m_transfers[idx];
}
//----------------------------------------------------------------------------------------------------
-std::vector<size_t> wallet2::select_available_unmixable_outputs(bool trusted_daemon)
+std::vector<size_t> wallet2::select_available_unmixable_outputs()
{
// request all outputs with less than 3 instances
const size_t min_mixin = use_fork_rules(7, 10) ? 6 : use_fork_rules(6, 10) ? 4 : 2; // v6 increases min mixin from 2 to 4, v7 to 6
- return select_available_outputs_from_histogram(min_mixin + 1, false, true, false, trusted_daemon);
+ return select_available_outputs_from_histogram(min_mixin + 1, false, true, false);
}
//----------------------------------------------------------------------------------------------------
-std::vector<size_t> wallet2::select_available_mixable_outputs(bool trusted_daemon)
+std::vector<size_t> wallet2::select_available_mixable_outputs()
{
// request all outputs with at least 3 instances, so we can use mixin 2 with
const size_t min_mixin = use_fork_rules(7, 10) ? 6 : use_fork_rules(6, 10) ? 4 : 2; // v6 increases min mixin from 2 to 4, v7 to 6
- return select_available_outputs_from_histogram(min_mixin + 1, true, true, true, trusted_daemon);
+ return select_available_outputs_from_histogram(min_mixin + 1, true, true, true);
}
//----------------------------------------------------------------------------------------------------
-std::vector<wallet2::pending_tx> wallet2::create_unmixable_sweep_transactions(bool trusted_daemon)
+std::vector<wallet2::pending_tx> wallet2::create_unmixable_sweep_transactions()
{
// From hard fork 1, we don't consider small amounts to be dust anymore
const bool hf1_rules = use_fork_rules(2, 10); // first hard fork has version 2
@@ -8874,7 +8878,7 @@ std::vector<wallet2::pending_tx> wallet2::create_unmixable_sweep_transactions(bo
const uint64_t fee_per_kb = get_per_kb_fee();
// may throw
- std::vector<size_t> unmixable_outputs = select_available_unmixable_outputs(trusted_daemon);
+ std::vector<size_t> unmixable_outputs = select_available_unmixable_outputs();
size_t num_dust_outputs = unmixable_outputs.size();
if (num_dust_outputs == 0)
@@ -8892,13 +8896,13 @@ std::vector<wallet2::pending_tx> wallet2::create_unmixable_sweep_transactions(bo
unmixable_transfer_outputs.push_back(n);
}
- return create_transactions_from(m_account_public_address, false, unmixable_transfer_outputs, unmixable_dust_outputs, 0 /*fake_outs_count */, 0 /* unlock_time */, 1 /*priority */, std::vector<uint8_t>(), trusted_daemon);
+ return create_transactions_from(m_account_public_address, false, unmixable_transfer_outputs, unmixable_dust_outputs, 0 /*fake_outs_count */, 0 /* unlock_time */, 1 /*priority */, std::vector<uint8_t>());
}
//----------------------------------------------------------------------------------------------------
-void wallet2::discard_unmixable_outputs(bool trusted_daemon)
+void wallet2::discard_unmixable_outputs()
{
// may throw
- std::vector<size_t> unmixable_outputs = select_available_unmixable_outputs(trusted_daemon);
+ std::vector<size_t> unmixable_outputs = select_available_unmixable_outputs();
for (size_t idx : unmixable_outputs)
{
m_transfers[idx].m_spent = true;
diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h
index 2d45f4e3e..556679f51 100644
--- a/src/wallet/wallet2.h
+++ b/src/wallet/wallet2.h
@@ -637,13 +637,16 @@ namespace tools
// the minimum block size.
bool deinit();
bool init(bool rpc, std::string daemon_address = "http://localhost:8080",
- boost::optional<epee::net_utils::http::login> daemon_login = boost::none, uint64_t upper_transaction_size_limit = 0, bool ssl = false);
+ boost::optional<epee::net_utils::http::login> daemon_login = boost::none, uint64_t upper_transaction_size_limit = 0, bool ssl = false, bool trusted_daemon = false);
void stop() { m_run.store(false, std::memory_order_relaxed); }
i_wallet2_callback* callback() const { return m_callback; }
void callback(i_wallet2_callback* callback) { m_callback = callback; }
+ bool is_trusted_daemon() const { return m_trusted_daemon; }
+ void set_trusted_daemon(bool trusted) { m_trusted_daemon = trusted; }
+
/*!
* \brief Checks if deterministic wallet
*/
@@ -715,11 +718,11 @@ namespace tools
uint64_t balance_all() const;
uint64_t unlocked_balance_all() const;
template<typename T>
- void transfer(const std::vector<cryptonote::tx_destination_entry>& dsts, const size_t fake_outputs_count, const std::vector<size_t> &unused_transfers_indices, uint64_t unlock_time, uint64_t fee, const std::vector<uint8_t>& extra, T destination_split_strategy, const tx_dust_policy& dust_policy, bool trusted_daemon);
+ void transfer(const std::vector<cryptonote::tx_destination_entry>& dsts, const size_t fake_outputs_count, const std::vector<size_t> &unused_transfers_indices, uint64_t unlock_time, uint64_t fee, const std::vector<uint8_t>& extra, T destination_split_strategy, const tx_dust_policy& dust_policy);
template<typename T>
- void transfer(const std::vector<cryptonote::tx_destination_entry>& dsts, const size_t fake_outputs_count, const std::vector<size_t> &unused_transfers_indices, 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, bool trusted_daemon);
- void transfer(const std::vector<cryptonote::tx_destination_entry>& dsts, const size_t fake_outputs_count, const std::vector<size_t> &unused_transfers_indices, uint64_t unlock_time, uint64_t fee, const std::vector<uint8_t>& extra, bool trusted_daemon);
- void transfer(const std::vector<cryptonote::tx_destination_entry>& dsts, const size_t fake_outputs_count, const std::vector<size_t> &unused_transfers_indices, uint64_t unlock_time, uint64_t fee, const std::vector<uint8_t>& extra, cryptonote::transaction& tx, pending_tx& ptx, bool trusted_daemon);
+ void transfer(const std::vector<cryptonote::tx_destination_entry>& dsts, const size_t fake_outputs_count, const std::vector<size_t> &unused_transfers_indices, 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);
+ void transfer(const std::vector<cryptonote::tx_destination_entry>& dsts, const size_t fake_outputs_count, const std::vector<size_t> &unused_transfers_indices, uint64_t unlock_time, uint64_t fee, const std::vector<uint8_t>& extra);
+ void transfer(const std::vector<cryptonote::tx_destination_entry>& dsts, const size_t fake_outputs_count, const std::vector<size_t> &unused_transfers_indices, uint64_t unlock_time, uint64_t fee, const std::vector<uint8_t>& extra, cryptonote::transaction& tx, pending_tx& ptx);
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,
@@ -748,18 +751,18 @@ namespace tools
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<pending_tx> create_transactions(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, bool trusted_daemon);
- 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, bool trusted_daemon); // 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 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, bool trusted_daemon);
- 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 fake_outs_count, const uint64_t unlock_time, uint32_t priority, const std::vector<uint8_t>& extra, bool trusted_daemon);
- std::vector<wallet2::pending_tx> create_transactions_from(const cryptonote::account_public_address &address, bool is_subaddress, 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, bool trusted_daemon);
+ std::vector<pending_tx> create_transactions(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);
+ 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); // 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 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 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, 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);
bool load_multisig_tx(cryptonote::blobdata blob, multisig_tx_set &exported_txs, std::function<bool(const multisig_tx_set&)> accept_func = NULL);
bool load_multisig_tx_from_file(const std::string &filename, multisig_tx_set &exported_txs, std::function<bool(const multisig_tx_set&)> accept_func = NULL);
bool sign_multisig_tx_from_file(const std::string &filename, std::vector<crypto::hash> &txids, std::function<bool(const multisig_tx_set&)> accept_func);
bool sign_multisig_tx(multisig_tx_set &exported_txs, std::vector<crypto::hash> &txids);
bool sign_multisig_tx_to_file(multisig_tx_set &exported_txs, const std::string &filename, std::vector<crypto::hash> &txids);
- std::vector<pending_tx> create_unmixable_sweep_transactions(bool trusted_daemon);
- void discard_unmixable_outputs(bool trusted_daemon);
+ std::vector<pending_tx> create_unmixable_sweep_transactions();
+ void discard_unmixable_outputs();
bool check_connection(uint32_t *version = NULL, uint32_t timeout = 200000);
void get_transfers(wallet2::transfer_container& incoming_transfers) const;
void get_payments(const crypto::hash& payment_id, std::list<wallet2::payment_details>& payments, uint64_t min_height = 0, const boost::optional<uint32_t>& subaddr_account = boost::none, const std::set<uint32_t>& subaddr_indices = {}) const;
@@ -996,10 +999,10 @@ namespace tools
*/
uint64_t get_approximate_blockchain_height() const;
uint64_t estimate_blockchain_height();
- std::vector<size_t> select_available_outputs_from_histogram(uint64_t count, bool atleast, bool unlocked, bool allow_rct, bool trusted_daemon);
+ std::vector<size_t> select_available_outputs_from_histogram(uint64_t count, bool atleast, bool unlocked, bool allow_rct);
std::vector<size_t> select_available_outputs(const std::function<bool(const transfer_details &td)> &f) const;
- std::vector<size_t> select_available_unmixable_outputs(bool trusted_daemon);
- std::vector<size_t> select_available_mixable_outputs(bool trusted_daemon);
+ std::vector<size_t> select_available_unmixable_outputs();
+ std::vector<size_t> select_available_mixable_outputs();
size_t pop_best_value_from(const transfer_container &transfers, std::vector<size_t> &unused_dust_indices, const std::vector<size_t>& selected_transfers, bool smallest = false) const;
size_t pop_best_value(std::vector<size_t> &unused_dust_indices, const std::vector<size_t>& selected_transfers, bool smallest = false) const;
@@ -1195,7 +1198,7 @@ namespace tools
void fast_refresh(uint64_t stop_height, uint64_t &blocks_start_height, std::list<crypto::hash> &short_chain_history, bool force = false);
void pull_and_parse_next_blocks(uint64_t start_height, uint64_t &blocks_start_height, std::list<crypto::hash> &short_chain_history, const std::vector<cryptonote::block_complete_entry> &prev_blocks, const std::vector<parsed_block> &prev_parsed_blocks, std::vector<cryptonote::block_complete_entry> &blocks, std::vector<parsed_block> &parsed_blocks, bool &error);
void process_parsed_blocks(uint64_t start_height, const std::vector<cryptonote::block_complete_entry> &blocks, const std::vector<parsed_block> &parsed_blocks, uint64_t& blocks_added);
- uint64_t select_transfers(uint64_t needed_money, std::vector<size_t> unused_transfers_indices, std::vector<size_t>& selected_transfers, bool trusted_daemon) const;
+ uint64_t select_transfers(uint64_t needed_money, std::vector<size_t> unused_transfers_indices, std::vector<size_t>& selected_transfers) const;
bool prepare_file_names(const std::string& file_path);
void process_unconfirmed(const crypto::hash &txid, const cryptonote::transaction& tx, uint64_t height);
void process_outgoing(const crypto::hash &txid, const cryptonote::transaction& tx, uint64_t height, uint64_t ts, uint64_t spent, uint64_t received, uint32_t subaddr_account, const std::set<uint32_t>& subaddr_indices);
@@ -1274,6 +1277,7 @@ namespace tools
boost::mutex m_daemon_rpc_mutex;
+ bool m_trusted_daemon;
i_wallet2_callback* m_callback;
bool m_key_on_device;
cryptonote::network_type m_nettype;
@@ -1817,16 +1821,16 @@ namespace tools
//----------------------------------------------------------------------------------------------------
template<typename T>
void wallet2::transfer(const std::vector<cryptonote::tx_destination_entry>& dsts, const size_t fake_outs_count, const std::vector<size_t> &unused_transfers_indices,
- uint64_t unlock_time, uint64_t fee, const std::vector<uint8_t>& extra, T destination_split_strategy, const tx_dust_policy& dust_policy, bool trusted_daemon)
+ uint64_t unlock_time, uint64_t fee, const std::vector<uint8_t>& extra, T destination_split_strategy, const tx_dust_policy& dust_policy)
{
pending_tx ptx;
cryptonote::transaction tx;
- transfer(dsts, fake_outs_count, unused_transfers_indices, unlock_time, fee, extra, destination_split_strategy, dust_policy, tx, ptx, trusted_daemon);
+ transfer(dsts, fake_outs_count, unused_transfers_indices, unlock_time, fee, extra, destination_split_strategy, dust_policy, tx, ptx);
}
template<typename T>
void wallet2::transfer(const std::vector<cryptonote::tx_destination_entry>& dsts, const size_t fake_outputs_count, const std::vector<size_t> &unused_transfers_indices,
- 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, bool trusted_daemon)
+ 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)
{
using namespace cryptonote;
// throw if attempting a transaction with no destinations
@@ -1849,7 +1853,7 @@ namespace tools
// randomly select inputs for transaction
// throw if requested send amount is greater than (unlocked) amount available to send
std::vector<size_t> selected_transfers;
- uint64_t found_money = select_transfers(needed_money, unused_transfers_indices, selected_transfers, trusted_daemon);
+ uint64_t found_money = select_transfers(needed_money, unused_transfers_indices, selected_transfers);
THROW_WALLET_EXCEPTION_IF(found_money < needed_money, error::not_enough_unlocked_money, found_money, needed_money - fee, fee);
uint32_t subaddr_account = m_transfers[*selected_transfers.begin()].m_subaddr_index.major;
diff --git a/src/wallet/wallet_rpc_server.cpp b/src/wallet/wallet_rpc_server.cpp
index 2cddea25d..67f26c7a7 100644
--- a/src/wallet/wallet_rpc_server.cpp
+++ b/src/wallet/wallet_rpc_server.cpp
@@ -59,7 +59,6 @@ namespace
{
const command_line::arg_descriptor<std::string, true> arg_rpc_bind_port = {"rpc-bind-port", "Sets bind port for server"};
const command_line::arg_descriptor<bool> arg_disable_rpc_login = {"disable-rpc-login", "Disable HTTP authentication for RPC connections served by this process"};
- const command_line::arg_descriptor<bool> arg_trusted_daemon = {"trusted-daemon", "Enable commands which rely on a trusted daemon", false};
const command_line::arg_descriptor<bool> arg_restricted = {"restricted-rpc", "Restricts to view-only commands", false};
const command_line::arg_descriptor<std::string> arg_wallet_dir = {"wallet-dir", "Directory for newly created wallets"};
const command_line::arg_descriptor<bool> arg_prompt_for_password = {"prompt-for-password", "Prompts for password when not provided", false};
@@ -100,7 +99,7 @@ namespace tools
}
//------------------------------------------------------------------------------------------------------------------------------
- wallet_rpc_server::wallet_rpc_server():m_wallet(NULL), rpc_login_file(), m_stop(false), m_trusted_daemon(false), m_restricted(false), m_vm(NULL)
+ wallet_rpc_server::wallet_rpc_server():m_wallet(NULL), rpc_login_file(), m_stop(false), m_restricted(false), m_vm(NULL)
{
}
//------------------------------------------------------------------------------------------------------------------------------
@@ -120,7 +119,7 @@ namespace tools
m_stop = false;
m_net_server.add_idle_handler([this](){
try {
- if (m_wallet) m_wallet->refresh(m_trusted_daemon);
+ if (m_wallet) m_wallet->refresh(m_wallet->is_trusted_daemon());
} catch (const std::exception& ex) {
LOG_ERROR("Exception at while refreshing, what=" << ex.what());
}
@@ -169,15 +168,6 @@ namespace tools
boost::optional<epee::net_utils::http::login> http_login{};
std::string bind_port = command_line::get_arg(*m_vm, arg_rpc_bind_port);
const bool disable_auth = command_line::get_arg(*m_vm, arg_disable_rpc_login);
- m_trusted_daemon = command_line::get_arg(*m_vm, arg_trusted_daemon);
- if (!command_line::has_arg(*m_vm, arg_trusted_daemon))
- {
- if (tools::is_local_address(walvars->get_daemon_address()))
- {
- MINFO(tr("Daemon is local, assuming trusted"));
- m_trusted_daemon = true;
- }
- }
m_restricted = command_line::get_arg(*m_vm, arg_restricted);
if (command_line::has_arg(*m_vm, arg_wallet_dir))
{
@@ -857,7 +847,7 @@ namespace tools
mixin = m_wallet->adjust_mixin(req.mixin);
}
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, m_trusted_daemon);
+ 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);
if (ptx_vector.empty())
{
@@ -918,7 +908,7 @@ namespace tools
}
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, m_trusted_daemon);
+ 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);
LOG_PRINT_L2("on_transfer_split called create_transactions_2");
return fill_response(ptx_vector, req.get_tx_keys, res.tx_key_list, res.amount_list, res.fee_list, res.multisig_txset, res.unsigned_txset, req.do_not_relay,
@@ -1079,7 +1069,7 @@ namespace tools
try
{
- std::vector<wallet2::pending_tx> ptx_vector = m_wallet->create_unmixable_sweep_transactions(m_trusted_daemon);
+ std::vector<wallet2::pending_tx> ptx_vector = m_wallet->create_unmixable_sweep_transactions();
return fill_response(ptx_vector, req.get_tx_keys, res.tx_key_list, res.amount_list, res.fee_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, er);
@@ -1127,7 +1117,7 @@ namespace tools
mixin = m_wallet->adjust_mixin(req.mixin);
}
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, mixin, req.unlock_time, priority, extra, req.account_index, req.subaddr_indices, m_trusted_daemon);
+ std::vector<wallet2::pending_tx> ptx_vector = m_wallet->create_transactions_all(req.below_amount, dsts[0].addr, dsts[0].is_subaddress, mixin, req.unlock_time, priority, extra, req.account_index, req.subaddr_indices);
return fill_response(ptx_vector, req.get_tx_keys, res.tx_key_list, res.amount_list, res.fee_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, er);
@@ -1183,7 +1173,7 @@ namespace tools
mixin = m_wallet->adjust_mixin(req.mixin);
}
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, mixin, req.unlock_time, priority, extra, m_trusted_daemon);
+ std::vector<wallet2::pending_tx> ptx_vector = m_wallet->create_transactions_single(ki, dsts[0].addr, dsts[0].is_subaddress, mixin, req.unlock_time, priority, extra);
if (ptx_vector.empty())
{
@@ -2304,7 +2294,7 @@ namespace tools
er.message = "Command unavailable in restricted mode.";
return false;
}
- if (!m_trusted_daemon)
+ if (!m_wallet->is_trusted_daemon())
{
er.code = WALLET_RPC_ERROR_CODE_UNKNOWN_ERROR;
er.message = "This command requires a trusted daemon.";
@@ -2518,7 +2508,7 @@ namespace tools
}
try
{
- m_wallet->refresh(m_trusted_daemon, req.start_height, res.blocks_fetched, res.received_money);
+ m_wallet->refresh(m_wallet->is_trusted_daemon(), req.start_height, res.blocks_fetched, res.received_money);
return true;
}
catch (const std::exception& e)
@@ -2554,7 +2544,7 @@ namespace tools
bool wallet_rpc_server::on_start_mining(const wallet_rpc::COMMAND_RPC_START_MINING::request& req, wallet_rpc::COMMAND_RPC_START_MINING::response& res, epee::json_rpc::error& er)
{
if (!m_wallet) return not_open(er);
- if (!m_trusted_daemon)
+ if (!m_wallet->is_trusted_daemon())
{
er.code = WALLET_RPC_ERROR_CODE_UNKNOWN_ERROR;
er.message = "This command requires a trusted daemon.";
@@ -2752,6 +2742,38 @@ namespace tools
return true;
}
//------------------------------------------------------------------------------------------------------------------------------
+ bool wallet_rpc_server::on_change_wallet_password(const wallet_rpc::COMMAND_RPC_CHANGE_WALLET_PASSWORD::request& req, wallet_rpc::COMMAND_RPC_CHANGE_WALLET_PASSWORD::response& res, epee::json_rpc::error& er)
+ {
+ if (!m_wallet) return not_open(er);
+ if (m_restricted)
+ {
+ er.code = WALLET_RPC_ERROR_CODE_DENIED;
+ er.message = "Command unavailable in restricted mode.";
+ return false;
+ }
+ if (m_wallet->verify_password(req.old_password))
+ {
+ try
+ {
+ m_wallet->rewrite(m_wallet->get_wallet_file(), req.new_password);
+ m_wallet->store();
+ LOG_PRINT_L0("Wallet password changed.");
+ }
+ catch (const std::exception& e)
+ {
+ handle_rpc_exception(std::current_exception(), er, WALLET_RPC_ERROR_CODE_UNKNOWN_ERROR);
+ return false;
+ }
+ }
+ else
+ {
+ er.code = WALLET_RPC_ERROR_CODE_INVALID_PASSWORD;
+ er.message = "Invalid original password.";
+ return false;
+ }
+ return true;
+ }
+ //------------------------------------------------------------------------------------------------------------------------------
void wallet_rpc_server::handle_rpc_exception(const std::exception_ptr& e, epee::json_rpc::error& er, int default_error_code) {
try
{
@@ -2993,7 +3015,7 @@ namespace tools
return false;
}
- if (m_trusted_daemon)
+ if (m_wallet->is_trusted_daemon())
{
try
{
@@ -3216,7 +3238,6 @@ int main(int argc, char** argv) {
tools::wallet2::init_options(desc_params);
command_line::add_arg(desc_params, arg_rpc_bind_port);
command_line::add_arg(desc_params, arg_disable_rpc_login);
- command_line::add_arg(desc_params, arg_trusted_daemon);
command_line::add_arg(desc_params, arg_restricted);
cryptonote::rpc_args::init_options(desc_params);
command_line::add_arg(desc_params, arg_wallet_file);
@@ -3309,7 +3330,7 @@ int main(int argc, char** argv) {
wal->stop();
});
- wal->refresh(command_line::get_arg(*vm, arg_trusted_daemon));
+ wal->refresh(wal->is_trusted_daemon());
// if we ^C during potentially length load/refresh, there's no server loop yet
if (quit)
{
diff --git a/src/wallet/wallet_rpc_server.h b/src/wallet/wallet_rpc_server.h
index bfe49a459..7525b9dd0 100644
--- a/src/wallet/wallet_rpc_server.h
+++ b/src/wallet/wallet_rpc_server.h
@@ -133,6 +133,7 @@ namespace tools
MAP_JON_RPC_WE("get_languages", on_get_languages, wallet_rpc::COMMAND_RPC_GET_LANGUAGES)
MAP_JON_RPC_WE("create_wallet", on_create_wallet, wallet_rpc::COMMAND_RPC_CREATE_WALLET)
MAP_JON_RPC_WE("open_wallet", on_open_wallet, wallet_rpc::COMMAND_RPC_OPEN_WALLET)
+ MAP_JON_RPC_WE("change_wallet_password", on_change_wallet_password, wallet_rpc::COMMAND_RPC_CHANGE_WALLET_PASSWORD)
MAP_JON_RPC_WE("is_multisig", on_is_multisig, wallet_rpc::COMMAND_RPC_IS_MULTISIG)
MAP_JON_RPC_WE("prepare_multisig", on_prepare_multisig, wallet_rpc::COMMAND_RPC_PREPARE_MULTISIG)
MAP_JON_RPC_WE("make_multisig", on_make_multisig, wallet_rpc::COMMAND_RPC_MAKE_MULTISIG)
@@ -208,6 +209,7 @@ namespace tools
bool on_get_languages(const wallet_rpc::COMMAND_RPC_GET_LANGUAGES::request& req, wallet_rpc::COMMAND_RPC_GET_LANGUAGES::response& res, epee::json_rpc::error& er);
bool on_create_wallet(const wallet_rpc::COMMAND_RPC_CREATE_WALLET::request& req, wallet_rpc::COMMAND_RPC_CREATE_WALLET::response& res, epee::json_rpc::error& er);
bool on_open_wallet(const wallet_rpc::COMMAND_RPC_OPEN_WALLET::request& req, wallet_rpc::COMMAND_RPC_OPEN_WALLET::response& res, epee::json_rpc::error& er);
+ bool on_change_wallet_password(const wallet_rpc::COMMAND_RPC_CHANGE_WALLET_PASSWORD::request& req, wallet_rpc::COMMAND_RPC_CHANGE_WALLET_PASSWORD::response& res, epee::json_rpc::error& er);
bool on_is_multisig(const wallet_rpc::COMMAND_RPC_IS_MULTISIG::request& req, wallet_rpc::COMMAND_RPC_IS_MULTISIG::response& res, epee::json_rpc::error& er);
bool on_prepare_multisig(const wallet_rpc::COMMAND_RPC_PREPARE_MULTISIG::request& req, wallet_rpc::COMMAND_RPC_PREPARE_MULTISIG::response& res, epee::json_rpc::error& er);
bool on_make_multisig(const wallet_rpc::COMMAND_RPC_MAKE_MULTISIG::request& req, wallet_rpc::COMMAND_RPC_MAKE_MULTISIG::response& res, epee::json_rpc::error& er);
@@ -238,7 +240,6 @@ namespace tools
std::string m_wallet_dir;
tools::private_file rpc_login_file;
std::atomic<bool> m_stop;
- bool m_trusted_daemon;
bool m_restricted;
const boost::program_options::variables_map *m_vm;
};
diff --git a/src/wallet/wallet_rpc_server_commands_defs.h b/src/wallet/wallet_rpc_server_commands_defs.h
index 3f946eaed..62fb98ebb 100644
--- a/src/wallet/wallet_rpc_server_commands_defs.h
+++ b/src/wallet/wallet_rpc_server_commands_defs.h
@@ -47,7 +47,7 @@
// advance which version they will stop working with
// Don't go over 32767 for any of these
#define WALLET_RPC_VERSION_MAJOR 1
-#define WALLET_RPC_VERSION_MINOR 2
+#define WALLET_RPC_VERSION_MINOR 3
#define MAKE_WALLET_RPC_VERSION(major,minor) (((major)<<16)|(minor))
#define WALLET_RPC_VERSION MAKE_WALLET_RPC_VERSION(WALLET_RPC_VERSION_MAJOR, WALLET_RPC_VERSION_MINOR)
namespace tools
@@ -445,7 +445,6 @@ namespace wallet_rpc
{
std::string tx_hash;
std::string tx_key;
- std::list<std::string> amount_keys;
uint64_t amount;
uint64_t fee;
std::string tx_blob;
@@ -456,7 +455,6 @@ namespace wallet_rpc
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(tx_hash)
KV_SERIALIZE(tx_key)
- KV_SERIALIZE(amount_keys)
KV_SERIALIZE(amount)
KV_SERIALIZE(fee)
KV_SERIALIZE(tx_blob)
@@ -1831,6 +1829,25 @@ namespace wallet_rpc
};
};
+ struct COMMAND_RPC_CHANGE_WALLET_PASSWORD
+ {
+ struct request
+ {
+ std::string old_password;
+ std::string new_password;
+
+ BEGIN_KV_SERIALIZE_MAP()
+ KV_SERIALIZE(old_password)
+ KV_SERIALIZE(new_password)
+ END_KV_SERIALIZE_MAP()
+ };
+ struct response
+ {
+ BEGIN_KV_SERIALIZE_MAP()
+ END_KV_SERIALIZE_MAP()
+ };
+ };
+
struct COMMAND_RPC_IS_MULTISIG
{
struct request
diff --git a/tests/functional_tests/transactions_flow_test.cpp b/tests/functional_tests/transactions_flow_test.cpp
index 03bfc0a9b..7248efade 100644
--- a/tests/functional_tests/transactions_flow_test.cpp
+++ b/tests/functional_tests/transactions_flow_test.cpp
@@ -86,7 +86,7 @@ bool do_send_money(tools::wallet2& w1, tools::wallet2& w2, size_t mix_in_factor,
{
tools::wallet2::pending_tx ptx;
std::vector<size_t> indices = w1.select_available_outputs([](const tools::wallet2::transfer_details&) { return true; });
- w1.transfer(dsts, mix_in_factor, indices, 0, TEST_FEE, std::vector<uint8_t>(), tools::detail::null_split_strategy, tools::tx_dust_policy(TEST_DUST_THRESHOLD), tx, ptx, true);
+ w1.transfer(dsts, mix_in_factor, indices, 0, TEST_FEE, std::vector<uint8_t>(), tools::detail::null_split_strategy, tools::tx_dust_policy(TEST_DUST_THRESHOLD), tx, ptx);
w1.commit_tx(ptx);
return true;
}
diff --git a/tests/fuzz/signature.cpp b/tests/fuzz/signature.cpp
index 7f22757b2..6dadf960d 100644
--- a/tests/fuzz/signature.cpp
+++ b/tests/fuzz/signature.cpp
@@ -64,6 +64,7 @@ int SignatureFuzzer::init()
std::cerr << "failed to parse address" << std::endl;
return 1;
}
+ address = info.address;
}
catch (const std::exception &e)
{
diff --git a/tests/unit_tests/CMakeLists.txt b/tests/unit_tests/CMakeLists.txt
index 145e3820e..076a4a873 100644
--- a/tests/unit_tests/CMakeLists.txt
+++ b/tests/unit_tests/CMakeLists.txt
@@ -52,6 +52,7 @@ set(unit_tests_sources
get_xtype_from_string.cpp
hashchain.cpp
http.cpp
+ keccak.cpp
main.cpp
memwipe.cpp
mlocker.cpp
diff --git a/tests/unit_tests/keccak.cpp b/tests/unit_tests/keccak.cpp
new file mode 100644
index 000000000..4276b0e1d
--- /dev/null
+++ b/tests/unit_tests/keccak.cpp
@@ -0,0 +1,150 @@
+// Copyright (c) 2018, The Monero Project
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without modification, are
+// permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice, this list of
+// conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright notice, this list
+// of conditions and the following disclaimer in the documentation and/or other
+// materials provided with the distribution.
+//
+// 3. Neither the name of the copyright holder nor the names of its contributors may be
+// used to endorse or promote products derived from this software without specific
+// prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
+// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
+// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include "gtest/gtest.h"
+
+extern "C" {
+#include "crypto/keccak.h"
+}
+
+#define KECCAK_BLOCKLEN 136
+
+#define TEST_KECCAK(sz, chunks) \
+ std::string data; \
+ data.resize(sz); \
+ for (size_t i = 0; i < sz; ++i) \
+ data[i] = i * 17; \
+ uint8_t md0[32], md1[32]; \
+ keccak((const uint8_t*)data.data(), data.size(), md0, 32); \
+ KECCAK_CTX ctx; \
+ keccak_init(&ctx); \
+ size_t offset = 0; \
+ for (size_t i = 0; i < sizeof(chunks) / sizeof(chunks[0]); ++i) \
+ { \
+ ASSERT_TRUE(offset + chunks[i] <= data.size()); \
+ keccak_update(&ctx, (const uint8_t*)data.data() + offset, chunks[i]); \
+ offset += chunks[i]; \
+ } \
+ ASSERT_TRUE(offset == data.size()); \
+ keccak_finish(&ctx, md1); \
+ ASSERT_EQ(memcmp(md0, md1, 32), 0);
+
+TEST(keccak, )
+{
+}
+
+TEST(keccak, 0_and_0)
+{
+ static const size_t chunks[] = {0};
+ TEST_KECCAK(0, chunks);
+}
+
+TEST(keccak, 1_and_1)
+{
+ static const size_t chunks[] = {1};
+ TEST_KECCAK(1, chunks);
+}
+
+TEST(keccak, 1_and_0_1_0)
+{
+ static const size_t chunks[] = {0, 1, 0};
+ TEST_KECCAK(1, chunks);
+}
+
+TEST(keccak, 2_and_1_1)
+{
+ static const size_t chunks[] = {1, 1};
+ TEST_KECCAK(2, chunks);
+}
+
+TEST(keccak, 4_and_0_0_1_0_2_1_0)
+{
+ static const size_t chunks[] = {0, 0, 1, 0, 2, 1, 0};
+ TEST_KECCAK(4, chunks);
+}
+
+TEST(keccak, 15_and_1_14)
+{
+ static const size_t chunks[] = {1, 14};
+ TEST_KECCAK(15, chunks);
+}
+
+TEST(keccak, 135_and_134_1)
+{
+ static const size_t chunks[] = {134, 1};
+ TEST_KECCAK(135, chunks);
+}
+
+TEST(keccak, 135_and_135_0)
+{
+ static const size_t chunks[] = {135, 0};
+ TEST_KECCAK(135, chunks);
+}
+
+TEST(keccak, 135_and_0_135)
+{
+ static const size_t chunks[] = {0, 135};
+ TEST_KECCAK(135, chunks);
+}
+
+TEST(keccak, 136_and_135_1)
+{
+ static const size_t chunks[] = {135, 1};
+ TEST_KECCAK(136, chunks);
+}
+
+TEST(keccak, 136_and_136_0)
+{
+ static const size_t chunks[] = {136, 0};
+ TEST_KECCAK(136, chunks);
+}
+
+TEST(keccak, 136_and_0_136)
+{
+ static const size_t chunks[] = {0, 136};
+ TEST_KECCAK(136, chunks);
+}
+
+TEST(keccak, 136_and_136)
+{
+ static const size_t chunks[] = {136};
+ TEST_KECCAK(136, chunks);
+}
+
+TEST(keccak, 137_and_136_1)
+{
+ static const size_t chunks[] = {136, 1};
+ TEST_KECCAK(137, chunks);
+}
+
+TEST(keccak, 137_and_1_136)
+{
+ static const size_t chunks[] = {1, 136};
+ TEST_KECCAK(137, chunks);
+}
+
diff --git a/tests/unit_tests/serialization.cpp b/tests/unit_tests/serialization.cpp
index 5bec280b1..2f7b5aac7 100644
--- a/tests/unit_tests/serialization.cpp
+++ b/tests/unit_tests/serialization.cpp
@@ -824,7 +824,7 @@ TEST(Serialization, portability_outputs)
return {};
}
crypto::chacha8(ciphertext.data() + sizeof(iv), ciphertext.size() - prefix_size, key, iv, &plaintext[0]);
- return std::move(plaintext);
+ return plaintext;
};
crypto::secret_key view_secret_key;
epee::string_tools::hex_to_pod("339673bb1187e2f73ba7841ab6841c5553f96e9f13f8fe6612e69318db4e9d0a", view_secret_key);
diff --git a/translations/CMakeLists.txt b/translations/CMakeLists.txt
index db60190b1..fdd5014a7 100644
--- a/translations/CMakeLists.txt
+++ b/translations/CMakeLists.txt
@@ -30,7 +30,17 @@ cmake_minimum_required(VERSION 2.8.7)
project(translations)
-add_executable(generate_translations_header generate_translations_header.c)
+# when crosscompiling import the executable targets from a file
+IF(CMAKE_CROSSCOMPILING)
+ message(WARNING "CrossCompiling")
+ SET(IMPORT_EXECUTABLES "${CMAKE_CURRENT_BINARY_DIR}/ImportExecutables.cmake" CACHE FILEPATH "Point it to the export file from a native build")
+ INCLUDE(${IMPORT_EXECUTABLES})
+ENDIF(CMAKE_CROSSCOMPILING)
+
+# only build the generator if not crosscompiling
+IF(NOT CMAKE_CROSSCOMPILING)
+ add_executable(generate_translations_header generate_translations_header.c)
+ENDIF(NOT CMAKE_CROSSCOMPILING)
find_program(LRELEASE lrelease)
if(LRELEASE STREQUAL "LRELEASE-NOTFOUND")
@@ -61,3 +71,8 @@ add_custom_command(TARGET generate_translations_header
COMMAND generate_translations_header ${qm_files}
WORKING_DIRECTORY "${CMAKE_CURRENT_BIN_DIR}"
COMMENT "Generating embedded translations header")
+
+# export the generator target to a file, so it can be imported (see above) by another build
+IF(NOT CMAKE_CROSSCOMPILING)
+ EXPORT(TARGETS generate_translations_header FILE ${CMAKE_CURRENT_BINARY_DIR}/ImportExecutables.cmake )
+ENDIF(NOT CMAKE_CROSSCOMPILING)
diff --git a/utils/build_scripts/android32.Dockerfile b/utils/build_scripts/android32.Dockerfile
index d0d25aa3d..e56fade50 100644
--- a/utils/build_scripts/android32.Dockerfile
+++ b/utils/build_scripts/android32.Dockerfile
@@ -1,65 +1,93 @@
-FROM debian:jessie
+FROM debian:stable
RUN apt-get update && apt-get install -y unzip automake build-essential curl file pkg-config git python libtool
+ARG NPROC=1
+
WORKDIR /opt/android
## INSTALL ANDROID SDK
-RUN curl -s -O https://dl.google.com/android/android-sdk_r24.4.1-linux.tgz \
- && tar --no-same-owner -xzf android-sdk_r24.4.1-linux.tgz \
- && rm -f android-sdk_r24.4.1-linux.tgz
+ENV ANDROID_SDK_REVISION 4333796
+ENV ANDROID_SDK_HASH 92ffee5a1d98d856634e8b71132e8a95d96c83a63fde1099be3d86df3106def9
+RUN curl -s -O https://dl.google.com/android/repository/sdk-tools-linux-${ANDROID_SDK_REVISION}.zip \
+ && echo "${ANDROID_SDK_HASH} sdk-tools-linux-${ANDROID_SDK_REVISION}.zip" | sha256sum -c \
+ && unzip sdk-tools-linux-${ANDROID_SDK_REVISION}.zip \
+ && rm -f sdk-tools-linux-${ANDROID_SDK_REVISION}.zip
## INSTALL ANDROID NDK
-ENV ANDROID_NDK_REVISION 14
+ENV ANDROID_NDK_REVISION 17b
+ENV ANDROID_NDK_HASH 5dfbbdc2d3ba859fed90d0e978af87c71a91a5be1f6e1c40ba697503d48ccecd
RUN curl -s -O https://dl.google.com/android/repository/android-ndk-r${ANDROID_NDK_REVISION}-linux-x86_64.zip \
+ && echo "${ANDROID_NDK_HASH} android-ndk-r${ANDROID_NDK_REVISION}-linux-x86_64.zip" | sha256sum -c \
&& unzip android-ndk-r${ANDROID_NDK_REVISION}-linux-x86_64.zip \
&& rm -f android-ndk-r${ANDROID_NDK_REVISION}-linux-x86_64.zip
ENV WORKDIR /opt/android
-ENV ANDROID_SDK_ROOT ${WORKDIR}/android-sdk-linux
+ENV ANDROID_SDK_ROOT ${WORKDIR}/tools
ENV ANDROID_NDK_ROOT ${WORKDIR}/android-ndk-r${ANDROID_NDK_REVISION}
-## INSTALL BOOST
-ENV BOOST_VERSION 1_62_0
-ENV BOOST_VERSION_DOT 1.62.0
-RUN curl -s -L -o boost_${BOOST_VERSION}.tar.bz2 https://sourceforge.net/projects/boost/files/boost/${BOOST_VERSION_DOT}/boost_${BOOST_VERSION}.tar.bz2/download \
- && tar -xvf boost_${BOOST_VERSION}.tar.bz2 \
- && rm -f /usr/boost_${BOOST_VERSION}.tar.bz2 \
- && cd boost_${BOOST_VERSION} \
- && ./bootstrap.sh
-
ENV TOOLCHAIN_DIR ${WORKDIR}/toolchain-arm
RUN ${ANDROID_NDK_ROOT}/build/tools/make_standalone_toolchain.py \
--arch arm \
--api 21 \
- --install-dir $TOOLCHAIN_DIR \
+ --install-dir ${TOOLCHAIN_DIR} \
--stl=libc++
-ENV PATH $TOOLCHAIN_DIR/arm-linux-androideabi/bin:$TOOLCHAIN_DIR/bin:$PATH
-## Build BOOST
-RUN cd boost_${BOOST_VERSION} \
- && ./b2 --build-type=minimal link=static runtime-link=static --with-chrono --with-date_time --with-filesystem --with-program_options --with-regex --with-serialization --with-system --with-thread --build-dir=android32 --stagedir=android32 toolset=clang threading=multi threadapi=pthread target-os=android stage
-
-#INSTALL cmake (avoid 3.7 : https://github.com/android-ndk/ndk/issues/254)
-ENV CMAKE_VERSION 3.6.3
+#INSTALL cmake
+ENV CMAKE_VERSION 3.12.1
RUN cd /usr \
- && curl -s -O https://cmake.org/files/v3.6/cmake-${CMAKE_VERSION}-Linux-x86_64.tar.gz \
+ && curl -s -O https://cmake.org/files/v3.12/cmake-${CMAKE_VERSION}-Linux-x86_64.tar.gz \
&& tar -xzf /usr/cmake-${CMAKE_VERSION}-Linux-x86_64.tar.gz \
&& rm -f /usr/cmake-${CMAKE_VERSION}-Linux-x86_64.tar.gz
ENV PATH /usr/cmake-${CMAKE_VERSION}-Linux-x86_64/bin:$PATH
+## Boost
+ARG BOOST_VERSION=1_68_0
+ARG BOOST_VERSION_DOT=1.68.0
+ARG BOOST_HASH=7f6130bc3cf65f56a618888ce9d5ea704fa10b462be126ad053e80e553d6d8b7
+RUN set -ex \
+ && curl -s -L -o boost_${BOOST_VERSION}.tar.bz2 https://dl.bintray.com/boostorg/release/${BOOST_VERSION_DOT}/source/boost_${BOOST_VERSION}.tar.bz2 \
+ && echo "${BOOST_HASH} boost_${BOOST_VERSION}.tar.bz2" | sha256sum -c \
+ && tar -xvf boost_${BOOST_VERSION}.tar.bz2 \
+ && rm -f boost_${BOOST_VERSION}.tar.bz2 \
+ && cd boost_${BOOST_VERSION} \
+ && ./bootstrap.sh
+
+ENV HOST_PATH $PATH
+ENV PATH $TOOLCHAIN_DIR/arm-linux-androideabi/bin:$TOOLCHAIN_DIR/bin:$PATH
+
+# Build iconv for lib boost locale
+ENV ICONV_VERSION 1.15
+ENV ICONV_HASH ccf536620a45458d26ba83887a983b96827001e92a13847b45e4925cc8913178
+RUN curl -s -O http://ftp.gnu.org/pub/gnu/libiconv/libiconv-${ICONV_VERSION}.tar.gz \
+ && echo "${ICONV_HASH} libiconv-${ICONV_VERSION}.tar.gz" | sha256sum -c \
+ && tar -xzf libiconv-${ICONV_VERSION}.tar.gz \
+ && rm -f libiconv-${ICONV_VERSION}.tar.gz \
+ && cd libiconv-${ICONV_VERSION} \
+ && CC=arm-linux-androideabi-clang CXX=arm-linux-androideabi-clang++ ./configure --build=x86_64-linux-gnu --host=arm-eabi --prefix=${WORKDIR}/libiconv --disable-rpath \
+ && make -j${NPROC} && make install
+
+## Build BOOST
+RUN cd boost_${BOOST_VERSION} \
+ && ./b2 --build-type=minimal link=static runtime-link=static --with-chrono --with-date_time --with-filesystem --with-program_options --with-regex --with-serialization --with-system --with-thread --with-locale --build-dir=android32 --stagedir=android32 toolset=clang threading=multi threadapi=pthread target-os=android -sICONV_PATH=${WORKDIR}/libiconv stage -j${NPROC}
+
#Note : we build openssl because the default lacks DSA1
# download, configure and make Zlib
ENV ZLIB_VERSION 1.2.11
+ENV ZLIB_HASH c3e5e9fdd5004dcb542feda5ee4f0ff0744628baf8ed2dd5d66f8ca1197cb1a1
RUN curl -s -O https://zlib.net/zlib-${ZLIB_VERSION}.tar.gz \
+ && echo "${ZLIB_HASH} zlib-${ZLIB_VERSION}.tar.gz" | sha256sum -c \
&& tar -xzf zlib-${ZLIB_VERSION}.tar.gz \
&& rm zlib-${ZLIB_VERSION}.tar.gz \
&& mv zlib-${ZLIB_VERSION} zlib \
&& cd zlib && CC=clang CXX=clang++ ./configure --static \
- && make
+ && make -j${NPROC}
+
# open ssl
-ENV OPENSSL_VERSION 1.0.2j
+ARG OPENSSL_VERSION=1.0.2p
+ARG OPENSSL_HASH=50a98e07b1a89eb8f6a99477f262df71c6fa7bef77df4dc83025a2845c827d00
RUN curl -s -O https://www.openssl.org/source/openssl-${OPENSSL_VERSION}.tar.gz \
+ && echo "${OPENSSL_HASH} openssl-${OPENSSL_VERSION}.tar.gz" | sha256sum -c \
&& tar -xzf openssl-${OPENSSL_VERSION}.tar.gz \
&& rm openssl-${OPENSSL_VERSION}.tar.gz \
&& cd openssl-${OPENSSL_VERSION} \
@@ -69,26 +97,33 @@ RUN curl -s -O https://www.openssl.org/source/openssl-${OPENSSL_VERSION}.tar.gz
no-asm \
no-shared --static \
--with-zlib-include=${WORKDIR}/zlib/include --with-zlib-lib=${WORKDIR}/zlib/lib \
- && make build_crypto build_ssl \
+ && make -j${NPROC} \
&& cd .. && mv openssl-${OPENSSL_VERSION} openssl
# ZMQ
-RUN git clone https://github.com/zeromq/zeromq4-1.git \
- && git clone https://github.com/zeromq/cppzmq.git \
- && cd zeromq4-1 \
+ARG ZMQ_VERSION=v4.2.5
+ARG ZMQ_HASH=d062edd8c142384792955796329baf1e5a3377cd
+RUN git clone https://github.com/zeromq/libzmq.git -b ${ZMQ_VERSION} \
+ && cd libzmq \
+ && test `git rev-parse HEAD` = ${ZMQ_HASH} || exit 1 \
&& ./autogen.sh \
- && CC=clang CXX=clang++ ./configure --host=arm-none-linux-gnueabi \
- && make
+ && CC=clang CXX=clang++ ./configure --prefix=${PWD}/prebuilt --host=arm-linux-androideabi --enable-static --disable-shared \
+ && make -j${NPROC} \
+ && make install
-RUN ln -s /opt/android/openssl/libcrypto.a /opt/android/openssl/libssl.a ${TOOLCHAIN_DIR}/arm-linux-androideabi/lib/armv7-a
+# zmq.hpp
+ARG CPPZMQ_VERSION=v4.2.3
+ARG CPPZMQ_HASH=6aa3ab686e916cb0e62df7fa7d12e0b13ae9fae6
+RUN git clone https://github.com/zeromq/cppzmq.git -b ${CPPZMQ_VERSION} \
+ && cd cppzmq \
+ && test `git rev-parse HEAD` = ${CPPZMQ_HASH} || exit 1
-RUN git clone https://github.com/monero-project/monero.git \
- && cd monero \
- && mkdir -p build/release \
- && CC=clang CXX=clang++ \
- BOOST_ROOT=${WORKDIR}/boost_${BOOST_VERSION} BOOST_LIBRARYDIR=${WORKDIR}/boost_${BOOST_VERSION}/android32/lib/ \
+ADD . /src
+RUN cd /src \
+ && BOOST_ROOT=${WORKDIR}/boost_${BOOST_VERSION} BOOST_LIBRARYDIR=${WORKDIR}/boost_${BOOST_VERSION}/android32/lib/ \
OPENSSL_ROOT_DIR=${WORKDIR}/openssl/ \
- CMAKE_INCLUDE_PATH=${WORKDIR}/cppzmq/ \
- CMAKE_LIBRARY_PATH=${WORKDIR}/zeromq4-1/.libs \
- CXXFLAGS="-I ${WORKDIR}/zeromq4-1/include/" \
- make release-static-android
+ CMAKE_INCLUDE_PATH="${WORKDIR}/cppzmq:${WORKDIR}/libzmq/prebuilt/include" \
+ CMAKE_LIBRARY_PATH=${WORKDIR}/libzmq/prebuilt/lib \
+ ANDROID_STANDALONE_TOOLCHAIN_PATH=${TOOLCHAIN_DIR} \
+ CXXFLAGS="-I ${WORKDIR}/libzmq/prebuilt/include/" \
+ PATH=${HOST_PATH} make release-static-android -j${NPROC}
diff --git a/utils/build_scripts/android64.Dockerfile b/utils/build_scripts/android64.Dockerfile
deleted file mode 100644
index a9504fd2c..000000000
--- a/utils/build_scripts/android64.Dockerfile
+++ /dev/null
@@ -1,95 +0,0 @@
-FROM debian:jessie
-
-RUN apt-get update && apt-get install -y unzip automake build-essential curl file pkg-config git python libtool
-
-WORKDIR /opt/android
-## INSTALL ANDROID SDK
-RUN curl -s -O https://dl.google.com/android/android-sdk_r24.4.1-linux.tgz \
- && tar --no-same-owner -xzf android-sdk_r24.4.1-linux.tgz \
- && rm -f android-sdk_r24.4.1-linux.tgz
-
-## INSTALL ANDROID NDK
-ENV ANDROID_NDK_REVISION 14
-RUN curl -s -O https://dl.google.com/android/repository/android-ndk-r${ANDROID_NDK_REVISION}-linux-x86_64.zip \
- && unzip android-ndk-r${ANDROID_NDK_REVISION}-linux-x86_64.zip \
- && rm -f android-ndk-r${ANDROID_NDK_REVISION}-linux-x86_64.zip
-
-ENV WORKDIR /opt/android
-ENV ANDROID_SDK_ROOT ${WORKDIR}/android-sdk-linux
-ENV ANDROID_NDK_ROOT ${WORKDIR}/android-ndk-r${ANDROID_NDK_REVISION}
-
-## INSTALL BOOST
-ENV BOOST_VERSION 1_62_0
-ENV BOOST_VERSION_DOT 1.62.0
-RUN curl -s -L -o boost_${BOOST_VERSION}.tar.bz2 https://sourceforge.net/projects/boost/files/boost/${BOOST_VERSION_DOT}/boost_${BOOST_VERSION}.tar.bz2/download \
- && tar -xvf boost_${BOOST_VERSION}.tar.bz2 \
- && rm -f /usr/boost_${BOOST_VERSION}.tar.bz2 \
- && cd boost_${BOOST_VERSION} \
- && ./bootstrap.sh
-
-ENV TOOLCHAIN_DIR ${WORKDIR}/toolchain-arm
-RUN ${ANDROID_NDK_ROOT}/build/tools/make_standalone_toolchain.py \
- --arch arm64 \
- --api 21 \
- --install-dir $TOOLCHAIN_DIR \
- --stl=libc++
-ENV PATH $TOOLCHAIN_DIR/aarch64-linux-android/bin:$TOOLCHAIN_DIR/bin:$PATH
-
-## Build BOOST
-RUN cd boost_${BOOST_VERSION} \
- && ./b2 --build-type=minimal link=static runtime-link=static --with-chrono --with-date_time --with-filesystem --with-program_options --with-regex --with-serialization --with-system --with-thread --build-dir=android64 --stagedir=android64 toolset=clang threading=multi threadapi=pthread target-os=android stage
-
-#INSTALL cmake (avoid 3.7 : https://github.com/android-ndk/ndk/issues/254)
-ENV CMAKE_VERSION 3.6.3
-RUN cd /usr \
- && curl -s -O https://cmake.org/files/v3.6/cmake-${CMAKE_VERSION}-Linux-x86_64.tar.gz \
- && tar -xzf /usr/cmake-${CMAKE_VERSION}-Linux-x86_64.tar.gz \
- && rm -f /usr/cmake-${CMAKE_VERSION}-Linux-x86_64.tar.gz
-ENV PATH /usr/cmake-${CMAKE_VERSION}-Linux-x86_64/bin:$PATH
-
-#Note : we build openssl because the default lacks DSA1
-
-# download, configure and make Zlib
-ENV ZLIB_VERSION 1.2.11
-RUN curl -s -O https://zlib.net/zlib-${ZLIB_VERSION}.tar.gz \
- && tar -xzf zlib-${ZLIB_VERSION}.tar.gz \
- && rm zlib-${ZLIB_VERSION}.tar.gz \
- && mv zlib-${ZLIB_VERSION} zlib \
- && cd zlib && CC=clang CXX=clang++ ./configure --static \
- && make
-# open ssl
-ENV OPENSSL_VERSION 1.0.2j
-RUN curl -s -O https://www.openssl.org/source/openssl-${OPENSSL_VERSION}.tar.gz \
- && tar -xzf openssl-${OPENSSL_VERSION}.tar.gz \
- && rm openssl-${OPENSSL_VERSION}.tar.gz \
- && cd openssl-${OPENSSL_VERSION} \
- && sed -i -e "s/mandroid/target\ aarch64\-none\-linux\-android/" Configure \
- && CC=clang CXX=clang++ \
- ./Configure android \
- no-asm \
- no-shared --static \
- --with-zlib-include=${WORKDIR}/zlib/include --with-zlib-lib=${WORKDIR}/zlib/lib \
- && make build_crypto build_ssl \
- && cd .. && mv openssl-${OPENSSL_VERSION} openssl
-
-RUN git clone https://github.com/zeromq/zeromq4-1.git \
- && git clone https://github.com/zeromq/cppzmq.git \
- && cd zeromq4-1 \
- && ./autogen.sh \
- && CC=clang CXX=clang++ ./configure --host=aarch64-linux-android \
- && make
-
-RUN ln -s /opt/android/openssl/libcrypto.a /opt/android/openssl/libssl.a ${TOOLCHAIN_DIR}/aarch64-linux-android/lib
-
-RUN git clone https://github.com/monero-project/monero.git \
- && cd monero \
- && mkdir -p build/release \
- && cd build/release \
- && CC=clang CXX=clang++ \
- BOOST_ROOT=${WORKDIR}/boost_${BOOST_VERSION} BOOST_LIBRARYDIR=${WORKDIR}/boost_${BOOST_VERSION}/android64/lib/ \
- OPENSSL_ROOT_DIR=${WORKDIR}/openssl/ \
- CMAKE_INCLUDE_PATH=${WORKDIR}/cppzmq/ \
- CMAKE_LIBRARY_PATH=${WORKDIR}/zeromq4-1/.libs \
- CXXFLAGS="-I ${WORKDIR}/zeromq4-1/include/" \
- cmake -D BUILD_TESTS=OFF -D ARCH="armv8-a" -D STATIC=ON -D BUILD_64=ON -D CMAKE_BUILD_TYPE=release -D ANDROID=true -D INSTALL_VENDORED_LIBUNBOUND=ON -D BUILD_TAG="android" ../.. \
- && make -j3