Skip to content
Permalink
Browse files

Adding "light wallet server" that is mymonero compatible:

      - An epee-based HTTP server that polls in the background for new txes
      - Admin utility for inspecting state, manipulating some account info,
        and approving account creation/imports
      - Optional (off by default) exchange rate retrieval from
        cryptocompare.com
  • Loading branch information...
vtnerd committed Nov 17, 2018
1 parent 8adde33 commit 98fc8a7a25442da6f4cfa2670881a987c1d4cfa2
Showing with 9,644 additions and 165 deletions.
  1. +1 −0 contrib/epee/include/net/http_protocol_handler.h
  2. +3 −0 contrib/epee/include/net/http_protocol_handler.inl
  3. +11 −5 contrib/epee/include/net/http_server_impl_base.h
  4. +1 −0 contrib/epee/include/net/net_helper.h
  5. +1 −0 src/CMakeLists.txt
  6. +1 −1 src/common/download.cpp
  7. +4 −0 src/common/error.cpp
  8. +4 −2 src/common/error.h
  9. +0 −3 src/crypto/crypto.cpp
  10. +8 −2 src/crypto/crypto.h
  11. +15 −0 src/cryptonote_core/cryptonote_tx_utils.cpp
  12. +4 −0 src/cryptonote_core/cryptonote_tx_utils.h
  13. +13 −10 src/device/device_default.cpp
  14. +12 −0 src/device/device_default.hpp
  15. +58 −0 src/light_wallet_server/CMakeLists.txt
  16. +418 −0 src/light_wallet_server/admin_main.cpp
  17. +9 −0 src/light_wallet_server/config.cpp
  18. +11 −0 src/light_wallet_server/config.h
  19. +9 −0 src/light_wallet_server/db/CMakeLists.txt
  20. +180 −0 src/light_wallet_server/db/account.cpp
  21. +114 −0 src/light_wallet_server/db/account.h
  22. +52 −0 src/light_wallet_server/db/data.cpp
  23. +254 −0 src/light_wallet_server/db/data.h
  24. +55 −0 src/light_wallet_server/db/fwd.h
  25. +297 −0 src/light_wallet_server/db/json.cpp
  26. +107 −0 src/light_wallet_server/db/json.h
  27. +1,840 −0 src/light_wallet_server/db/storage.cpp
  28. +240 −0 src/light_wallet_server/db/storage.h
  29. +113 −0 src/light_wallet_server/db/string.cpp
  30. +75 −0 src/light_wallet_server/db/string.h
  31. +127 −0 src/light_wallet_server/error.cpp
  32. +77 −0 src/light_wallet_server/error.h
  33. +9 −0 src/light_wallet_server/fwd.h
  34. +84 −0 src/light_wallet_server/json.cpp
  35. +46 −0 src/light_wallet_server/json.h
  36. +46 −0 src/light_wallet_server/options.h
  37. +312 −0 src/light_wallet_server/random_outputs.cpp
  38. +90 −0 src/light_wallet_server/random_outputs.h
  39. +54 −0 src/light_wallet_server/rates.cpp
  40. +71 −0 src/light_wallet_server/rates.h
  41. +1,232 −0 src/light_wallet_server/rest_server.cpp
  42. +70 −0 src/light_wallet_server/rest_server.h
  43. +380 −0 src/light_wallet_server/rpc.cpp
  44. +218 −0 src/light_wallet_server/rpc.h
  45. +766 −0 src/light_wallet_server/scanner.cpp
  46. +59 −0 src/light_wallet_server/scanner.h
  47. +242 −0 src/light_wallet_server/server_main.cpp
  48. +4 −2 src/rpc/CMakeLists.txt
  49. +2 −0 src/serialization/CMakeLists.txt
  50. +8 −0 src/serialization/new/CMakeLists.txt
  51. +149 −0 src/serialization/new/json_core.cpp
  52. +362 −0 src/serialization/new/json_core.h
  53. +99 −0 src/serialization/new/json_error.cpp
  54. +67 −0 src/serialization/new/json_error.h
  55. +196 −0 src/serialization/new/json_input.h
  56. +178 −0 src/serialization/new/json_output.h
  57. +3 −1 src/wallet/CMakeLists.txt
  58. +33 −0 src/wallet/fwd.h
  59. +112 −0 src/wallet/output_selection.cpp
  60. +88 −0 src/wallet/output_selection.h
  61. +32 −69 src/wallet/wallet2.cpp
  62. +0 −23 src/wallet/wallet2.h
  63. +2 −0 tests/unit_tests/CMakeLists.txt
  64. +8 −2 tests/unit_tests/crypto.cpp
  65. +362 −0 tests/unit_tests/light_wallet_server.cpp
  66. +146 −45 tests/unit_tests/output_selection.cpp
