Skip to content

Commit

Permalink
Adding "light wallet server" that is mymonero compatible:
Browse files Browse the repository at this point in the history
      - 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 Oct 30, 2019
1 parent 3e3db92 commit d738342
Show file tree
Hide file tree
Showing 66 changed files with 9,647 additions and 166 deletions.
1 change: 1 addition & 0 deletions contrib/epee/include/net/http_protocol_handler.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
};

/************************************************************************/
Expand Down
3 changes: 3 additions & 0 deletions contrib/epee/include/net/http_protocol_handler.inl
Original file line number Diff line number Diff line change
Expand Up @@ -678,6 +678,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
Expand Down
16 changes: 11 additions & 5 deletions contrib/epee/include/net/http_server_impl_base.h
Original file line number Diff line number Diff line change
Expand Up @@ -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",
const std::string& bind_ipv6_address = "::", bool use_ipv6 = false, bool require_ipv4 = true,
Expand Down
1 change: 1 addition & 0 deletions contrib/epee/include/net/net_helper.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
//#include <Ws2tcpip.h>
#include <atomic>
#include <string>
#include <atomic>
#include <boost/version.hpp>
#include <boost/asio/io_service.hpp>
#include <boost/asio/ip/tcp.hpp>
Expand Down
1 change: 1 addition & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ if(NOT IOS)
add_subdirectory(serialization)
endif()
add_subdirectory(wallet)
add_subdirectory(light_wallet_server)
if(NOT IOS)
add_subdirectory(p2p)
endif()
Expand Down
2 changes: 1 addition & 1 deletion src/common/download.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
4 changes: 4 additions & 0 deletions src/common/error.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
6 changes: 4 additions & 2 deletions src/common/error.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
3 changes: 0 additions & 3 deletions src/crypto/crypto.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down
10 changes: 8 additions & 2 deletions src/crypto/crypto.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down Expand Up @@ -303,8 +309,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)
Expand Down
15 changes: 15 additions & 0 deletions src/cryptonote_core/cryptonote_tx_utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,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};
Expand Down
4 changes: 4 additions & 0 deletions src/cryptonote_core/cryptonote_tx_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
{
Expand Down Expand Up @@ -108,6 +111,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);
Expand Down
23 changes: 13 additions & 10 deletions src/device/device_default.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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() { }

Expand Down Expand Up @@ -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;
}

Expand Down
12 changes: 12 additions & 0 deletions src/device/device_default.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();

Expand Down
58 changes: 58 additions & 0 deletions src/light_wallet_server/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -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)
Loading

0 comments on commit d738342

Please sign in to comment.