@@ -57,6 +57,7 @@ namespace net_utils
std::vector<std::string> m_access_control_origins;
boost::optional<login> m_user;
critical_section m_lock;
bool m_access_control_credentials;
};

/************************************************************************/
@@ -673,6 +673,9 @@ namespace net_utils
buf += "Access-Control-Allow-Headers: Content-Type, Authorization, X-Requested-With\r\n";
buf += "Access-Control-Allow-Methods: POST, PUT, GET, OPTIONS\r\n";
}

if (m_config.m_access_control_credentials)
buf += "Access-Control-Allow-Credentials: true\r\n";
}

//add additional fields, if it is
@@ -48,13 +48,19 @@ namespace epee
{

public:
http_server_impl_base()
//! allow_credentials => adds HTTP Cors header `Access-Control-Allow-Credentials: true`, use carefully
http_server_impl_base(bool allow_credentials = false)
: m_net_server(epee::net_utils::e_connection_type_RPC)
{}
{
m_net_server.get_config_object().m_access_control_credentials = allow_credentials;
}

explicit http_server_impl_base(boost::asio::io_service& external_io_service)
: m_net_server(external_io_service)
{}
//! allow_credentials => adds HTTP Cors header `Access-Control-Allow-Credentials: true`, use carefully
explicit http_server_impl_base(boost::asio::io_service& external_io_service, bool allow_credentials = false)
: m_net_server(external_io_service, net_utils::e_connection_type_RPC)
{
m_net_server.get_config_object().m_access_control_credentials = allow_credentials;
}

bool init(std::function<void(size_t, uint8_t*)> rng, const std::string& bind_port = "0", const std::string& bind_ip = "0.0.0.0",
std::vector<std::string> access_control_origins = std::vector<std::string>(),
@@ -32,6 +32,7 @@
//#include <Winsock2.h>
//#include <Ws2tcpip.h>
#include <string>
#include <atomic>
#include <boost/version.hpp>
#include <boost/asio/io_service.hpp>
#include <boost/asio/ip/tcp.hpp>
@@ -121,6 +121,7 @@ if(NOT IOS)
add_subdirectory(serialization)
endif()
add_subdirectory(wallet)
add_subdirectory(light_wallet_server)
if(NOT IOS)
add_subdirectory(p2p)
endif()
@@ -101,7 +101,7 @@ namespace tools
{
for (const auto &kv: headers.m_header_info.m_etc_fields)
MDEBUG("Header: " << kv.first << ": " << kv.second);
ssize_t length;
ssize_t length = 0;
if (epee::string_tools::get_xtype_from_string(length, headers.m_header_info.m_content_length) && length >= 0)
{
MINFO("Content-Length: " << length);
@@ -41,6 +41,10 @@ namespace
{
switch (common_error(value))
{
case common_error::configuration:
return "Invalid process configuration";
case common_error::crypto_failure:
return "A cryptographic function failed";
case common_error::kInvalidArgument:
return make_error_code(std::errc::invalid_argument).message();
case common_error::kInvalidErrorCode:
@@ -32,8 +32,10 @@
enum class common_error : int
{
// 0 is reserved for no error, as per expect<T>
kInvalidArgument = 1, //!< A function argument is invalid
kInvalidErrorCode //!< Default `std::error_code` given to `expect<T>`
configuration = 1, //!< Process configuration failure
crypto_failure, //<! A `crypto::` function failed.
kInvalidArgument, //!< A function argument is invalid
kInvalidErrorCode, //!< Default `std::error_code` given to `expect<T>`
};

std::error_category const& common_category() noexcept;
@@ -69,9 +69,6 @@ namespace crypto {
#include "random.h"
}

const crypto::public_key null_pkey = crypto::public_key{};
const crypto::secret_key null_skey = crypto::secret_key{};

static inline unsigned char *operator &(ec_point &point) {
return &reinterpret_cast<unsigned char &>(point);
}
@@ -96,6 +96,12 @@ namespace crypto {
};
#pragma pack(pop)

template<typename T>
struct null_key
{
operator T() const { return T{}; }
};

void hash_to_scalar(const void *data, size_t length, ec_scalar &res);
void random32_unbiased(unsigned char *bytes);

@@ -302,8 +308,8 @@ namespace crypto {
epee::to_hex::formatted(o, epee::as_byte_span(v)); return o;
}

const extern crypto::public_key null_pkey;
const extern crypto::secret_key null_skey;
constexpr const null_key<public_key> null_pkey{};
constexpr const null_key<secret_key> null_skey{};
}

CRYPTO_MAKE_HASHABLE(public_key)
@@ -176,6 +176,21 @@ namespace cryptonote
return true;
}
//---------------------------------------------------------------
boost::optional<std::pair<uint64_t, rct::key>> decode_amount(const rct::key& commitment, const rct::ecdhTuple& info, const crypto::key_derivation& sk, std::size_t index, const bool bulletproof2)
{
crypto::secret_key scalar{};
crypto::derivation_to_scalar(sk, index, scalar);

rct::ecdhTuple copy{info};
rct::ecdhDecode(copy, rct::sk2rct(scalar), bulletproof2);

rct::key Ctmp;
rct::addKeys2(Ctmp, copy.mask, copy.amount, rct::H);
if (rct::equalKeys(commitment, Ctmp))
return {{rct::h2d(copy.amount), copy.mask}};
return boost::none;
}
//---------------------------------------------------------------
crypto::public_key get_destination_view_key_pub(const std::vector<tx_destination_entry> &destinations, const boost::optional<cryptonote::account_public_address>& change_addr)
{
account_public_address addr = {null_pkey, null_pkey};
@@ -29,10 +29,13 @@
// Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers

#pragma once
#include "crypto/hash.h"
#include "cryptonote_basic/cryptonote_format_utils.h"
#include <boost/optional/optional.hpp>
#include <boost/serialization/vector.hpp>
#include <boost/serialization/utility.hpp>
#include "ringct/rctOps.h"
#include "ringct/rctTypes.h"

namespace cryptonote
{
@@ -93,6 +96,7 @@ namespace cryptonote
};

//---------------------------------------------------------------
boost::optional<std::pair<uint64_t, rct::key>> decode_amount(const rct::key &commitment, const rct::ecdhTuple &info, const crypto::key_derivation &sk, size_t index, bool bulletproof2);
crypto::public_key get_destination_view_key_pub(const std::vector<tx_destination_entry> &destinations, const boost::optional<cryptonote::account_public_address>& change_addr);
bool construct_tx(const account_keys& sender_account_keys, std::vector<tx_source_entry> &sources, const std::vector<tx_destination_entry>& destinations, const boost::optional<cryptonote::account_public_address>& change_addr, const std::vector<uint8_t> &extra, transaction& tx, uint64_t unlock_time);
bool construct_tx_with_tx_key(const account_keys& sender_account_keys, const std::unordered_map<crypto::public_key, subaddress_index>& subaddresses, std::vector<tx_source_entry>& sources, std::vector<tx_destination_entry>& destinations, const boost::optional<cryptonote::account_public_address>& change_addr, const std::vector<uint8_t> &extra, transaction& tx, uint64_t unlock_time, const crypto::secret_key &tx_key, const std::vector<crypto::secret_key> &additional_tx_keys, bool rct = false, const rct::RCTConfig &rct_config = { rct::RangeProofBorromean, 0 }, rct::multisig_out *msout = NULL, bool shuffle_outs = true);
@@ -43,6 +43,18 @@
namespace hw {

namespace core {
void device_default::do_encrypt_payment_id(crypto::hash8& out, const crypto::key_derivation& key)
{
crypto::hash hash;
char data[33]; /* A hash, and an extra byte */

memcpy(data, &key, 32);
data[32] = ENCRYPTED_PAYMENT_ID_TAIL;
cn_fast_hash(data, 33, hash);

for (size_t b = 0; b < 8; ++b)
out.data[b] ^= hash.data[b];
}

device_default::device_default() { }

@@ -337,19 +349,10 @@ namespace hw {

bool device_default::encrypt_payment_id(crypto::hash8 &payment_id, const crypto::public_key &public_key, const crypto::secret_key &secret_key) {
crypto::key_derivation derivation;
crypto::hash hash;
char data[33]; /* A hash, and an extra byte */

if (!generate_key_derivation(public_key, secret_key, derivation))
return false;

memcpy(data, &derivation, 32);
data[32] = ENCRYPTED_PAYMENT_ID_TAIL;
cn_fast_hash(data, 33, hash);

for (size_t b = 0; b < 8; ++b)
payment_id.data[b] ^= hash.data[b];

do_encrypt_payment_id(payment_id, derivation);
return true;
}

@@ -39,6 +39,18 @@ namespace hw {

class device_default : public hw::device {
public:
/*! \TODO These 2 functions, and a few others should be elsewhere.
Unfortunately, "cryptonote_core", "ringct", and "wallet"
libraries all depend on the device library creating a cyclic
dependency. None of those libraries should be dependent on
the hardware abstraction, it should only be dependent on them.
*/
static void do_encrypt_payment_id(crypto::hash8& out, crypto::key_derivation const& key);
static void do_decrypt_payment_id(crypto::hash8& out, crypto::key_derivation const& key)
{
do_encrypt_payment_id(out, key);
}

device_default();
~device_default();

@@ -0,0 +1,58 @@

add_subdirectory(db)

# For both the server and admin utility.
set(lws_common_sources config.cpp error.cpp json.cpp)
set(lws_common_headers config.h error.h fwd.h json.h)

monero_add_library(light_wallet_server-common ${lws_common_sources} ${lws_common_headers})
target_link_libraries(light_wallet_server-common common serialization-new)

# Only used by server (not admin). For utilities that are unit tested
set(lws_lib_sources random_outputs.cpp)
set(lws_lib_headers random_outputs.h)

monero_add_library(light_wallet_server-lib ${lws_lib_sources} ${lws_lib_headers})
target_link_libraries(light_wallet_server-lib light_wallet_server-common wallet)

monero_add_executable(light_wallet_server server_main.cpp rates.cpp rest_server.cpp rpc.cpp scanner.cpp)
target_include_directories(light_wallet_server PUBLIC ${ZMQ_INCLUDE_PATH})
target_link_libraries(light_wallet_server
PRIVATE
cryptonote_core
cncrypto
common
daemon_messages
device
epee
light_wallet_server-common
light_wallet_server-db
light_wallet_server-lib
lmdb_lib
daemon_messages
${Boost_CHRONO_LIBRARY}
${Boost_FILESYSTEM_LIBRARY}
${Boost_PROGRAM_OPTIONS_LIBRARY}
${Boost_THREAD_LIBRARY}
${CMAKE_THREAD_LIBS_INIT}
${EXTRA_LIBRARIES}
${ZMQ_LIB}
)
set_property(TARGET light_wallet_server PROPERTY OUTPUT_NAME "monero-light-wallet-server")

monero_add_executable(light_wallet_server_admin admin_main.cpp)
target_link_libraries(light_wallet_server_admin
PRIVATE
cryptonote_core
cncrypto
common
light_wallet_server-common
light_wallet_server-db
serialization-new
${Boost_PROGRAM_OPTIONS_LIBRARY}
${EXTRA_LIBRARIES}
)
set_property(TARGET light_wallet_server_admin PROPERTY OUTPUT_NAME "monero-light-wallet-server-admin")

install(TARGETS light_wallet_server DESTINATION bin)
install(TARGETS light_wallet_server_admin DESTINATION bin)

0 comments on commit 98fc8a7

Please sign in to comment.
You can’t perform that action at this time.