aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/build.yml2
-rw-r--r--Makefile24
-rw-r--r--README.md44
-rw-r--r--contrib/epee/demo/.gitignore1
-rw-r--r--contrib/epee/demo/CMakeLists.txt49
-rw-r--r--contrib/epee/demo/README.txt0
-rw-r--r--contrib/epee/demo/demo_http_server/stdafx.cpp8
-rw-r--r--contrib/epee/demo/demo_http_server/stdafx.h40
-rw-r--r--contrib/epee/demo/demo_http_server/targetver.h13
-rw-r--r--contrib/epee/demo/demo_levin_server/stdafx.cpp30
-rw-r--r--contrib/epee/demo/demo_levin_server/stdafx.h41
-rw-r--r--contrib/epee/demo/demo_levin_server/targetver.h13
-rw-r--r--contrib/epee/demo/generate_gcc.sh4
-rw-r--r--contrib/epee/demo/generate_vc_proj.bat7
-rw-r--r--contrib/epee/demo/iface/transport_defs.h225
-rw-r--r--contrib/epee/include/ado_db_helper.h1095
-rw-r--r--contrib/epee/include/copyable_atomic.h56
-rw-r--r--contrib/epee/include/file_io_utils.h3
-rw-r--r--contrib/epee/include/global_stream_operators.h35
-rw-r--r--contrib/epee/include/math_helper.h2
-rw-r--r--contrib/epee/include/misc_language.h62
-rw-r--r--contrib/epee/include/misc_os_dependent.h129
-rw-r--r--contrib/epee/include/net/abstract_tcp_server.h318
-rw-r--r--contrib/epee/include/net/abstract_tcp_server2.inl10
-rw-r--r--contrib/epee/include/net/abstract_tcp_server_cp.h236
-rw-r--r--contrib/epee/include/net/abstract_tcp_server_cp.inl607
-rw-r--r--contrib/epee/include/net/http_client.h1
-rw-r--r--contrib/epee/include/net/http_client_via_api_helper.h180
-rw-r--r--contrib/epee/include/net/http_protocol_handler.h1
-rw-r--r--contrib/epee/include/net/http_protocol_handler.inl2
-rw-r--r--contrib/epee/include/net/http_server_cp.h52
-rw-r--r--contrib/epee/include/net/http_server_cp2.h51
-rw-r--r--contrib/epee/include/net/http_server_thread_per_connect.h48
-rw-r--r--contrib/epee/include/net/jsonrpc_protocol_handler.h167
-rw-r--r--contrib/epee/include/net/jsonrpc_server_handlers_map.h86
-rw-r--r--contrib/epee/include/net/jsonrpc_server_impl_base.h84
-rw-r--r--contrib/epee/include/net/levin_client.h89
-rw-r--r--contrib/epee/include/net/levin_client.inl199
-rw-r--r--contrib/epee/include/net/levin_client_async.h585
-rw-r--r--contrib/epee/include/net/levin_client_async.inl0
-rw-r--r--contrib/epee/include/net/levin_helper.h161
-rw-r--r--contrib/epee/include/net/levin_protocol_handler_async.h2
-rw-r--r--contrib/epee/include/net/levin_server_cp.h47
-rw-r--r--contrib/epee/include/net/levin_server_cp2.h49
-rw-r--r--contrib/epee/include/net/local_ip.h9
-rw-r--r--contrib/epee/include/net/multiprotocols_server.h47
-rw-r--r--contrib/epee/include/net/munin_connection_handler.h376
-rw-r--r--contrib/epee/include/net/munin_node_server.h49
-rw-r--r--contrib/epee/include/net/net_fwd.h38
-rw-r--r--contrib/epee/include/net/network_throttle.hpp1
-rw-r--r--contrib/epee/include/net/protocol_switcher.h121
-rw-r--r--contrib/epee/include/net/rpc_method_name.h31
-rw-r--r--contrib/epee/include/net/smtp.h181
-rw-r--r--contrib/epee/include/net/smtp.inl1569
-rw-r--r--contrib/epee/include/net/smtp_helper.h88
-rw-r--r--contrib/epee/include/pragma_comp_defs.h14
-rw-r--r--contrib/epee/include/profile_tools.h2
-rw-r--r--contrib/epee/include/reg_utils.h249
-rw-r--r--contrib/epee/include/rolling_median.h15
-rw-r--r--contrib/epee/include/serialization/serialize_base.h2
-rw-r--r--contrib/epee/include/service_impl_base.h323
-rw-r--r--contrib/epee/include/sha1.h51
-rw-r--r--contrib/epee/include/sha1.inl179
-rw-r--r--contrib/epee/include/soci_helper.h142
-rw-r--r--contrib/epee/include/static_initializer.h82
-rw-r--r--contrib/epee/include/storages/crypted_storage.h62
-rw-r--r--contrib/epee/include/storages/gzipped_inmemstorage.h68
-rw-r--r--contrib/epee/include/storages/levin_abstract_invoke2.h48
-rw-r--r--contrib/epee/include/storages/portable_storage_to_bin.h14
-rw-r--r--contrib/epee/include/time_helper.h130
-rw-r--r--contrib/epee/include/tiny_ini.h61
-rw-r--r--contrib/epee/include/to_nonconst_iterator.h52
-rw-r--r--contrib/epee/include/winobj.h227
-rw-r--r--contrib/epee/include/zlib_helper.h139
-rw-r--r--contrib/epee/src/CMakeLists.txt2
-rw-r--r--contrib/epee/src/connection_basic.cpp1
-rw-r--r--contrib/epee/src/file_io_utils.cpp43
-rw-r--r--contrib/epee/src/misc_os_dependent.cpp44
-rw-r--r--contrib/epee/src/mlog.cpp2
-rw-r--r--contrib/epee/src/network_throttle-detail.cpp1
-rw-r--r--contrib/epee/src/tiny_ini.cpp46
-rw-r--r--contrib/epee/tests/.gitignore1
-rw-r--r--contrib/epee/tests/data/storages/invalid_storage_1.binbin109578 -> 0 bytes
-rw-r--r--contrib/epee/tests/data/storages/invalid_storage_2.binbin20 -> 0 bytes
-rw-r--r--contrib/epee/tests/data/storages/invalid_storage_3.bin1
-rw-r--r--contrib/epee/tests/data/storages/invalid_storage_4.binbin19 -> 0 bytes
-rw-r--r--contrib/epee/tests/data/storages/valid_storage.binbin180346 -> 0 bytes
-rw-r--r--contrib/epee/tests/generate_vc_proj.bat5
-rw-r--r--contrib/epee/tests/src/CMakeLists.txt40
-rw-r--r--contrib/epee/tests/src/misc/test_math.h82
-rw-r--r--contrib/epee/tests/src/net/test_net.h408
-rw-r--r--contrib/epee/tests/src/storages/portable_storages_test.h232
-rw-r--r--contrib/epee/tests/src/storages/storage_tests.h142
-rw-r--r--contrib/epee/tests/src/tests.cpp59
m---------external/randomx0
-rw-r--r--src/blockchain_db/CMakeLists.txt5
-rw-r--r--src/blockchain_db/lmdb/db_lmdb.cpp7
-rw-r--r--src/checkpoints/CMakeLists.txt3
-rw-r--r--src/common/CMakeLists.txt31
-rw-r--r--src/common/perf_timer.cpp2
-rw-r--r--src/common/util.cpp2
-rw-r--r--src/crypto/CMakeLists.txt22
-rw-r--r--src/crypto/crypto.cpp24
-rw-r--r--src/crypto/crypto.h20
-rw-r--r--src/cryptonote_basic/CMakeLists.txt15
-rw-r--r--src/cryptonote_basic/connection_context.h39
-rw-r--r--src/cryptonote_basic/cryptonote_basic.h19
-rw-r--r--src/cryptonote_basic/cryptonote_boost_serialization.h13
-rw-r--r--src/cryptonote_basic/cryptonote_format_utils.cpp222
-rw-r--r--src/cryptonote_basic/cryptonote_format_utils.h11
-rw-r--r--src/cryptonote_config.h4
-rw-r--r--src/cryptonote_core/CMakeLists.txt8
-rw-r--r--src/cryptonote_core/blockchain.cpp193
-rw-r--r--src/cryptonote_core/blockchain.h16
-rw-r--r--src/cryptonote_core/cryptonote_core.cpp14
-rw-r--r--src/cryptonote_core/cryptonote_core.h3
-rw-r--r--src/cryptonote_core/cryptonote_tx_utils.cpp35
-rw-r--r--src/cryptonote_core/cryptonote_tx_utils.h10
-rw-r--r--src/cryptonote_protocol/cryptonote_protocol_handler-base.cpp1
-rw-r--r--src/daemon/CMakeLists.txt25
-rw-r--r--src/daemon/command_parser_executor.h1
-rw-r--r--src/daemon/command_server.h1
-rw-r--r--src/daemon/rpc_command_executor.h1
-rw-r--r--src/device/device.hpp3
-rw-r--r--src/device/device_default.cpp14
-rw-r--r--src/device/device_default.hpp4
-rw-r--r--src/device/device_ledger.cpp8
-rw-r--r--src/device/device_ledger.hpp3
-rw-r--r--src/device_trezor/trezor/protocol.cpp3
-rw-r--r--src/hardforks/CMakeLists.txt3
-rw-r--r--src/lmdb/CMakeLists.txt2
-rw-r--r--src/mnemonics/CMakeLists.txt18
-rw-r--r--src/multisig/CMakeLists.txt5
-rw-r--r--src/net/CMakeLists.txt3
-rw-r--r--src/p2p/net_node.inl1
-rw-r--r--src/p2p/net_peerlist.h23
-rw-r--r--src/p2p/p2p_protocol_defs.h1
-rw-r--r--src/ringct/CMakeLists.txt7
-rw-r--r--src/rpc/core_rpc_server.cpp13
-rw-r--r--src/rpc/core_rpc_server_commands_defs.h2
-rw-r--r--src/serialization/CMakeLists.txt3
-rw-r--r--src/serialization/crypto.h2
-rw-r--r--src/serialization/json_object.cpp31
-rw-r--r--src/serialization/json_object.h3
-rw-r--r--src/simplewallet/CMakeLists.txt3
-rw-r--r--src/simplewallet/simplewallet.cpp71
-rw-r--r--src/simplewallet/simplewallet.h1
-rw-r--r--src/wallet/api/wallet.cpp2
-rw-r--r--src/wallet/node_rpc_proxy.cpp16
-rw-r--r--src/wallet/node_rpc_proxy.h2
-rw-r--r--src/wallet/wallet2.cpp395
-rw-r--r--src/wallet/wallet2.h51
-rw-r--r--tests/core_tests/block_validation.cpp124
-rw-r--r--tests/core_tests/block_validation.h34
-rw-r--r--tests/core_tests/chaingen.cpp22
-rw-r--r--tests/core_tests/chaingen.h9
-rw-r--r--tests/core_tests/chaingen_main.cpp13
-rw-r--r--tests/core_tests/rct.cpp108
-rw-r--r--tests/core_tests/rct.h70
-rw-r--r--tests/crypto/main.cpp10
-rw-r--r--tests/crypto/tests.txt56
-rwxr-xr-xtests/functional_tests/blockchain.py8
-rwxr-xr-xtests/functional_tests/cold_signing.py4
-rw-r--r--tests/functional_tests/main.cpp2
-rwxr-xr-xtests/functional_tests/multisig.py4
-rwxr-xr-xtests/functional_tests/transfer.py16
-rw-r--r--tests/performance_tests/CMakeLists.txt1
-rw-r--r--tests/performance_tests/derive_view_tag.h (renamed from src/p2p/stdafx.h)53
-rw-r--r--tests/performance_tests/is_out_to_acc.h5
-rw-r--r--tests/performance_tests/main.cpp6
-rw-r--r--tests/performance_tests/out_can_be_to_acc.h103
-rw-r--r--tests/unit_tests/CMakeLists.txt1
-rw-r--r--tests/unit_tests/epee_utils.cpp1
-rw-r--r--tests/unit_tests/rolling_median.cpp18
-rw-r--r--tests/unit_tests/scaling_2021.cpp187
175 files changed, 1854 insertions, 10778 deletions
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index bd2e26484..69040d0af 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -11,7 +11,7 @@ on:
env:
REMOVE_BUNDLED_BOOST : rm -rf /usr/local/share/boost
BUILD_DEFAULT_LINUX: |
- cmake -S . -B build -D ARCH="default" -D BUILD_TESTS=ON -D CMAKE_BUILD_TYPE=release && cmake --build build -j3
+ cmake -S . -B build -D ARCH="default" -D BUILD_TESTS=ON -D CMAKE_BUILD_TYPE=Release && cmake --build build -j3
APT_INSTALL_LINUX: 'sudo apt -y install build-essential cmake libboost-all-dev miniupnpc libunbound-dev graphviz doxygen libunwind8-dev pkg-config libssl-dev libzmq3-dev libsodium-dev libhidapi-dev libnorm-dev libusb-1.0-0-dev libpgm-dev libprotobuf-dev protobuf-compiler ccache'
APT_SET_CONF: |
echo "Acquire::Retries \"3\";" | sudo tee -a /etc/apt/apt.conf.d/80-custom
diff --git a/Makefile b/Makefile
index e16786ec2..8a804c39a 100644
--- a/Makefile
+++ b/Makefile
@@ -96,15 +96,15 @@ release: cmake-release
release-test:
mkdir -p $(builddir)/release
- cd $(builddir)/release && cmake -D BUILD_TESTS=ON -D CMAKE_BUILD_TYPE=release $(topdir) && $(MAKE) && $(MAKE) test
+ cd $(builddir)/release && cmake -D BUILD_TESTS=ON -D CMAKE_BUILD_TYPE=Release $(topdir) && $(MAKE) && $(MAKE) test
release-all:
mkdir -p $(builddir)/release
- cd $(builddir)/release && cmake -D BUILD_TESTS=ON -D CMAKE_BUILD_TYPE=release $(topdir) && $(MAKE)
+ cd $(builddir)/release && cmake -D BUILD_TESTS=ON -D CMAKE_BUILD_TYPE=Release $(topdir) && $(MAKE)
release-static:
mkdir -p $(builddir)/release
- cd $(builddir)/release && cmake -D STATIC=ON -D ARCH="x86-64" -D BUILD_64=ON -D CMAKE_BUILD_TYPE=release $(topdir) && $(MAKE)
+ cd $(builddir)/release && cmake -D STATIC=ON -D ARCH="x86-64" -D BUILD_64=ON -D CMAKE_BUILD_TYPE=Release $(topdir) && $(MAKE)
coverage:
mkdir -p $(builddir)/debug
@@ -114,41 +114,41 @@ coverage:
release-static-linux-armv6:
mkdir -p $(builddir)/release
- cd $(builddir)/release && cmake -D BUILD_TESTS=OFF -D ARCH="armv6zk" -D STATIC=ON -D BUILD_64=OFF -D CMAKE_BUILD_TYPE=release -D BUILD_TAG="linux-armv6" $(topdir) && $(MAKE)
+ cd $(builddir)/release && cmake -D BUILD_TESTS=OFF -D ARCH="armv6zk" -D STATIC=ON -D BUILD_64=OFF -D CMAKE_BUILD_TYPE=Release -D BUILD_TAG="linux-armv6" $(topdir) && $(MAKE)
release-static-linux-armv7:
mkdir -p $(builddir)/release
- cd $(builddir)/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" $(topdir) && $(MAKE)
+ cd $(builddir)/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" $(topdir) && $(MAKE)
release-static-android-armv7:
mkdir -p $(builddir)/release/translations
cd $(builddir)/release/translations && cmake ../../../translations && $(MAKE)
- cd $(builddir)/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 BUILD_TAG="android-armv7" -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)
+ cd $(builddir)/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 BUILD_TAG="android-armv7" -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-android-armv8:
mkdir -p $(builddir)/release/translations
cd $(builddir)/release/translations && cmake ../../../translations && $(MAKE)
- cd $(builddir)/release && CC=aarch64-linux-android-clang CXX=aarch64-linux-android-clang++ 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 BUILD_TAG="android-armv8" -D CMAKE_SYSTEM_NAME="Android" -D CMAKE_ANDROID_STANDALONE_TOOLCHAIN="${ANDROID_STANDALONE_TOOLCHAIN_PATH}" -D CMAKE_ANDROID_ARCH_ABI="arm64-v8a" ../.. && $(MAKE)
+ cd $(builddir)/release && CC=aarch64-linux-android-clang CXX=aarch64-linux-android-clang++ 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 BUILD_TAG="android-armv8" -D CMAKE_SYSTEM_NAME="Android" -D CMAKE_ANDROID_STANDALONE_TOOLCHAIN="${ANDROID_STANDALONE_TOOLCHAIN_PATH}" -D CMAKE_ANDROID_ARCH_ABI="arm64-v8a" ../.. && $(MAKE)
release-static-linux-armv8:
mkdir -p $(builddir)/release
- cd $(builddir)/release && cmake -D BUILD_TESTS=OFF -D ARCH="armv8-a" -D STATIC=ON -D BUILD_64=ON -D CMAKE_BUILD_TYPE=release -D BUILD_TAG="linux-armv8" $(topdir) && $(MAKE)
+ cd $(builddir)/release && cmake -D BUILD_TESTS=OFF -D ARCH="armv8-a" -D STATIC=ON -D BUILD_64=ON -D CMAKE_BUILD_TYPE=Release -D BUILD_TAG="linux-armv8" $(topdir) && $(MAKE)
release-static-linux-x86_64:
mkdir -p $(builddir)/release
- cd $(builddir)/release && cmake -D STATIC=ON -D ARCH="x86-64" -D BUILD_64=ON -D CMAKE_BUILD_TYPE=release -D BUILD_TAG="linux-x64" $(topdir) && $(MAKE)
+ cd $(builddir)/release && cmake -D STATIC=ON -D ARCH="x86-64" -D BUILD_64=ON -D CMAKE_BUILD_TYPE=Release -D BUILD_TAG="linux-x64" $(topdir) && $(MAKE)
release-static-freebsd-x86_64:
mkdir -p $(builddir)/release
- cd $(builddir)/release && cmake -D STATIC=ON -D ARCH="x86-64" -D BUILD_64=ON -D CMAKE_BUILD_TYPE=release -D BUILD_TAG="freebsd-x64" $(topdir) && $(MAKE)
+ cd $(builddir)/release && cmake -D STATIC=ON -D ARCH="x86-64" -D BUILD_64=ON -D CMAKE_BUILD_TYPE=Release -D BUILD_TAG="freebsd-x64" $(topdir) && $(MAKE)
release-static-mac-x86_64:
mkdir -p $(builddir)/release
- cd $(builddir)/release && cmake -D STATIC=ON -D ARCH="x86-64" -D BUILD_64=ON -D CMAKE_BUILD_TYPE=release -D BUILD_TAG="mac-x64" $(topdir) && $(MAKE)
+ cd $(builddir)/release && cmake -D STATIC=ON -D ARCH="x86-64" -D BUILD_64=ON -D CMAKE_BUILD_TYPE=Release -D BUILD_TAG="mac-x64" $(topdir) && $(MAKE)
release-static-linux-i686:
mkdir -p $(builddir)/release
- cd $(builddir)/release && cmake -D STATIC=ON -D ARCH="i686" -D BUILD_64=OFF -D CMAKE_BUILD_TYPE=release -D BUILD_TAG="linux-x86" $(topdir) && $(MAKE)
+ cd $(builddir)/release && cmake -D STATIC=ON -D ARCH="i686" -D BUILD_64=OFF -D CMAKE_BUILD_TYPE=Release -D BUILD_TAG="linux-x86" $(topdir) && $(MAKE)
release-static-win64:
mkdir -p $(builddir)/release
diff --git a/README.md b/README.md
index 02e27014e..ad31b127a 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
# Monero
-Copyright (c) 2014-2022 The Monero Project.
+Copyright (c) 2014-2022 The Monero Project.
Portions Copyright (c) 2012-2013 The Cryptonote developers.
## Table of Contents
@@ -33,7 +33,7 @@ Portions Copyright (c) 2012-2013 The Cryptonote developers.
- Mail: [dev@getmonero.org](mailto:dev@getmonero.org)
- GitHub: [https://github.com/monero-project/monero](https://github.com/monero-project/monero)
- IRC: [#monero-dev on Libera](https://web.libera.chat/#monero-dev)
-- It is HIGHLY recommended that you join the #monero-dev IRC channel if you are developing software that uses Monero. Due to the nature of this open source software project, joining this channel and idling is the best way to stay updated on best practices and new developments in the Monero ecosystem. All you need to do is join the IRC channel and idle to stay updated with the latest in Monero development. If you do not, you risk wasting resources on developing integrations that are not compatible with the Monero network. The Monero core team and community continuously make efforts to communicate updates, developments, and documentation via other platforms – but for the best information, you need to talk to other Monero developers, and they are on IRC. #monero-dev is about Monero development, not getting help about using Monero, or help about development of other software, including yours, unless it also pertains to Monero code itself. For these cases, checkout #monero.
+- It is HIGHLY recommended that you join the #monero-dev IRC channel if you are developing software that uses Monero. Due to the nature of this open source software project, joining this channel and idling is the best way to stay updated on best practices and new developments in the Monero ecosystem. All you need to do is join the IRC channel and idle to stay updated with the latest in Monero development. If you do not, you risk wasting resources on developing integrations that are not compatible with the Monero network. The Monero core team and community continuously make efforts to communicate updates, developments, and documentation via other platforms – but for the best information, you need to talk to other Monero developers, and they are on IRC. #monero-dev is about Monero development, not getting help about using Monero, or help about development of other software, including yours, unless it also pertains to Monero code itself. For these cases, checkout #monero.
## Vulnerability response
@@ -75,7 +75,7 @@ Monero is a private, secure, untraceable, decentralised digital currency. You ar
**Untraceability:** By taking advantage of ring signatures, a special property of a certain type of cryptography, Monero is able to ensure that transactions are not only untraceable but have an optional measure of ambiguity that ensures that transactions cannot easily be tied back to an individual user or computer.
-**Decentralization:** The utility of Monero depends on its decentralised peer-to-peer consensus network - anyone should be able to run the monero software, validate the integrity of the blockchain, and participate in all aspects of the monero network using consumer-grade commodity hardware. Decentralization of the monero network is maintained by software development that minimizes the costs of running the monero software and inhibits the proliferation of specialized, non-commodity hardware.
+**Decentralization:** The utility of Monero depends on its decentralised peer-to-peer consensus network - anyone should be able to run the monero software, validate the integrity of the blockchain, and participate in all aspects of the monero network using consumer-grade commodity hardware. Decentralization of the monero network is maintained by software development that minimizes the costs of running the monero software and inhibits the proliferation of specialized, non-commodity hardware.
## About this project
@@ -117,7 +117,7 @@ Monero uses a fixed-schedule software upgrade (hard fork) mechanism to implement
Dates are provided in the format YYYY-MM-DD.
-| Software upgrade block height | Date | Fork version | Minimum Monero version | Recommended Monero version | Details |
+| Software upgrade block height | Date | Fork version | Minimum Monero version | Recommended Monero version | Details |
| ------------------------------ | -----------| ----------------- | ---------------------- | -------------------------- | ---------------------------------------------------------------------------------- |
| 1009827 | 2016-03-22 | v2 | v0.9.4 | v0.9.4 | Allow only >= ringsize 3, blocktime = 120 seconds, fee-free blocksize 60 kb |
| 1141317 | 2016-09-21 | v3 | v0.9.4 | v0.10.0 | Splits coinbase into denominations |
@@ -196,30 +196,44 @@ then:
Install all dependencies at once on Debian/Ubuntu:
-``` sudo apt update && sudo apt install build-essential cmake pkg-config libssl-dev libzmq3-dev libunbound-dev libsodium-dev libunwind8-dev liblzma-dev libreadline6-dev libldns-dev libexpat1-dev libpgm-dev qttools5-dev-tools libhidapi-dev libusb-1.0-0-dev libprotobuf-dev protobuf-compiler libudev-dev libboost-chrono-dev libboost-date-time-dev libboost-filesystem-dev libboost-locale-dev libboost-program-options-dev libboost-regex-dev libboost-serialization-dev libboost-system-dev libboost-thread-dev ccache doxygen graphviz ```
+```
+sudo apt update && sudo apt install build-essential cmake pkg-config libssl-dev libzmq3-dev libunbound-dev libsodium-dev libunwind8-dev liblzma-dev libreadline6-dev libldns-dev libexpat1-dev libpgm-dev qttools5-dev-tools libhidapi-dev libusb-1.0-0-dev libprotobuf-dev protobuf-compiler libudev-dev libboost-chrono-dev libboost-date-time-dev libboost-filesystem-dev libboost-locale-dev libboost-program-options-dev libboost-regex-dev libboost-serialization-dev libboost-system-dev libboost-thread-dev ccache doxygen graphviz
+```
Install all dependencies at once on openSUSE:
-``` sudo zypper ref && sudo zypper in cppzmq-devel ldns-devel libboost_chrono-devel libboost_date_time-devel libboost_filesystem-devel libboost_locale-devel libboost_program_options-devel libboost_regex-devel libboost_serialization-devel libboost_system-devel libboost_thread-devel libexpat-devel libminiupnpc-devel libsodium-devel libunwind-devel unbound-devel cmake doxygen ccache fdupes gcc-c++ libevent-devel libopenssl-devel pkgconf-pkg-config readline-devel xz-devel libqt5-qttools-devel patterns-devel-C-C++-devel_C_C++```
+```
+sudo zypper ref && sudo zypper in cppzmq-devel ldns-devel libboost_chrono-devel libboost_date_time-devel libboost_filesystem-devel libboost_locale-devel libboost_program_options-devel libboost_regex-devel libboost_serialization-devel libboost_system-devel libboost_thread-devel libexpat-devel libminiupnpc-devel libsodium-devel libunwind-devel unbound-devel cmake doxygen ccache fdupes gcc-c++ libevent-devel libopenssl-devel pkgconf-pkg-config readline-devel xz-devel libqt5-qttools-devel patterns-devel-C-C++-devel_C_C++
+```
Install all dependencies at once on macOS with the provided Brewfile:
-``` brew update && brew bundle --file=contrib/brew/Brewfile ```
+
+```
+brew update && brew bundle --file=contrib/brew/Brewfile
+```
FreeBSD 12.1 one-liner required to build dependencies:
-```pkg install git gmake cmake pkgconf boost-libs libzmq4 libsodium unbound```
+
+```
+pkg install git gmake cmake pkgconf boost-libs libzmq4 libsodium unbound
+```
### Cloning the repository
Clone recursively to pull-in needed submodule(s):
-`$ git clone --recursive https://github.com/monero-project/monero`
+```
+git clone --recursive https://github.com/monero-project/monero
+```
If you already have a repo cloned, initialize and update:
-`$ cd monero && git submodule init && git submodule update`
+```
+cd monero && git submodule init && git submodule update
+```
*Note*: If there are submodule differences between branches, you may need
-to use ```git submodule sync && git submodule update``` after changing branches
+to use `git submodule sync && git submodule update` after changing branches
to build successfully.
### Build instructions
@@ -383,15 +397,15 @@ application.
* Download and install the [MSYS2 installer](https://www.msys2.org), either the 64-bit or the 32-bit package, depending on your system.
* Open the MSYS shell via the `MSYS2 Shell` shortcut
-* Update packages using pacman:
+* Update packages using pacman:
```bash
pacman -Syu
```
-* Exit the MSYS shell using Alt+F4
+* Exit the MSYS shell using Alt+F4
* Edit the properties for the `MSYS2 Shell` shortcut changing "msys2_shell.bat" to "msys2_shell.cmd -mingw64" for 64-bit builds or "msys2_shell.cmd -mingw32" for 32-bit builds
-* Restart MSYS shell via modified shortcut and update packages again using pacman:
+* Restart MSYS shell via modified shortcut and update packages again using pacman:
```bash
pacman -Syu
@@ -471,7 +485,7 @@ application.
The project can be built from scratch by following instructions for Linux above(but use `gmake` instead of `make`).
If you are running Monero in a jail, you need to add `sysvsem="new"` to your jail configuration, otherwise lmdb will throw the error message: `Failed to open lmdb environment: Function not implemented`.
-Monero is also available as a port or package as 'monero-cli`.
+Monero is also available as a port or package as `monero-cli`.
### On OpenBSD:
diff --git a/contrib/epee/demo/.gitignore b/contrib/epee/demo/.gitignore
deleted file mode 100644
index d9b4f015d..000000000
--- a/contrib/epee/demo/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-/build/*
diff --git a/contrib/epee/demo/CMakeLists.txt b/contrib/epee/demo/CMakeLists.txt
deleted file mode 100644
index d2ae0ed55..000000000
--- a/contrib/epee/demo/CMakeLists.txt
+++ /dev/null
@@ -1,49 +0,0 @@
-cmake_minimum_required(VERSION 3.5)
-set(Boost_USE_MULTITHREADED ON)
-#set(Boost_DEBUG 1)
-find_package(Boost COMPONENTS system filesystem thread date_time chrono regex )
-
-include_directories( ${Boost_INCLUDE_DIRS} )
-
-
-IF (MSVC)
- add_definitions( "/W3 /D_CRT_SECURE_NO_WARNINGS /wd4996 /wd4345 /nologo /D_WIN32_WINNT=0x0600 /DWIN32_LEAN_AND_MEAN /bigobj" )
-ELSE()
- # set stuff for other systems
- SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wall -Wno-reorder -D_GNU_SOURCE")
-ENDIF()
-
-
-include_directories(.)
-include_directories(../include)
-include_directories(iface)
-
-
-# Add folders to filters
-file(GLOB_RECURSE LEVIN_GENERAL_SECTION RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
- ${CMAKE_CURRENT_SOURCE_DIR}/demo_levin_server/*.h
- ${CMAKE_CURRENT_SOURCE_DIR}/demo_levin_server/*.inl
- ${CMAKE_CURRENT_SOURCE_DIR}/demo_levin_server/*.cpp)
-
-file(GLOB_RECURSE HTTP_GENERAL_SECTION RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
- ${CMAKE_CURRENT_SOURCE_DIR}/demo_http_server/*.h
- ${CMAKE_CURRENT_SOURCE_DIR}/demo_http_server/*.inl
- ${CMAKE_CURRENT_SOURCE_DIR}/demo_http_server/*.cpp)
-
-
-
-source_group(general FILES ${LEVIN_GENERAL_SECTION} FILES ${HTTP_GENERAL_SECTION})
-#source_group(general FILES ${HTTP_GENERAL_SECTION})
-
-add_executable(demo_http_server ${HTTP_GENERAL_SECTION} )
-add_executable(demo_levin_server ${LEVIN_GENERAL_SECTION} )
-
-target_link_libraries( demo_http_server ${Boost_LIBRARIES} )
-target_link_libraries( demo_levin_server ${Boost_LIBRARIES} )
-
-IF (NOT WIN32)
- target_link_libraries (demo_http_server rt)
- target_link_libraries (demo_levin_server rt)
-ENDIF()
-
-
diff --git a/contrib/epee/demo/README.txt b/contrib/epee/demo/README.txt
deleted file mode 100644
index e69de29bb..000000000
--- a/contrib/epee/demo/README.txt
+++ /dev/null
diff --git a/contrib/epee/demo/demo_http_server/stdafx.cpp b/contrib/epee/demo/demo_http_server/stdafx.cpp
deleted file mode 100644
index ecec24657..000000000
--- a/contrib/epee/demo/demo_http_server/stdafx.cpp
+++ /dev/null
@@ -1,8 +0,0 @@
-// stdafx.cpp : source file that includes just the standard includes
-// demo_http_server.pch will be the pre-compiled header
-// stdafx.obj will contain the pre-compiled type information
-
-#include "stdafx.h"
-
-// TODO: reference any additional headers you need in STDAFX.H
-// and not in this file
diff --git a/contrib/epee/demo/demo_http_server/stdafx.h b/contrib/epee/demo/demo_http_server/stdafx.h
deleted file mode 100644
index e28883202..000000000
--- a/contrib/epee/demo/demo_http_server/stdafx.h
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * 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.
-// * Neither the name of the Andrey N. Sabelnikov 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 OWNER 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.
-//
-
-
-#pragma once
-
-#include "targetver.h"
-
-
-#include <stdio.h>
-
-
-#define BOOST_FILESYSTEM_VERSION 3
-#define ENABLE_RELEASE_LOGGING
-#include "misc_log_ex.h"
-
-
diff --git a/contrib/epee/demo/demo_http_server/targetver.h b/contrib/epee/demo/demo_http_server/targetver.h
deleted file mode 100644
index 6fe8eb79e..000000000
--- a/contrib/epee/demo/demo_http_server/targetver.h
+++ /dev/null
@@ -1,13 +0,0 @@
-#pragma once
-
-// The following macros define the minimum required platform. The minimum required platform
-// is the earliest version of Windows, Internet Explorer etc. that has the necessary features to run
-// your application. The macros work by enabling all features available on platform versions up to and
-// including the version specified.
-
-// Modify the following defines if you have to target a platform prior to the ones specified below.
-// Refer to MSDN for the latest info on corresponding values for different platforms.
-#ifndef _WIN32_WINNT // Specifies that the minimum required platform is Windows Vista.
-#define _WIN32_WINNT 0x0600 // Change this to the appropriate value to target other versions of Windows.
-#endif
-
diff --git a/contrib/epee/demo/demo_levin_server/stdafx.cpp b/contrib/epee/demo/demo_levin_server/stdafx.cpp
deleted file mode 100644
index d6ea1c6f2..000000000
--- a/contrib/epee/demo/demo_levin_server/stdafx.cpp
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * 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.
-// * Neither the name of the Andrey N. Sabelnikov 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 OWNER 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 "stdafx.h"
-
diff --git a/contrib/epee/demo/demo_levin_server/stdafx.h b/contrib/epee/demo/demo_levin_server/stdafx.h
deleted file mode 100644
index f69d5922b..000000000
--- a/contrib/epee/demo/demo_levin_server/stdafx.h
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * 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.
-// * Neither the name of the Andrey N. Sabelnikov 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 OWNER 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.
-//
-
-
-#pragma once
-
-#include "targetver.h"
-
-
-#include <stdio.h>
-
-
-#define BOOST_FILESYSTEM_VERSION 3
-#define ENABLE_RELEASE_LOGGING
-#include "log_opt_defs.h"
-#include "misc_log_ex.h"
-
-
diff --git a/contrib/epee/demo/demo_levin_server/targetver.h b/contrib/epee/demo/demo_levin_server/targetver.h
deleted file mode 100644
index 6fe8eb79e..000000000
--- a/contrib/epee/demo/demo_levin_server/targetver.h
+++ /dev/null
@@ -1,13 +0,0 @@
-#pragma once
-
-// The following macros define the minimum required platform. The minimum required platform
-// is the earliest version of Windows, Internet Explorer etc. that has the necessary features to run
-// your application. The macros work by enabling all features available on platform versions up to and
-// including the version specified.
-
-// Modify the following defines if you have to target a platform prior to the ones specified below.
-// Refer to MSDN for the latest info on corresponding values for different platforms.
-#ifndef _WIN32_WINNT // Specifies that the minimum required platform is Windows Vista.
-#define _WIN32_WINNT 0x0600 // Change this to the appropriate value to target other versions of Windows.
-#endif
-
diff --git a/contrib/epee/demo/generate_gcc.sh b/contrib/epee/demo/generate_gcc.sh
deleted file mode 100644
index fcd0a8a7e..000000000
--- a/contrib/epee/demo/generate_gcc.sh
+++ /dev/null
@@ -1,4 +0,0 @@
-mkdir build
-cd build
-cmake ..
-#cmake -DBOOST_ROOT=/usr/local/proj/boost_1_49_0 -DBOOST_LIBRARYDIR=/usr/local/proj/boost_1_49_0/stage/lib ..
diff --git a/contrib/epee/demo/generate_vc_proj.bat b/contrib/epee/demo/generate_vc_proj.bat
deleted file mode 100644
index 7d83ced6f..000000000
--- a/contrib/epee/demo/generate_vc_proj.bat
+++ /dev/null
@@ -1,7 +0,0 @@
-mkdir build
-
-cd build
-
-cmake "-DBoost_USE_STATIC_LIBS=TRUE" -G "Visual Studio 11 Win64" ..
-cd ..
-pause
diff --git a/contrib/epee/demo/iface/transport_defs.h b/contrib/epee/demo/iface/transport_defs.h
deleted file mode 100644
index 61968ed71..000000000
--- a/contrib/epee/demo/iface/transport_defs.h
+++ /dev/null
@@ -1,225 +0,0 @@
-#pragma once
-
-#include "serialization/keyvalue_serialization.h"
-#include "storages/portable_storage_base.h"
-
-namespace demo
-{
-
- struct some_test_subdata
- {
- std::string m_str;
-
- BEGIN_KV_SERIALIZE_MAP()
- KV_SERIALIZE(m_str)
- END_KV_SERIALIZE_MAP()
- };
-
- struct some_test_data
- {
- std::string m_str;
- uint64_t m_uint64;
- uint32_t m_uint32;
- uint16_t m_uint16;
- uint8_t m_uint8;
- int64_t m_int64;
- int32_t m_int32;
- int16_t m_int16;
- int8_t m_int8;
- double m_double;
- bool m_bool;
- std::list<std::string> m_list_of_str;
- std::list<uint64_t> m_list_of_uint64_t;
- std::list<uint32_t> m_list_of_uint32_t;
- std::list<uint16_t> m_list_of_uint16_t;
- std::list<uint8_t> m_list_of_uint8_t;
- std::list<int64_t> m_list_of_int64_t;
- std::list<int32_t> m_list_of_int32_t;
- std::list<int16_t> m_list_of_int16_t;
- std::list<int8_t> m_list_of_int8_t;
- std::list<double> m_list_of_double;
- std::list<bool> m_list_of_bool;
- some_test_subdata m_subobj;
- std::list<some_test_data> m_list_of_self;
- epee::serialization::storage_entry m_storage_entry_int;
- epee::serialization::storage_entry m_storage_entry_string;
-
- BEGIN_KV_SERIALIZE_MAP()
- KV_SERIALIZE(m_str)
- KV_SERIALIZE(m_uint64)
- KV_SERIALIZE(m_uint32)
- KV_SERIALIZE(m_uint16)
- KV_SERIALIZE(m_uint8)
- KV_SERIALIZE(m_int64)
- KV_SERIALIZE(m_int32)
- KV_SERIALIZE(m_int16)
- KV_SERIALIZE(m_int8)
- KV_SERIALIZE(m_double)
- KV_SERIALIZE(m_bool)
- KV_SERIALIZE(m_subobj)
- KV_SERIALIZE(m_list_of_str)
- KV_SERIALIZE(m_list_of_uint64_t)
- KV_SERIALIZE(m_list_of_uint32_t)
- KV_SERIALIZE(m_list_of_uint16_t)
- KV_SERIALIZE(m_list_of_uint8_t)
- KV_SERIALIZE(m_list_of_int64_t)
- KV_SERIALIZE(m_list_of_int32_t)
- KV_SERIALIZE(m_list_of_int16_t)
- KV_SERIALIZE(m_list_of_int8_t)
- KV_SERIALIZE(m_list_of_double)
- KV_SERIALIZE(m_list_of_bool)
- KV_SERIALIZE(m_list_of_self)
- KV_SERIALIZE(m_storage_entry_int)
- KV_SERIALIZE(m_storage_entry_string)
- END_KV_SERIALIZE_MAP()
- };
-
- /************************************************************************/
- /* */
- /************************************************************************/
- struct COMMAND_EXAMPLE_1
- {
- const static int ID = 1000;
-
- struct request_t
- {
- std::string example_string_data;
- some_test_data sub;
-
- BEGIN_KV_SERIALIZE_MAP()
- KV_SERIALIZE(example_string_data)
- KV_SERIALIZE(sub)
- END_KV_SERIALIZE_MAP()
- };
- typedef epee::misc_utils::struct_init<request_t> request;
-
-
- struct response_t
- {
- bool m_success;
- std::list<some_test_data> subs;
-
- BEGIN_KV_SERIALIZE_MAP()
- KV_SERIALIZE(m_success)
- KV_SERIALIZE(subs)
- END_KV_SERIALIZE_MAP()
- };
- };
- typedef epee::misc_utils::struct_init<response_t> response;
-
-
-
- struct COMMAND_EXAMPLE_2
- {
- const static int ID = 1001;
-
- struct request_t
- {
- std::string example_string_data2;
-
- BEGIN_KV_SERIALIZE_MAP()
- KV_SERIALIZE(example_string_data2)
- END_KV_SERIALIZE_MAP()
- };
- typedef epee::misc_utils::struct_init<request_t> request;
-
- struct response_t
- {
- bool m_success;
-
-
- BEGIN_KV_SERIALIZE_MAP()
- KV_SERIALIZE(m_success)
- END_KV_SERIALIZE_MAP()
- };
- typedef epee::misc_utils::struct_init<response_t> response;
- };
-
-
- //-------------------------------------------------------------------------------------
- //-------------------------------------------------------------------------------------
- //in debug purpose
- bool operator != (const some_test_subdata& a, const some_test_subdata& b)
- {
- return b.m_str != a.m_str;
- }
-
- bool operator == (const some_test_data& a, const some_test_data& b)
- {
- if( b.m_str != a.m_str
- || b.m_uint64 != a.m_uint64
- || b.m_uint32 != a.m_uint32
- || b.m_uint16 != a.m_uint16
- || b.m_uint8 != a.m_uint8
- || b.m_int64 != a.m_int64
- || b.m_int32 != a.m_int32
- || b.m_int16 != a.m_int16
- || b.m_int8 != a.m_int8
- || b.m_double != a.m_double
- || b.m_bool != a.m_bool
- || b.m_list_of_str != a.m_list_of_str
- || b.m_list_of_uint64_t != a.m_list_of_uint64_t
- || b.m_list_of_uint32_t != a.m_list_of_uint32_t
- || b.m_list_of_uint16_t != a.m_list_of_uint16_t
- || b.m_list_of_uint8_t != a.m_list_of_uint8_t
- || b.m_list_of_int64_t != a.m_list_of_int64_t
- || b.m_list_of_int32_t != a.m_list_of_int32_t
- || b.m_list_of_int16_t != a.m_list_of_int16_t
- || b.m_list_of_int8_t != a.m_list_of_int8_t
- || b.m_list_of_double != a.m_list_of_double
- || b.m_list_of_bool != a.m_list_of_bool
- || b.m_subobj != a.m_subobj
- || b.m_list_of_self != a.m_list_of_self
- || b.m_storage_entry_int.which() != a.m_storage_entry_int.which()
- || b.m_storage_entry_string.which() != a.m_storage_entry_string.which()
- )
- return false;
- return true;
- }
-
- inline some_test_data get_test_data()
- {
- some_test_data s;
- s.m_str = "zuzuzuzuzuz";
- s.m_uint64 = 111111111111111;
- s.m_uint32 = 2222222;
- s.m_uint16 = 2222;
- s.m_uint8 = 22;
- s.m_int64 = -111111111111111;
- s.m_int32 = -2222222;
- s.m_int16 = -2222;
- s.m_int8 = -24;
- s.m_double = 0.11111;
- s.m_bool = true;
- s.m_list_of_str.push_back("1112121");
- s.m_list_of_uint64_t.push_back(1111111111);
- s.m_list_of_uint64_t.push_back(2222222222);
- s.m_list_of_uint32_t.push_back(1111111);
- s.m_list_of_uint32_t.push_back(2222222);
- s.m_list_of_uint16_t.push_back(1111);
- s.m_list_of_uint16_t.push_back(2222);
- s.m_list_of_uint8_t.push_back(11);
- s.m_list_of_uint8_t.push_back(22);
-
-
- s.m_list_of_int64_t.push_back(-1111111111);
- s.m_list_of_int64_t.push_back(-222222222);
- s.m_list_of_int32_t.push_back(-1111111);
- s.m_list_of_int32_t.push_back(-2222222);
- s.m_list_of_int16_t.push_back(-1111);
- s.m_list_of_int16_t.push_back(-2222);
- s.m_list_of_int8_t.push_back(-11);
- s.m_list_of_int8_t.push_back(-22);
-
- s.m_list_of_double.push_back(0.11111);
- s.m_list_of_double.push_back(0.22222);
- s.m_list_of_bool.push_back(true);
- s.m_list_of_bool.push_back(false);
-
- s.m_subobj.m_str = "subszzzzzzzz";
- s.m_list_of_self.push_back(s);
- s.m_storage_entry_int = epee::serialization::storage_entry(uint64_t(22222));
- s.m_storage_entry_string = epee::serialization::storage_entry(std::string("sdsvsdvs"));
- return s;
- }
-}
diff --git a/contrib/epee/include/ado_db_helper.h b/contrib/epee/include/ado_db_helper.h
deleted file mode 100644
index ed4e5b30f..000000000
--- a/contrib/epee/include/ado_db_helper.h
+++ /dev/null
@@ -1,1095 +0,0 @@
-// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * 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.
-// * Neither the name of the Andrey N. Sabelnikov 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 OWNER 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.
-//
-
-
-#ifndef _DB_ADO_HELPER_H_
-#define _DB_ADO_HELPER_H_
-
-#include <vector>
-#include <comutil.h>
-#include "string_coding.h"
-#include "math_helper.h"
-#include "file_io_utils.h"
-#include "global_stream_operators.h"
-
-
-
-#define BEGIN_TRY_SECTION() try {
-
-#define CATCH_TRY_SECTION(ret_val) CATCH_TRY_SECTION_MESS(ret_val, "")
-
-#define CATCH_TRY_SECTION_MESS(ret_val, mess_where) }\
- catch(const std::exception&ex)\
- {\
- LOG_PRINT_J("DB_ERROR: " << ex.what(), LOG_LEVEL_0);\
- return ret_val;\
- }\
- catch(const _com_error& comm_err)\
- {\
- const TCHAR* pstr = comm_err.Description();\
- std::string descr = string_encoding::convert_to_ansii(pstr?pstr:TEXT(""));\
- const TCHAR* pmessage = comm_err.ErrorMessage();\
- pstr = comm_err.Source();\
- std::string source = string_encoding::convert_to_ansii(pstr?pstr:TEXT(""));\
- LOG_PRINT_J("COM_ERROR " << mess_where << ":\n\tDescriprion:" << descr << ", \n\t Message: " << string_encoding::convert_to_ansii(pmessage) << "\n\t Source: " << source, LOG_LEVEL_0);\
- return ret_val;\
- }\
- catch(...)\
- {\
- LOG_PRINT_J("..._ERROR: Unknown error.", LOG_LEVEL_0);\
- return ret_val;\
- }\
-
-namespace epee
-{
-namespace ado_db_helper
-{
-
- struct profile_entry
- {
- profile_entry():m_call_count(0), m_max_time(0), m_min_time(0)
- {}
- //std::string m_sql;
- math_helper::average<DWORD, 10> m_avrg;
- size_t m_call_count;
- DWORD m_max_time;
- DWORD m_min_time;
- };
-
- class profiler_manager
- {
- public:
- typedef std::map<std::string, profile_entry> sqls_map;
- profiler_manager(){}
-
- static bool sort_by_timing(const sqls_map::iterator& a, const sqls_map::iterator& b)
- {
- return a->second.m_avrg.get_avg() > b->second.m_avrg.get_avg();
- }
-
- bool flush_log(const std::string& path)
- {
- CRITICAL_REGION_BEGIN(m_sqls_lock);
- std::stringstream strm;
- strm << "SQL PROFILE:\r\nStatements: " << m_sqls.size() << "\r\n";
- std::list<sqls_map::iterator> m_sorted_by_time_sqls;
- for(std::map<std::string, profile_entry>::iterator it = m_sqls.begin();it!=m_sqls.end();it++)
- m_sorted_by_time_sqls.push_back(it);
-
- m_sorted_by_time_sqls.sort(sort_by_timing);
-
- for(std::list<sqls_map::iterator>::iterator it = m_sorted_by_time_sqls.begin();it!=m_sorted_by_time_sqls.end();it++)
- {
- strm << "---------------------------------------------------------------------------------------------------------\r\nSQL: " << (*it)->first << "\r\n";
- strm << "\tavrg: " << (*it)->second.m_avrg.get_avg() << "\r\n\tmax: " << (*it)->second.m_max_time << "\r\n\tmin: " << (*it)->second.m_min_time << "\r\n\tcount: " << (*it)->second.m_call_count << "\r\n";
- }
-
- return file_io_utils::save_string_to_file(path.c_str(), strm.str());
- CRITICAL_REGION_END();
- }
-
- bool push_entry(const std::string sql, DWORD time)
- {
- CRITICAL_REGION_BEGIN(m_sqls_lock);
- profile_entry& entry_ref = m_sqls[sql];
- entry_ref.m_avrg.push(time);
- entry_ref.m_call_count++;
- if(time > entry_ref.m_max_time) entry_ref.m_max_time = time;
- if(time < entry_ref.m_min_time || entry_ref.m_min_time == 0) entry_ref.m_min_time = time;
- CRITICAL_REGION_END();
- return true;
- }
-
- bool get_entry_avarege(const std::string sql, DWORD& time)
- {
- CRITICAL_REGION_BEGIN(m_sqls_lock);
- sqls_map::iterator it = m_sqls.find(sql);
- if(it==m_sqls.end())
- return false;
-
- time = static_cast<DWORD>(it->second.m_avrg.get_avg());
- CRITICAL_REGION_END();
- return true;
- }
-
- private:
-
- sqls_map m_sqls;
- critical_section m_sqls_lock;
- };
-inline
- profiler_manager* get_set_profiler(bool need_to_set = false, profiler_manager** pprofiler = NULL)
- {
- static profiler_manager* pmanager = NULL;
- if(need_to_set)
- pmanager = *pprofiler;
- //else
- // *pprofiler = pmanager;
-
- return pmanager;
- }
-inline
- bool init() // INIT and DEINIT are NOT THREAD SAFE operations, CALL it BEFOR u start using this wrapper.
- {
- profiler_manager* pmanager = new profiler_manager();
- get_set_profiler(true, &pmanager);
- return true;
- }
-inline
- bool deinit()
- {
- profiler_manager* pmanager = get_set_profiler();
- //get_set_profiler(false, &pmanager);
- if(pmanager)
- delete pmanager;
- return true;
- }
- inline bool push_timing(const std::string sql, DWORD time)
- {
- profiler_manager* pmanager = get_set_profiler();
- //get_set_profiler(false, &pmanager);
- if(pmanager)
- return pmanager->push_entry(sql, time);
- return true;
- }
-
- inline bool flush_profiler(const std::string path)
- {
- profiler_manager* pmanager = get_set_profiler();
- //get_set_profiler(false, &pmanager);
- if(pmanager)
- return pmanager->flush_log(path);
- return true;
- }
-
- class timing_guard
- {
- DWORD m_start_time;
- std::string m_sql;
-
- public:
- timing_guard(const std::string& sql)
- {
- m_start_time = ::GetTickCount();
- m_sql = sql;
- }
-
- ~timing_guard()
- {
- DWORD timing = ::GetTickCount() - m_start_time;
- push_timing(m_sql, timing);
- }
- };
-#define PROFILE_SQL(sql) timing_guard local_timing(sql)
-
-
- typedef std::vector<std::vector<_variant_t> > table;
-
- inline bool add_parametr(ADODB::_CommandPtr cmd, const std::string& parametr)
- {
- _variant_t param(parametr.c_str());
- ADODB::ADO_LONGPTR size = sizeof(parametr);
- ADODB::_ParameterPtr param_obj = cmd->CreateParameter("", ADODB::adVarChar, ADODB::adParamInput, static_cast<long>(parametr.size()+1), param);
- cmd->Parameters->Append(param_obj);
- return true;
- }
-
- inline bool add_parametr(ADODB::_CommandPtr cmd, const std::wstring& parametr)
- {
- _variant_t param(parametr.c_str());
- ADODB::ADO_LONGPTR size = sizeof(parametr);
- ADODB::_ParameterPtr param_obj = cmd->CreateParameter("", ADODB::adVarWChar, ADODB::adParamInput, static_cast<long>(parametr.size()+2), param);
- cmd->Parameters->Append(param_obj);
- return true;
- }
-
- inline bool add_parametr(ADODB::_CommandPtr cmd, const __int64 parametr)
- {
- _variant_t param(parametr);
- ADODB::ADO_LONGPTR size = static_cast<long>(sizeof(parametr));
- ADODB::_ParameterPtr param_obj = cmd->CreateParameter("parametr", ADODB::adBigInt, ADODB::adParamInput, static_cast<long>(size), param);
- cmd->Parameters->Append(param_obj);
- return true;
- }
-
- inline bool add_parametr(ADODB::_CommandPtr cmd, const unsigned __int64 parametr)
- {
- _variant_t param(parametr);
- ADODB::ADO_LONGPTR size = static_cast<long>(sizeof(parametr));
- ADODB::_ParameterPtr param_obj = cmd->CreateParameter("parametr", ADODB::adUnsignedBigInt, ADODB::adParamInput, static_cast<long>(size), param);
- cmd->Parameters->Append(param_obj);
- return true;
- }
-
-
- inline bool add_parametr(ADODB::_CommandPtr cmd, const int parametr)
- {
- _variant_t param(parametr);
- ADODB::ADO_LONGPTR size = static_cast<long>(sizeof(parametr));
- ADODB::_ParameterPtr param_obj = cmd->CreateParameter("parametr", ADODB::adInteger, ADODB::adParamInput, static_cast<long>(size), param);
- cmd->Parameters->Append(param_obj);
- return true;
- }
-
- inline bool add_parametr(ADODB::_CommandPtr cmd, const unsigned int parametr)
- {
- _variant_t param(parametr);
- ADODB::ADO_LONGPTR size = static_cast<long>(sizeof(parametr));
- ADODB::_ParameterPtr param_obj = cmd->CreateParameter("parametr", ADODB::adUnsignedInt, ADODB::adParamInput, static_cast<long>(size), param);
- cmd->Parameters->Append(param_obj);
- return true;
- }
-
- inline bool add_parametr(ADODB::_CommandPtr cmd, float parametr)
- {
- _variant_t param;
- param.ChangeType(VT_R4);
- param.fltVal = parametr;
- ADODB::_ParameterPtr param_obj = cmd->CreateParameter("parametr", ADODB::adSingle, ADODB::adParamInput, static_cast<long>(sizeof(float)), param);
- cmd->Parameters->Append(param_obj);
- return true;
- }
-
- inline bool add_parametr(ADODB::_CommandPtr cmd, bool parametr)
- {
- _variant_t param;
- param = parametr;
- ADODB::_ParameterPtr param_obj = cmd->CreateParameter("parametr", ADODB::adBoolean, ADODB::adParamInput, sizeof(parametr), param);
- cmd->Parameters->Append(param_obj);
- return true;
- }
-
-
- inline bool add_parametr(ADODB::_CommandPtr cmd, _variant_t parametr)
- {
- ADODB::_ParameterPtr param_obj = cmd->CreateParameter("parametr", ADODB::adDBTimeStamp, ADODB::adParamInput, sizeof(parametr), parametr);
- cmd->Parameters->Append(param_obj);
- return true;
- }
-
-
- inline bool add_parametr_as_double(ADODB::_CommandPtr cmd, const DATE parametr)
- {
- _variant_t param;
- param.ChangeType(VT_R8);
- param.dblVal = parametr;
- ADODB::_ParameterPtr param_obj = cmd->CreateParameter("parametr", ADODB::adDouble, ADODB::adParamInput, sizeof(float), param);
- cmd->Parameters->Append(param_obj);
- return true;
- }
-
- template<typename TParam>
- inline bool add_parametr(ADODB::_CommandPtr cmd, const std::list<TParam> params)
- {
- for(std::list<TParam>::const_iterator it = params.begin(); it!=params.end(); it++)
- if(!add_parametr(cmd, *it))
- return false;
- return true;
- }
-
- /*
- inline bool add_parametr(ADODB::_CommandPtr cmd, const size_t parametr)
- {
- _variant_t param;
- param.ChangeType(VT_I4);
- param.intVal = parametr;
- ADODB::_ParameterPtr param_obj = cmd->CreateParameter("parametr", ADODB::adInteger, ADODB::adParamInput, sizeof(parametr), param);
- cmd->Parameters->Append(param_obj);
- return true;
- }*/
-
-
- inline bool add_parametr(ADODB::_CommandPtr cmd, const DATE parametr)
- {
- /*_variant_t param;
- param.ChangeType(VT_R8);
- param.dblVal = parametr;
- ADODB::_ParameterPtr param_obj = cmd->CreateParameter("parametr", ADODB::adDouble, ADODB::adParamInput, sizeof(float), param);
- cmd->Parameters->Append(param_obj);*/
-
- _variant_t param;
- param.ChangeType(VT_DATE);
- param.date = parametr;
- ADODB::_ParameterPtr param_obj = cmd->CreateParameter("parametr", ADODB::adDBDate, ADODB::adParamInput, sizeof(parametr), param);
- cmd->Parameters->Append(param_obj);
-
- return true;
- }
-
-
- inline bool execute_helper(ADODB::_CommandPtr cmd, _variant_t* pcount_processed = NULL)
- {
- //BEGIN_TRY_SECTION();
-
- cmd->Execute(pcount_processed, NULL, ADODB::adExecuteNoRecords);
-
-
- //CATCH_TRY_SECTION(false);
-
- return true;
- }
-
-
- inline bool select_helper(ADODB::_CommandPtr cmd, table& result_vector)
- {
- result_vector.clear();
- //BEGIN_TRY_SECTION();
-
- ADODB::_RecordsetPtr precordset = cmd->Execute(NULL, NULL, NULL);
- if(!precordset)
- {
- LOG_ERROR("DB_ERROR: cmd->Execute returned NULL!!!");
- return false;
- }
-
- //if(precordset->EndOfFile == EOF)
- //{
- // return true;
- //}
- /*try
- {
- if(precordset->MoveFirst()!= S_OK)
- {
- LOG_ERROR("DB_ERROR: Filed to move first!!!");
- return false;
- }
- }
- catch (...)
- {
- return true;
- }*/
-
- size_t current_record_index = 0;
- while(precordset->EndOfFile != EOF)
- {
- result_vector.push_back(table::value_type());
- size_t fields_count = precordset->Fields->Count;
- result_vector[current_record_index].resize(fields_count);
- for(size_t current_field_index = 0; current_field_index < fields_count; current_field_index++)
- {
- _variant_t var;
- var.ChangeType(VT_I2);
- var.intVal = static_cast<INT>(current_field_index);
- result_vector[current_record_index][current_field_index] = precordset->Fields->GetItem(var)->Value;
- }
- precordset->MoveNext();
- current_record_index++;
- }
- //CATCH_TRY_SECTION(false);
- return true;
- }
-
-
- template<typename TParam1>
- struct adapter_zero
- {
-
- };
-
- template<typename TParam1>
- struct adapter_single
- {
- TParam1 tparam1;
- };
- template<typename TParam1, typename TParam2>
- struct adapter_double
- {
- TParam1 tparam1;
- TParam2 tparam2;
- };
-
-
- template<typename TParam1, typename TParam2, typename TParam3>
- struct adapter_triple
- {
- TParam1 tparam1;
- TParam2 tparam2;
- TParam3 tparam3;
- };
-
- template<typename TParam1, typename TParam2, typename TParam3, typename TParam4>
- struct adapter_quad
- {
- TParam1 tparam1;
- TParam2 tparam2;
- TParam3 tparam3;
- TParam4 tparam4;
- };
-
- template<typename TParam1, typename TParam2, typename TParam3, typename TParam4, typename TParam5>
- struct adapter_quanto
- {
- TParam1 tparam1;
- TParam2 tparam2;
- TParam3 tparam3;
- TParam4 tparam4;
- TParam5 tparam5;
- };
-
- template<typename TParam1, typename TParam2, typename TParam3, typename TParam4, typename TParam5, typename TParam6>
- struct adapter_sixto
- {
- TParam1 tparam1;
- TParam2 tparam2;
- TParam3 tparam3;
- TParam4 tparam4;
- TParam5 tparam5;
- TParam6 tparam6;
- };
-
- template<typename TParam1, typename TParam2, typename TParam3, typename TParam4, typename TParam5, typename TParam6, typename TParam7>
- struct adapter_sevento
- {
- TParam1 tparam1;
- TParam2 tparam2;
- TParam3 tparam3;
- TParam4 tparam4;
- TParam5 tparam5;
- TParam6 tparam6;
- TParam7 tparam7;
- };
-
- template<typename TParam1, typename TParam2, typename TParam3, typename TParam4, typename TParam5, typename TParam6, typename TParam7, typename TParam8, typename TParam9>
- struct adapter_nine
- {
- TParam1 tparam1;
- TParam2 tparam2;
- TParam3 tparam3;
- TParam4 tparam4;
- TParam5 tparam5;
- TParam6 tparam6;
- TParam7 tparam7;
- TParam8 tparam8;
- TParam9 tparam9;
- };
-
- template<typename TParam1>
- bool add_parametrs_multi(ADODB::_CommandPtr cmd, const adapter_zero<TParam1>& params)
- {
- return true;
- }
-
- template<typename TParam1>
- bool add_parametrs_multi(ADODB::_CommandPtr cmd, const adapter_single<TParam1>& params)
- {
- return add_parametr(cmd, params.tparam1);
- }
-
- template<typename TParam1, typename TParam2>
- bool add_parametrs_multi(ADODB::_CommandPtr cmd, const adapter_double<TParam1, TParam2>& params)
- {
- if(!add_parametr(cmd, params.tparam1)) return false;
- return add_parametr(cmd, params.tparam2);
- }
-
- template<typename TParam1, typename TParam2, typename TParam3>
- bool add_parametrs_multi(ADODB::_CommandPtr cmd, const adapter_triple<TParam1, TParam2, TParam3>& params)
- {
- if(!add_parametr(cmd, params.tparam1)) return false;
- if(!add_parametr(cmd, params.tparam2)) return false;
- return add_parametr(cmd, params.tparam3);
- }
-
- template<typename TParam1, typename TParam2, typename TParam3, typename TParam4>
- bool add_parametrs_multi(ADODB::_CommandPtr cmd, const adapter_quad<TParam1, TParam2, TParam3, TParam4>& params)
- {
- if(!add_parametr(cmd, params.tparam1)) return false;
- if(!add_parametr(cmd, params.tparam2)) return false;
- if(!add_parametr(cmd, params.tparam3)) return false;
- return add_parametr(cmd, params.tparam4);
- }
-
- template<typename TParam1, typename TParam2, typename TParam3, typename TParam4, typename TParam5>
- bool add_parametrs_multi(ADODB::_CommandPtr cmd, const adapter_quanto<TParam1, TParam2, TParam3, TParam4, TParam5>& params)
- {
- if(!add_parametr(cmd, params.tparam1)) return false;
- if(!add_parametr(cmd, params.tparam2)) return false;
- if(!add_parametr(cmd, params.tparam3)) return false;
- if(!add_parametr(cmd, params.tparam4)) return false;
- return add_parametr(cmd, params.tparam5);
- }
-
- template<typename TParam1, typename TParam2, typename TParam3, typename TParam4, typename TParam5, typename TParam6>
- bool add_parametrs_multi(ADODB::_CommandPtr cmd, const adapter_sixto<TParam1, TParam2, TParam3, TParam4, TParam5, TParam6>& params)
- {
- if(!add_parametr(cmd, params.tparam1)) return false;
- if(!add_parametr(cmd, params.tparam2)) return false;
- if(!add_parametr(cmd, params.tparam3)) return false;
- if(!add_parametr(cmd, params.tparam4)) return false;
- if(!add_parametr(cmd, params.tparam5)) return false;
- return add_parametr(cmd, params.tparam6);
- }
-
- template<typename TParam1, typename TParam2, typename TParam3, typename TParam4, typename TParam5, typename TParam6, typename TParam7>
- bool add_parametrs_multi(ADODB::_CommandPtr cmd, const adapter_sevento<TParam1, TParam2, TParam3, TParam4, TParam5, TParam6, TParam7>& params)
- {
- if(!add_parametr(cmd, params.tparam1)) return false;
- if(!add_parametr(cmd, params.tparam2)) return false;
- if(!add_parametr(cmd, params.tparam3)) return false;
- if(!add_parametr(cmd, params.tparam4)) return false;
- if(!add_parametr(cmd, params.tparam5)) return false;
- if(!add_parametr(cmd, params.tparam6)) return false;
- return add_parametr(cmd, params.tparam7);
- }
-
- template<typename TParam1, typename TParam2, typename TParam3, typename TParam4, typename TParam5, typename TParam6, typename TParam7, typename TParam8, typename TParam9>
- bool add_parametrs_multi(ADODB::_CommandPtr cmd, const adapter_nine<TParam1, TParam2, TParam3, TParam4, TParam5, TParam6, TParam7, TParam8, TParam9>& params)
- {
- if(!add_parametr(cmd, params.tparam1)) return false;
- if(!add_parametr(cmd, params.tparam2)) return false;
- if(!add_parametr(cmd, params.tparam3)) return false;
- if(!add_parametr(cmd, params.tparam4)) return false;
- if(!add_parametr(cmd, params.tparam5)) return false;
- if(!add_parametr(cmd, params.tparam6)) return false;
- if(!add_parametr(cmd, params.tparam7)) return false;
- if(!add_parametr(cmd, params.tparam8)) return false;
- return add_parametr(cmd, params.tparam9);
- }
-
- template<typename TParam1, typename TParam2, typename TParam3, typename TParam4, typename TParam5, typename TParam6, typename TParam7>
- std::string print_parameters_multi(const adapter_sevento<TParam1, TParam2, TParam3, TParam4, TParam5, TParam6, TParam7>& params)
- {
- std::stringstream strm;
- strm << params.tparam1 << ", " << params.tparam2 << ", " << params.tparam3 << ", " << params.tparam4 << ", " << params.tparam5 << ", " << params.tparam6 << ", " << params.tparam7;
- return strm.str();
- }
-
- template<typename TParam1, typename TParam2, typename TParam3, typename TParam4, typename TParam5, typename TParam6, typename TParam7, typename TParam8, typename TParam9>
- std::string print_parameters_multi(const adapter_nine<TParam1, TParam2, TParam3, TParam4, TParam5, TParam6, TParam7, TParam8, TParam9>& params)
- {
- std::stringstream strm;
- strm << params.tparam1 << ", " << params.tparam2 << ", " << params.tparam3 << ", " << params.tparam4 << ", " << params.tparam5 << ", " << params.tparam6 << ", " << params.tparam7 << ", " << params.tparam8 << ", " << params.tparam9;
- return strm.str();
- }
-
- template<typename TParam1, typename TParam2, typename TParam3, typename TParam4, typename TParam5, typename TParam6>
- std::string print_parameters_multi(const adapter_sixto<TParam1, TParam2, TParam3, TParam4, TParam5, TParam6>& params)
- {
- std::stringstream strm;
- strm << params.tparam1 << ", " << params.tparam2 << ", " << params.tparam3 << ", " << params.tparam4 << ", " << params.tparam5 << ", " << params.tparam6;
- return strm.str();
- }
-
- template<typename TParam1, typename TParam2, typename TParam3, typename TParam4, typename TParam5>
- std::string print_parameters_multi(const adapter_quanto<TParam1, TParam2, TParam3, TParam4, TParam5>& params)
- {
- std::stringstream strm;
- strm << params.tparam1 << ", " << params.tparam2 << ", " << params.tparam3 << ", " << params.tparam4 << ", " << params.tparam5;
- return strm.str();
- }
-
-
- template<typename TParam1, typename TParam2, typename TParam3, typename TParam4>
- std::string print_parameters_multi(const adapter_quad<TParam1, TParam2, TParam3, TParam4>& params)
- {
- std::stringstream strm;
- strm << params.tparam1 << ", " << params.tparam2 << ", " << params.tparam3 << ", " << params.tparam4;
- return strm.str();
- }
-
- template<typename TParam1, typename TParam2, typename TParam3>
- std::string print_parameters_multi(const adapter_triple<TParam1, TParam2, TParam3>& params)
- {
- std::stringstream strm;
- strm << params.tparam1 << ", " << params.tparam2 << ", " << params.tparam3;
- return strm.str();
- }
-
- template<typename TParam>
- std::string get_str_param(const TParam& prm)
- {
- std::stringstream strm;
- strm << prm;
- return strm.str();
- }
-
- template<typename TParam>
- std::string get_str_param(const std::list<TParam>& prm_lst)
- {
- std::stringstream strm;
- for(std::list<TParam>::const_iterator it = prm_lst.begin();it!=prm_lst.end();it++)
- strm << get_str_param(*it) << ", ";
- return strm.str();
- }
-
-
- template<typename TParam1, typename TParam2>
- std::string print_parameters_multi(const adapter_double<TParam1, TParam2>& params)
- {
- std::stringstream strm;
- strm << get_str_param(params.tparam1) << ", " << get_str_param(params.tparam2);
- return strm.str();
- }
-
- template<typename TParam1>
- std::string print_parameters_multi(const adapter_single<TParam1>& params)
- {
- std::stringstream strm;
- strm << get_str_param(params.tparam1);
- return strm.str();
- }
-
- template<typename TParam1>
- std::string print_parameters_multi(const adapter_zero<TParam1>& params)
- {
- std::stringstream strm;
- strm << "(no parametrs)";
- return strm.str();
- }
-
-
- template<typename TParams>
- bool execute_helper_multiparam(ADODB::_ConnectionPtr pconnection, const std::string& sql_statment, const TParams& parametrs, _variant_t* pcount_processed = NULL)
- {
- PROFILE_SQL(sql_statment);
- bool res = false;
- BEGIN_TRY_SECTION();
-
- ADODB::_CommandPtr cmd;
- cmd.CreateInstance(__uuidof(ADODB::Command));
- cmd->CommandText = _bstr_t(sql_statment.c_str());
-
- if(!add_parametrs_multi(cmd, parametrs))
- return false;
-
- cmd->ActiveConnection = pconnection;
- res = execute_helper(cmd, pcount_processed);
-
- CATCH_TRY_SECTION_MESS(false, "while statment: " << sql_statment << " [params]: " << print_parameters_multi(parametrs));
- return res;
- }
-
-
- template<typename TParams>
- inline
- bool select_helper_multiparam(ADODB::_ConnectionPtr pconnection, const std::string& sql_statment, const TParams& parametrs, table& result_vector)
- {
- PROFILE_SQL(sql_statment);
- bool res = false;
- BEGIN_TRY_SECTION();
- ADODB::_CommandPtr cmd;
- cmd.CreateInstance(__uuidof(ADODB::Command));
- cmd->CommandText = _bstr_t(sql_statment.c_str());
-
-
- if(!add_parametrs_multi(cmd, parametrs))
- return false;
-
- cmd->ActiveConnection = pconnection;
- res = select_helper(cmd, result_vector);
- CATCH_TRY_SECTION_MESS(false, "while statment: " << sql_statment << " [params]: " << print_parameters_multi(parametrs));
- return res;
- }
-
-
- template<typename TParams>
- inline
- bool select_helper_param_container(ADODB::_ConnectionPtr pconnection, const std::string& sql_statment, const TParams& parametrs, table& result_vector)
- {
- PROFILE_SQL(sql_statment);
- bool res = false;
- BEGIN_TRY_SECTION();
- ADODB::_CommandPtr cmd;
- cmd.CreateInstance(__uuidof(ADODB::Command));
- cmd->CommandText = _bstr_t(sql_statment.c_str());
-
-
- for(TParams::const_iterator it = parametrs.begin(); it!=parametrs.end(); it++)
- {
- add_parametr(cmd, *it);
- }
-
- cmd->ActiveConnection = pconnection;
- res = select_helper(cmd, result_vector);
-
- CATCH_TRY_SECTION(false);
- return res;
- }
-
-
- inline
- bool execute_helper(ADODB::_ConnectionPtr pconnection, const std::string& sql_statment, _variant_t* pvt = NULL)
- {
- adapter_zero<int> params;
- return execute_helper_multiparam(pconnection, sql_statment, params, pvt);
- }
-
- template<typename TParam>
- bool execute_helper(ADODB::_ConnectionPtr pconnection, const std::string& sql_statment, const TParam& parametr)
- {
- adapter_single<TParam> params;
- params.tparam1 = parametr;
- return execute_helper_multiparam(pconnection, sql_statment, params);
- }
-
-
- template<typename TParam1, typename TParam2>
- bool execute_helper(ADODB::_ConnectionPtr pconnection, const std::string& sql_statment, const TParam1& parametr1, const TParam2& parametr2)
- {
- adapter_double<TParam1, TParam2> params;
- params.tparam1 = parametr1;
- params.tparam2 = parametr2;
- return execute_helper_multiparam(pconnection, sql_statment, params);
-
- }
-
- template<typename TParam1, typename TParam2, typename TParam3>
- bool execute_helper(ADODB::_ConnectionPtr pconnection, const std::string& sql_statment, const TParam1& parametr1, const TParam2& parametr2, const TParam3& parametr3)
- {
- adapter_triple<TParam1, TParam2, typename TParam3> params;
- params.tparam1 = parametr1;
- params.tparam2 = parametr2;
- params.tparam3 = parametr3;
- return execute_helper_multiparam(pconnection, sql_statment, params);
- }
-
- template<typename TParam1, typename TParam2, typename TParam3, typename TParam4>
- bool execute_helper(ADODB::_ConnectionPtr pconnection, const std::string& sql_statment, const TParam1& parametr1, const TParam2& parametr2, const TParam3& parametr3, const TParam4& parametr4)
- {
- adapter_quad<TParam1, TParam2, TParam3, TParam4> params;
- params.tparam1 = parametr1;
- params.tparam2 = parametr2;
- params.tparam3 = parametr3;
- params.tparam4 = parametr4;
- return execute_helper_multiparam(pconnection, sql_statment, params);
- }
-
- template<typename TParam1, typename TParam2, typename TParam3, typename TParam4, typename TParam5>
- bool execute_helper(ADODB::_ConnectionPtr pconnection, const std::string& sql_statment, const TParam1& parametr1, const TParam2& parametr2, const TParam3& parametr3, const TParam4& parametr4, const TParam5& parametr5)
- {
- adapter_quanto<TParam1, TParam2, TParam3, TParam4, TParam5> params;
- params.tparam1 = parametr1;
- params.tparam2 = parametr2;
- params.tparam3 = parametr3;
- params.tparam4 = parametr4;
- params.tparam5 = parametr5;
- return execute_helper_multiparam(pconnection, sql_statment, params);
- }
-
- template<typename TParam1, typename TParam2, typename TParam3, typename TParam4, typename TParam5, typename TParam6>
- bool execute_helper(ADODB::_ConnectionPtr pconnection, const std::string& sql_statment, const TParam1& parametr1, const TParam2& parametr2, const TParam3& parametr3, const TParam4& parametr4, const TParam5& parametr5, const TParam6& parametr6)
- {
- adapter_sixto<TParam1, TParam2, TParam3, TParam4, TParam5, TParam6> params;
- params.tparam1 = parametr1;
- params.tparam2 = parametr2;
- params.tparam3 = parametr3;
- params.tparam4 = parametr4;
- params.tparam5 = parametr5;
- params.tparam6 = parametr6;
- return execute_helper_multiparam(pconnection, sql_statment, params);
- }
-
-
- template<typename TParam1, typename TParam2, typename TParam3, typename TParam4, typename TParam5, typename TParam6, typename TParam7>
- bool execute_helper(ADODB::_ConnectionPtr pconnection, const std::string& sql_statment, const TParam1& parametr1, const TParam2& parametr2, const TParam3& parametr3, const TParam4& parametr4, const TParam5& parametr5, const TParam6& parametr6, const TParam7& parametr7)
- {
- adapter_sevento<TParam1, TParam2, TParam3, TParam4, TParam5, TParam6, TParam7> params;
- params.tparam1 = parametr1;
- params.tparam2 = parametr2;
- params.tparam3 = parametr3;
- params.tparam4 = parametr4;
- params.tparam5 = parametr5;
- params.tparam6 = parametr6;
- params.tparam7 = parametr7;
- return execute_helper_multiparam(pconnection, sql_statment, params);
- }
-
- inline
- bool select_helper(ADODB::_ConnectionPtr pconnection, const std::string& sql_statment, table& result_vector)
- {
- adapter_zero<int> params;
- return select_helper_multiparam(pconnection, sql_statment, params, result_vector);
- }
-
-
- template<typename TParam>
- bool select_helper(ADODB::_ConnectionPtr pconnection, const std::string& sql_statment, const TParam& parametr, table& result_vector)
- {
- adapter_single<TParam> params;
- params.tparam1 = parametr;
- return select_helper_multiparam(pconnection, sql_statment, params, result_vector);
- }
-
- template<typename TParam1, typename TParam2>
- bool select_helper(ADODB::_ConnectionPtr pconnection, const std::string& sql_statment, const TParam1 parametr1, const TParam2 parametr2, table& result_vector)
- {
- adapter_double<TParam1, TParam2> params;
- params.tparam1 = parametr1;
- params.tparam2 = parametr2;
- return select_helper_multiparam(pconnection, sql_statment, params, result_vector);
-
- }
-
- template<typename TParam1, typename TParam2, typename TParam3>
- bool select_helper(ADODB::_ConnectionPtr pconnection, const std::string& sql_statment, const TParam1 parametr1, const TParam2 parametr2, const TParam3 parametr3, table& result_vector)
- {
- adapter_triple<TParam1, TParam2, typename TParam3> params;
- params.tparam1 = parametr1;
- params.tparam2 = parametr2;
- params.tparam3 = parametr3;
- return select_helper_multiparam(pconnection, sql_statment, params, result_vector);
-
- }
-
- template<typename TParam1, typename TParam2, typename TParam3, typename TParam4>
- bool select_helper(ADODB::_ConnectionPtr pconnection, const std::string& sql_statment, const TParam1 parametr1, const TParam2 parametr2, const TParam3 parametr3, const TParam4 parametr4, table& result_vector)
- {
- adapter_quad<TParam1, TParam2, TParam3, TParam4> params;
- params.tparam1 = parametr1;
- params.tparam2 = parametr2;
- params.tparam3 = parametr3;
- params.tparam4 = parametr4;
- return select_helper_multiparam(pconnection, sql_statment, params, result_vector);
- }
-
- template<typename TParam1, typename TParam2, typename TParam3, typename TParam4, typename TParam5>
- bool select_helper(ADODB::_ConnectionPtr pconnection, const std::string& sql_statment, const TParam1 parametr1, const TParam2 parametr2, const TParam3 parametr3, const TParam4 parametr4, const TParam5 parametr5, table& result_vector)
- {
- adapter_quanto<TParam1, TParam2, TParam3, TParam4, TParam5> params;
- params.tparam1 = parametr1;
- params.tparam2 = parametr2;
- params.tparam3 = parametr3;
- params.tparam4 = parametr4;
- params.tparam5 = parametr5;
- return select_helper_multiparam(pconnection, sql_statment, params, result_vector);
- }
-
-
- template<typename TParam1, typename TParam2, typename TParam3, typename TParam4, typename TParam5, typename TParam6>
- bool select_helper(ADODB::_ConnectionPtr pconnection, const std::string& sql_statment, const TParam1 parametr1, const TParam2 parametr2, const TParam3 parametr3, const TParam4 parametr4, const TParam5 parametr5, const TParam6 parametr6, table& result_vector)
- {
- adapter_sixto<TParam1, TParam2, TParam3, TParam4, TParam5, TParam6> params;
- params.tparam1 = parametr1;
- params.tparam2 = parametr2;
- params.tparam3 = parametr3;
- params.tparam4 = parametr4;
- params.tparam5 = parametr5;
- params.tparam6 = parametr6;
- return select_helper_multiparam(pconnection, sql_statment, params, result_vector);
- }
-
- template<typename TParam1, typename TParam2, typename TParam3, typename TParam4, typename TParam5, typename TParam6, typename TParam7>
- bool select_helper(ADODB::_ConnectionPtr pconnection, const std::string& sql_statment, const TParam1 parametr1, const TParam2 parametr2, const TParam3 parametr3, const TParam4 parametr4, const TParam5 parametr5, const TParam6 parametr6, const TParam7 parametr7, table& result_vector)
- {
- adapter_sevento<TParam1, TParam2, TParam3, TParam4, TParam5, TParam6, TParam7> params;
- params.tparam1 = parametr1;
- params.tparam2 = parametr2;
- params.tparam3 = parametr3;
- params.tparam4 = parametr4;
- params.tparam5 = parametr5;
- params.tparam6 = parametr6;
- params.tparam7 = parametr7;
- return select_helper_multiparam(pconnection, sql_statment, params, result_vector);
- }
-
- template<typename TParam1, typename TParam2, typename TParam3, typename TParam4, typename TParam5, typename TParam6, typename TParam7, typename TParam8, typename TParam9>
- bool select_helper(ADODB::_ConnectionPtr pconnection, const std::string& sql_statment, const TParam1 parametr1, const TParam2 parametr2, const TParam3 parametr3, const TParam4 parametr4, const TParam5 parametr5, const TParam6 parametr6, const TParam7 parametr7,const TParam8 parametr8,const TParam9 parametr9, table& result_vector)
- {
- adapter_nine<TParam1, TParam2, TParam3, TParam4, TParam5, TParam6, TParam7, TParam8, TParam9> params;
- params.tparam1 = parametr1;
- params.tparam2 = parametr2;
- params.tparam3 = parametr3;
- params.tparam4 = parametr4;
- params.tparam5 = parametr5;
- params.tparam6 = parametr6;
- params.tparam7 = parametr7;
- params.tparam8 = parametr8;
- params.tparam9 = parametr9;
- return select_helper_multiparam(pconnection, sql_statment, params, result_vector);
- }
-
-
-
-
- /************************************************************************/
- /* */
- /************************************************************************/
-
- class per_thread_connection_pool
- {
- public:
- bool init(const std::string& connection_string, const std::string& login, const std::string& pass)
- {
- m_connection_string = connection_string;
- m_login = login;
- m_password = pass;
- if(!get_db_connection().GetInterfacePtr())
- return false;
-
- return true;
- }
-
- ADODB::_ConnectionPtr& get_db_connection()
- {
-
- //soci::session
-
- m_db_connections_lock.lock();
- boost::shared_ptr<ADODB::_ConnectionPtr>& conn_ptr = m_db_connections[::GetCurrentThreadId()];
- m_db_connections_lock.unlock();
- if(!conn_ptr.get())
- {
- conn_ptr.reset(new ADODB::_ConnectionPtr());
- ADODB::_ConnectionPtr& conn = *conn_ptr.get();
- //init new connection
-
- BEGIN_TRY_SECTION();
- //_bstr_t str = _bstr_t("Provider=SQLOLEDB;Data Source=SRV1;Integrated Security=SSPI;Initial Catalog=dispatcher;");
-
- if(S_OK != conn.CreateInstance(__uuidof(ADODB::Connection)))
- {
- LOG_ERROR("Failed to Create, instance, was CoInitialize called ???!");
- return conn;
- }
-
- HRESULT res = conn->Open(_bstr_t(m_connection_string.c_str()), _bstr_t(m_login.c_str()), _bstr_t(m_password.c_str()), NULL);
- if(res != S_OK)
- {
- LOG_ERROR("Failed to connect do DB, connection str:" << m_connection_string);
- return conn;
- }
- CATCH_TRY_SECTION_MESS(conn, "while creating another connection");
- LOG_PRINT("New DB Connection added for threadid=" << ::GetCurrentThreadId(), LOG_LEVEL_0);
- ado_db_helper::execute_helper(conn, "set enable_seqscan=false;");
- return conn;
- }
-
- return *conn_ptr.get();
- }
-
- //----------------------------------------------------------------------------------------------
- bool check_status()
- {
- ADODB::_ConnectionPtr& rconn = get_db_connection();
- if(!ado_db_helper::execute_helper(rconn, "SET CLIENT_ENCODING TO 'SQL_ASCII'"))
- {
-
- try{
- HRESULT res = rconn->Close();
- }
- catch(...)
- {
-
- };
- BEGIN_TRY_SECTION();
-
- HRESULT res = rconn->Open(_bstr_t(m_connection_string.c_str()), _bstr_t(m_login.c_str()), _bstr_t(m_password.c_str()), NULL);
- if(res != S_OK)
- {
- LOG_PRINT("Failed to restore connection to local AI DB", LOG_LEVEL_1);
- return false;
- }
- CATCH_TRY_SECTION(false);
- }
-
- return true;
- }
-
- protected:
- private:
- std::map<DWORD, boost::shared_ptr<ADODB::_ConnectionPtr> > m_db_connections;
- critical_section m_db_connections_lock;
- std::string m_connection_string;
- std::string m_login;
- std::string m_password;
- };
-
-
- template<typename TParam1, typename default_id_type, typename t_conn>
- bool find_or_add_t(const std::string& sql_select_statment, const std::string& sql_insert_statment, OUT default_id_type& id, OUT bool& new_object_added, TParam1 parametr_1, t_conn& c)
- {
- ado_db_helper::adapter_single<TParam1> params;
- params.tparam1 = parametr_1;
- return find_or_add_t_multiparametred(sql_select_statment, sql_insert_statment, id, new_object_added, params, c);
- }
-
-
- template<typename TParam1, typename TParam2, typename default_id_type, typename t_conn>
- bool find_or_add_t(const std::string& sql_select_statment, const std::string& sql_insert_statment, OUT default_id_type& id, OUT bool& new_object_added, TParam1 parametr_1, TParam2 parametr_2, t_conn& c)
- {
- ado_db_helper::adapter_double<TParam1, TParam2> params;
- params.tparam1 = parametr_1;
- params.tparam2 = parametr_2;
- return find_or_add_t_multiparametred(sql_select_statment, sql_insert_statment, id, new_object_added, params, c);
- }
-
-
- template<typename TParam1, typename TParam2, typename TParam3, typename default_id_type, typename t_conn>
- bool find_or_add_t(const std::string& sql_select_statment, const std::string& sql_insert_statment, OUT default_id_type& id, OUT bool& new_object_added, TParam1 parametr_1, TParam2 parametr_2, TParam3 parametr_3, t_conn& c)
- {
- ado_db_helper::adapter_triple<TParam1, TParam2, TParam3> params;
- params.tparam1 = parametr_1;
- params.tparam2 = parametr_2;
- params.tparam3 = parametr_3;
- return find_or_add_t_multiparametred(sql_select_statment, sql_insert_statment, id, new_object_added, params, c);
- }
-
- template<typename TParam1, typename TParam2, typename TParam3, typename TParam4, typename default_id_type, typename t_conn>
- bool find_or_add_t(const std::string& sql_select_statment, const std::string& sql_insert_statment, OUT default_id_type& id, OUT bool& new_object_added, TParam1 parametr_1, TParam2 parametr_2, TParam3 parametr_3, TParam4 parametr_4, t_conn& c)
- {
- ado_db_helper::adapter_quad<TParam1, TParam2, TParam3, TParam4> params;
- params.tparam1 = parametr_1;
- params.tparam2 = parametr_2;
- params.tparam3 = parametr_3;
- params.tparam4 = parametr_4;
- return find_or_add_t_multiparametred(sql_select_statment, sql_insert_statment, id, new_object_added, params, c);
- }
-
- template<typename TParams, typename default_id_type, typename t_conn>
- bool find_or_add_t_multiparametred(const std::string& sql_select_statment, const std::string& sql_insert_statment, OUT default_id_type& id, OUT bool& new_object_added, TParams params, t_conn& c)
- {
-
- //CHECK_CONNECTION(false);
-
- new_object_added = false;
- ado_db_helper::table result_table;
-
- bool res = select_helper_multiparam(c.get_db_connection(), sql_select_statment, params, result_table);
- if(!result_table.size())
- {
- res = select_helper_multiparam(c.get_db_connection(), sql_insert_statment, params, result_table);
- if(!res || !result_table.size())
- {
- //last time try to select
- res = select_helper_multiparam(c.get_db_connection(), sql_select_statment, params, result_table);
- CHECK_AND_ASSERT_MES(res, false, "Failed to execute statment: " << sql_select_statment);
- CHECK_AND_ASSERT_MES(result_table.size(), false, "No records returned from statment: " << sql_select_statment);
- }else
- {
- new_object_added = true;
- }
- }
-
- BEGIN_TRY_SECTION()
- id = result_table[0][0];
- CATCH_TRY_SECTION_MESS(false, "while converting returned value [find_or_add_t_multiparametred()]");
-
- return true;
- }
-
-}
-}
-#endif //!_DB_HELPER_H_
diff --git a/contrib/epee/include/copyable_atomic.h b/contrib/epee/include/copyable_atomic.h
deleted file mode 100644
index 00a5f484b..000000000
--- a/contrib/epee/include/copyable_atomic.h
+++ /dev/null
@@ -1,56 +0,0 @@
-// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * 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.
-// * Neither the name of the Andrey N. Sabelnikov 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 OWNER 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.
-//
-
-#pragma once
-
-#include <atomic>
-
-namespace epee
-{
- class copyable_atomic: public std::atomic<uint32_t>
- {
- public:
- copyable_atomic()
- {};
- copyable_atomic(uint32_t value)
- { store(value); }
- copyable_atomic(const copyable_atomic& a):std::atomic<uint32_t>(a.load())
- {}
- copyable_atomic& operator= (const copyable_atomic& a)
- {
- store(a.load());
- return *this;
- }
- uint32_t operator++()
- {
- return std::atomic<uint32_t>::operator++();
- }
- uint32_t operator++(int fake)
- {
- return std::atomic<uint32_t>::operator++(fake);
- }
- };
-}
diff --git a/contrib/epee/include/file_io_utils.h b/contrib/epee/include/file_io_utils.h
index 84dc79266..da05520c1 100644
--- a/contrib/epee/include/file_io_utils.h
+++ b/contrib/epee/include/file_io_utils.h
@@ -36,10 +36,7 @@ namespace file_io_utils
{
bool is_file_exist(const std::string& path);
bool save_string_to_file(const std::string& path_to_file, const std::string& str);
- bool get_file_time(const std::string& path_to_file, time_t& ft);
- bool set_file_time(const std::string& path_to_file, const time_t& ft);
bool load_file_to_string(const std::string& path_to_file, std::string& target_str, size_t max_size = 1000000000);
- bool append_string_to_file(const std::string& path_to_file, const std::string& str);
bool get_file_size(const std::string& path_to_file, uint64_t &size);
}
}
diff --git a/contrib/epee/include/global_stream_operators.h b/contrib/epee/include/global_stream_operators.h
deleted file mode 100644
index 6fbdbc2ed..000000000
--- a/contrib/epee/include/global_stream_operators.h
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * 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.
-// * Neither the name of the Andrey N. Sabelnikov 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 OWNER 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.
-//
-
-
-#pragma once
-
-std::stringstream& operator<<(std::stringstream& out, const std::wstring& ws)
-{
- std::string as = string_encoding::convert_to_ansii(ws);
- out << as;
- return out;
-}
diff --git a/contrib/epee/include/math_helper.h b/contrib/epee/include/math_helper.h
index 29acffaea..6a759b515 100644
--- a/contrib/epee/include/math_helper.h
+++ b/contrib/epee/include/math_helper.h
@@ -37,8 +37,8 @@
#include <boost/uuid/uuid.hpp>
#include <boost/uuid/random_generator.hpp>
-#include "misc_os_dependent.h"
#include "syncobj.h"
+#include "time_helper.h"
namespace epee
{
diff --git a/contrib/epee/include/misc_language.h b/contrib/epee/include/misc_language.h
index 5ccfe6fcc..ee07bbe8f 100644
--- a/contrib/epee/include/misc_language.h
+++ b/contrib/epee/include/misc_language.h
@@ -30,74 +30,14 @@
#include <boost/utility/value_init.hpp>
#include <boost/shared_ptr.hpp>
-#include <limits>
-#include <functional>
#include <vector>
namespace epee
{
-#define STD_TRY_BEGIN() try {
-
-#define STD_TRY_CATCH(where_, ret_val) \
- } \
- catch (const std::exception &e) \
- { \
- LOG_ERROR("EXCEPTION: " << where_ << ", mes: "<< e.what()); \
- return ret_val; \
- } \
- catch (...) \
- { \
- LOG_ERROR("EXCEPTION: " << where_ ); \
- return ret_val; \
- }
-
-
-
#define AUTO_VAL_INIT(v) boost::value_initialized<decltype(v)>()
namespace misc_utils
{
- template<typename t_type>
- t_type get_max_t_val(t_type t)
- {
- return (std::numeric_limits<t_type>::max)();
- }
-
-
- template<typename t_iterator>
- t_iterator move_it_forward(t_iterator it, size_t count)
- {
- while(count--)
- it++;
- return it;
- }
-
- template<typename t_iterator>
- t_iterator move_it_backward(t_iterator it, size_t count)
- {
- while(count--)
- it--;
- return it;
- }
-
-
- // TEMPLATE STRUCT less
- template<class _Ty>
- struct less_as_pod
- : public std::binary_function<_Ty, _Ty, bool>
- { // functor for operator<
- bool operator()(const _Ty& _Left, const _Ty& _Right) const
- { // apply operator< to operands
- return memcmp(&_Left, &_Right, sizeof(_Left)) < 0;
- }
- };
-
- template<class _Ty>
- bool is_less_as_pod(const _Ty& _Left, const _Ty& _Right)
- { // apply operator< to operands
- return memcmp(&_Left, &_Right, sizeof(_Left)) < 0;
- }
-
- bool sleep_no_w(long ms );
+ bool sleep_no_w(long ms);
template <typename T>
T get_mid(const T &a, const T &b)
diff --git a/contrib/epee/include/misc_os_dependent.h b/contrib/epee/include/misc_os_dependent.h
deleted file mode 100644
index 522cdf263..000000000
--- a/contrib/epee/include/misc_os_dependent.h
+++ /dev/null
@@ -1,129 +0,0 @@
-// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * 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.
-// * Neither the name of the Andrey N. Sabelnikov 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 OWNER 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.
-//
-#ifdef _WIN32
-#include <winsock2.h>
-#endif
-
-#ifdef WIN32
- #ifndef WIN32_LEAN_AND_MEAN
- #define WIN32_LEAN_AND_MEAN
- #endif
-
- //#ifdef _WIN32_WINNT
- // #undef _WIN32_WINNT
- // #define _WIN32_WINNT 0x0600
- //#endif
-
-
-#include <windows.h>
-#endif
-
-#ifdef __MACH__
-#include <mach/clock.h>
-#include <mach/mach.h>
-#endif
-
-#include <iostream>
-#include <ctime>
-
-#pragma once
-namespace epee
-{
-namespace misc_utils
-{
-
- inline uint64_t get_ns_count()
- {
-#if defined(_MSC_VER)
- return ::GetTickCount64() * 1000000;
-#elif defined(WIN32)
- static LARGE_INTEGER pcfreq = {0};
- LARGE_INTEGER ticks;
- if (!pcfreq.QuadPart)
- QueryPerformanceFrequency(&pcfreq);
- QueryPerformanceCounter(&ticks);
- ticks.QuadPart *= 1000000000; /* we want nsec */
- return ticks.QuadPart / pcfreq.QuadPart;
-#elif defined(__MACH__)
- clock_serv_t cclock;
- mach_timespec_t mts;
-
- host_get_clock_service(mach_host_self(), SYSTEM_CLOCK, &cclock);
- clock_get_time(cclock, &mts);
- mach_port_deallocate(mach_task_self(), cclock);
-
- return ((uint64_t)mts.tv_sec * 1000000000) + (mts.tv_nsec);
-#else
- struct timespec ts;
- if(clock_gettime(CLOCK_MONOTONIC, &ts) != 0) {
- return 0;
- }
- return ((uint64_t)ts.tv_sec * 1000000000) + (ts.tv_nsec);
-#endif
- }
-
- inline uint64_t get_tick_count()
- {
- return get_ns_count() / 1000000;
- }
-
-
- inline int call_sys_cmd(const std::string& cmd)
- {
- std::cout << "# " << cmd << std::endl;
-
- FILE * fp ;
- //char tstCommand[] ="ls *";
- char path[1000] = {0};
-#if !defined(__GNUC__)
- fp = _popen(cmd.c_str(), "r");
-#else
- fp = popen(cmd.c_str(), "r");
-#endif
- while ( fgets( path, 1000, fp ) != NULL )
- std::cout << path;
-
-#if !defined(__GNUC__)
- _pclose(fp);
-#else
- pclose(fp);
-#endif
- return 0;
-
- }
-
- std::string get_thread_string_id();
-
- inline bool get_gmt_time(time_t t, struct tm &tm)
- {
-#ifdef _WIN32
- return gmtime_s(&tm, &t);
-#else
- return gmtime_r(&t, &tm);
-#endif
- }
-}
-}
diff --git a/contrib/epee/include/net/abstract_tcp_server.h b/contrib/epee/include/net/abstract_tcp_server.h
deleted file mode 100644
index cbad1717c..000000000
--- a/contrib/epee/include/net/abstract_tcp_server.h
+++ /dev/null
@@ -1,318 +0,0 @@
-// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * 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.
-// * Neither the name of the Andrey N. Sabelnikov 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 OWNER 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.
-//
-
-
-
-#ifndef _ABSTRACT_TCP_SERVER_H_
-#define _ABSTRACT_TCP_SERVER_H_
-
-#include <process.h>
-#include <list>
-#include <winsock2.h>
-#include "winobj.h"
-//#include "threads_helper.h"
-#include "net_utils_base.h"
-
-#pragma comment(lib, "Ws2_32.lib")
-
-#undef MONERO_DEFAULT_LOG_CATEGORY
-#define MONERO_DEFAULT_LOG_CATEGORY "net"
-
-namespace epee
-{
-namespace net_utils
-{
- /************************************************************************/
- /* */
- /************************************************************************/
- class soket_sender: public i_service_endpoint
- {
- public:
- soket_sender(SOCKET sock):m_sock(sock){}
- private:
- virtual bool handle_send(const void* ptr, size_t cb)
- {
- if(cb != send(m_sock, (char*)ptr, (int)cb, 0))
- {
- int sock_err = WSAGetLastError();
- LOG_ERROR("soket_sender: Failed to send " << cb << " bytes, Error=" << sock_err);
- return false;
- }
- return true;
-
- }
-
- SOCKET m_sock;
- };
-
-
-
- /************************************************************************/
- /* */
- /************************************************************************/
- template<class THandler>
- class abstract_tcp_server
- {
- public:
- abstract_tcp_server();
-
- bool init_server(int port_no);
- bool deinit_server();
- bool run_server();
- bool send_stop_signal();
-
- typename THandler::config_type& get_config_object(){return m_config;}
-
- private:
- bool invoke_connection(SOCKET hnew_sock, long ip_from, int post_from);
- static unsigned __stdcall ConnectionHandlerProc(void* lpParameter);
-
- class thread_context;
- typedef std::list<thread_context> connections_container;
- typedef typename connections_container::iterator connections_iterator;
-
- struct thread_context
- {
- HANDLE m_htread;
- SOCKET m_socket;
- abstract_tcp_server* powner;
- connection_context m_context;
- typename connections_iterator m_self_it;
- };
-
- SOCKET m_listen_socket;
- int m_port;
- bool m_initialized;
- volatile LONG m_stop_server;
- volatile LONG m_threads_count;
- typename THandler::config_type m_config;
- connections_container m_connections;
- critical_section m_connections_lock;
- };
-
- template<class THandler>
- unsigned __stdcall abstract_tcp_server<THandler>::ConnectionHandlerProc(void* lpParameter)
- {
-
- thread_context* pthread_context = (thread_context*)lpParameter;
- if(!pthread_context)
- return 0;
- abstract_tcp_server<THandler>* pthis = pthread_context->powner;
-
- ::InterlockedIncrement(&pthis->m_threads_count);
-
- ::CoInitialize(NULL);
-
-
- LOG_PRINT("Handler thread STARTED with socket=" << pthread_context->m_socket, LOG_LEVEL_2);
- int res = 0;
-
- soket_sender sndr(pthread_context->m_socket);
- THandler srv(&sndr, pthread_context->powner->m_config, pthread_context->m_context);
-
-
- srv.after_init_connection();
-
- char buff[1000] = {0};
- std::string ansver;
- while ( (res = recv(pthread_context->m_socket, (char*)buff, 1000, 0)) > 0)
- {
- LOG_PRINT("Data in, " << res << " bytes", LOG_LEVEL_3);
- if(!srv.handle_recv(buff, res))
- break;
- }
- shutdown(pthread_context->m_socket, SD_BOTH);
- closesocket(pthread_context->m_socket);
-
- abstract_tcp_server* powner = pthread_context->powner;
- LOG_PRINT("Handler thread with socket=" << pthread_context->m_socket << " STOPPED", LOG_LEVEL_2);
- powner->m_connections_lock.lock();
- ::CloseHandle(pthread_context->m_htread);
- pthread_context->powner->m_connections.erase(pthread_context->m_self_it);
- powner->m_connections_lock.unlock();
- CoUninitialize();
- ::InterlockedDecrement(&pthis->m_threads_count);
- return 1;
- }
- //----------------------------------------------------------------------------------------
- template<class THandler>
- abstract_tcp_server<THandler>::abstract_tcp_server():m_listen_socket(INVALID_SOCKET),
- m_initialized(false),
- m_stop_server(0), m_port(0), m_threads_count(0)
- {
-
- }
-
- //----------------------------------------------------------------------------------------
- template<class THandler>
- bool abstract_tcp_server<THandler>::init_server(int port_no)
- {
- m_port = port_no;
- WSADATA wsad = {0};
- int err = ::WSAStartup(MAKEWORD(2,2), &wsad);
- if ( err != 0 || LOBYTE( wsad.wVersion ) != 2 || HIBYTE( wsad.wVersion ) != 2 )
- {
- LOG_ERROR("Could not find a usable WinSock DLL, err = " << err << " \"" << socket_errors::get_socket_error_text(err) <<"\"");
- return false;
- }
-
- m_initialized = true;
-
- m_listen_socket = ::WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, 0);
- if(INVALID_SOCKET == m_listen_socket)
- {
- err = ::WSAGetLastError();
- LOG_ERROR("Failed to create socket, err = " << err << " \"" << socket_errors::get_socket_error_text(err) <<"\"");
- return false;
- }
-
- int opt = 1;
- setsockopt (m_listen_socket, SOL_SOCKET,SO_REUSEADDR, reinterpret_cast<char*>(&opt), sizeof(int));
-
- sockaddr_in adr = {0};
- adr.sin_family = AF_INET;
- adr.sin_addr.s_addr = htonl(INADDR_ANY);
- adr.sin_port = (u_short)htons(port_no);
-
- err = bind(m_listen_socket, (const sockaddr*)&adr, sizeof(adr ));
- if(SOCKET_ERROR == err )
- {
- err = ::WSAGetLastError();
- LOG_PRINT("Failed to Bind, err = " << err << " \"" << socket_errors::get_socket_error_text(err) <<"\"", LOG_LEVEL_2);
- deinit_server();
- return false;
- }
-
- ::InterlockedExchange(&m_stop_server, 0);
-
- return true;
- }
- //----------------------------------------------------------------------------------------
- template<class THandler>
- bool abstract_tcp_server<THandler>::deinit_server()
- {
-
- if(!m_initialized)
- return true;
-
- if(INVALID_SOCKET != m_listen_socket)
- {
- shutdown(m_listen_socket, SD_BOTH);
- int res = closesocket(m_listen_socket);
- if(SOCKET_ERROR == res)
- {
- int err = ::WSAGetLastError();
- LOG_ERROR("Failed to closesocket(), err = " << err << " \"" << socket_errors::get_socket_error_text(err) <<"\"");
- }
- m_listen_socket = INVALID_SOCKET;
- }
-
- int res = ::WSACleanup();
- if(SOCKET_ERROR == res)
- {
- int err = ::WSAGetLastError();
- LOG_ERROR("Failed to WSACleanup(), err = " << err << " \"" << socket_errors::get_socket_error_text(err) <<"\"");
- }
- m_initialized = false;
-
- return true;
- }
- //----------------------------------------------------------------------------------------
- template<class THandler>
- bool abstract_tcp_server<THandler>::send_stop_signal()
- {
- InterlockedExchange(&m_stop_server, 1);
- return true;
- }
- //----------------------------------------------------------------------------------------
- template<class THandler>
- bool abstract_tcp_server<THandler>::run_server()
- {
- int err = listen(m_listen_socket, 10000);
- if(SOCKET_ERROR == err )
- {
- err = ::WSAGetLastError();
- LOG_ERROR("Failed to listen, err = " << err << " \"" << socket_errors::get_socket_error_text(err) <<"\"");
- return false;
- }
-
- LOG_PRINT("Listening port "<< m_port << "...." , LOG_LEVEL_2);
-
- while(!m_stop_server)
- {
- sockaddr_in adr_from = {0};
- int adr_len = sizeof(adr_from);
- fd_set read_fs = {0};
- read_fs.fd_count = 1;
- read_fs.fd_array[0] = m_listen_socket;
- TIMEVAL tv = {0};
- tv.tv_usec = 100;
- int select_res = select(0, &read_fs, NULL, NULL, &tv);
- if(!select_res)
- continue;
- SOCKET new_sock = WSAAccept(m_listen_socket, (sockaddr *)&adr_from, &adr_len, NULL, NULL);
- LOG_PRINT("Accepted connection on socket=" << new_sock, LOG_LEVEL_2);
- invoke_connection(new_sock, adr_from.sin_addr.s_addr, adr_from.sin_port);
- }
-
- deinit_server();
-
-#define ABSTR_TCP_SRV_WAIT_COUNT_MAX 5000
-#define ABSTR_TCP_SRV_WAIT_COUNT_INTERVAL 1000
-
- int wait_count = 0;
-
- while(m_threads_count && wait_count*1000 < ABSTR_TCP_SRV_WAIT_COUNT_MAX)
- {
- ::Sleep(ABSTR_TCP_SRV_WAIT_COUNT_INTERVAL);
- wait_count++;
- }
- LOG_PRINT("abstract_tcp_server exit with wait count=" << wait_count*ABSTR_TCP_SRV_WAIT_COUNT_INTERVAL << "(max=" << ABSTR_TCP_SRV_WAIT_COUNT_MAX <<")", LOG_LEVEL_0);
-
- return true;
- }
- //----------------------------------------------------------------------------------------
- template<class THandler>
- bool abstract_tcp_server<THandler>::invoke_connection(SOCKET hnew_sock, const network_address &remote_address)
- {
- m_connections_lock.lock();
- m_connections.push_back(thread_context());
- m_connections_lock.unlock();
- m_connections.back().m_socket = hnew_sock;
- m_connections.back().powner = this;
- m_connections.back().m_self_it = --m_connections.end();
- m_connections.back().m_context.m_remote_address = remote_address;
- m_connections.back().m_htread = threads_helper::create_thread(ConnectionHandlerProc, &m_connections.back()); // ugh, seems very risky
-
- return true;
- }
- //----------------------------------------------------------------------------------------
-
- //----------------------------------------------------------------------------------------
- //----------------------------------------------------------------------------------------
-}
-}
-#endif //_ABSTRACT_TCP_SERVER_H_
diff --git a/contrib/epee/include/net/abstract_tcp_server2.inl b/contrib/epee/include/net/abstract_tcp_server2.inl
index 58cec5520..0c3b457bc 100644
--- a/contrib/epee/include/net/abstract_tcp_server2.inl
+++ b/contrib/epee/include/net/abstract_tcp_server2.inl
@@ -44,8 +44,6 @@
#include "warnings.h"
#include "string_tools_lexical.h"
#include "misc_language.h"
-#include "net/local_ip.h"
-#include "pragma_comp_defs.h"
#include <sstream>
#include <iomanip>
@@ -64,7 +62,6 @@
#define TIMEOUT_EXTRA_MS_PER_BYTE 0.2
-PRAGMA_WARNING_PUSH
namespace epee
{
namespace net_utils
@@ -79,8 +76,6 @@ namespace net_utils
/************************************************************************/
/* */
/************************************************************************/
-PRAGMA_WARNING_DISABLE_VS(4355)
-
template<class t_protocol_handler>
connection<t_protocol_handler>::connection( boost::asio::io_service& io_service,
std::shared_ptr<shared_state> state,
@@ -111,7 +106,6 @@ PRAGMA_WARNING_DISABLE_VS(4355)
MDEBUG("test, connection constructor set m_connection_type="<<m_connection_type);
}
-PRAGMA_WARNING_DISABLE_VS(4355)
//---------------------------------------------------------------------------------
template<class t_protocol_handler>
connection<t_protocol_handler>::~connection() noexcept(false)
@@ -1092,8 +1086,6 @@ PRAGMA_WARNING_DISABLE_VS(4355)
}
}
//-----------------------------------------------------------------------------
-PUSH_WARNINGS
-DISABLE_GCC_WARNING(maybe-uninitialized)
template<class t_protocol_handler>
bool boosted_tcp_server<t_protocol_handler>::init_server(const std::string port, const std::string& address,
const std::string port_ipv6, const std::string address_ipv6, bool use_ipv6, bool require_ipv4,
@@ -1113,7 +1105,6 @@ DISABLE_GCC_WARNING(maybe-uninitialized)
}
return this->init_server(p, address, p_ipv6, address_ipv6, use_ipv6, require_ipv4, std::move(ssl_options));
}
-POP_WARNINGS
//---------------------------------------------------------------------------------
template<class t_protocol_handler>
bool boosted_tcp_server<t_protocol_handler>::worker_thread()
@@ -1734,4 +1725,3 @@ POP_WARNINGS
} // namespace
} // namespace
-PRAGMA_WARNING_POP
diff --git a/contrib/epee/include/net/abstract_tcp_server_cp.h b/contrib/epee/include/net/abstract_tcp_server_cp.h
deleted file mode 100644
index f10f4203f..000000000
--- a/contrib/epee/include/net/abstract_tcp_server_cp.h
+++ /dev/null
@@ -1,236 +0,0 @@
-// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * 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.
-// * Neither the name of the Andrey N. Sabelnikov 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 OWNER 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.
-//
-
-
-#ifndef _LEVIN_CP_SERVER_H_
-#define _LEVIN_CP_SERVER_H_
-
-#include <winsock2.h>
-#include <rpc.h>
-#include <string>
-#include <map>
-#include <boost/shared_ptr.hpp>
-
-#include "misc_log_ex.h"
-//#include "threads_helper.h"
-#include "syncobj.h"
-#define ENABLE_PROFILING
-#include "profile_tools.h"
-#include "net_utils_base.h"
-#include "pragma_comp_defs.h"
-
-#undef MONERO_DEFAULT_LOG_CATEGORY
-#define MONERO_DEFAULT_LOG_CATEGORY "net"
-
-#define LEVIN_DEFAULT_DATA_BUFF_SIZE 2000
-
-namespace epee
-{
-namespace net_utils
-{
-
- template<class TProtocol>
- class cp_server_impl//: public abstract_handler
- {
- public:
- cp_server_impl(/*abstract_handler* phandler = NULL*/);
- virtual ~cp_server_impl();
-
- bool init_server(int port_no);
- bool deinit_server();
- bool run_server(int threads_count = 0);
- bool send_stop_signal();
- bool is_stop_signal();
- virtual bool on_net_idle(){return true;}
- size_t get_active_connections_num();
- typename TProtocol::config_type& get_config_object(){return m_config;}
- private:
- enum overlapped_operation_type
- {
- op_type_recv,
- op_type_send,
- op_type_stop
- };
-
- struct io_data_base
- {
- OVERLAPPED m_overlapped;
- WSABUF DataBuf;
- overlapped_operation_type m_op_type;
- DWORD TotalBuffBytes;
- volatile LONG m_is_in_use;
- char Buffer[1];
- };
-
-PRAGMA_WARNING_PUSH
-PRAGMA_WARNING_DISABLE_VS(4355)
- template<class TProtocol>
- struct connection: public net_utils::i_service_endpoint
- {
- connection(typename TProtocol::config_type& ref_config):m_sock(INVALID_SOCKET), m_tprotocol_handler(this, ref_config, context), m_psend_data(NULL), m_precv_data(NULL), m_asked_to_shutdown(0), m_connection_shutwoned(0)
- {
- }
-
- //connection():m_sock(INVALID_SOCKET), m_tprotocol_handler(this, m_dummy_config, context), m_psend_data(NULL), m_precv_data(NULL), m_asked_to_shutdown(0), m_connection_shutwoned(0)
- //{
- //}
-
- connection<TProtocol>& operator=(const connection<TProtocol>& obj)
- {
- return *this;
- }
-
- bool init_buffers()
- {
- m_psend_data = (io_data_base*)new char[sizeof(io_data_base) + LEVIN_DEFAULT_DATA_BUFF_SIZE-1];
- m_psend_data->TotalBuffBytes = LEVIN_DEFAULT_DATA_BUFF_SIZE;
- m_precv_data = (io_data_base*)new char[sizeof(io_data_base) + LEVIN_DEFAULT_DATA_BUFF_SIZE-1];
- m_precv_data->TotalBuffBytes = LEVIN_DEFAULT_DATA_BUFF_SIZE;
- return true;
- }
-
- bool query_shutdown()
- {
- if(!::InterlockedCompareExchange(&m_asked_to_shutdown, 1, 0))
- {
- m_psend_data->m_op_type = op_type_stop;
- ::PostQueuedCompletionStatus(m_completion_port, 0, (ULONG_PTR)this, &m_psend_data->m_overlapped);
- }
- return true;
- }
-
- //bool set_config(typename TProtocol::config_type& config)
- //{
- // this->~connection();
- // new(this) connection<TProtocol>(config);
- // return true;
- //}
- ~connection()
- {
- if(m_psend_data)
- delete m_psend_data;
-
- if(m_precv_data)
- delete m_precv_data;
- }
- virtual bool handle_send(const void* ptr, size_t cb)
- {
- PROFILE_FUNC("[handle_send]");
- if(m_psend_data->TotalBuffBytes < cb)
- resize_send_buff((DWORD)cb);
-
- ZeroMemory(&m_psend_data->m_overlapped, sizeof(OVERLAPPED));
- m_psend_data->DataBuf.len = (u_long)cb;//m_psend_data->TotalBuffBytes;
- m_psend_data->DataBuf.buf = m_psend_data->Buffer;
- memcpy(m_psend_data->DataBuf.buf, ptr, cb);
- m_psend_data->m_op_type = op_type_send;
- InterlockedExchange(&m_psend_data->m_is_in_use, 1);
- DWORD bytes_sent = 0;
- DWORD flags = 0;
- int res = 0;
- {
- PROFILE_FUNC("[handle_send] ::WSASend");
- res = ::WSASend(m_sock, &(m_psend_data->DataBuf), 1, &bytes_sent, flags, &(m_psend_data->m_overlapped), NULL);
- }
-
- if(res == SOCKET_ERROR )
- {
- int err = ::WSAGetLastError();
- if(WSA_IO_PENDING == err )
- return true;
- }
- LOG_ERROR("BIG FAIL: WSASend error code not correct, res=" << res << " last_err=" << err);
- ::InterlockedExchange(&m_psend_data->m_is_in_use, 0);
- query_shutdown();
- //closesocket(m_psend_data);
- return false;
- }else if(0 == res)
- {
- ::InterlockedExchange(&m_psend_data->m_is_in_use, 0);
- if(!bytes_sent || bytes_sent != cb)
- {
- int err = ::WSAGetLastError();
- LOG_ERROR("BIG FAIL: WSASend immediatly complete? but bad results, res=" << res << " last_err=" << err);
- query_shutdown();
- return false;
- }else
- {
- return true;
- }
- }
-
- return true;
- }
- bool resize_send_buff(DWORD new_size)
- {
- if(m_psend_data->TotalBuffBytes >= new_size)
- return true;
-
- delete m_psend_data;
- m_psend_data = (io_data_base*)new char[sizeof(io_data_base) + new_size-1];
- m_psend_data->TotalBuffBytes = new_size;
- LOG_PRINT("Connection buffer resized up to " << new_size, LOG_LEVEL_3);
- return true;
- }
-
-
- SOCKET m_sock;
- net_utils::connection_context_base context;
- TProtocol m_tprotocol_handler;
- typename TProtocol::config_type m_dummy_config;
- io_data_base* m_precv_data;
- io_data_base* m_psend_data;
- HANDLE m_completion_port;
- volatile LONG m_asked_to_shutdown;
- volatile LONG m_connection_shutwoned;
- };
-PRAGMA_WARNING_POP
-
- bool worker_thread_member();
- static unsigned CALLBACK worker_thread(void* param);
-
- bool add_new_connection(SOCKET new_sock, long ip_from, int port_from);
- bool shutdown_connection(connection<TProtocol>* pconn);
-
-
- typedef std::map<SOCKET, boost::shared_ptr<connection<TProtocol> > > connections_container;
- SOCKET m_listen_socket;
- HANDLE m_completion_port;
- connections_container m_connections;
- critical_section m_connections_lock;
- int m_port;
- volatile LONG m_stop;
- //abstract_handler* m_phandler;
- bool m_initialized;
- volatile LONG m_worker_thread_counter;
- typename TProtocol::config_type m_config;
- };
-}
-}
-#include "abstract_tcp_server_cp.inl"
-
-
-#endif //_LEVIN_SERVER_H_
diff --git a/contrib/epee/include/net/abstract_tcp_server_cp.inl b/contrib/epee/include/net/abstract_tcp_server_cp.inl
deleted file mode 100644
index e0ef6470e..000000000
--- a/contrib/epee/include/net/abstract_tcp_server_cp.inl
+++ /dev/null
@@ -1,607 +0,0 @@
-// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * 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.
-// * Neither the name of the Andrey N. Sabelnikov 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 OWNER 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.
-//
-
-
-#pragma comment(lib, "Ws2_32.lib")
-
-#undef MONERO_DEFAULT_LOG_CATEGORY
-#define MONERO_DEFAULT_LOG_CATEGORY "net"
-
-namespace epee
-{
-namespace net_utils
-{
-template<class TProtocol>
-cp_server_impl<TProtocol>::cp_server_impl():
- m_port(0), m_stop(false),
- m_worker_thread_counter(0), m_listen_socket(INVALID_SOCKET)
-{
-}
-//-------------------------------------------------------------
-template<class TProtocol>
-cp_server_impl<TProtocol>::~cp_server_impl()
-{
- deinit_server();
-}
-//-------------------------------------------------------------
-template<class TProtocol>
-bool cp_server_impl<TProtocol>::init_server(int port_no)
-{
- m_port = port_no;
-
- WSADATA wsad = {0};
- int err = ::WSAStartup(MAKEWORD(2,2), &wsad);
- if ( err != 0 || LOBYTE( wsad.wVersion ) != 2 || HIBYTE( wsad.wVersion ) != 2 )
- {
- LOG_ERROR("Could not find a usable WinSock DLL, err = " << err << " \"" << socket_errors::get_socket_error_text(err) <<"\"");
- return false;
- }
-
- m_initialized = true;
-
- m_listen_socket = ::WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, WSA_FLAG_OVERLAPPED);
- if(INVALID_SOCKET == m_listen_socket)
- {
- err = ::WSAGetLastError();
- LOG_ERROR("Failed to create socket, err = " << err << " \"" << socket_errors::get_socket_error_text(err) <<"\"");
- return false;
- }
-
-
- int opt = 1;
- err = setsockopt (m_listen_socket, SOL_SOCKET,SO_REUSEADDR, reinterpret_cast<char*>(&opt), sizeof(int));
- if(SOCKET_ERROR == err )
- {
- err = ::WSAGetLastError();
- LOG_PRINT("Failed to setsockopt(SO_REUSEADDR), err = " << err << " \"" << socket_errors::get_socket_error_text(err) <<"\"", LOG_LEVEL_1);
- deinit_server();
- return false;
- }
-
-
- sockaddr_in adr = {0};
- adr.sin_family = AF_INET;
- adr.sin_addr.s_addr = htonl(INADDR_ANY);
- adr.sin_port = (u_short)htons(m_port);
-
- //binding
- err = bind(m_listen_socket, (const sockaddr*)&adr, sizeof(adr ));
- if(SOCKET_ERROR == err )
- {
- err = ::WSAGetLastError();
- LOG_PRINT("Failed to Bind, err = " << err << " \"" << socket_errors::get_socket_error_text(err) <<"\"", LOG_LEVEL_1);
- deinit_server();
- return false;
- }
-
-
- m_completion_port = ::CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0);
- if(INVALID_HANDLE_VALUE == m_completion_port)
- {
- err = ::WSAGetLastError();
- LOG_PRINT("Failed to CreateIoCompletionPort, err = " << err << " \"" << socket_errors::get_socket_error_text(err) <<"\"", LOG_LEVEL_1);
- deinit_server();
- return false;
- }
-
-
- return true;
-}
-//-------------------------------------------------------------
-
-//-------------------------------------------------------------
-static int CALLBACK CPConditionFunc(
- IN LPWSABUF lpCallerId,
- IN LPWSABUF lpCallerData,
- IN OUT LPQOS lpSQOS,
- IN OUT LPQOS lpGQOS,
- IN LPWSABUF lpCalleeId,
- OUT LPWSABUF lpCalleeData,
- OUT GROUP FAR *g,
- IN DWORD_PTR dwCallbackData
- )
-{
-
- /*cp_server_impl* pthis = (cp_server_impl*)dwCallbackData;
- if(!pthis)
- return CF_REJECT;*/
- /*if(pthis->get_active_connections_num()>=FD_SETSIZE-1)
- {
- LOG_PRINT("Maximum connections count overfull.", LOG_LEVEL_2);
- return CF_REJECT;
- }*/
-
- return CF_ACCEPT;
-}
-//-------------------------------------------------------------
-template<class TProtocol>
-size_t cp_server_impl<TProtocol>::get_active_connections_num()
-{
- return m_connections.size();
-}
-//-------------------------------------------------------------
-template<class TProtocol>
-unsigned CALLBACK cp_server_impl<TProtocol>::worker_thread(void* param)
-{
- if(!param)
- return 0;
-
- cp_server_impl<TProtocol>* pthis = (cp_server_impl<TProtocol>*)param;
- pthis->worker_thread_member();
- return 1;
-}
-//-------------------------------------------------------------
-template<class TProtocol>
-bool cp_server_impl<TProtocol>::worker_thread_member()
-{
- LOG_PRINT("Worker thread STARTED", LOG_LEVEL_1);
- bool stop_handling = false;
- while(!stop_handling)
- {
- PROFILE_FUNC("[worker_thread]Worker Loop");
- DWORD bytes_transfered = 0;
- connection<TProtocol>* pconnection = 0;
- io_data_base* pio_data = 0;
-
- {
- PROFILE_FUNC("[worker_thread]GetQueuedCompletionStatus");
- BOOL res = ::GetQueuedCompletionStatus (m_completion_port, &bytes_transfered , (PULONG_PTR)&pconnection, (LPOVERLAPPED *)&pio_data, INFINITE);
- if (res == 0)
- {
- // check return code for error
- int err = GetLastError();
- LOG_PRINT("GetQueuedCompletionStatus failed with error " << err << " " << log_space::get_win32_err_descr(err), LOG_LEVEL_1);
-
- if(pio_data)
- ::InterlockedExchange(&pio_data->m_is_in_use, 0);
-
-
- continue;
- }
- }
-
- if(pio_data)
- ::InterlockedExchange(&pio_data->m_is_in_use, 0);
-
-
-
- if(!bytes_transfered && !pconnection && !pio_data)
- {
- //signal to stop
- break;
- }
- if(!pconnection || !pio_data)
- {
- LOG_PRINT("BIG FAIL: pconnection or pio_data is empty: pconnection=" << pconnection << " pio_data=" << pio_data, LOG_LEVEL_0);
- break;
- }
-
-
-
- if(::InterlockedCompareExchange(&pconnection->m_connection_shutwoned, 0, 0))
- {
- LOG_ERROR("InterlockedCompareExchange(&pconnection->m_connection_shutwoned, 0, 0)");
- //DebugBreak();
- }
-
- if(pio_data->m_op_type == op_type_stop)
- {
- if(!pconnection)
- {
- LOG_ERROR("op_type=op_type_stop, but pconnection is empty!!!");
- continue;
- }
- shutdown_connection(pconnection);
- continue;//
- }
- else if(pio_data->m_op_type == op_type_send)
- {
- continue;
- //do nothing, just queuing request
- }else if(pio_data->m_op_type == op_type_recv)
- {
- PROFILE_FUNC("[worker_thread]m_tprotocol_handler.handle_recv");
- if(bytes_transfered)
- {
- bool res = pconnection->m_tprotocol_handler.handle_recv(pio_data->Buffer, bytes_transfered);
- if(!res)
- pconnection->query_shutdown();
- }
- else
- {
- pconnection->query_shutdown();
- continue;
- }
-
- }
-
- //preparing new request,
-
- {
- PROFILE_FUNC("[worker_thread]RECV Request small loop");
- int res = 0;
- while(true)
- {
- LOG_PRINT("Prepearing data for WSARecv....", LOG_LEVEL_3);
- ZeroMemory(&pio_data->m_overlapped, sizeof(OVERLAPPED));
- pio_data->DataBuf.len = pio_data->TotalBuffBytes;
- pio_data->DataBuf.buf = pio_data->Buffer;
- pio_data->m_op_type = op_type_recv;
- //calling WSARecv() and go to completion waiting
- DWORD bytes_recvd = 0;
- DWORD flags = 0;
-
- LOG_PRINT("Calling WSARecv....", LOG_LEVEL_3);
- ::InterlockedExchange(&pio_data->m_is_in_use, 1);
- res = WSARecv(pconnection->m_sock, &(pio_data->DataBuf), 1, &bytes_recvd , &flags, &(pio_data->m_overlapped), NULL);
- if(res == SOCKET_ERROR )
- {
- int err = ::WSAGetLastError();
- if(WSA_IO_PENDING == err )
- {//go pending, ok
- LOG_PRINT("WSARecv return WSA_IO_PENDING", LOG_LEVEL_3);
- break;
- }
- LOG_ERROR("BIG FAIL: WSARecv error code not correct, res=" << res << " last_err=" << err);
- ::InterlockedExchange(&pio_data->m_is_in_use, 0);
- pconnection->query_shutdown();
- break;
- }
- break;
- /*else if(0 == res)
- {
- if(!bytes_recvd)
- {
- ::InterlockedExchange(&pio_data->m_is_in_use, 0);
- LOG_PRINT("WSARecv return 0, bytes_recvd=0, graceful close.", LOG_LEVEL_3);
- int err = ::WSAGetLastError();
- //LOG_ERROR("BIG FAIL: WSARecv error code not correct, res=" << res << " last_err=" << err);
- //pconnection->query_shutdown();
- break;
- }else
- {
- LOG_PRINT("WSARecv return immediatily 0, bytes_recvd=" << bytes_recvd, LOG_LEVEL_3);
- //pconnection->m_tprotocol_handler.handle_recv(pio_data->Buffer, bytes_recvd);
- }
- }*/
- }
- }
- }
-
-
- LOG_PRINT("Worker thread STOPED", LOG_LEVEL_1);
- ::InterlockedDecrement(&m_worker_thread_counter);
- return true;
-}
-//-------------------------------------------------------------
-template<class TProtocol>
-bool cp_server_impl<TProtocol>::shutdown_connection(connection<TProtocol>* pconn)
-{
- PROFILE_FUNC("[shutdown_connection]");
-
- if(!pconn)
- {
- LOG_ERROR("Attempt to remove null pptr connection!");
- return false;
- }
- else
- {
- LOG_PRINT("Shutting down connection ("<< pconn << ")", LOG_LEVEL_3);
- }
- m_connections_lock.lock();
- connections_container::iterator it = m_connections.find(pconn->m_sock);
- m_connections_lock.unlock();
- if(it == m_connections.end())
- {
- LOG_ERROR("Failed to find closing socket=" << pconn->m_sock);
- return false;
- }
- SOCKET sock = it->second->m_sock;
- {
- PROFILE_FUNC("[shutdown_connection] shutdown, close");
- ::shutdown(it->second->m_sock, SD_SEND );
- }
- size_t close_sock_wait_count = 0;
- {
- LOG_PRINT("Entered to 'in_use wait zone'", LOG_LEVEL_3);
- PROFILE_FUNC("[shutdown_connection] wait for in_use");
- while(::InterlockedCompareExchange(&it->second->m_precv_data->m_is_in_use, 1, 1))
- {
-
- Sleep(100);
- close_sock_wait_count++;
- }
- LOG_PRINT("First step to 'in_use wait zone'", LOG_LEVEL_3);
-
-
- while(::InterlockedCompareExchange(&it->second->m_psend_data->m_is_in_use, 1, 1))
- {
- Sleep(100);
- close_sock_wait_count++;
- }
- LOG_PRINT("Leaved 'in_use wait zone'", LOG_LEVEL_3);
- }
-
- ::closesocket(it->second->m_sock);
-
- ::InterlockedExchange(&it->second->m_connection_shutwoned, 1);
- m_connections_lock.lock();
- m_connections.erase(it);
- m_connections_lock.unlock();
- LOG_PRINT("Socked " << sock << " closed, wait_count=" << close_sock_wait_count, LOG_LEVEL_2);
- return true;
-}
-//-------------------------------------------------------------
-template<class TProtocol>
-bool cp_server_impl<TProtocol>::run_server(int threads_count = 0)
-{
- int err = listen(m_listen_socket, 100);
- if(SOCKET_ERROR == err )
- {
- err = ::WSAGetLastError();
- LOG_ERROR("Failed to listen, err = " << err << " \"" << socket_errors::get_socket_error_text(err) <<"\"");
- return false;
- }
-
- if(!threads_count)
- {
- SYSTEM_INFO si = {0};
- ::GetSystemInfo(&si);
- threads_count = si.dwNumberOfProcessors + 2;
- }
- for(int i = 0; i != threads_count; i++)
- {
- boost::thread(boost::bind(&cp_server_impl::worker_thread_member, this));
- //HANDLE h_thread = threads_helper::create_thread(worker_thread, this);
- InterlockedIncrement(&m_worker_thread_counter);
- //::CloseHandle(h_thread);
- }
-
- LOG_PRINT("Numbers of worker threads started: " << threads_count, LOG_LEVEL_1);
-
- m_stop = false;
- while(!m_stop)
- {
- PROFILE_FUNC("[run_server] main_loop");
- TIMEVAL tv = {0};
- tv.tv_sec = 0;
- tv.tv_usec = 100;
- fd_set sock_set;
- sock_set.fd_count = 1;
- sock_set.fd_array[0] = m_listen_socket;
- int select_res = 0;
- {
- PROFILE_FUNC("[run_server] select");
- select_res = select(0, &sock_set, &sock_set, NULL, &tv);
- }
-
- if(SOCKET_ERROR == select_res)
- {
- err = ::WSAGetLastError();
- LOG_ERROR("Failed to select, err = " << err << " \"" << socket_errors::get_socket_error_text(err) <<"\"");
- return false;
- }
- if(!select_res)
- {
- on_net_idle();
- continue;
- }
- else
- {
- sockaddr_in adr_from = {0};
- int adr_len = sizeof(adr_from);
- SOCKET new_sock = INVALID_SOCKET;
- {
- PROFILE_FUNC("[run_server] WSAAccept");
- new_sock = ::WSAAccept(m_listen_socket, (sockaddr *)&adr_from, &adr_len, CPConditionFunc, (DWORD_PTR)this);
- }
-
- if(INVALID_SOCKET == new_sock)
- {
- if(m_stop)
- break;
- int err = ::WSAGetLastError();
- LOG_PRINT("Failed to WSAAccept, err = " << err << " \"" << socket_errors::get_socket_error_text(err) <<"\"", LOG_LEVEL_2);
- continue;
- }
- LOG_PRINT("Accepted connection (new socket=" << new_sock << ")", LOG_LEVEL_2);
- {
- PROFILE_FUNC("[run_server] Add new connection");
- add_new_connection(new_sock, adr_from.sin_addr.s_addr, adr_from.sin_port);
- }
-
- }
-
- }
- LOG_PRINT("Closing connections("<< m_connections.size() << ") and waiting...", LOG_LEVEL_2);
- m_connections_lock.lock();
- for(connections_container::iterator it = m_connections.begin(); it != m_connections.end(); it++)
- {
- ::shutdown(it->second->m_sock, SD_BOTH);
- ::closesocket(it->second->m_sock);
- }
- m_connections_lock.unlock();
- size_t wait_count = 0;
- while(m_connections.size() && wait_count < 100)
- {
- ::Sleep(100);
- wait_count++;
- }
- LOG_PRINT("Connections closed OK (wait_count=" << wait_count << ")", LOG_LEVEL_2);
-
-
- LOG_PRINT("Stopping worker threads("<< m_worker_thread_counter << ").", LOG_LEVEL_2);
- for(int i = 0; i<m_worker_thread_counter; i++)
- {
- ::PostQueuedCompletionStatus(m_completion_port, 0, 0, 0);
- }
-
- wait_count = 0;
- while(InterlockedCompareExchange(&m_worker_thread_counter, 0, 0) && wait_count < 100)
- {
- Sleep(100);
- wait_count++;
- }
-
- LOG_PRINT("Net Server STOPPED, wait_count = " << wait_count, LOG_LEVEL_1);
- return true;
-}
-//-------------------------------------------------------------
-template<class TProtocol>
-bool cp_server_impl<TProtocol>::add_new_connection(SOCKET new_sock, const network_address &address_from)
-{
- PROFILE_FUNC("[add_new_connection]");
-
- LOG_PRINT("Add new connection zone: entering lock", LOG_LEVEL_3);
- m_connections_lock.lock();
-
- boost::shared_ptr<connection<TProtocol> > ptr;
- ptr.reset(new connection<TProtocol>(m_config));
-
- connection<TProtocol>& conn = *ptr.get();
- m_connections[new_sock] = ptr;
- LOG_PRINT("Add new connection zone: leaving lock", LOG_LEVEL_3);
- m_connections_lock.unlock();
- conn.init_buffers();
- conn.m_sock = new_sock;
- conn.context.m_remote_address = address_from;
- conn.m_completion_port = m_completion_port;
- {
- PROFILE_FUNC("[add_new_connection] CreateIoCompletionPort");
- ::CreateIoCompletionPort((HANDLE)new_sock, m_completion_port, (ULONG_PTR)&conn, 0);
- }
-
- //if(NULL == ::CreateIoCompletionPort((HANDLE)new_sock, m_completion_port, (ULONG_PTR)&conn, 0))
- //{
- // int err = ::GetLastError();
- // LOG_PRINT("Failed to CreateIoCompletionPort(associate socket and completion port), err = " << err << " \"" << socket_errors::get_socket_error_text(err) <<"\"", LOG_LEVEL_2);
- // return false;
- //}
-
- conn.m_tprotocol_handler.after_init_connection();
- {
- PROFILE_FUNC("[add_new_connection] starting loop");
- int res = 0;
- while(true)//res!=SOCKET_ERROR)
- {
- PROFILE_FUNC("[add_new_connection] in loop time");
- conn.m_precv_data->TotalBuffBytes = LEVIN_DEFAULT_DATA_BUFF_SIZE;
- ZeroMemory(&conn.m_precv_data->m_overlapped, sizeof(OVERLAPPED));
- conn.m_precv_data->DataBuf.len = conn.m_precv_data->TotalBuffBytes;
- conn.m_precv_data->DataBuf.buf = conn.m_precv_data->Buffer;
- conn.m_precv_data->m_op_type = op_type_recv;
- InterlockedExchange(&conn.m_precv_data->m_is_in_use, 1);
- DWORD bytes_recvd = 0;
- DWORD flags = 0;
-
- ::InterlockedExchange(&conn.m_precv_data->m_is_in_use, 1);
- {
- PROFILE_FUNC("[add_new_connection] ::WSARecv");
- res = ::WSARecv(conn.m_sock, &(conn.m_precv_data->DataBuf), 1, &bytes_recvd , &flags, &(conn.m_precv_data->m_overlapped), NULL);
- }
- if(res == SOCKET_ERROR )
- {
- int err = ::WSAGetLastError();
- if(WSA_IO_PENDING == err )
- {
- break;
- }
- LOG_ERROR("BIG FAIL: WSARecv error code not correct, res=" << res << " last_err=" << err << " " << log_space::get_win32_err_descr(err));
- ::InterlockedExchange(&conn.m_precv_data->m_is_in_use, 0);
- conn.query_shutdown();
- //shutdown_connection(&conn);
- break;
- }
-
-
- break;
- /*else if(0 == res)
- {
- if(!bytes_recvd)
- {
- PROFILE_FUNC("[add_new_connection] shutdown_connection");
- ::InterlockedExchange(&conn.m_precv_data->m_is_in_use, 0);
- conn.query_shutdown();
- //shutdown_connection(&conn);
- break;
- }else
- {
- PROFILE_FUNC("[add_new_connection] handle_recv");
- }
- }*/
- }
- }
-
-
-
- return true;
-}
-//-------------------------------------------------------------
-template<class TProtocol>
-bool cp_server_impl<TProtocol>::deinit_server()
-{
- if(!m_initialized)
- return true;
-
- if(INVALID_SOCKET != m_listen_socket)
- {
- shutdown(m_listen_socket, SD_BOTH);
- int res = closesocket(m_listen_socket);
- if(SOCKET_ERROR == res)
- {
- int err = ::WSAGetLastError();
- LOG_ERROR("Failed to closesocket(), err = " << err << " \"" << socket_errors::get_socket_error_text(err) <<"\"");
- }
- m_listen_socket = INVALID_SOCKET;
- }
-
- int res = ::WSACleanup();
- if(SOCKET_ERROR == res)
- {
- int err = ::WSAGetLastError();
- LOG_ERROR("Failed to WSACleanup(), err = " << err << " \"" << socket_errors::get_socket_error_text(err) <<"\"");
- }
- m_initialized = false;
-
- return true;
-}
-
-//-------------------------------------------------------------
-template<class TProtocol>
-bool cp_server_impl<TProtocol>::send_stop_signal()
-{
- ::InterlockedExchange(&m_stop, 1);
- return true;
-}
-//-------------------------------------------------------------
-template<class TProtocol>
-bool cp_server_impl<TProtocol>::is_stop_signal()
-{
- return m_stop?true:false;
-}
-//-------------------------------------------------------------
-}
-}
diff --git a/contrib/epee/include/net/http_client.h b/contrib/epee/include/net/http_client.h
index 29ef82fb1..056b50fe6 100644
--- a/contrib/epee/include/net/http_client.h
+++ b/contrib/epee/include/net/http_client.h
@@ -50,7 +50,6 @@
#include "abstract_http_client.h"
#include "http_base.h"
#include "http_auth.h"
-#include "to_nonconst_iterator.h"
#include "net_parse_helpers.h"
#include "syncobj.h"
diff --git a/contrib/epee/include/net/http_client_via_api_helper.h b/contrib/epee/include/net/http_client_via_api_helper.h
deleted file mode 100644
index 3242e4162..000000000
--- a/contrib/epee/include/net/http_client_via_api_helper.h
+++ /dev/null
@@ -1,180 +0,0 @@
-// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * 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.
-// * Neither the name of the Andrey N. Sabelnikov 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 OWNER 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.
-//
-
-
-
-
-#pragma once
-#include <wininet.h>
-#include <atlutil.h>
-#pragma comment(lib, "Wininet.lib")
-
-#undef MONERO_DEFAULT_LOG_CATEGORY
-#define MONERO_DEFAULT_LOG_CATEGORY "net.http"
-
-namespace epee
-{
-namespace net_utils
-{
- inline
- bool http_ssl_invoke(const std::string& url, const std::string usr, const std::string psw, std::string& http_response_body, bool use_post = false)
- {
- bool final_res = false;
-
- ATL::CUrl url_obj;
- BOOL crack_rss = url_obj.CrackUrl(string_encoding::convert_to_t<std::basic_string<TCHAR> >(url).c_str());
-
- HINTERNET hinet = ::InternetOpenA(SHARED_JOBSCOMMON_HTTP_AGENT, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
- if(!hinet)
- {
- int err = ::GetLastError();
- LOG_PRINT("Failed to call InternetOpenA, \nError: " << err << " " << log_space::get_win32_err_descr(err), LOG_LEVEL_0);
- return false;
- }
-
- DWORD dwFlags = 0;
- DWORD dwBuffLen = sizeof(dwFlags);
-
- if(usr.size())
- {
- dwFlags |= INTERNET_FLAG_IGNORE_CERT_CN_INVALID|INTERNET_FLAG_IGNORE_CERT_DATE_INVALID|
- INTERNET_FLAG_PRAGMA_NOCACHE | SECURITY_FLAG_IGNORE_UNKNOWN_CA|INTERNET_FLAG_SECURE;
- }else
- {
- dwFlags |= INTERNET_FLAG_PRAGMA_NOCACHE;
- }
-
-
- int port = url_obj.GetPortNumber();
- BOOL res = FALSE;
-
- HINTERNET hsession = ::InternetConnectA(hinet, string_encoding::convert_to_ansii(url_obj.GetHostName()).c_str(), port/*INTERNET_DEFAULT_HTTPS_PORT*/, usr.c_str(), psw.c_str(), INTERNET_SERVICE_HTTP, dwFlags, NULL);
- if(hsession)
- {
- const std::string uri = string_encoding::convert_to_ansii(url_obj.GetUrlPath()) + string_encoding::convert_to_ansii(url_obj.GetExtraInfo());
-
- HINTERNET hrequest = ::HttpOpenRequestA(hsession, use_post?"POST":NULL, uri.c_str(), NULL, NULL,NULL, dwFlags, NULL);
- if(hrequest)
- {
- while(true)
- {
- res = ::HttpSendRequestA(hrequest, NULL, 0, NULL, 0);
- if(!res)
- {
- //ERROR_INTERNET_INVALID_CA 45
- //ERROR_INTERNET_INVALID_URL (INTERNET_ERROR_BASE + 5)
- int err = ::GetLastError();
- LOG_PRINT("Failed to call HttpSendRequestA, \nError: " << log_space::get_win32_err_descr(err), LOG_LEVEL_0);
- break;
- }
-
- DWORD code = 0;
- DWORD buf_len = sizeof(code);
- DWORD index = 0;
- res = ::HttpQueryInfo(hrequest, HTTP_QUERY_FLAG_NUMBER|HTTP_QUERY_STATUS_CODE, &code, &buf_len, &index);
- if(!res)
- {
- //ERROR_INTERNET_INVALID_CA 45
- //ERROR_INTERNET_INVALID_URL (INTERNET_ERROR_BASE + 5)
- int err = ::GetLastError();
- LOG_PRINT("Failed to call HttpQueryInfo, \nError: " << log_space::get_win32_err_descr(err), LOG_LEVEL_0);
- break;
- }
- if(code < 200 || code > 299)
- {
- LOG_PRINT("Wrong server response, HttpQueryInfo returned statuse code" << code , LOG_LEVEL_0);
- break;
- }
-
-
- char buff[100000] = {0};
- DWORD readed = 0;
- while(true)
- {
- res = ::InternetReadFile(hrequest, buff, sizeof(buff), &readed);
- if(!res)
- {
- int err = ::GetLastError();
- LOG_PRINT("Failed to call InternetReadFile, \nError: " << log_space::get_win32_err_descr(err), LOG_LEVEL_0);
- break;
- }
- if(readed)
- {
- http_response_body.append(buff, readed);
- }
- else
- break;
- }
-
- if(!res)
- break;
-
-
- //we success
- final_res = true;
-
- res = ::InternetCloseHandle(hrequest);
- if(!res)
- {
- int err = ::GetLastError();
- LOG_PRINT("Failed to call InternetCloseHandle, \nError: " << log_space::get_win32_err_descr(err), LOG_LEVEL_0);
- }
-
- break;
- }
- }
- else
- {
- //ERROR_INTERNET_INVALID_CA
- int err = ::GetLastError();
- LOG_PRINT("Failed to call InternetOpenUrlA, \nError: " << log_space::get_win32_err_descr(err), LOG_LEVEL_0);
- return false;
- }
-
- res = ::InternetCloseHandle(hsession);
- if(!res)
- {
- int err = ::GetLastError();
- LOG_PRINT("Failed to call InternetCloseHandle, \nError: " << log_space::get_win32_err_descr(err), LOG_LEVEL_0);
- }
- }else
- {
- int err = ::GetLastError();
- LOG_PRINT("Failed to call InternetConnectA(" << string_encoding::convert_to_ansii(url_obj.GetHostName()) << ", port " << port << " \nError: " << log_space::get_win32_err_descr(err), LOG_LEVEL_0);
- }
-
-
-
- res = ::InternetCloseHandle(hinet);
- if(!res)
- {
- int err = ::GetLastError();
- LOG_PRINT("Failed to call InternetCloseHandle, \nError: " << log_space::get_win32_err_descr(err), LOG_LEVEL_0);
- }
- return final_res;
- }
-}
-}
diff --git a/contrib/epee/include/net/http_protocol_handler.h b/contrib/epee/include/net/http_protocol_handler.h
index a29f141e8..f68b2bc99 100644
--- a/contrib/epee/include/net/http_protocol_handler.h
+++ b/contrib/epee/include/net/http_protocol_handler.h
@@ -33,7 +33,6 @@
#include <boost/optional/optional.hpp>
#include <string>
#include "net_utils_base.h"
-#include "to_nonconst_iterator.h"
#include "http_auth.h"
#include "http_base.h"
diff --git a/contrib/epee/include/net/http_protocol_handler.inl b/contrib/epee/include/net/http_protocol_handler.inl
index 0f4a28c99..df0afc5cf 100644
--- a/contrib/epee/include/net/http_protocol_handler.inl
+++ b/contrib/epee/include/net/http_protocol_handler.inl
@@ -376,7 +376,7 @@ namespace net_utils
m_query_info.m_http_method_str = result[2];
m_query_info.m_full_request_str = result[0];
- m_cache.erase(m_cache.begin(), to_nonsonst_iterator(m_cache, result[0].second));
+ m_cache.erase(m_cache.begin(), result[0].second);
m_state = http_state_retriving_header;
diff --git a/contrib/epee/include/net/http_server_cp.h b/contrib/epee/include/net/http_server_cp.h
deleted file mode 100644
index 1ac2223c7..000000000
--- a/contrib/epee/include/net/http_server_cp.h
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * 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.
-// * Neither the name of the Andrey N. Sabelnikov 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 OWNER 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.
-//
-
-
-
-
-#ifndef _HTTP_SERVER_CP_H_
-#define _HTTP_SERVER_CP_H_
-
-#include "abstract_tcp_server_cp.h"
-#include "http_server.h"
-
-#undef MONERO_DEFAULT_LOG_CATEGORY
-#define MONERO_DEFAULT_LOG_CATEGORY "net.http"
-
-namespace epee
-{
-namespace net_utils
-{
- typedef cp_server_impl<http::simple_http_connection_handler> cp_http_server_file_system;
- typedef cp_server_impl<http::http_custom_handler> cp_http_server_custum_handling;
-}
-}
-
-
-
-#endif
-
-
diff --git a/contrib/epee/include/net/http_server_cp2.h b/contrib/epee/include/net/http_server_cp2.h
deleted file mode 100644
index 8dfd43a16..000000000
--- a/contrib/epee/include/net/http_server_cp2.h
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * 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.
-// * Neither the name of the Andrey N. Sabelnikov 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 OWNER 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.
-//
-
-
-
-
-#ifndef _HTTP_SERVER_CP2_H_
-#define _HTTP_SERVER_CP2_H_
-
-#include "abstract_tcp_server2.h"
-#include "http_protocol_handler.h"
-
-#undef MONERO_DEFAULT_LOG_CATEGORY
-#define MONERO_DEFAULT_LOG_CATEGORY "net.http"
-
-namespace epee
-{
-namespace net_utils
-{
- typedef boosted_tcp_server<http::simple_http_connection_handler<> > boosted_http_server_file_system;
- typedef boosted_tcp_server<http::http_custom_handler<> > boosted_http_server_custum_handling;
-}
-}
-
-
-#endif
-
-
diff --git a/contrib/epee/include/net/http_server_thread_per_connect.h b/contrib/epee/include/net/http_server_thread_per_connect.h
deleted file mode 100644
index bec43b726..000000000
--- a/contrib/epee/include/net/http_server_thread_per_connect.h
+++ /dev/null
@@ -1,48 +0,0 @@
-// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * 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.
-// * Neither the name of the Andrey N. Sabelnikov 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 OWNER 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.
-//
-
-
-
-#ifndef _HTTP_SERVER_CP_H_
-#define _HTTP_SERVER_CP_H_
-
-#include "abstract_tcp_server.h"
-#include "http_server.h"
-
-namespace epee
-{
-namespace net_utils
-{
- typedef abstract_tcp_server<http::simple_http_connection_handler> mt_http_server_file_system;
- typedef abstract_tcp_server<http::http_custom_handler> mt_http_server_custum_handling;
-
-}
-}
-
-
-#endif
-
-
diff --git a/contrib/epee/include/net/jsonrpc_protocol_handler.h b/contrib/epee/include/net/jsonrpc_protocol_handler.h
deleted file mode 100644
index b224c3429..000000000
--- a/contrib/epee/include/net/jsonrpc_protocol_handler.h
+++ /dev/null
@@ -1,167 +0,0 @@
-#ifndef JSONRPC_PROTOCOL_HANDLER_H
-#define JSONRPC_PROTOCOL_HANDLER_H
-
-#include <cstdint>
-#include <string>
-
-#include "net/net_utils_base.h"
-#include "jsonrpc_structs.h"
-#include "storages/portable_storage.h"
-#include "storages/portable_storage_template_helper.h"
-
-namespace epee
-{
-namespace net_utils
-{
- namespace jsonrpc2
- {
- inline
- std::string& make_error_resp_json(int64_t code, const std::string& message,
- std::string& response_data,
- const epee::serialization::storage_entry& id = nullptr)
- {
- epee::json_rpc::error_response rsp;
- rsp.id = id;
- rsp.jsonrpc = "2.0";
- rsp.error.code = code;
- rsp.error.message = message;
- epee::serialization::store_t_to_json(static_cast<epee::json_rpc::error_response&>(rsp), response_data, 0, false);
- response_data += "\n";
- return response_data;
- }
-
- template<class t_connection_context>
- struct i_jsonrpc2_server_handler
- {
- virtual ~i_jsonrpc2_server_handler()
- {}
- virtual bool handle_rpc_request(const std::string& req_data,
- std::string& resp_data,
- t_connection_context& conn_context) = 0;
- virtual bool init_server_thread()
- { return true; }
- virtual bool deinit_server_thread()
- { return true; }
- };
-
- template<class t_connection_context>
- struct jsonrpc2_server_config
- {
- i_jsonrpc2_server_handler<t_connection_context>* m_phandler;
- critical_section m_lock;
- };
-
- template<class t_connection_context = net_utils::connection_context_base>
- class jsonrpc2_connection_handler
- {
- public:
- typedef t_connection_context connection_context;
- typedef jsonrpc2_server_config<t_connection_context> config_type;
-
- jsonrpc2_connection_handler(i_service_endpoint* psnd_hndlr,
- config_type& config,
- t_connection_context& conn_context)
- : m_psnd_hndlr(psnd_hndlr),
- m_config(config),
- m_conn_context(conn_context),
- m_is_stop_handling(false)
- {}
- virtual ~jsonrpc2_connection_handler()
- {}
-
- bool release_protocol()
- {
- return true;
- }
- virtual bool thread_init()
- {
- return true;
- }
- virtual bool thread_deinit()
- {
- return true;
- }
- void handle_qued_callback()
- {}
- bool after_init_connection()
- {
- return true;
- }
- virtual bool handle_recv(const void* ptr, size_t cb)
- {
- std::string buf((const char*)ptr, cb);
- LOG_PRINT_L0("JSONRPC2_RECV: " << ptr << "\r\n" << buf);
-
- bool res = handle_buff_in(buf);
- return res;
- }
- private:
- bool handle_buff_in(std::string& buf)
- {
- if(m_cache.size())
- m_cache += buf;
- else
- m_cache.swap(buf);
-
- m_is_stop_handling = false;
- while (!m_is_stop_handling) {
- std::string::size_type pos = match_end_of_request(m_cache);
- if (std::string::npos == pos) {
- m_is_stop_handling = true;
- if (m_cache.size() > 4096) {
- LOG_ERROR("jsonrpc2_connection_handler::handle_buff_in: Too long request");
- return false;
- }
- break;
- } else {
- extract_cached_request_and_handle(pos);
- }
-
- if (!m_cache.size()) {
- m_is_stop_handling = true;
- }
- }
-
- return true;
- }
- bool extract_cached_request_and_handle(std::string::size_type pos)
- {
- std::string request_data(m_cache.begin(), m_cache.begin() + pos);
- m_cache.erase(0, pos);
- return handle_request_and_send_response(request_data);
- }
- bool handle_request_and_send_response(const std::string& request_data)
- {
- CHECK_AND_ASSERT_MES(m_config.m_phandler, false, "m_config.m_phandler is NULL!!!!");
- std::string response_data;
-
- LOG_PRINT_L3("JSONRPC2_REQUEST: >> \r\n" << request_data);
- bool rpc_result = m_config.m_phandler->handle_rpc_request(request_data, response_data, m_conn_context);
- LOG_PRINT_L3("JSONRPC2_RESPONSE: << \r\n" << response_data);
-
- m_psnd_hndlr->do_send((void*)response_data.data(), response_data.size());
- return rpc_result;
- }
- std::string::size_type match_end_of_request(const std::string& buf)
- {
- std::string::size_type res = buf.find("\n");
- if(std::string::npos != res) {
- return res + 2;
- }
- return res;
- }
-
- protected:
- i_service_endpoint* m_psnd_hndlr;
-
- private:
- config_type& m_config;
- t_connection_context& m_conn_context;
- std::string m_cache;
- bool m_is_stop_handling;
- };
- }
-}
-}
-
-#endif /* JSONRPC_PROTOCOL_HANDLER_H */
diff --git a/contrib/epee/include/net/jsonrpc_server_handlers_map.h b/contrib/epee/include/net/jsonrpc_server_handlers_map.h
deleted file mode 100644
index 8c747d1af..000000000
--- a/contrib/epee/include/net/jsonrpc_server_handlers_map.h
+++ /dev/null
@@ -1,86 +0,0 @@
-#ifndef JSONRPC_SERVER_HANDLERS_MAP_H
-#define JSONRPC_SERVER_HANDLERS_MAP_H
-
-#include <string>
-#include "serialization/keyvalue_serialization.h"
-#include "storages/portable_storage_template_helper.h"
-#include "storages/portable_storage_base.h"
-#include "jsonrpc_structs.h"
-#include "jsonrpc_protocol_handler.h"
-
-#define BEGIN_JSONRPC2_MAP(t_connection_context) \
-bool handle_rpc_request(const std::string& req_data, \
- std::string& resp_data, \
- t_connection_context& m_conn_context) \
-{ \
- bool handled = false; \
- uint64_t ticks = epee::misc_utils::get_tick_count(); \
- epee::serialization::portable_storage ps; \
- if (!ps.load_from_json(req_data)) \
- { \
- epee::net_utils::jsonrpc2::make_error_resp_json(-32700, "Parse error", resp_data); \
- return true; \
- } \
- epee::serialization::storage_entry id_; \
- id_ = epee::serialization::storage_entry(std::string()); \
- if (!ps.get_value("id", id_, nullptr)) \
- { \
- epee::net_utils::jsonrpc2::make_error_resp_json(-32600, "Invalid Request", resp_data); \
- return true; \
- } \
- std::string callback_name; \
- if (!ps.get_value("method", callback_name, nullptr)) \
- { \
- epee::net_utils::jsonrpc2::make_error_resp_json(-32600, "Invalid Request", resp_data, id_); \
- return true; \
- } \
- if (false) return true; //just a stub to have "else if"
-
-
-
-#define PREPARE_JSONRPC2_OBJECTS_FROM_JSON(command_type) \
- handled = true; \
- boost::value_initialized<epee::json_rpc::request<command_type::request> > req_; \
- epee::json_rpc::request<command_type::request>& req = static_cast<epee::json_rpc::request<command_type::request>&>(req_);\
- if(!req.load(ps)) \
- { \
- epee::net_utils::jsonrpc2::make_error_resp_json(-32602, "Invalid params", resp_data, req.id); \
- return true; \
- } \
- uint64_t ticks1 = epee::misc_utils::get_tick_count(); \
- boost::value_initialized<epee::json_rpc::response<command_type::response, epee::json_rpc::dummy_error> > resp_; \
- epee::json_rpc::response<command_type::response, epee::json_rpc::dummy_error>& resp = static_cast<epee::json_rpc::response<command_type::response, epee::json_rpc::dummy_error> &>(resp_); \
- resp.jsonrpc = "2.0"; \
- resp.id = req.id;
-
-#define FINALIZE_JSONRPC2_OBJECTS_TO_JSON(method_name) \
- uint64_t ticks2 = epee::misc_utils::get_tick_count(); \
- epee::serialization::store_t_to_json(resp, resp_data, 0, false); \
- resp_data += "\n"; \
- uint64_t ticks3 = epee::misc_utils::get_tick_count(); \
- LOG_PRINT("[" << method_name << "] processed with " << ticks1-ticks << "/"<< ticks2-ticks1 << "/" << ticks3-ticks2 << "ms", LOG_LEVEL_2);
-
-
-#define MAP_JSONRPC2_WE(method_name, callback_f, command_type) \
- else if (callback_name == method_name) \
- { \
- PREPARE_JSONRPC2_OBJECTS_FROM_JSON(command_type) \
- epee::json_rpc::error_response fail_resp = AUTO_VAL_INIT(fail_resp); \
- fail_resp.jsonrpc = "2.0"; \
- fail_resp.id = req.id; \
- if(!callback_f(req.params, resp.result, fail_resp.error, m_conn_context)) \
- { \
- epee::serialization::store_t_to_json(static_cast<epee::json_rpc::error_response&>(fail_resp), resp_data, 0, false); \
- resp_data += "\n"; \
- return true; \
- } \
- FINALIZE_JSONRPC2_OBJECTS_TO_JSON(method_name) \
- return true; \
- }
-
-#define END_JSONRPC2_MAP() \
- epee::net_utils::jsonrpc2::make_error_resp_json(-32601, "Method not found", resp_data, id_); \
- return true; \
-}
-
-#endif /* JSONRPC_SERVER_HANDLERS_MAP_H */
diff --git a/contrib/epee/include/net/jsonrpc_server_impl_base.h b/contrib/epee/include/net/jsonrpc_server_impl_base.h
deleted file mode 100644
index 8a5a9a5b6..000000000
--- a/contrib/epee/include/net/jsonrpc_server_impl_base.h
+++ /dev/null
@@ -1,84 +0,0 @@
-#ifndef JSONRPC_SERVER_IMPL_BASE_H
-#define JSONRPC_SERVER_IMPL_BASE_H
-
-#include <boost/thread.hpp>
-#include <boost/bind.hpp>
-
-#include "net/jsonrpc_protocol_handler.h"
-#include "net/jsonrpc_server_handlers_map.h"
-#include "net/abstract_tcp_server2.h"
-
-namespace epee
-{
-
-template<class t_child_class, class t_connection_context = epee::net_utils::connection_context_base>
- class jsonrpc_server_impl_base: public net_utils::jsonrpc2::i_jsonrpc2_server_handler<t_connection_context>
- {
-
- public:
- jsonrpc_server_impl_base()
- : m_net_server()
- {}
-
- explicit jsonrpc_server_impl_base(boost::asio::io_service& external_io_service)
- : m_net_server(external_io_service)
- {}
-
- bool init(const std::string& bind_port = "0", const std::string& bind_ip = "0.0.0.0")
- {
- //set self as callback handler
- m_net_server.get_config_object().m_phandler = static_cast<t_child_class*>(this);
-
- LOG_PRINT_L0("Binding on " << bind_ip << ":" << bind_port);
- bool res = m_net_server.init_server(bind_port, bind_ip);
- if (!res)
- {
- LOG_ERROR("Failed to bind server");
- return false;
- }
- return true;
- }
-
- bool run(size_t threads_count, bool wait = true)
- {
- //go to loop
- LOG_PRINT("Run net_service loop( " << threads_count << " threads)...", LOG_LEVEL_0);
- if(!m_net_server.run_server(threads_count, wait))
- {
- LOG_ERROR("Failed to run net tcp server!");
- }
-
- if(wait)
- LOG_PRINT("net_service loop stopped.", LOG_LEVEL_0);
- return true;
- }
-
- bool deinit()
- {
- return m_net_server.deinit_server();
- }
-
- bool timed_wait_server_stop(uint64_t ms)
- {
- return m_net_server.timed_wait_server_stop(ms);
- }
-
- bool send_stop_signal()
- {
- m_net_server.send_stop_signal();
- return true;
- }
-
- int get_binded_port()
- {
- return m_net_server.get_binded_port();
- }
-
- protected:
- net_utils::boosted_tcp_server<net_utils::jsonrpc2::jsonrpc2_connection_handler<t_connection_context> > m_net_server;
- };
-
-}
-
-#endif /* JSONRPC_SERVER_IMPL_BASE_H */
-
diff --git a/contrib/epee/include/net/levin_client.h b/contrib/epee/include/net/levin_client.h
deleted file mode 100644
index 76d528234..000000000
--- a/contrib/epee/include/net/levin_client.h
+++ /dev/null
@@ -1,89 +0,0 @@
-// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * 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.
-// * Neither the name of the Andrey N. Sabelnikov 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 OWNER 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.
-//
-
-
-
-
-
-#ifndef _LEVIN_CLIENT_H_
-#define _LEVIN_CLIENT_H_
-
-#include "net_helper.h"
-#include "levin_base.h"
-
-
-#ifndef MAKE_IP
-#define MAKE_IP( a1, a2, a3, a4 ) (a1|(a2<<8)|(a3<<16)|(a4<<24))
-#endif
-
-namespace epee
-{
-namespace levin
-{
- /************************************************************************/
- /* */
- /************************************************************************/
- class levin_client_impl
- {
- public:
- levin_client_impl();
- virtual ~levin_client_impl();
-
- bool connect(u_long ip, int port, unsigned int timeout, const std::string& bind_ip = "0.0.0.0");
- bool connect(const std::string& addr, int port, unsigned int timeout, const std::string& bind_ip = "0.0.0.0");
- bool is_connected();
- bool disconnect();
-
- virtual int invoke(int command, const epee::span<const uint8_t> in_buff, std::string& buff_out);
- virtual int notify(int command, const std::string& in_buff);
-
- protected:
- net_utils::blocked_mode_client m_transport;
- };
-
-
- /************************************************************************/
- /* */
- /************************************************************************/
- class levin_client_impl2: public levin_client_impl
- {
- public:
-
- int invoke(int command, const epee::span<const uint8_t> in_buff, std::string& buff_out);
- int notify(int command, const std::string& in_buff);
- };
-
-}
-namespace net_utils
-{
- typedef levin::levin_client_impl levin_client;
- typedef levin::levin_client_impl2 levin_client2;
-}
-}
-
-#include "levin_client.inl"
-
-#endif //_LEVIN_CLIENT_H_
diff --git a/contrib/epee/include/net/levin_client.inl b/contrib/epee/include/net/levin_client.inl
deleted file mode 100644
index 177dd8967..000000000
--- a/contrib/epee/include/net/levin_client.inl
+++ /dev/null
@@ -1,199 +0,0 @@
-// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * 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.
-// * Neither the name of the Andrey N. Sabelnikov 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 OWNER 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 "string_tools.h"
-
-#undef MONERO_DEFAULT_LOG_CATEGORY
-#define MONERO_DEFAULT_LOG_CATEGORY "net"
-
-namespace epee
-{
-namespace levin
-{
-inline
-bool levin_client_impl::connect(u_long ip, int port, unsigned int timeout, const std::string& bind_ip)
-{
- return m_transport.connect(string_tools::get_ip_string_from_int32(ip), port, timeout, timeout, bind_ip);
-}
-//------------------------------------------------------------------------------
-inline
- bool levin_client_impl::connect(const std::string& addr, int port, unsigned int timeout, const std::string& bind_ip)
-{
- return m_transport.connect(addr, port, timeout, timeout, bind_ip);
-}
-//------------------------------------------------------------------------------
-inline
-bool levin_client_impl::is_connected()
-{
- return m_transport.is_connected();
-}
-//------------------------------------------------------------------------------
-inline
-bool levin_client_impl::disconnect()
-{
- return m_transport.disconnect();
-}
-//------------------------------------------------------------------------------
-inline
-levin_client_impl::levin_client_impl()
-{
-}
-//------------------------------------------------------------------------------
-inline
-levin_client_impl::~levin_client_impl()
-{
- disconnect();
-}
-//------------------------------------------------------------------------------
-inline
-int levin_client_impl::invoke(int command, const epee::span<const uint8_t> in_buff, std::string& buff_out)
-{
- if(!is_connected())
- return -1;
-
- bucket_head head = {0};
- head.m_signature = SWAP64LE(LEVIN_SIGNATURE);
- head.m_cb = SWAP64LE(in_buff.size());
- head.m_have_to_return_data = 1;
- head.m_command = SWAP32LE(command);
- if(!m_transport.send(&head, sizeof(head)))
- return -1;
-
- if(!m_transport.send(in_buff))
- return -1;
-
- std::string local_buff;
- if(!m_transport.recv_n(local_buff, sizeof(bucket_head)))
- return -1;
-
- head = *(bucket_head*)local_buff.data();
-
-
- if(head.m_signature!=SWAP64LE(LEVIN_SIGNATURE))
- {
- LOG_PRINT_L1("Signature mismatch in response");
- return -1;
- }
-
- if(!m_transport.recv_n(buff_out, head.m_cb))
- return -1;
-
- return head.m_return_code;
-}
-//------------------------------------------------------------------------------
-inline
-int levin_client_impl::notify(int command, const std::string& in_buff)
-{
- if(!is_connected())
- return -1;
-
- bucket_head head = {0};
- head.m_signature = SWAP64LE(LEVIN_SIGNATURE);
- head.m_cb = SWAP64LE(in_buff.size());
- head.m_have_to_return_data = 0;
- head.m_command = SWAP32LE(command);
-
- if(!m_transport.send((const char*)&head, sizeof(head)))
- return -1;
-
- if(!m_transport.send(in_buff))
- return -1;
-
- return 1;
-}
-
-//------------------------------------------------------------------------------
-//------------------------------------------------------------------------------
-inline
- int levin_client_impl2::invoke(int command, epee::span<const uint8_t>string& in_buff, std::string& buff_out)
-{
- if(!is_connected())
- return -1;
-
- bucket_head2 head = {0};
- head.m_signature = SWAP64LE(LEVIN_SIGNATURE);
- head.m_cb = SWAP64LE(in_buff.size());
- head.m_have_to_return_data = 1;
- head.m_command = SWAP32LE(command);
- head.m_return_code = SWAP32LE(0);
- head.m_flags = SWAP32LE(LEVIN_PACKET_REQUEST);
- head.m_protocol_version = SWAP32LE(LEVIN_PROTOCOL_VER_1);
- if(!m_transport.send(&head, sizeof(head)))
- return -1;
-
- if(!m_transport.send(in_buff))
- return -1;
-
- std::string local_buff;
- if(!m_transport.recv_n(local_buff, sizeof(bucket_head2)))
- return -1;
-
- head = *(bucket_head2*)local_buff.data();
-
- if(head.m_signature != SWAP64LE(LEVIN_SIGNATURE))
- {
- LOG_PRINT_L1("Signature mismatch in response");
- return -1;
- }
-
- if(!m_transport.recv_n(buff_out, SWAP64LE(head.m_cb)))
- return -1;
-
- return head.m_return_code;
-}
-//------------------------------------------------------------------------------
-inline
- int levin_client_impl2::notify(int command, const std::string& in_buff)
-{
- if(!is_connected())
- return -1;
-
- bucket_head2 head = {0};
- head.m_signature = SWAP64LE(LEVIN_SIGNATURE);
- head.m_cb = SWAP64LE(in_buff.size());
- head.m_have_to_return_data = 0;
- head.m_command = SWAP32LE(command);
- head.m_return_code = SWAP32LE(0);
- head.m_flags = SWAP32LE(LEVIN_PACKET_REQUEST);
- head.m_protocol_version = SWAP32LE(LEVIN_PROTOCOL_VER_1);
-
- if(!m_transport.send((const char*)&head, sizeof(head)))
- return -1;
-
- if(!m_transport.send(in_buff))
- return -1;
-
- return 1;
-}
-
-}
-}
-//------------------------------------------------------------------------------
diff --git a/contrib/epee/include/net/levin_client_async.h b/contrib/epee/include/net/levin_client_async.h
deleted file mode 100644
index 067707edf..000000000
--- a/contrib/epee/include/net/levin_client_async.h
+++ /dev/null
@@ -1,585 +0,0 @@
-// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * 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.
-// * Neither the name of the Andrey N. Sabelnikov 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 OWNER 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.
-//
-
-
-#pragma once
-
-#include ""
-#include "net_helper.h"
-#include "levin_base.h"
-
-#undef MONERO_DEFAULT_LOG_CATEGORY
-#define MONERO_DEFAULT_LOG_CATEGORY "net"
-
-
-namespace epee
-{
-namespace levin
-{
-
- /************************************************************************
- * levin_client_async - probably it is not really fast implementation,
- * each handler thread could make up to 30 ms latency.
- * But, handling events in reader thread will cause dead locks in
- * case of recursive call (call invoke() to the same connection
- * on reader thread on remote invoke() handler)
- ***********************************************************************/
-
-
- class levin_client_async
- {
- levin_commands_handler* m_pcommands_handler;
- void (*commands_handler_destroy)(levin_commands_handler*);
- volatile uint32_t m_is_stop;
- volatile uint32_t m_threads_count;
- ::critical_section m_send_lock;
-
- std::string m_local_invoke_buff;
- ::critical_section m_local_invoke_buff_lock;
- volatile int m_invoke_res;
-
- volatile uint32_t m_invoke_data_ready;
- volatile uint32_t m_invoke_is_active;
-
- boost::mutex m_invoke_event;
- boost::condition_variable m_invoke_cond;
- size_t m_timeout;
-
- ::critical_section m_recieved_packets_lock;
- struct packet_entry
- {
- bucket_head m_hd;
- std::string m_body;
- uint32_t m_connection_index;
- };
- std::list<packet_entry> m_recieved_packets;
- /*
- m_current_connection_index needed when some connection was broken and reconnected - in this
- case we could have some received packets in que, which shoud not be handled
- */
- volatile uint32_t m_current_connection_index;
- ::critical_section m_invoke_lock;
- ::critical_section m_reciev_packet_lock;
- ::critical_section m_connection_lock;
- net_utils::blocked_mode_client m_transport;
- public:
- levin_client_async():m_pcommands_handler(NULL), commands_handler_destroy(NULL), m_is_stop(0), m_threads_count(0), m_invoke_data_ready(0), m_invoke_is_active(0)
- {}
- levin_client_async(const levin_client_async& /*v*/):m_pcommands_handler(NULL), commands_handler_destroy(NULL), m_is_stop(0), m_threads_count(0), m_invoke_data_ready(0), m_invoke_is_active(0)
- {}
- ~levin_client_async()
- {
- boost::interprocess::ipcdetail::atomic_write32(&m_is_stop, 1);
- disconnect();
-
-
- while(boost::interprocess::ipcdetail::atomic_read32(&m_threads_count))
- ::Sleep(100);
-
- set_handler(NULL);
- }
-
- void set_handler(levin_commands_handler* phandler, void (*destroy)(levin_commands_handler*) = NULL)
- {
- if (commands_handler_destroy && m_pcommands_handler)
- (*commands_handler_destroy)(m_pcommands_handler);
- m_pcommands_handler = phandler;
- m_pcommands_handler_destroy = destroy;
- }
-
- bool connect(uint32_t ip, uint32_t port, uint32_t timeout)
- {
- loop_call_guard();
- critical_region cr(m_connection_lock);
-
- m_timeout = timeout;
- bool res = false;
- CRITICAL_REGION_BEGIN(m_reciev_packet_lock);
- CRITICAL_REGION_BEGIN(m_send_lock);
- res = levin_client_impl::connect(ip, port, timeout);
- boost::interprocess::ipcdetail::atomic_inc32(&m_current_connection_index);
- CRITICAL_REGION_END();
- CRITICAL_REGION_END();
- if(res && !boost::interprocess::ipcdetail::atomic_read32(&m_threads_count) )
- {
- //boost::interprocess::ipcdetail::atomic_write32(&m_is_stop, 0);//m_is_stop = false;
- boost::thread( boost::bind(&levin_duplex_client::reciever_thread, this) );
- boost::thread( boost::bind(&levin_duplex_client::handler_thread, this) );
- boost::thread( boost::bind(&levin_duplex_client::handler_thread, this) );
- }
-
- return res;
- }
- bool is_connected()
- {
- loop_call_guard();
- critical_region cr(m_cs);
- return levin_client_impl::is_connected();
- }
-
- inline
- bool check_connection()
- {
- loop_call_guard();
- critical_region cr(m_cs);
-
- if(!is_connected())
- {
- if( !reconnect() )
- {
- LOG_ERROR("Reconnect Failed. Failed to invoke() because not connected!");
- return false;
- }
- }
- return true;
- }
-
- //------------------------------------------------------------------------------
- inline
- bool recv_n(SOCKET s, char* pbuff, size_t cb)
- {
- while(cb)
- {
- int res = ::recv(m_socket, pbuff, (int)cb, 0);
-
- if(SOCKET_ERROR == res)
- {
- if(!m_connected)
- return false;
-
- int err = ::WSAGetLastError();
- LOG_ERROR("Failed to recv(), err = " << err << " \"" << socket_errors::get_socket_error_text(err) <<"\"");
- disconnect();
- //reconnect();
- return false;
- }else if(res == 0)
- {
- disconnect();
- //reconnect();
- return false;
- }
- LOG_PRINT_L4("[" << m_socket <<"] RECV " << res);
- cb -= res;
- pbuff += res;
- }
-
- return true;
- }
-
- //------------------------------------------------------------------------------
- inline
- bool recv_n(SOCKET s, std::string& buff)
- {
- size_t cb_remain = buff.size();
- char* m_current_ptr = (char*)buff.data();
- return recv_n(s, m_current_ptr, cb_remain);
- }
-
- bool disconnect()
- {
- //boost::interprocess::ipcdetail::atomic_write32(&m_is_stop, 1);//m_is_stop = true;
- loop_call_guard();
- critical_region cr(m_cs);
- levin_client_impl::disconnect();
-
- CRITICAL_REGION_BEGIN(m_local_invoke_buff_lock);
- m_local_invoke_buff.clear();
- m_invoke_res = LEVIN_ERROR_CONNECTION_DESTROYED;
- CRITICAL_REGION_END();
- boost::interprocess::ipcdetail::atomic_write32(&m_invoke_data_ready, 1); //m_invoke_data_ready = true;
- m_invoke_cond.notify_all();
- return true;
- }
-
- void loop_call_guard()
- {
-
- }
-
- void on_leave_invoke()
- {
- boost::interprocess::ipcdetail::atomic_write32(&m_invoke_is_active, 0);
- }
-
- int invoke(const GUID& target, int command, const std::string& in_buff, std::string& buff_out)
- {
-
- critical_region cr_invoke(m_invoke_lock);
-
- boost::interprocess::ipcdetail::atomic_write32(&m_invoke_is_active, 1);
- boost::interprocess::ipcdetail::atomic_write32(&m_invoke_data_ready, 0);
- misc_utils::destr_ptr hdlr = misc_utils::add_exit_scope_handler(boost::bind(&levin_duplex_client::on_leave_invoke, this));
-
- loop_call_guard();
-
- if(!check_connection())
- return LEVIN_ERROR_CONNECTION_DESTROYED;
-
-
- bucket_head head = {0};
- head.m_signature = LEVIN_SIGNATURE;
- head.m_cb = in_buff.size();
- head.m_have_to_return_data = 1;
- head.m_id = target;
-#ifdef TRACE_LEVIN_PACKETS_BY_GUIDS
- ::UuidCreate(&head.m_id);
-#endif
- head.m_command = command;
- head.m_protocol_version = LEVIN_PROTOCOL_VER_1;
- head.m_flags = LEVIN_PACKET_REQUEST;
- LOG_PRINT("[" << m_socket <<"] Sending invoke data", LOG_LEVEL_4);
-
- CRITICAL_REGION_BEGIN(m_send_lock);
- LOG_PRINT_L4("[" << m_socket <<"] SEND " << sizeof(head));
- int res = ::send(m_socket, (const char*)&head, sizeof(head), 0);
- if(SOCKET_ERROR == res)
- {
- int err = ::WSAGetLastError();
- LOG_ERROR("Failed to send(), err = " << err << " \"" << socket_errors::get_socket_error_text(err) <<"\"");
- disconnect();
- return LEVIN_ERROR_CONNECTION_DESTROYED;
- }
- LOG_PRINT_L4("[" << m_socket <<"] SEND " << (int)in_buff.size());
- res = ::send(m_socket, in_buff.data(), (int)in_buff.size(), 0);
- if(SOCKET_ERROR == res)
- {
- int err = ::WSAGetLastError();
- LOG_ERROR("Failed to send(), err = " << err << " \"" << socket_errors::get_socket_error_text(err) <<"\"");
- disconnect();
- return LEVIN_ERROR_CONNECTION_DESTROYED;
- }
- CRITICAL_REGION_END();
- LOG_PRINT_L4("LEVIN_PACKET_SENT. [len=" << head.m_cb << ", flags=" << head.m_flags << ", is_cmd=" << head.m_have_to_return_data <<", cmd_id = " << head.m_command << ", pr_v=" << head.m_protocol_version << ", uid=" << string_tools::get_str_from_guid_a(head.m_id) << "]");
-
- //hard coded timeout in 10 minutes for maximum invoke period. if it happens, it could mean only some real troubles.
- boost::system_time timeout = boost::get_system_time()+ boost::posix_time::milliseconds(100);
- size_t timeout_count = 0;
- boost::unique_lock<boost::mutex> lock(m_invoke_event);
-
- while(!boost::interprocess::ipcdetail::atomic_read32(&m_invoke_data_ready))
- {
- if(!m_invoke_cond.timed_wait(lock, timeout))
- {
- if(timeout_count < 10)
- {
- //workaround to avoid freezing at timed_wait called after notify_all.
- timeout = boost::get_system_time()+ boost::posix_time::milliseconds(100);
- ++timeout_count;
- continue;
- }else if(timeout_count == 10)
- {
- //workaround to avoid freezing at timed_wait called after notify_all.
- timeout = boost::get_system_time()+ boost::posix_time::minutes(10);
- ++timeout_count;
- continue;
- }else
- {
- LOG_PRINT("[" << m_socket <<"] Timeout on waiting invoke result. ", LOG_LEVEL_0);
- //disconnect();
- return LEVIN_ERROR_CONNECTION_TIMEDOUT;
- }
- }
- }
-
-
- CRITICAL_REGION_BEGIN(m_local_invoke_buff_lock);
- buff_out.swap(m_local_invoke_buff);
- m_local_invoke_buff.clear();
- CRITICAL_REGION_END();
- return m_invoke_res;
- }
-
- int notify(const GUID& target, int command, const std::string& in_buff)
- {
- if(!check_connection())
- return LEVIN_ERROR_CONNECTION_DESTROYED;
-
- bucket_head head = {0};
- head.m_signature = LEVIN_SIGNATURE;
- head.m_cb = in_buff.size();
- head.m_have_to_return_data = 0;
- head.m_id = target;
-#ifdef TRACE_LEVIN_PACKETS_BY_GUIDS
- ::UuidCreate(&head.m_id);
-#endif
- head.m_command = command;
- head.m_protocol_version = LEVIN_PROTOCOL_VER_1;
- head.m_flags = LEVIN_PACKET_REQUEST;
- CRITICAL_REGION_BEGIN(m_send_lock);
- LOG_PRINT_L4("[" << m_socket <<"] SEND " << sizeof(head));
- int res = ::send(m_socket, (const char*)&head, sizeof(head), 0);
- if(SOCKET_ERROR == res)
- {
- int err = ::WSAGetLastError();
- LOG_ERROR("Failed to send(), err = " << err << " \"" << socket_errors::get_socket_error_text(err) <<"\"");
- disconnect();
- return LEVIN_ERROR_CONNECTION_DESTROYED;
- }
- LOG_PRINT_L4("[" << m_socket <<"] SEND " << (int)in_buff.size());
- res = ::send(m_socket, in_buff.data(), (int)in_buff.size(), 0);
- if(SOCKET_ERROR == res)
- {
- int err = ::WSAGetLastError();
- LOG_ERROR("Failed to send(), err = " << err << " \"" << socket_errors::get_socket_error_text(err) <<"\"");
- disconnect();
- return LEVIN_ERROR_CONNECTION_DESTROYED;
- }
- CRITICAL_REGION_END();
- LOG_PRINT_L4("LEVIN_PACKET_SENT. [len=" << head.m_cb << ", flags=" << head.m_flags << ", is_cmd=" << head.m_have_to_return_data <<", cmd_id = " << head.m_command << ", pr_v=" << head.m_protocol_version << ", uid=" << string_tools::get_str_from_guid_a(head.m_id) << "]");
-
- return 1;
- }
-
-
- private:
- bool have_some_data(SOCKET sock, int interval = 1)
- {
- fd_set fds;
- FD_ZERO(&fds);
- FD_SET(sock, &fds);
-
- fd_set fdse;
- FD_ZERO(&fdse);
- FD_SET(sock, &fdse);
-
-
- timeval tv;
- tv.tv_sec = interval;
- tv.tv_usec = 0;
-
- int sel_res = select(0, &fds, 0, &fdse, &tv);
- if(0 == sel_res)
- return false;
- else if(sel_res == SOCKET_ERROR)
- {
- if(m_is_stop)
- return false;
- int err_code = ::WSAGetLastError();
- LOG_ERROR("Filed to call select, err code = " << err_code);
- disconnect();
- }else
- {
- if(fds.fd_array[0])
- {//some read operations was performed
- return true;
- }else if(fdse.fd_array[0])
- {//some error was at the socket
- return true;
- }
- }
- return false;
- }
-
-
- bool reciev_and_process_incoming_data()
- {
- bucket_head head = {0};
- uint32_t conn_index = 0;
- bool is_request = false;
- std::string local_buff;
- CRITICAL_REGION_BEGIN(m_reciev_packet_lock);//to protect from socket reconnect between head and body
-
- if(!recv_n(m_socket, (char*)&head, sizeof(head)))
- {
- if(m_is_stop)
- return false;
- LOG_ERROR("Failed to recv_n");
- return false;
- }
-
- conn_index = boost::interprocess::ipcdetail::atomic_read32(&m_current_connection_index);
-
- if(head.m_signature!=LEVIN_SIGNATURE)
- {
- LOG_ERROR("Signature mismatch in response");
- return false;
- }
-
- is_request = (head.m_protocol_version == LEVIN_PROTOCOL_VER_1 && head.m_flags&LEVIN_PACKET_REQUEST);
-
-
- local_buff.resize((size_t)head.m_cb);
- if(!recv_n(m_socket, local_buff))
- {
- if(m_is_stop)
- return false;
- LOG_ERROR("Filed to reciev");
- return false;
- }
- CRITICAL_REGION_END();
-
- LOG_PRINT_L4("LEVIN_PACKET_RECEIVED. [len=" << head.m_cb << ", flags=" << head.m_flags << ", is_cmd=" << head.m_have_to_return_data <<", cmd_id = " << head.m_command << ", pr_v=" << head.m_protocol_version << ", uid=" << string_tools::get_str_from_guid_a(head.m_id) << "]");
-
- if(is_request)
- {
- CRITICAL_REGION_BEGIN(m_recieved_packets_lock);
- m_recieved_packets.resize(m_recieved_packets.size() + 1);
- m_recieved_packets.back().m_hd = head;
- m_recieved_packets.back().m_body.swap(local_buff);
- m_recieved_packets.back().m_connection_index = conn_index;
- CRITICAL_REGION_END();
- /*
-
- */
- }else
- {//this is some response
-
- CRITICAL_REGION_BEGIN(m_local_invoke_buff_lock);
- m_local_invoke_buff.swap(local_buff);
- m_invoke_res = head.m_return_code;
- CRITICAL_REGION_END();
- boost::interprocess::ipcdetail::atomic_write32(&m_invoke_data_ready, 1); //m_invoke_data_ready = true;
- m_invoke_cond.notify_all();
-
- }
- return true;
- }
-
- bool reciever_thread()
- {
- LOG_PRINT_L3("[" << m_socket <<"] Socket reciever thread started.[m_threads_count=" << m_threads_count << "]");
- log_space::log_singletone::set_thread_log_prefix("RECIEVER_WORKER");
- boost::interprocess::ipcdetail::atomic_inc32(&m_threads_count);
-
- while(!m_is_stop)
- {
- if(!m_connected)
- {
- Sleep(100);
- continue;
- }
-
- if(have_some_data(m_socket, 1))
- {
- if(!reciev_and_process_incoming_data())
- {
- if(m_is_stop)
- {
- break;//boost::interprocess::ipcdetail::atomic_dec32(&m_threads_count);
- //return true;
- }
- LOG_ERROR("Failed to reciev_and_process_incoming_data. shutting down");
- //boost::interprocess::ipcdetail::atomic_dec32(&m_threads_count);
- //disconnect_no_wait();
- //break;
- }
- }
- }
-
- boost::interprocess::ipcdetail::atomic_dec32(&m_threads_count);
- LOG_PRINT_L3("[" << m_socket <<"] Socket reciever thread stopped.[m_threads_count=" << m_threads_count << "]");
- return true;
- }
-
- bool process_recieved_packet(bucket_head& head, const std::string& local_buff, uint32_t conn_index)
- {
-
- net_utils::connection_context_base conn_context;
- conn_context.m_remote_address = m_address;
- if(head.m_have_to_return_data)
- {
- std::string return_buff;
- if(m_pcommands_handler)
- head.m_return_code = m_pcommands_handler->invoke(head.m_id, head.m_command, local_buff, return_buff, conn_context);
- else
- head.m_return_code = LEVIN_ERROR_CONNECTION_HANDLER_NOT_DEFINED;
-
-
-
- head.m_cb = return_buff.size();
- head.m_have_to_return_data = 0;
- head.m_protocol_version = LEVIN_PROTOCOL_VER_1;
- head.m_flags = LEVIN_PACKET_RESPONSE;
-
- std::string send_buff((const char*)&head, sizeof(head));
- send_buff += return_buff;
- CRITICAL_REGION_BEGIN(m_send_lock);
- if(conn_index != boost::interprocess::ipcdetail::atomic_read32(&m_current_connection_index))
- {//there was reconnect, send response back is not allowed
- return true;
- }
- int res = ::send(m_socket, (const char*)send_buff.data(), send_buff.size(), 0);
- if(res == SOCKET_ERROR)
- {
- int err_code = ::WSAGetLastError();
- LOG_ERROR("Failed to send, err = " << err_code);
- return false;
- }
- CRITICAL_REGION_END();
- LOG_PRINT_L4("LEVIN_PACKET_SENT. [len=" << head.m_cb << ", flags=" << head.m_flags << ", is_cmd=" << head.m_have_to_return_data <<", cmd_id = " << head.m_command << ", pr_v=" << head.m_protocol_version << ", uid=" << string_tools::get_str_from_guid_a(head.m_id) << "]");
-
- }
- else
- {
- if(m_pcommands_handler)
- m_pcommands_handler->notify(head.m_id, head.m_command, local_buff, conn_context);
- }
-
- return true;
- }
-
- bool handler_thread()
- {
- LOG_PRINT_L3("[" << m_socket <<"] Socket handler thread started.[m_threads_count=" << m_threads_count << "]");
- log_space::log_singletone::set_thread_log_prefix("HANDLER_WORKER");
- boost::interprocess::ipcdetail::atomic_inc32(&m_threads_count);
-
- while(!m_is_stop)
- {
- bool have_some_work = false;
- std::string local_buff;
- bucket_head bh = {0};
- uint32_t conn_index = 0;
-
- CRITICAL_REGION_BEGIN(m_recieved_packets_lock);
- if(m_recieved_packets.size())
- {
- bh = m_recieved_packets.begin()->m_hd;
- conn_index = m_recieved_packets.begin()->m_connection_index;
- local_buff.swap(m_recieved_packets.begin()->m_body);
- have_some_work = true;
- m_recieved_packets.pop_front();
- }
- CRITICAL_REGION_END();
-
- if(have_some_work)
- {
- process_recieved_packet(bh, local_buff, conn_index);
- }else
- {
- //Idle when no work
- Sleep(30);
- }
- }
-
- boost::interprocess::ipcdetail::atomic_dec32(&m_threads_count);
- LOG_PRINT_L3("[" << m_socket <<"] Socket handler thread stopped.[m_threads_count=" << m_threads_count << "]");
- return true;
- }
- };
-
-}
-}
diff --git a/contrib/epee/include/net/levin_client_async.inl b/contrib/epee/include/net/levin_client_async.inl
deleted file mode 100644
index e69de29bb..000000000
--- a/contrib/epee/include/net/levin_client_async.inl
+++ /dev/null
diff --git a/contrib/epee/include/net/levin_helper.h b/contrib/epee/include/net/levin_helper.h
deleted file mode 100644
index 541e0948d..000000000
--- a/contrib/epee/include/net/levin_helper.h
+++ /dev/null
@@ -1,161 +0,0 @@
-// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * 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.
-// * Neither the name of the Andrey N. Sabelnikov 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 OWNER 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.
-//
-
-
-
-#pragma once
-
-#include "levin_base.h"
-#include "serializeble_struct_helper.h"
-#include "int-util.h"
-
-#undef MONERO_DEFAULT_LOG_CATEGORY
-#define MONERO_DEFAULT_LOG_CATEGORY "net"
-
-namespace epee
-{
-namespace levin
-{
- template<class t_struct>
- bool pack_struct_to_levin_message(const t_struct& t, std::string& buff, int command_id)
- {
- buff.resize(sizeof(levin::bucket_head));
- levin::bucket_head& head = *(levin::bucket_head*)(&buff[0]);
- head.m_signature = SWAP64LE(LEVIN_SIGNATURE);
- head.m_cb = 0;
- head.m_have_to_return_data = 1;
- head.m_command = SWAP32LE(command_id);
- head.m_return_code = SWAP32LE(1);
- head.m_reservedA = rand(); //probably some flags in future
- head.m_reservedB = rand(); //probably some check summ in future
-
- std::string buff_strg;
- if(!StorageNamed::save_struct_as_storage_to_buff_t<t_struct, StorageNamed::DefaultStorageType>(t, buff_strg))
- return false;
-
- head.m_cb = SWAP64LE(buff_strg.size());
- buff.append(buff_strg);
- return true;
- }
-
-
- bool pack_data_to_levin_message(const std::string& data, std::string& buff, int command_id)
- {
- buff.resize(sizeof(levin::bucket_head));
- levin::bucket_head& head = *(levin::bucket_head*)(&buff[0]);
- head.m_signature = SWAP64LE(LEVIN_SIGNATURE);
- head.m_cb = 0;
- head.m_have_to_return_data = 1;
- head.m_command = SWAP32LE(command_id);
- head.m_return_code = SWAP32LE(1);
- head.m_reservedA = rand(); //probably some flags in future
- head.m_reservedB = rand(); //probably some check summ in future
-
- head.m_cb = SWAP64LE(data.size());
- buff.append(data);
- return true;
- }
-
- bool load_levin_data_from_levin_message(std::string& levin_data, const std::string& buff, int& command)
- {
- if(buff.size() < sizeof(levin::bucket_head) )
- {
- LOG_PRINT_L3("size of buff(" << buff.size() << ") is too small, at load_struct_from_levin_message");
- return false;
- }
-
-#if BYTE_ORDER == LITTLE_ENDIAN
- levin::bucket_head &head = *(levin::bucket_head*)(&buff[0]);
-#else
- levin::bucket_head head = *(levin::bucket_head*)(&buff[0]);
- head.m_signature = SWAP64LE(head.m_signature);
- head.m_cb = SWAP64LE(head.m_cb);
- head.m_command = SWAP32LE(head.m_command);
- head.m_return_code = SWAP32LE(head.m_return_code);
- head.m_reservedA = SWAP32LE(head.m_reservedA);
- head.m_reservedB = SWAP32LE(head.m_reservedB);
-#endif
- if(head.m_signature != LEVIN_SIGNATURE)
- {
- LOG_PRINT_L3("Failed to read signature in levin message, at load_struct_from_levin_message");
- return false;
- }
- if(head.m_cb != buff.size()-sizeof(levin::bucket_head))
- {
- LOG_PRINT_L3("sizes mismatch, at load_struct_from_levin_message");
- return false;
- }
-
- //std::string buff_strg;
- levin_data.assign(&buff[sizeof(levin::bucket_head)], buff.size()-sizeof(levin::bucket_head));
- command = head.m_command;
- return true;
- }
-
- template<class t_struct>
- bool load_struct_from_levin_message(t_struct& t, const std::string& buff, int& command)
- {
- if(buff.size() < sizeof(levin::bucket_head) )
- {
- LOG_ERROR("size of buff(" << buff.size() << ") is too small, at load_struct_from_levin_message");
- return false;
- }
-
-#if BYTE_ORDER == LITTLE_ENDIAN
- levin::bucket_head &head = *(levin::bucket_head*)(&buff[0]);
-#else
- levin::bucket_head head = *(levin::bucket_head*)(&buff[0]);
- head.m_signature = SWAP64LE(head.m_signature);
- head.m_cb = SWAP64LE(head.m_cb);
- head.m_command = SWAP32LE(head.m_command);
- head.m_return_code = SWAP32LE(head.m_return_code);
- head.m_reservedA = SWAP32LE(head.m_reservedA);
- head.m_reservedB = SWAP32LE(head.m_reservedB);
-#endif
- if(head.m_signature != LEVIN_SIGNATURE)
- {
- LOG_ERROR("Failed to read signature in levin message, at load_struct_from_levin_message");
- return false;
- }
- if(head.m_cb != buff.size()-sizeof(levin::bucket_head))
- {
- LOG_ERROR("sizes mismatch, at load_struct_from_levin_message");
- return false;
- }
-
- std::string buff_strg;
- buff_strg.assign(&buff[sizeof(levin::bucket_head)], buff.size()-sizeof(levin::bucket_head));
-
- if(!StorageNamed::load_struct_from_storage_buff_t<t_struct, StorageNamed::DefaultStorageType>(t, buff_strg))
- {
- LOG_ERROR("Failed to read storage, at load_struct_from_levin_message");
- return false;
- }
- command = head.m_command;
- return true;
- }
-}
-}
diff --git a/contrib/epee/include/net/levin_protocol_handler_async.h b/contrib/epee/include/net/levin_protocol_handler_async.h
index 7cc42b5c4..bd6ffe930 100644
--- a/contrib/epee/include/net/levin_protocol_handler_async.h
+++ b/contrib/epee/include/net/levin_protocol_handler_async.h
@@ -37,7 +37,7 @@
#include "buffer.h"
#include "misc_language.h"
#include "syncobj.h"
-#include "misc_os_dependent.h"
+#include "time_helper.h"
#include "int-util.h"
#include <random>
diff --git a/contrib/epee/include/net/levin_server_cp.h b/contrib/epee/include/net/levin_server_cp.h
deleted file mode 100644
index 8ece35059..000000000
--- a/contrib/epee/include/net/levin_server_cp.h
+++ /dev/null
@@ -1,47 +0,0 @@
-// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * 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.
-// * Neither the name of the Andrey N. Sabelnikov 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 OWNER 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.
-//
-
-
-
-
-#ifndef _HTTP_SERVER_CP_H_
-#define _HTTP_SERVER_CP_H_
-
-#include "abstract_tcp_server_cp.h"
-#include "levin_protocol_handler.h"
-namespace epee
-{
-namespace net_utils
-{
- typedef cp_server_impl<levin::protocol_handler> cp_levin_server;
-}
-}
-
-
-
-#endif
-
-
diff --git a/contrib/epee/include/net/levin_server_cp2.h b/contrib/epee/include/net/levin_server_cp2.h
deleted file mode 100644
index b29d49bf8..000000000
--- a/contrib/epee/include/net/levin_server_cp2.h
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * 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.
-// * Neither the name of the Andrey N. Sabelnikov 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 OWNER 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.
-//
-
-
-
-#ifndef _HTTP_SERVER_CP_H_
-#define _HTTP_SERVER_CP_H_
-
-#include "abstract_tcp_server2.h"
-#include "levin_protocol_handler.h"
-#include "levin_protocol_handler_async.h"
-
-namespace epee
-{
-namespace net_utils
-{
- typedef boosted_tcp_server<levin::protocol_handler<> > boosted_levin_server;
- typedef boosted_tcp_server<levin::async_protocol_handler<> > boosted_levin_async_server;
-}
-}
-
-
-
-#endif
-
-
diff --git a/contrib/epee/include/net/local_ip.h b/contrib/epee/include/net/local_ip.h
index 1eeab2dc5..6dfa19e6e 100644
--- a/contrib/epee/include/net/local_ip.h
+++ b/contrib/epee/include/net/local_ip.h
@@ -27,7 +27,6 @@
#pragma once
-#include <string>
#include "int-util.h"
// IP addresses are kept in network byte order
@@ -44,9 +43,9 @@ namespace epee
ip = SWAP32LE(ip);
/*
local ip area
- 10.0.0.0 — 10.255.255.255
- 172.16.0.0 — 172.31.255.255
- 192.168.0.0 — 192.168.255.255
+ 10.0.0.0 ... 10.255.255.255
+ 172.16.0.0 ... 172.31.255.255
+ 192.168.0.0 ... 192.168.255.255
*/
if( (ip | 0xffffff00) == 0xffffff0a)
return true;
@@ -71,7 +70,7 @@ namespace epee
//MAKE_IP
/*
loopback ip
- 127.0.0.0 — 127.255.255.255
+ 127.0.0.0 ... 127.255.255.255
*/
return false;
}
diff --git a/contrib/epee/include/net/multiprotocols_server.h b/contrib/epee/include/net/multiprotocols_server.h
deleted file mode 100644
index 4807a4421..000000000
--- a/contrib/epee/include/net/multiprotocols_server.h
+++ /dev/null
@@ -1,47 +0,0 @@
-// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * 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.
-// * Neither the name of the Andrey N. Sabelnikov 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 OWNER 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.
-//
-
-
-
-#ifndef _MULTIPROTOCOLS_SERVER_H_
-#define _MULTIPROTOCOLS_SERVER_H_
-
-//#include "abstract_tcp_server_cp.h"
-#include "protocol_switcher.h"
-#include "abstract_tcp_server2.h"
-
-namespace epee
-{
-namespace net_utils
-{
- //typedef cp_server_impl<net_utils::protocol_switcher> multiprotocol_server;
- typedef boosted_tcp_server<net_utils::protocol_switcher> boosted_multiprotocol_server;
-}
-}
-
-
-#endif //_MULTIPROTOCOLS_SERVER_H_
-
diff --git a/contrib/epee/include/net/munin_connection_handler.h b/contrib/epee/include/net/munin_connection_handler.h
deleted file mode 100644
index 20dc38507..000000000
--- a/contrib/epee/include/net/munin_connection_handler.h
+++ /dev/null
@@ -1,376 +0,0 @@
-// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * 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.
-// * Neither the name of the Andrey N. Sabelnikov 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 OWNER 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.
-//
-
-
-
-#ifndef _MUNIN_CONNECTION_HANDLER_H_
-#define _MUNIN_CONNECTION_HANDLER_H_
-
-#include <string>
-#include "net_utils_base.h"
-#include "to_nonconst_iterator.h"
-#include "http_base.h"
-#include "reg_exp_definer.h"
-
-#define MUNIN_ARGS_DEFAULT(vertial_lable_str) "graph_args --base 1000 -l 0 --vertical-label " vertial_lable_str " \n"
-#define MUNIN_ARGS_FORCE_AUPPER_LIMIT(vertial_lable_str, limit) "graph_args --base 1000 -l 0 --vertical-label " vertial_lable_str " --rigid --upper-limit " limit " \n"
-#define MUNIN_TITLE(title_str) "graph_title " title_str "\n"
-#define MUNIN_CATEGORY(category_str) "graph_category " category_str "\n"
-#define MUNIN_INFO(info_str) "graph_info " info_str "\n"
-#define MUNIN_ENTRY(var_name) #var_name".label " #var_name "\n" #var_name".info "#var_name".\n"
-#define MUNIN_ENTRY_AREA(var_name) #var_name".label " #var_name "\n" #var_name".info "#var_name".\n" #var_name".draw AREASTACK\n"
-#define MUNIN_ENTRY_ALIAS(var_name, alias) #var_name".label " #alias"\n" #var_name".info "#alias".\n"
-#define BEGIN_MUNIN_SERVICE(servivece_name_str) if(servivece_name_str == pservice->m_service_name) {
-#define END_MUNIN_SERVICE() }
-#define MUNIN_SERVICE_PARAM(munin_var_name_str, variable) paramters_text += std::string() + munin_var_name_str ".value " + boost::lexical_cast<std::string>(variable) + "\n"
-
-
-
-
-namespace epee
-{
-namespace net_utils
-{
- namespace munin
- {
-
-
- /************************************************************************/
- /* */
- /************************************************************************/
- struct munin_service;
-
- struct munin_service_data_provider
- {
- virtual bool update_service_data(munin_service* pservice, std::string& paramters_text)=0;
- };
-
- struct munin_service
- {
- std::string m_service_name;
- std::string m_service_config_string;
- munin_service_data_provider* m_pdata_provider;
- };
-
- struct node_server_config
- {
- std::list<munin_service> m_services;
- //TODO:
- };
-
- struct fake_send_handler: public i_service_endpoint
- {
- virtual bool do_send(const void* ptr, size_t cb)
- {
- m_cache += std::string((const char*)ptr, cb);
- return true;
- }
- public:
-
- std::string m_cache;
- };
-
- /************************************************************************/
- /* */
- /************************************************************************/
- class munin_node_server_connection_handler
- {
- public:
- typedef node_server_config config_type;
- typedef connection_context_base connection_context;
-
- munin_node_server_connection_handler(i_service_endpoint* psnd_hndlr, config_type& config, const connection_context_base& context):m_psnd_hndlr(psnd_hndlr),
- m_machine_state(http_state_retriving_comand_line),
- m_config(config)
- {
- init();
- }
- virtual ~munin_node_server_connection_handler()
- {
-
- }
-
- bool release_protocol()
- {
- return true;
- }
- bool after_init_connection()
- {
- std::string hello_str = "# munin node at ";
- hello_str += m_host_name + "\n";
- send_hook(hello_str);
- return true;
- }
-
- virtual bool thread_init()
- {
- return true;
- }
-
- virtual bool thread_deinit()
- {
- return true;
- }
-
- void handle_qued_callback()
- {
-
- }
-
- virtual bool handle_recv(const void* ptr, size_t cb)
- {
-
- const char* pbuff = (const char*)ptr;
- std::string recvd_buff(pbuff, cb);
- LOG_PRINT("munin_recv: \n" << recvd_buff, LOG_LEVEL_3);
-
- m_cache += recvd_buff;
-
- bool stop_handling = false;
- while(!stop_handling)
- {
- switch(m_machine_state)
- {
- case http_state_retriving_comand_line:
- {
-
- std::string::size_type fpos = m_cache.find('\n');
- if(std::string::npos != fpos )
- {
- bool res = handle_command(m_cache);
- if(!res)
- return false;
- m_cache.erase(0, fpos+1);
- continue;
- }
- stop_handling = true;
- }
- break;
- case http_state_error:
- stop_handling = true;
- return false;
- default:
- LOG_ERROR("Error in munin state machine! Unknown state=" << m_machine_state);
- stop_handling = true;
- m_machine_state = http_state_error;
- return false;
- }
-
- }
-
- return true;
- }
-
- private:
-
-
- bool init()
- {
- char hostname[64] = {0};
- int res = gethostname(hostname, 64);
- hostname[63] = 0;//be happy
- m_host_name = hostname;
- return true;
- }
- bool handle_command(const std::string& command)
- {
- // list, nodes, config, fetch, version or quit
- STATIC_REGEXP_EXPR_1(rexp_match_command_line, "^((list)|(nodes)|(config)|(fetch)|(version)|(quit))(\\s+(\\S+))?", boost::regex::icase | boost::regex::normal);
- // 12 3 4 5 6 7 8 9
- size_t match_len = 0;
- boost::smatch result;
- if(boost::regex_search(command, result, rexp_match_command_line, boost::match_default) && result[0].matched)
- {
- if(result[2].matched)
- {//list command
- return handle_list_command();
- }else if(result[3].matched)
- {//nodes command
- return handle_nodes_command();
- }else if(result[4].matched)
- {//config command
- if(result[9].matched)
- return handle_config_command(result[9]);
- else
- {
- send_hook("Unknown service\n");
- }
- }else if(result[5].matched)
- {//fetch command
- if(result[9].matched)
- return handle_fetch_command(result[9]);
- else
- {
- send_hook("Unknown service\n");
- }
- }else if(result[6].matched)
- {//version command
- return handle_version_command();
- }else if(result[7].matched)
- {//quit command
- return handle_quit_command();
- }
- else
- return send_hook("Unknown command. Try list, nodes, config, fetch, version or quit\n");
- }
-
- return send_hook("Unknown command. Try list, nodes, config, fetch, version or quit\n");
- }
-
- bool handle_list_command()
- {
- std::string buff_to_send;
- for(std::list<munin_service>::const_iterator it = m_config.m_services.begin(); it!=m_config.m_services.end();it++)
- {
- buff_to_send += it->m_service_name + " ";
- }
- buff_to_send+='\n';
- return send_hook(buff_to_send);
- }
- bool handle_nodes_command()
- {
- //supports only one node - host name
- send_hook(m_host_name + "\n.\n");
- return true;
- }
- bool handle_config_command(const std::string& service_name)
- {
- munin_service* psrv = get_service_by_name(service_name);
- if(!psrv)
- return send_hook(std::string() + "Unknown service\n");
-
-
- return send_hook(psrv->m_service_config_string + ".\n");
- }
-
- bool handle_fetch_command(const std::string& service_name)
- {
- munin_service* psrv = get_service_by_name(service_name);
- if(!psrv)
- return send_hook(std::string() + "Unknown service\n");
-
- std::string buff;
- psrv->m_pdata_provider->update_service_data(psrv, buff);
-
- buff += ".\n";
- return send_hook(buff);
- }
- bool handle_version_command()
- {
- return send_hook("Munin node component by Andrey Sabelnikov\n");
- }
- bool handle_quit_command()
- {
- return false;
- }
-
- bool send_hook(const std::string& buff)
- {
- LOG_PRINT("munin_send: \n" << buff, LOG_LEVEL_3);
-
- if(m_psnd_hndlr)
- return m_psnd_hndlr->do_send(buff.data(), buff.size());
- else
- return false;
- }
-
-
- munin_service* get_service_by_name(const std::string& srv_name)
- {
- std::list<munin_service>::iterator it = m_config.m_services.begin();
- for(; it!=m_config.m_services.end(); it++)
- if(it->m_service_name == srv_name)
- break;
-
- if(it==m_config.m_services.end())
- return NULL;
-
- return &(*it);
- }
-
- enum machine_state{
- http_state_retriving_comand_line,
- http_state_error
- };
-
-
- config_type& m_config;
- machine_state m_machine_state;
- std::string m_cache;
- std::string m_host_name;
- protected:
- i_service_endpoint* m_psnd_hndlr;
- };
-
-
- inline bool test_self()
- {
- /*WSADATA w;
- ::WSAStartup(MAKEWORD(1, 1), &w);
- node_server_config sc;
- sc.m_services.push_back(munin_service());
- sc.m_services.back().m_service_name = "test_service";
-
- sc.m_services.back().m_service_config_string =
- "graph_args --base 1000 -l 0 --vertical-label N --upper-limit 329342976\n"
- "graph_title REPORTS STATICTICS\n"
- "graph_category bind\n"
- "graph_info This graph shows how many reports came in fixed time period.\n"
- "graph_order apps free swap\n"
- "apps.label apps\n"
- "apps.draw AREA\n"
- "apps.info Memory used by user-space applications.\n"
- "swap.label swap\n"
- "swap.draw STACK\n"
- "swap.info Swap space used.\n"
- "free.label unused\n"
- "free.draw STACK\n"
- "free.info Wasted memory. Memory that is not used for anything at all.\n"
- "committed.label committed\n"
- "committed.draw LINE2\n"
- "committed.warn 625410048\n"
- "committed.info The amount of memory that would be used if all the memory that's been allocated were to be used.\n";
-
-
- sc.m_services.push_back(munin_service());
- sc.m_services.back().m_service_name = "test_service1";
- fake_send_handler fh;
- munin_node_server_connection_handler mh(&fh, sc);
-
- std::string buff = "list\n";
- mh.handle_recv(buff.data(), buff.size());
-
-
- buff = "nodes\n";
- mh.handle_recv(buff.data(), buff.size());
-*/
- return true;
- }
-
- }
-}
-}
-#endif//!_MUNIN_CONNECTION_HANDLER_H_
diff --git a/contrib/epee/include/net/munin_node_server.h b/contrib/epee/include/net/munin_node_server.h
deleted file mode 100644
index e6df390cb..000000000
--- a/contrib/epee/include/net/munin_node_server.h
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * 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.
-// * Neither the name of the Andrey N. Sabelnikov 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 OWNER 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.
-//
-
-
-
-#ifndef _MUNIN_NODE_SERVER_H_
-#define _MUNIN_NODE_SERVER_H_
-
-#include <string>
-//#include "net_utils_base.h"
-#include "munin_connection_handler.h"
-//#include "abstract_tcp_server.h"
-//#include "abstract_tcp_server_cp.h"
-#include "abstract_tcp_server2.h"
-namespace epee
-{
-namespace net_utils
-{
- namespace munin
- {
- typedef boosted_tcp_server<munin_node_server_connection_handler> munin_node_server;
- //typedef cp_server_impl<munin_node_server_connection_handler> munin_node_cp_server;
- }
-}
-}
-#endif//!_MUNIN_NODE_SERVER_H_
diff --git a/contrib/epee/include/net/net_fwd.h b/contrib/epee/include/net/net_fwd.h
deleted file mode 100644
index d7240fba1..000000000
--- a/contrib/epee/include/net/net_fwd.h
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright (c) 2019-2022, 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.
-
-#pragma once
-
-namespace epee
-{
- namespace net_utils
- {
- struct ssl_authentication_t;
- class ssl_options_t;
- }
-}
diff --git a/contrib/epee/include/net/network_throttle.hpp b/contrib/epee/include/net/network_throttle.hpp
index 378fd5de4..750231610 100644
--- a/contrib/epee/include/net/network_throttle.hpp
+++ b/contrib/epee/include/net/network_throttle.hpp
@@ -59,7 +59,6 @@
#include <boost/asio/deadline_timer.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include "misc_language.h"
-#include "pragma_comp_defs.h"
#include <sstream>
#include <iomanip>
#include <algorithm>
diff --git a/contrib/epee/include/net/protocol_switcher.h b/contrib/epee/include/net/protocol_switcher.h
deleted file mode 100644
index 3b153d19c..000000000
--- a/contrib/epee/include/net/protocol_switcher.h
+++ /dev/null
@@ -1,121 +0,0 @@
-// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * 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.
-// * Neither the name of the Andrey N. Sabelnikov 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 OWNER 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.
-//
-
-
-
-#ifndef _PROTOCOL_SWITCHER_H_
-#define _PROTOCOL_SWITCHER_H_
-
-#include "levin_base.h"
-#include "http_server.h"
-#include "levin_protocol_handler.h"
-//#include "abstract_tcp_server.h"
-
-namespace epee
-{
-namespace net_utils
-{
- struct protocl_switcher_config
- {
- http::http_custom_handler::config_type m_http_config;
- levin::protocol_handler::config_type m_levin_config;
- };
-
-
- struct i_protocol_handler
- {
- virtual bool handle_recv(const void* ptr, size_t cb)=0;
- };
-
- template<class t>
- class t_protocol_handler: public i_protocol_handler
- {
- public:
- typedef t t_type;
- t_protocol_handler(i_service_endpoint* psnd_hndlr, typename t_type::config_type& config, const connection_context& conn_context):m_hadler(psnd_hndlr, config, conn_context)
- {}
- private:
- bool handle_recv(const void* ptr, size_t cb)
- {
- return m_hadler.handle_recv(ptr, cb);
- }
- t_type m_hadler;
- };
-
-
- class protocol_switcher
- {
- public:
- typedef protocl_switcher_config config_type;
-
- protocol_switcher(net_utils::i_service_endpoint* psnd_hndlr, config_type& config, const net_utils::connection_context_base& conn_context);
- virtual ~protocol_switcher(){}
-
- virtual bool handle_recv(const void* ptr, size_t cb);
-
- bool after_init_connection(){return true;}
- private:
- t_protocol_handler<http::http_custom_handler> m_http_handler;
- t_protocol_handler<levin::protocol_handler> m_levin_handler;
- i_protocol_handler* pcurrent_handler;
-
- std::string m_cached_buff;
- };
-
- protocol_switcher::protocol_switcher(net_utils::i_service_endpoint* psnd_hndlr, config_type& config, const net_utils::connection_context_base& conn_context):m_http_handler(psnd_hndlr, config.m_http_config, conn_context), m_levin_handler(psnd_hndlr, config.m_levin_config, conn_context), pcurrent_handler(NULL)
- {}
-
- bool protocol_switcher::handle_recv(const void* ptr, size_t cb)
- {
- if(pcurrent_handler)
- return pcurrent_handler->handle_recv(ptr, cb);
- else
- {
- m_cached_buff.append((const char*)ptr, cb);
- if(m_cached_buff.size() < sizeof(uint64_t))
- return true;
-
- if(*((uint64_t*)&m_cached_buff[0]) == LEVIN_SIGNATURE)
- {
- pcurrent_handler = &m_levin_handler;
- return pcurrent_handler->handle_recv(m_cached_buff.data(), m_cached_buff.size());
- }
- if(m_cached_buff.substr(0, 4) == "GET " || m_cached_buff.substr(0, 4) == "POST")
- {
- pcurrent_handler = &m_http_handler;
- return pcurrent_handler->handle_recv(m_cached_buff.data(), m_cached_buff.size());
- }else
- {
- LOG_ERROR("Wrong protocol accepted on port...");
- return false;
- }
- }
-
- return true;
- }
-}
-}
-#endif //_PROTOCOL_SWITCHER_H_
diff --git a/contrib/epee/include/net/rpc_method_name.h b/contrib/epee/include/net/rpc_method_name.h
deleted file mode 100644
index 1c327bc31..000000000
--- a/contrib/epee/include/net/rpc_method_name.h
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * 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.
-// * Neither the name of the Andrey N. Sabelnikov 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 OWNER 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.
-//
-
-
-#pragma once
-
-
-#define RPC_METHOD_NAME(name) static inline const char* methodname(){return name;}
diff --git a/contrib/epee/include/net/smtp.h b/contrib/epee/include/net/smtp.h
deleted file mode 100644
index 5f2b842d5..000000000
--- a/contrib/epee/include/net/smtp.h
+++ /dev/null
@@ -1,181 +0,0 @@
-// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * 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.
-// * Neither the name of the Andrey N. Sabelnikov 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 OWNER 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.
-//
-
-
-
-
-#pragma once
-#include <iostream>
-#include <istream>
-#include <ostream>
-#include <string>
-#include <boost/asio.hpp>
-#include <boost/bind.hpp>
-#include <boost/lexical_cast.hpp>
-#include <boost/archive/iterators/base64_from_binary.hpp>
-#include <boost/archive/iterators/transform_width.hpp>
-#include <boost/archive/iterators/ostream_iterator.hpp>
-
-
-namespace epee
-{
-namespace net_utils
-{
- namespace smtp
- {
-
- using boost::asio::ip::tcp;
- using namespace boost::archive::iterators;
- typedef base64_from_binary<transform_width<const char *,6,8> > base64_text;
-
- /************************************************************************/
- /* */
- /************************************************************************/
- class smtp_client
- {
- public:
- smtp_client(std::string pServer,unsigned int pPort,std::string pUser,std::string pPassword):
- mServer(pServer),mPort(pPort),mUserName(pUser),mPassword(pPassword),mSocket(mIOService),mResolver(mIOService)
- {
- tcp::resolver::query qry(mServer,boost::lexical_cast<std::string>( mPort ));
- mResolver.async_resolve(qry,boost::bind(&smtp_client::handleResolve,this,boost::asio::placeholders::error,
- boost::asio::placeholders::iterator));
- }
- bool Send(std::string pFrom,std::string pTo,std::string pSubject,std::string pMessage)
- {
- mHasError = true;
- mFrom=pFrom;
- mTo=pTo;
- mSubject=pSubject;
- mMessage=pMessage;
- mIOService.run();
- return !mHasError;
- }
- private:
- std::string encodeBase64(std::string pData)
- {
- std::stringstream os;
- size_t sz=pData.size();
- std::copy(base64_text(pData.c_str()),base64_text(pData.c_str()+sz),std::ostream_iterator<char>(os));
- return os.str();
- }
- void handleResolve(const boost::system::error_code& err,tcp::resolver::iterator endpoint_iterator)
- {
- if(!err)
- {
- tcp::endpoint endpoint=*endpoint_iterator;
- mSocket.async_connect(endpoint,
- boost::bind(&smtp_client::handleConnect,this,boost::asio::placeholders::error,++endpoint_iterator));
- }
- else
- {
- mHasError=true;
- mErrorMsg= err.message();
- }
- }
- void writeLine(std::string pData)
- {
- std::ostream req_strm(&mRequest);
- req_strm << pData << "\r\n";
- boost::asio::write(mSocket,mRequest);
- req_strm.clear();
- }
- void readLine(std::string& pData)
- {
- boost::asio::streambuf response;
- boost::asio::read_until(mSocket, response, "\r\n");
- std::istream response_stream(&response);
- response_stream >> pData;
- }
- void handleConnect(const boost::system::error_code& err,tcp::resolver::iterator endpoint_iterator)
- {
- if (!err)
- {
- std::string read_buff;
- // The connection was successful. Send the request.
- std::ostream req_strm(&mRequest);
- writeLine("EHLO "+mServer);
- readLine(read_buff);//220
- writeLine("AUTH LOGIN");
- readLine(read_buff);//
- writeLine(encodeBase64(mUserName));
- readLine(read_buff);
- writeLine(encodeBase64(mPassword));
- readLine(read_buff);
- writeLine( "MAIL FROM:<"+mFrom+">");
- writeLine( "RCPT TO:<"+mTo+">");
- writeLine( "DATA");
- writeLine( "SUBJECT:"+mSubject);
- writeLine( "From:"+mFrom);
- writeLine( "To:"+mTo);
- writeLine( "");
- writeLine( mMessage );
- writeLine( "\r\n.\r\n");
- readLine(read_buff);
- if(read_buff == "250")
- mHasError = false;
- writeLine( "QUIT");
- }
- else
- {
- mHasError=true;
- mErrorMsg= err.message();
- }
- }
- std::string mServer;
- std::string mUserName;
- std::string mPassword;
- std::string mFrom;
- std::string mTo;
- std::string mSubject;
- std::string mMessage;
- unsigned int mPort;
- boost::asio::io_service mIOService;
- tcp::resolver mResolver;
- tcp::socket mSocket;
- boost::asio::streambuf mRequest;
- boost::asio::streambuf mResponse;
- bool mHasError;
- std::string mErrorMsg;
- };
-
-
- bool send_mail(const std::string& server, int port, const std::string& login, const std::string& pass, const std::string& from_email, /*"STIL CRAWLER",*/
- const std::string& maillist, const std::string& subject, const std::string& body)
- {
- STD_TRY_BEGIN();
- //smtp_client mailc("yoursmtpserver.com",25,"user@yourdomain.com","password");
- //mailc.Send("from@yourdomain.com","to@somewhere.com","subject","Hello from C++ SMTP Client!");
- smtp_client mailc(server,port,login,pass);
- return mailc.Send(from_email,maillist,subject,body);
- STD_TRY_CATCH("at send_mail", false);
- }
-
- }
-}
-}
-
-//#include "smtp.inl"
diff --git a/contrib/epee/include/net/smtp.inl b/contrib/epee/include/net/smtp.inl
deleted file mode 100644
index c16372c88..000000000
--- a/contrib/epee/include/net/smtp.inl
+++ /dev/null
@@ -1,1569 +0,0 @@
-// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * 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.
-// * Neither the name of the Andrey N. Sabelnikov 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 OWNER 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 "md5.h"
-
-namespace epee
-{
-namespace net_utils
-{
- namespace smtp
- {
-
-
- //////////////////////////////////////////////////////////////////////////
- inline char * convert_hex( unsigned char *in, int len )
- {
- static char hex[] = "0123456789abcdef";
- char * out;
- int i;
-
- out = (char *) malloc(len * 2 + 1);
- if (out == NULL)
- return NULL;
-
- for (i = 0; i < len; i++) {
- out[i * 2] = hex[in[i] >> 4];
- out[i * 2 + 1] = hex[in[i] & 15];
- }
-
- out[i*2] = 0;
-
- return out;
- }
-
- //////////////////////////////////////////////////////////////////////////
- inline char * hash_md5(const char * sec_key, const char * data, int len)
- {
- char key[65], digest[24];
- char * hash_hex;
-
- int sec_len, i;
-
- sec_len = strlen(sec_key);
-
- if (sec_len < 64) {
- memcpy(key, sec_key, sec_len);
- for (i = sec_len; i < 64; i++) {
- key[i] = 0;
- }
- } else {
- memcpy(key, sec_key, 64);
- }
-
- md5::hmac_md5( (const unsigned char*)data, len, (const unsigned char*)key, 64, (unsigned char*)digest );
- hash_hex = convert_hex( (unsigned char*)digest, 16 );
-
- return hash_hex;
- }
- //////////////////////////////////////////////////////////////////////////
- //////////////////////////////////////////////////////////////////////////
- //////////////////////////////////////////////////////////////////////////
- //////////////////////////////////////////////////////////////////////////
- inline CSMTPClient::CSMTPClient(void)
- {
- m_dwSupportedAuthModesCount = 0;
- m_bConnected = FALSE;
- m_hSocket = INVALID_SOCKET;
- m_pErrorText = NULL;
-
- // Initialize WinSock
- WORD wVer = MAKEWORD( 2, 2 );
- if ( WSAStartup( wVer, &m_wsaData ) != NO_ERROR )
- {
- SetErrorText( "WSAStartup.", WSAGetLastError() );
- throw;
- }
- if ( LOBYTE( m_wsaData.wVersion ) != 2 || HIBYTE( m_wsaData.wVersion ) != 2 )
- {
- SetErrorText( "Can't find a useable WinSock DLL." );
- WSACleanup();
- throw;
- }
- }
-
- //////////////////////////////////////////////////////////////////////////
- inline CSMTPClient::~CSMTPClient(void)
- {
- if ( m_pErrorText )
- {
- free( m_pErrorText );
- m_pErrorText = NULL;
- }
-
- if ( m_bConnected )
- ServerDisconnect();
-
- // Cleanup
- WSACleanup();
- }
-
- //////////////////////////////////////////////////////////////////////////
- inline void CSMTPClient::SetErrorText( LPCSTR szErrorText, DWORD dwErrorCode )
- {
- if ( m_pErrorText )
- {
- free( m_pErrorText );
- m_pErrorText = NULL;
- }
-
- LPVOID lpMsgBuf = NULL;
- if ( dwErrorCode )
- {
- FormatMessageA(
- FORMAT_MESSAGE_ALLOCATE_BUFFER |
- FORMAT_MESSAGE_FROM_SYSTEM,
- NULL,
- dwErrorCode,
- MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
- (LPSTR) &lpMsgBuf,
- 0, NULL );
- }
-
- if ( szErrorText && strlen( szErrorText ) )
- {
- m_pErrorText = (LPBYTE)malloc( strlen( szErrorText ) + 1 );
- strcpy( (char*)m_pErrorText, szErrorText );
-
- if ( lpMsgBuf )
- {
- strcat( (char*)m_pErrorText, " " );
- strcpy( (char*)m_pErrorText, (char*)lpMsgBuf );
-
- LocalFree( lpMsgBuf );
- }
- }
- }
-
- inline void CSMTPClient::SetErrorText( PBYTE szErrorText, DWORD dwErrorCode )
- {
- SetErrorText( (LPCSTR)szErrorText, dwErrorCode );
- }
-
- //////////////////////////////////////////////////////////////////////////
- inline char* CSMTPClient::GetLastErrorText()
- {
- return (char*)m_pErrorText;
- }
-
- //////////////////////////////////////////////////////////////////////////
- inline DWORD CSMTPClient::ReceiveData( SOCKET hSocket, PBYTE pReceiveBuffer, DWORD dwReceiveBufferSize )
- {
- DWORD dwReceivedDataSize = 0;
-
- if ( hSocket != INVALID_SOCKET && pReceiveBuffer && dwReceiveBufferSize )
- {
- int iReceived = 0;
- int iLength = 0;
-
- iLength = recv( hSocket, (LPSTR)pReceiveBuffer + iReceived, dwReceiveBufferSize - iReceived,
- NO_FLAGS );
-
- if ( iLength != 0 && iLength != SOCKET_ERROR )
- iReceived += iLength;
-
- dwReceivedDataSize = iReceived;
-
- pReceiveBuffer[ iReceived ] = 0;
- }
-
- return dwReceivedDataSize;
- }
-
- inline //////////////////////////////////////////////////////////////////////////
- DWORD CSMTPClient::SendData( SOCKET hSocket, PBYTE pSendBuffer, DWORD dwSendBufferSize )
- {
- DWORD dwSended = 0;
-
- if ( hSocket != INVALID_SOCKET && pSendBuffer && dwSendBufferSize )
- {
- int iSended = 0;
- int iLength = 0;
-
- while ( iLength != SOCKET_ERROR && dwSendBufferSize - iSended > 0 )
- {
- iLength = send( hSocket, (LPSTR)pSendBuffer + iSended, dwSendBufferSize - iSended,
- NO_FLAGS );
-
- if ( iLength != 0 && iLength != SOCKET_ERROR )
- iSended += iLength;
- }
-
- dwSended = iSended;
- }
-
- //if ( dwSended )
- // printf( "C: %s", pSendBuffer );
-
- return dwSended;
- }
-
- //////////////////////////////////////////////////////////////////////////
- inline unsigned short CSMTPClient::GetResponseCode( LPBYTE pBuffer, DWORD dwBufferSize )
- {
- unsigned short iCode = 0;
-
- if ( dwBufferSize >= 3 )
- {
- CHAR szResponseCode[ 4 ] = { 0 };
- memcpy( szResponseCode, pBuffer, 3 );
- szResponseCode[ 3 ] = 0;
- iCode = atoi( szResponseCode );
- }
-
- return iCode;
- }
-
- //////////////////////////////////////////////////////////////////////////
- inline void CSMTPClient::ParseESMTPExtensions( LPBYTE pBuffer, DWORD dwBufferSize )
- {
- const char *szSubstring = strstr( (const char*)pBuffer, "250-AUTH " );
- if ( !szSubstring )
- {
- szSubstring = strstr( (const char*)pBuffer, "250 AUTH " );
- }
-
- if ( szSubstring )
- {
- const char *szSubstringEnd = strstr( (const char*)szSubstring, "\r\n" );
- if ( szSubstringEnd )
- {
- szSubstring += 9;
- char szAuthMode[ 256 ] = { 0 };
- for ( ; szSubstring < szSubstringEnd + 1 ; szSubstring++ )
- {
- if ( *szSubstring == ' ' || *szSubstring == '\r' )
- {
- if ( _strcmpi( szAuthMode, SMTP_COMMAND_AUTH_PLAIN ) == 0 )
- {
- m_aSupportedAuthModes[ m_dwSupportedAuthModesCount ] = AUTH_MODE_PLAIN;
- m_dwSupportedAuthModesCount++;
- }
- else if ( _strcmpi( szAuthMode, SMTP_COMMAND_AUTH_LOGIN ) == 0 )
- {
- m_aSupportedAuthModes[ m_dwSupportedAuthModesCount ] = AUTH_MODE_LOGIN;
- m_dwSupportedAuthModesCount++;
- }
- else if ( _strcmpi( szAuthMode, SMTP_COMMAND_AUTH_CRAM_MD5 ) == 0 )
- {
- m_aSupportedAuthModes[ m_dwSupportedAuthModesCount ] = AUTH_MODE_CRAM_MD5;
- m_dwSupportedAuthModesCount++;
- }
-
- szAuthMode[ 0 ] = 0;
-
- if ( m_dwSupportedAuthModesCount == MAX_AUTH_MODES_COUND )
- break;
- }
- else
- {
- szAuthMode[ strlen( szAuthMode ) + 1 ] = 0;
- szAuthMode[ strlen( szAuthMode ) ] = *szSubstring;
- }
- }
- }
- }
- }
-
- //////////////////////////////////////////////////////////////////////////
- inline BOOL CSMTPClient::ServerConnect( LPCSTR szServerAddress, const unsigned short iPortNumber )
- {
- if ( m_bConnected )
- ServerDisconnect();
-
- m_bConnected = FALSE;
- m_hSocket = INVALID_SOCKET;
-
- m_hSocket = _connectServerSocket( szServerAddress, iPortNumber );
-
- if ( m_hSocket != INVALID_SOCKET )
- {
- DWORD dwReceiveBufferSize = 1024*16;
- PBYTE pReceiveBuffer = (PBYTE)malloc( dwReceiveBufferSize );
- if ( pReceiveBuffer )
- {
- // Connected. Wait server hello string.
- DWORD iReceived = ReceiveData( m_hSocket, pReceiveBuffer, dwReceiveBufferSize );
- if ( iReceived )
- {
- // Check 220
- int iResponseCode = GetResponseCode( pReceiveBuffer, iReceived );
- if ( iResponseCode != 220 )
- {
- SetErrorText( pReceiveBuffer );
- free( pReceiveBuffer );
- ServerDisconnect();
- return FALSE;
- }
- }
- else
- {
- SetErrorText( "ReceiveData error. ", WSAGetLastError() );
- free( pReceiveBuffer );
- ServerDisconnect();
- return FALSE;
- }
-
- // EHLO / HELO
- BYTE szHelloBuffer[ 256 ];
- sprintf( (char*)szHelloBuffer, "%s %s\r\n", (char*)SMTP_COMMAND_EHLO, (char*)szServerAddress );
- if ( SendData( m_hSocket, (PBYTE)szHelloBuffer, strlen( (const char*)szHelloBuffer ) ) == 0 )
- {
- SetErrorText( "SendData error.", WSAGetLastError() );
- free( pReceiveBuffer );
- ServerDisconnect();
- return FALSE;
- }
-
- iReceived = ReceiveData( m_hSocket, pReceiveBuffer, dwReceiveBufferSize );
- if ( iReceived )
- {
- // Check 250
- int iResponseCode = GetResponseCode( pReceiveBuffer, iReceived );
- if ( iResponseCode == 500 )
- {
- SetErrorText( pReceiveBuffer );
-
- sprintf( (char*)szHelloBuffer, "%s %s\r\n", (char*)SMTP_COMMAND_HELO, (char*)szServerAddress );
- if ( SendData( m_hSocket, (PBYTE)szHelloBuffer, strlen( (const char*)szHelloBuffer ) ) == 0 )
- {
- SetErrorText( "SendData error.", WSAGetLastError() );
- free( pReceiveBuffer );
- ServerDisconnect();
- return FALSE;
- }
-
- iResponseCode = GetResponseCode( pReceiveBuffer, iReceived );
- if ( iResponseCode != 250 )
- {
- SetErrorText( pReceiveBuffer );
- free( pReceiveBuffer );
- ServerDisconnect();
- return FALSE;
- }
- }
- else if ( iResponseCode != 250 )
- {
- SetErrorText( pReceiveBuffer );
- free( pReceiveBuffer );
- ServerDisconnect();
- return FALSE;
- }
-
- // Parse AUTH supported modes
- ParseESMTPExtensions( pReceiveBuffer, iReceived );
- }
- else
- {
- SetErrorText( "ReceiveData error.", WSAGetLastError() );
- free( pReceiveBuffer );
- ServerDisconnect();
- return FALSE;
- }
-
- free( pReceiveBuffer );
- }
- }
- else
- {
- return FALSE;
- }
-
- m_bConnected = TRUE;
-
- return TRUE;
- }
-
- //////////////////////////////////////////////////////////////////////////
- inline BOOL CSMTPClient::ServerConnect( LPCSTR szServerAddress, const unsigned short iPortNumber, LPCSTR szUsername, LPCSTR szPassword )
- {
- BOOL bSuccess = FALSE;
-
- bSuccess = ServerConnect( szServerAddress, iPortNumber );
- if ( bSuccess )
- {
- if ( GetAuthModeIsSupported( AUTH_MODE_CRAM_MD5 ) )
- {
- ServerLogin( szUsername, szPassword, AUTH_MODE_CRAM_MD5 );
- }
- else
- if ( GetAuthModeIsSupported( AUTH_MODE_PLAIN ) )
- {
- ServerLogin( szUsername, szPassword, AUTH_MODE_PLAIN );
- }
- else
- if ( GetAuthModeIsSupported( AUTH_MODE_LOGIN ) )
- {
- ServerLogin( szUsername, szPassword, AUTH_MODE_LOGIN );
- }
- }
-
- return bSuccess;
- }
-
- //////////////////////////////////////////////////////////////////////////
- inline SOCKET CSMTPClient::_connectServerSocket( LPCSTR szServerAddress, const unsigned short iPortNumber )
- {
- int nConnect;
- short nProtocolPort = iPortNumber;
- LPHOSTENT lpHostEnt;
- SOCKADDR_IN sockAddr;
-
- SOCKET hServerSocket = INVALID_SOCKET;
-
- lpHostEnt = gethostbyname( szServerAddress );
- if (lpHostEnt)
- {
- hServerSocket = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );
- if (hServerSocket != INVALID_SOCKET)
- {
- sockAddr.sin_family = AF_INET;
- sockAddr.sin_port = htons( nProtocolPort );
- sockAddr.sin_addr = *((LPIN_ADDR)*lpHostEnt->h_addr_list);
-
- nConnect = connect( hServerSocket, (PSOCKADDR)&sockAddr,
- sizeof(sockAddr) );
-
- if ( nConnect != 0 )
- {
- SetErrorText( "connect error.", WSAGetLastError() );
- hServerSocket = INVALID_SOCKET;
- }
- }
- else
- {
- SetErrorText( "Invalid socket." );
- throw;
- }
- }
- else
- {
- SetErrorText( "Error retrieving host by name.", WSAGetLastError() );
- }
-
- return hServerSocket ;
- }
-
- //////////////////////////////////////////////////////////////////////////
- inline void CSMTPClient::ServerDisconnect()
- {
- if ( m_hSocket != INVALID_SOCKET )
- {
- if ( SendData( m_hSocket, (PBYTE)SMTP_COMMAND_QUIT, strlen( SMTP_COMMAND_QUIT ) ) == 0 )
- {
- SetErrorText( "SendData error.", WSAGetLastError() );
- return;
- }
-
- DWORD dwReceiveBufferSize = 1024*16;
- PBYTE pReceiveBuffer = (PBYTE)malloc( dwReceiveBufferSize );
- if ( pReceiveBuffer )
- {
- DWORD iReceived = ReceiveData( m_hSocket, pReceiveBuffer, dwReceiveBufferSize );
-
- if ( iReceived )
- SetErrorText( pReceiveBuffer );
-
- free( pReceiveBuffer );
- }
-
- m_hSocket = INVALID_SOCKET;
- }
-
- m_bConnected = FALSE;
- }
-
- //////////////////////////////////////////////////////////////////////////
- inline BOOL CSMTPClient::GetAuthModeIsSupported( int iMode )
- {
- BOOL bSupported = FALSE;
-
- for ( int i = 0 ; i < m_dwSupportedAuthModesCount ; i++ )
- {
- if ( m_aSupportedAuthModes[ i ] == iMode )
- {
- bSupported = TRUE;
- break;
- }
- }
-
- return bSupported;
- }
-
- //////////////////////////////////////////////////////////////////////////
- inline BOOL CSMTPClient::ServerLogin( LPCSTR szUsername, LPCSTR szPassword, int iAuthMode )
- {
- BOOL bSuccess = FALSE;
-
- if ( iAuthMode == AUTH_MODE_PLAIN )
- {
- bSuccess = ServerLoginMethodPlain( szUsername, szPassword );
- }
- else if ( iAuthMode == AUTH_MODE_LOGIN )
- {
- bSuccess = ServerLoginMethodLogin( szUsername, szPassword );
- }
- else if ( iAuthMode == AUTH_MODE_CRAM_MD5 )
- {
- bSuccess = ServerLoginMethodCramMD5( szUsername, szPassword );
- }
-
- return bSuccess;
- }
-
- //////////////////////////////////////////////////////////////////////////
- inline BOOL CSMTPClient::ServerLogin( LPCSTR szUsername, LPCSTR szPassword )
- {
- BOOL bSuccess = FALSE;
-
- if ( GetAuthModeIsSupported( AUTH_MODE_CRAM_MD5 ) )
- {
- bSuccess = ServerLogin( szUsername, szPassword, AUTH_MODE_CRAM_MD5 );
- }
- else
- if ( GetAuthModeIsSupported( AUTH_MODE_PLAIN ) )
- {
- bSuccess = ServerLogin( szUsername, szPassword, AUTH_MODE_PLAIN );
- }
- else
- if ( GetAuthModeIsSupported( AUTH_MODE_LOGIN ) )
- {
- bSuccess = ServerLogin( szUsername, szPassword, AUTH_MODE_LOGIN );
- }
-
- return bSuccess;
- }
-
- //////////////////////////////////////////////////////////////////////////
- inline BOOL CSMTPClient::ServerLoginMethodPlain( LPCSTR szUsername, LPCSTR szPassword )
- {
- BOOL bSuccess = FALSE;
-
- BYTE szCommandBuffer[ 256 ];
- sprintf( (char*)szCommandBuffer, "%s %s\r\n", (char*)SMTP_COMMAND_AUTH, (char*)SMTP_COMMAND_AUTH_PLAIN );
- if ( SendData( m_hSocket, (PBYTE)szCommandBuffer, strlen( (const char*)szCommandBuffer ) ) == 0 )
- {
- SetErrorText( "SendData error.", WSAGetLastError() );
- return FALSE;
- }
-
- DWORD dwReceiveBufferSize = 1024*16;
- PBYTE pReceiveBuffer = (PBYTE)malloc( dwReceiveBufferSize );
- if ( pReceiveBuffer )
- {
- // Connected. Wait server hello string.
- DWORD iReceived = ReceiveData( m_hSocket, pReceiveBuffer, dwReceiveBufferSize );
- if ( iReceived )
- {
- SetErrorText( pReceiveBuffer );
-
- // Check 334
- int iResponseCode = GetResponseCode( pReceiveBuffer, iReceived );
- if ( iResponseCode != 334 )
- {
- free( pReceiveBuffer );
- return FALSE;
- }
- }
- else
- {
- SetErrorText( "ReceiveData error.", WSAGetLastError() );
- free( pReceiveBuffer );
- return FALSE;
- }
-
- // Encode.
- DWORD dwLoginBuffer = strlen( szUsername ) + strlen( szPassword ) + 3;
- char *pLoginBuffer = (char*)malloc( dwLoginBuffer );
- if ( pLoginBuffer )
- {
- ZeroMemory( pLoginBuffer, dwLoginBuffer );
- strcpy( pLoginBuffer + 1, szUsername );
- strcpy( pLoginBuffer + 1 + strlen( szUsername ) + 1, szPassword );
-
- Base64Coder coder;
- coder.Encode( (const PBYTE)pLoginBuffer, dwLoginBuffer - 1 );
- LPCSTR szLoginBufferEncoded = coder.EncodedMessage();
-
- if ( szLoginBufferEncoded && strlen( szLoginBufferEncoded ) > 0 )
- {
- DWORD dwSendBufferSize = strlen( szLoginBufferEncoded ) + 4;
- char* pSendBuffer = (char*)malloc( dwSendBufferSize );
- if ( pSendBuffer )
- {
- strcpy( pSendBuffer, szLoginBufferEncoded );
- strcat( pSendBuffer, "\r\n" );
-
- if ( SendData( m_hSocket, (PBYTE)pSendBuffer, strlen( (const char*)pSendBuffer ) ) == 0 )
- {
- SetErrorText( "SendData error.", WSAGetLastError() );
- free( pSendBuffer );
- free( pLoginBuffer );
- free( pReceiveBuffer );
- return FALSE;
- }
-
- free( pSendBuffer );
- }
- }
-
- free( pLoginBuffer );
-
- // check result
- iReceived = ReceiveData( m_hSocket, pReceiveBuffer, dwReceiveBufferSize );
- if ( iReceived )
- {
- SetErrorText( pReceiveBuffer );
-
- // Check 235
- int iResponseCode = GetResponseCode( pReceiveBuffer, iReceived );
- if ( iResponseCode != 235 )
- {
- free( pReceiveBuffer );
- return FALSE;
- }
-
- bSuccess = TRUE;
- }
- else
- {
- SetErrorText( "ReceiveData error.", WSAGetLastError() );
- free( pReceiveBuffer );
- return FALSE;
- }
- }
-
- free( pReceiveBuffer );
- }
-
- return bSuccess;
- }
-
- //////////////////////////////////////////////////////////////////////////
- inline BOOL CSMTPClient::ServerLoginMethodLogin( LPCSTR szUsername, LPCSTR szPassword )
- {
- BOOL bSuccess = FALSE;
-
- BYTE szCommandBuffer[ 256 ];
- sprintf( (char*)szCommandBuffer, "%s %s\r\n", (char*)SMTP_COMMAND_AUTH, (char*)SMTP_COMMAND_AUTH_LOGIN );
- if ( SendData( m_hSocket, (PBYTE)szCommandBuffer, strlen( (const char*)szCommandBuffer ) ) == 0 )
- {
- SetErrorText( "SendData error.", WSAGetLastError() );
- return FALSE;
- }
-
- DWORD dwReceiveBufferSize = 1024*16;
- PBYTE pReceiveBuffer = (PBYTE)malloc( dwReceiveBufferSize );
- if ( pReceiveBuffer )
- {
- DWORD iReceived = ReceiveData( m_hSocket, pReceiveBuffer, dwReceiveBufferSize );
- if ( iReceived )
- {
- SetErrorText( pReceiveBuffer );
-
- // Check 334
- int iResponseCode = GetResponseCode( pReceiveBuffer, iReceived );
- if ( iResponseCode != 334 )
- {
- free( pReceiveBuffer );
- return FALSE;
- }
-
- // Check request
- if ( iReceived > 6 )
- {
- Base64Coder coder;
- coder.Decode( pReceiveBuffer + 4, iReceived - 6 );
- LPCSTR szRequest = coder.DecodedMessage();
- if ( szRequest && strlen( szRequest ) > 0 )
- {
- if ( strcmpi( szRequest, "Username:" ) == 0 )
- {
- coder.Encode( (const PBYTE)szUsername, strlen( szUsername ) );
- LPCSTR szUsernameEncoded = coder.EncodedMessage();
-
- char* szLoginUsernameBuffer = (char*)malloc( strlen( szUsernameEncoded ) + 4 );
- if ( szLoginUsernameBuffer )
- {
- strcpy( szLoginUsernameBuffer, szUsernameEncoded );
- strcat( szLoginUsernameBuffer, "\r\n" );
-
- if ( SendData( m_hSocket, (PBYTE)szLoginUsernameBuffer, strlen( (const char*)szLoginUsernameBuffer ) ) == 0 )
- {
- SetErrorText( "SendData error.", WSAGetLastError() );
- free( pReceiveBuffer );
- return FALSE;
- }
-
- free( szLoginUsernameBuffer );
- }
- else
- {
- free( pReceiveBuffer );
- return FALSE;
- }
-
- iReceived = ReceiveData( m_hSocket, pReceiveBuffer, dwReceiveBufferSize );
- if ( iReceived )
- {
- SetErrorText( pReceiveBuffer );
-
- // Check 334
- int iResponseCode = GetResponseCode( pReceiveBuffer, iReceived );
- if ( iResponseCode != 334 )
- {
- free( pReceiveBuffer );
- return FALSE;
- }
-
- // Check request
- if ( iReceived > 6 )
- {
- coder.Decode( pReceiveBuffer + 4, iReceived - 6 );
- LPCSTR szRequest2 = coder.DecodedMessage();
- if ( szRequest2 && strlen( szRequest2 ) > 0 )
- {
- if ( strcmpi( szRequest2, "Password:" ) == 0 )
- {
- coder.Encode( (const PBYTE)szPassword, strlen( szPassword ) );
- LPCSTR szPasswordEncoded = coder.EncodedMessage();
-
- char* szLoginPasswordBuffer = (char*)malloc( strlen( szPasswordEncoded ) + 4 );
- if ( szLoginPasswordBuffer )
- {
- strcpy( szLoginPasswordBuffer, szPasswordEncoded );
- strcat( szLoginPasswordBuffer, "\r\n" );
-
- if ( SendData( m_hSocket, (PBYTE)szLoginPasswordBuffer, strlen( (const char*)szLoginPasswordBuffer ) ) == 0 )
- {
- SetErrorText( "SendData error.", WSAGetLastError() );
- free( pReceiveBuffer );
- return FALSE;
- }
-
- free( szLoginPasswordBuffer );
- }
- else
- {
- free( pReceiveBuffer );
- return FALSE;
- }
-
- iReceived = ReceiveData( m_hSocket, pReceiveBuffer, dwReceiveBufferSize );
- if ( iReceived )
- {
- SetErrorText( pReceiveBuffer );
-
- // Check 235
- int iResponseCode = GetResponseCode( pReceiveBuffer, iReceived );
- if ( iResponseCode != 235 )
- {
- free( pReceiveBuffer );
- return FALSE;
- }
-
- bSuccess = TRUE;
- }
- else
- {
- SetErrorText( "ReceiveData error.", WSAGetLastError() );
- free( pReceiveBuffer );
- return FALSE;
- }
- }
- }
- }
- }
- else
- {
- free( pReceiveBuffer );
- return FALSE;
- }
- }
- }
- else
- {
- free( pReceiveBuffer );
- return FALSE;
- }
- }
- else
- {
- free( pReceiveBuffer );
- return FALSE;
- }
- }
- else
- {
- SetErrorText( "ReceiveData error.", WSAGetLastError() );
- free( pReceiveBuffer );
- return FALSE;
- }
-
- free( pReceiveBuffer );
- }
-
- return bSuccess;
- }
-
- //////////////////////////////////////////////////////////////////////////
- inline BOOL CSMTPClient::ServerLoginMethodCramMD5( LPCSTR szUsername, LPCSTR szPassword )
- {
- BOOL bSuccess = FALSE;
-
- BYTE szCommandBuffer[ 256 ];
- sprintf( (char*)szCommandBuffer, "%s %s\r\n", (char*)SMTP_COMMAND_AUTH, (char*)SMTP_COMMAND_AUTH_CRAM_MD5 );
- if ( SendData( m_hSocket, (PBYTE)szCommandBuffer, strlen( (const char*)szCommandBuffer ) ) == 0 )
- {
- SetErrorText( "SendData error.", WSAGetLastError() );
- return FALSE;
- }
-
- DWORD dwReceiveBufferSize = 1024*16;
- PBYTE pReceiveBuffer = (PBYTE)malloc( dwReceiveBufferSize );
- if ( pReceiveBuffer )
- {
- // Connected. Wait server hello string.
- DWORD iReceived = ReceiveData( m_hSocket, pReceiveBuffer, dwReceiveBufferSize );
- if ( iReceived )
- {
- SetErrorText( pReceiveBuffer );
-
- // Check 334
- int iResponseCode = GetResponseCode( pReceiveBuffer, iReceived );
- if ( iResponseCode != 334 )
- {
- free( pReceiveBuffer );
- return FALSE;
- }
-
- // Check request
- if ( iReceived > 6 )
- {
- Base64Coder coder;
- coder.Decode( pReceiveBuffer + 4, iReceived - 6 );
- LPCSTR szResponse = coder.DecodedMessage();
- if ( szResponse && strlen( szResponse ) > 0 )
- {
- char *auth_hex = hash_md5( szPassword, szResponse, strlen(szResponse) );
- if ( !auth_hex )
- {
- free( pReceiveBuffer );
- return FALSE;
- }
-
- char *szCommand = (char*)malloc( strlen( szUsername ) + strlen( auth_hex ) + 5 );
- if ( szCommand )
- {
- sprintf( szCommand, "%s %s", szUsername, auth_hex );
-
- free( auth_hex );
-
- coder.Encode( (const PBYTE)szCommand, strlen( szCommand ) );
-
- free( szCommand );
-
- LPCSTR szAuthEncoded = coder.EncodedMessage();
- if ( szAuthEncoded == NULL )
- {
- free( pReceiveBuffer );
- return FALSE;
- }
-
- char *szAuthCommand = (char*)malloc( strlen( szAuthEncoded ) + 4 );
- if ( szAuthCommand )
- {
- strcpy( szAuthCommand, szAuthEncoded );
- strcat( szAuthCommand, "\r\n" );
-
- // Send auth data
- if ( SendData( m_hSocket, (PBYTE)szAuthCommand, strlen( (const char*)szAuthCommand ) ) == 0 )
- {
- SetErrorText( "SendData error.", WSAGetLastError() );
- free( szAuthCommand );
- free( pReceiveBuffer );
- return FALSE;
- }
-
- // Check response
- iReceived = ReceiveData( m_hSocket, pReceiveBuffer, dwReceiveBufferSize );
- if ( iReceived )
- {
- SetErrorText( pReceiveBuffer );
-
- // Check 235
- int iResponseCode = GetResponseCode( pReceiveBuffer, iReceived );
- if ( iResponseCode != 235 )
- {
- free( pReceiveBuffer );
- return FALSE;
- }
-
- bSuccess = TRUE;
- }
- else
- {
- SetErrorText( "ReceiveData error.", WSAGetLastError() );
- free( pReceiveBuffer );
- return FALSE;
- }
-
- free( szAuthCommand );
- }
- else
- {
- free( pReceiveBuffer );
- return FALSE;
- }
- }
- else
- {
- free( auth_hex );
- free( pReceiveBuffer );
- return FALSE;
- }
- }
- else
- {
- free( pReceiveBuffer );
- return FALSE;
- }
- }
-
- }
- else
- {
- SetErrorText( "ReceiveData error.", WSAGetLastError() );
- free( pReceiveBuffer );
- return FALSE;
- }
-
- free( pReceiveBuffer );
- }
- else
- {
- SetErrorText( "malloc() failed.", GetLastError() );
- }
-
- return bSuccess;
- }
-
- //////////////////////////////////////////////////////////////////////////
- inline BOOL CSMTPClient::SendMessage( LPCSTR szFromAddress, LPCSTR szFromName, LPCSTR szToAddresses, LPCSTR szSubject, LPCSTR szXMailer, LPBYTE pBodyBuffer, DWORD dwBodySize )
- {
- BOOL bSuccess = FALSE;
-
- // Format Header
- if ( !szFromAddress )
- {
- SetErrorText( "SendMessage. Invalid Parameters!" );
- return NULL;
- }
-
- char *szHeaderBuffer = (char*)malloc( 1024 * 16 );
- if ( szHeaderBuffer )
- {
- // get the current date and time
- char szDate[ 500 ];
- char sztTime[ 500 ];
-
- SYSTEMTIME st = { 0 };
- ::GetSystemTime(&st);
-
- ::GetDateFormatA( MAKELCID( MAKELANGID( LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT), 0, &st, "ddd',' dd MMM yyyy", szDate , sizeof( szDate ) );
- ::GetTimeFormatA( MAKELCID( MAKELANGID( LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT), TIME_FORCE24HOURFORMAT, &st, "HH':'mm':'ss", sztTime, sizeof( sztTime ) );
-
- sprintf( szHeaderBuffer, "DATE: %s %s\r\n", szDate, sztTime );
-
- // X-Mailer Field
- if ( szXMailer && strlen( szXMailer ) )
- {
- strcat( szHeaderBuffer, "X-Mailer: " );
- strcat( szHeaderBuffer, szXMailer );
- strcat( szHeaderBuffer, "\r\n" );
- }
-
- // From:
- strcat( szHeaderBuffer, "From: " );
- if ( szFromName )
- {
- strcat( szHeaderBuffer, "\"" );
- strcat( szHeaderBuffer, szFromName );
- strcat( szHeaderBuffer, "\" <" );
- strcat( szHeaderBuffer, szFromAddress );
- strcat( szHeaderBuffer, ">\r\n" );
- }
- else
- {
- strcat( szHeaderBuffer, "<" );
- strcat( szHeaderBuffer, szFromAddress );
- strcat( szHeaderBuffer, ">\r\n" );
- }
-
- // Subject:
- if ( szSubject && strlen( szSubject ) )
- {
- strcat( szHeaderBuffer, "Subject: " );
- strcat( szHeaderBuffer, szSubject );
- strcat( szHeaderBuffer, "\r\n" );
- }
-
- // To Fields
- strcat( szHeaderBuffer, "To: " );
- strcat( szHeaderBuffer, szToAddresses );
- strcat( szHeaderBuffer, "\r\n" );
-
- // MIME
- strcat( szHeaderBuffer, "MIME-Version: 1.0\r\nContent-type: text/plain; charset=US-ASCII\r\n" );
-
- // End Header
- strcat( szHeaderBuffer, "\r\n" );
- }
- else
- {
- SetErrorText( "malloc error.", GetLastError() );
- return FALSE;
- }
-
-
- BYTE szCommandBuffer[ 256 ];
- sprintf( (char*)szCommandBuffer, "MAIL FROM:<%s> SIZE=%u\r\n", (char*)szFromAddress, strlen( szHeaderBuffer ) + dwBodySize + 2 );
- if ( SendData( m_hSocket, (PBYTE)szCommandBuffer, strlen( (const char*)szCommandBuffer ) ) == 0 )
- {
- SetErrorText( "SendData error.", WSAGetLastError() );
- free( szHeaderBuffer );
- return FALSE;
- }
-
- DWORD dwReceiveBufferSize = 1024*16;
- PBYTE pReceiveBuffer = (PBYTE)malloc( dwReceiveBufferSize );
- if ( pReceiveBuffer )
- {
- DWORD iReceived = ReceiveData( m_hSocket, pReceiveBuffer, dwReceiveBufferSize );
- if ( iReceived )
- {
- SetErrorText( pReceiveBuffer );
-
- // Check 250
- int iResponseCode = GetResponseCode( pReceiveBuffer, iReceived );
- if ( iResponseCode != 250 )
- {
- free( szHeaderBuffer );
- free( pReceiveBuffer );
- return FALSE;
- }
- }
- else
- {
- SetErrorText( "ReceiveData error.", WSAGetLastError() );
- free( szHeaderBuffer );
- free( pReceiveBuffer );
- return FALSE;
- }
-
- // Post "RCTP TO:"
- char *szCurrentAddr = (char*)malloc( strlen( szToAddresses ) + 1 );
- if ( !szCurrentAddr )
- {
- SetErrorText( "malloc error.", GetLastError() );
- free( szHeaderBuffer );
- free( pReceiveBuffer );
- return FALSE;
- }
-
- const char* szToOffset = szToAddresses;
- char* szZap = NULL;
-
- BOOL bRCPTAccepted = FALSE;
- do
- {
- strcpy( szCurrentAddr, szToOffset );
- char *szExtractedAdress = szCurrentAddr;
- szZap = strchr( szCurrentAddr, ',' );
-
- if ( szZap )
- {
- *szZap = 0;
- szToOffset = szZap + 1;
- }
-
- char *pSkobka1 = strchr( szCurrentAddr, '<' );
- char *pSkobka2 = strchr( szCurrentAddr, '>' );
-
- if ( pSkobka1 && pSkobka2 && pSkobka2 > pSkobka1 )
- {
- szExtractedAdress = pSkobka1 + 1;
- *pSkobka2 = NULL;
- }
-
- if ( szExtractedAdress && strlen( szExtractedAdress ) > 0 )
- {
- sprintf( (char*)szCommandBuffer, "RCPT TO:<%s>\r\n", (char*)szExtractedAdress );
- if ( SendData( m_hSocket, (PBYTE)szCommandBuffer, strlen( (const char*)szCommandBuffer ) ) == 0 )
- {
- SetErrorText( "SendData error.", WSAGetLastError() );
- free( szCurrentAddr );
- free( pReceiveBuffer );
- free( szHeaderBuffer );
- return FALSE;
- }
-
- iReceived = ReceiveData( m_hSocket, pReceiveBuffer, dwReceiveBufferSize );
- if ( iReceived )
- {
- SetErrorText( pReceiveBuffer );
-
- // Check 250
- int iResponseCode = GetResponseCode( pReceiveBuffer, iReceived );
- if ( iResponseCode == 250 )
- {
- bRCPTAccepted = TRUE;
- }
- }
- else
- {
- SetErrorText( "ReceiveData error.", WSAGetLastError() );
- free( szCurrentAddr );
- free( pReceiveBuffer );
- free( szHeaderBuffer );
- return FALSE;
- }
- }
-
- } while( szZap );
-
- free( szCurrentAddr );
-
- if ( bRCPTAccepted )
- {
- sprintf( (char*)szCommandBuffer, "DATA\r\n" );
- if ( SendData( m_hSocket, (PBYTE)szCommandBuffer, strlen( (const char*)szCommandBuffer ) ) == 0 )
- {
- SetErrorText( "SendData error.", WSAGetLastError() );
- free( pReceiveBuffer );
- free( szHeaderBuffer );
- return FALSE;
- }
-
- iReceived = ReceiveData( m_hSocket, pReceiveBuffer, dwReceiveBufferSize );
- if ( iReceived )
- {
- SetErrorText( pReceiveBuffer );
-
- // Check 354
- int iResponseCode = GetResponseCode( pReceiveBuffer, iReceived );
- if ( iResponseCode != 354 )
- {
- free( pReceiveBuffer );
- free( szHeaderBuffer );
- return FALSE;
- }
- }
- else
- {
- SetErrorText( "ReceiveData error.", WSAGetLastError() );
- free( pReceiveBuffer );
- free( szHeaderBuffer );
- return FALSE;
- }
-
- // Send message data (header + body + .)
- if ( SendData( m_hSocket, (PBYTE)szHeaderBuffer, strlen( (const char*)szHeaderBuffer ) ) == 0 )
- {
- SetErrorText( "SendData error.", WSAGetLastError() );
- free( pReceiveBuffer );
- free( szHeaderBuffer );
- return FALSE;
- }
-
- if ( SendData( m_hSocket, (PBYTE)pBodyBuffer, dwBodySize ) == 0 )
- {
- SetErrorText( "SendData error.", WSAGetLastError() );
- free( pReceiveBuffer );
- free( szHeaderBuffer );
- return FALSE;
- }
-
- if ( SendData( m_hSocket, (PBYTE)"\r\n.\r\n", 5 ) == 0 )
- {
- SetErrorText( "SendData error.", WSAGetLastError() );
- free( pReceiveBuffer );
- free( szHeaderBuffer );
- return FALSE;
- }
-
- iReceived = ReceiveData( m_hSocket, pReceiveBuffer, dwReceiveBufferSize );
- if ( iReceived )
- {
- SetErrorText( pReceiveBuffer );
-
- // Check 250
- int iResponseCode = GetResponseCode( pReceiveBuffer, iReceived );
- if ( iResponseCode == 250 )
- {
- bSuccess = TRUE;
- }
- }
- else
- {
- SetErrorText( "ReceiveData error.", WSAGetLastError() );
- }
- }
-
- free( pReceiveBuffer );
- }
- else
- {
- SetErrorText( "malloc error.", GetLastError() );
- }
-
- if ( szHeaderBuffer )
- free( szHeaderBuffer );
-
- return bSuccess;
- }
-
-
-
- //////////////////////////////////////////////////////////////////////////
- //////////////////////////////////////////////////////////////////////////
- //////////////////////////////////////////////////////////////////////////
- //////////////////////////////////////////////////////////////////////////
-
-
-#ifndef PAGESIZE
-#define PAGESIZE 4096
-#endif
-
-#ifndef ROUNDTOPAGE
-#define ROUNDTOPAGE(a) (((a/4096)+1)*4096)
-#endif
-
- //////////////////////////////////////////////////////////////////////
- // Construction/Destruction
- //////////////////////////////////////////////////////////////////////
-
- inline Base64Coder::Base64Coder()
- : m_pDBuffer(NULL),
- m_pEBuffer(NULL),
- m_nDBufLen(0),
- m_nEBufLen(0)
- {
-
- }
-
- inline Base64Coder::~Base64Coder()
- {
- if(m_pDBuffer != NULL)
- delete [] m_pDBuffer;
-
- if(m_pEBuffer != NULL)
- delete [] m_pEBuffer;
- }
-
- inline LPCSTR Base64Coder::DecodedMessage() const
- {
- return (LPCSTR) m_pDBuffer;
- }
-
- inline LPCSTR Base64Coder::EncodedMessage() const
- {
- return (LPCSTR) m_pEBuffer;
- }
-
- inline void Base64Coder::AllocEncode(DWORD nSize)
- {
- if(m_nEBufLen < nSize)
- {
- if(m_pEBuffer != NULL)
- delete [] m_pEBuffer;
-
- m_nEBufLen = ROUNDTOPAGE(nSize);
- m_pEBuffer = new BYTE[m_nEBufLen];
- }
-
- ::ZeroMemory(m_pEBuffer, m_nEBufLen);
- m_nEDataLen = 0;
- }
-
- inline void Base64Coder::AllocDecode(DWORD nSize)
- {
- if(m_nDBufLen < nSize)
- {
- if(m_pDBuffer != NULL)
- delete [] m_pDBuffer;
-
- m_nDBufLen = ROUNDTOPAGE(nSize);
- m_pDBuffer = new BYTE[m_nDBufLen];
- }
-
- ::ZeroMemory(m_pDBuffer, m_nDBufLen);
- m_nDDataLen = 0;
- }
-
- inline void Base64Coder::SetEncodeBuffer(const PBYTE pBuffer, DWORD nBufLen)
- {
- DWORD i = 0;
-
- AllocEncode(nBufLen);
- while(i < nBufLen)
- {
- if(!_IsBadMimeChar(pBuffer[i]))
- {
- m_pEBuffer[m_nEDataLen] = pBuffer[i];
- m_nEDataLen++;
- }
-
- i++;
- }
- }
-
- inline void Base64Coder::SetDecodeBuffer(const PBYTE pBuffer, DWORD nBufLen)
- {
- AllocDecode(nBufLen);
- ::CopyMemory(m_pDBuffer, pBuffer, nBufLen);
- m_nDDataLen = nBufLen;
- }
-
- inline void Base64Coder::Encode(const PBYTE pBuffer, DWORD nBufLen)
- {
- SetDecodeBuffer(pBuffer, nBufLen);
- AllocEncode(nBufLen * 2);
-
- TempBucket Raw;
- DWORD nIndex = 0;
-
- while((nIndex + 3) <= nBufLen)
- {
- Raw.Clear();
- ::CopyMemory(&Raw, m_pDBuffer + nIndex, 3);
- Raw.nSize = 3;
- _EncodeToBuffer(Raw, m_pEBuffer + m_nEDataLen);
- nIndex += 3;
- m_nEDataLen += 4;
- }
-
- if(nBufLen > nIndex)
- {
- Raw.Clear();
- Raw.nSize = (BYTE) (nBufLen - nIndex);
- ::CopyMemory(&Raw, m_pDBuffer + nIndex, nBufLen - nIndex);
- _EncodeToBuffer(Raw, m_pEBuffer + m_nEDataLen);
- m_nEDataLen += 4;
- }
- }
-
- inline void Base64Coder::Encode(LPCSTR szMessage)
- {
- if(szMessage != NULL)
- Base64Coder::Encode((const PBYTE)szMessage, strlen( (const char*)szMessage));
- }
-
- inline void Base64Coder::Decode(const PBYTE pBuffer, DWORD dwBufLen)
- {
- if(is_init())
- _Init();
-
- SetEncodeBuffer(pBuffer, dwBufLen);
-
- AllocDecode(dwBufLen);
-
- TempBucket Raw;
-
- DWORD nIndex = 0;
-
- while((nIndex + 4) <= m_nEDataLen)
- {
- Raw.Clear();
- Raw.nData[0] = DecodeTable()[m_pEBuffer[nIndex]];
- Raw.nData[1] = DecodeTable()[m_pEBuffer[nIndex + 1]];
- Raw.nData[2] = DecodeTable()[m_pEBuffer[nIndex + 2]];
- Raw.nData[3] = DecodeTable()[m_pEBuffer[nIndex + 3]];
-
- if(Raw.nData[2] == 255)
- Raw.nData[2] = 0;
- if(Raw.nData[3] == 255)
- Raw.nData[3] = 0;
-
- Raw.nSize = 4;
- _DecodeToBuffer(Raw, m_pDBuffer + m_nDDataLen);
- nIndex += 4;
- m_nDDataLen += 3;
- }
-
- // If nIndex < m_nEDataLen, then we got a decode message without padding.
- // We may want to throw some kind of warning here, but we are still required
- // to handle the decoding as if it was properly padded.
- if(nIndex < m_nEDataLen)
- {
- Raw.Clear();
- for(DWORD i = nIndex; i < m_nEDataLen; i++)
- {
- Raw.nData[i - nIndex] = DecodeTable()[m_pEBuffer[i]];
- Raw.nSize++;
- if(Raw.nData[i - nIndex] == 255)
- Raw.nData[i - nIndex] = 0;
- }
-
- _DecodeToBuffer(Raw, m_pDBuffer + m_nDDataLen);
- m_nDDataLen += (m_nEDataLen - nIndex);
- }
- }
-
- inline void Base64Coder::Decode(LPCSTR szMessage)
- {
- if(szMessage != NULL)
- Base64Coder::Decode((const PBYTE)szMessage, strlen((const char*)szMessage));
- }
-
- inline DWORD Base64Coder::_DecodeToBuffer(const TempBucket &Decode, PBYTE pBuffer)
- {
- TempBucket Data;
- DWORD nCount = 0;
-
- _DecodeRaw(Data, Decode);
-
- for(int i = 0; i < 3; i++)
- {
- pBuffer[i] = Data.nData[i];
- if(pBuffer[i] != 255)
- nCount++;
- }
-
- return nCount;
- }
-
-
- inline void Base64Coder::_EncodeToBuffer(const TempBucket &Decode, PBYTE pBuffer)
- {
- TempBucket Data;
-
- _EncodeRaw(Data, Decode);
-
- for(int i = 0; i < 4; i++)
- pBuffer[i] = Base64Digits()[Data.nData[i]];
-
- switch(Decode.nSize)
- {
- case 1:
- pBuffer[2] = '=';
- case 2:
- pBuffer[3] = '=';
- }
- }
-
- inline void Base64Coder::_DecodeRaw(TempBucket &Data, const TempBucket &Decode)
- {
- BYTE nTemp;
-
- Data.nData[0] = Decode.nData[0];
- Data.nData[0] <<= 2;
-
- nTemp = Decode.nData[1];
- nTemp >>= 4;
- nTemp &= 0x03;
- Data.nData[0] |= nTemp;
-
- Data.nData[1] = Decode.nData[1];
- Data.nData[1] <<= 4;
-
- nTemp = Decode.nData[2];
- nTemp >>= 2;
- nTemp &= 0x0F;
- Data.nData[1] |= nTemp;
-
- Data.nData[2] = Decode.nData[2];
- Data.nData[2] <<= 6;
- nTemp = Decode.nData[3];
- nTemp &= 0x3F;
- Data.nData[2] |= nTemp;
- }
-
- inline void Base64Coder::_EncodeRaw(TempBucket &Data, const TempBucket &Decode)
- {
- BYTE nTemp;
-
- Data.nData[0] = Decode.nData[0];
- Data.nData[0] >>= 2;
-
- Data.nData[1] = Decode.nData[0];
- Data.nData[1] <<= 4;
- nTemp = Decode.nData[1];
- nTemp >>= 4;
- Data.nData[1] |= nTemp;
- Data.nData[1] &= 0x3F;
-
- Data.nData[2] = Decode.nData[1];
- Data.nData[2] <<= 2;
-
- nTemp = Decode.nData[2];
- nTemp >>= 6;
-
- Data.nData[2] |= nTemp;
- Data.nData[2] &= 0x3F;
-
- Data.nData[3] = Decode.nData[2];
- Data.nData[3] &= 0x3F;
- }
-
- inline BOOL Base64Coder::_IsBadMimeChar(BYTE nData)
- {
- switch(nData)
- {
- case '\r': case '\n': case '\t': case ' ' :
- case '\b': case '\a': case '\f': case '\v':
- return TRUE;
- default:
- return FALSE;
- }
- }
-
- inline void Base64Coder::_Init()
- { // Initialize Decoding table.
-
- int i;
-
- for(i = 0; i < 256; i++)
- DecodeTable()[i] = -2;
-
- for(i = 0; i < 64; i++)
- {
- DecodeTable()[Base64Digits()[i]] = i;
- DecodeTable()[Base64Digits()[i]|0x80] = i;
- }
-
- DecodeTable()['='] = -1;
- DecodeTable()['='|0x80] = -1;
-
- is_init() = TRUE;
- }
-
-
- }
-}
-}
diff --git a/contrib/epee/include/net/smtp_helper.h b/contrib/epee/include/net/smtp_helper.h
deleted file mode 100644
index 7827315a2..000000000
--- a/contrib/epee/include/net/smtp_helper.h
+++ /dev/null
@@ -1,88 +0,0 @@
-// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * 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.
-// * Neither the name of the Andrey N. Sabelnikov 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 OWNER 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.
-//
-
-
-
-
-#pragma once
-#include "smtp.h"
-
-namespace epee
-{
-namespace net_utils
-{
- namespace smtp
- {
-
- inline bool send_mail(const std::string& server, int port, const std::string& login, const std::string& pass, const std::string& from_addres, const std::string& from_name, const std::string& maillist, const std::string& subject, const std::string& mail_body)
- {
- net_utils::smtp::CSMTPClient smtp;
-
- if ( !smtp.ServerConnect( server.c_str(), port ) )
- {
- LOG_PRINT("Reporting: Failed to connect to server " << server <<":"<< port, LOG_LEVEL_0);
- return false;
- }
-
- if(login.size() && pass.size())
- {
- if ( !smtp.ServerLogin( login.c_str(), pass.c_str()) )
- {
- LOG_PRINT("Reporting: Failed to auth on server " << server <<":"<< port, LOG_LEVEL_0);
- return false;
-
- }
- }
-
- if ( !smtp.SendMessage( from_addres.c_str(),
- from_name.c_str(),
- maillist.c_str(),
- subject.c_str(),
- "bicycle-client",
- (LPBYTE)mail_body.data(),
- mail_body.size()))
- {
- char *szErrorText = smtp.GetLastErrorText();
- if ( szErrorText )
- {
- LOG_PRINT("Failed to send message, error text: " << szErrorText, LOG_LEVEL_0);
- }
- else
- {
- LOG_PRINT("Failed to send message, error text: null", LOG_LEVEL_0);
- }
- return false;
- }
-
- smtp.ServerDisconnect();
-
- return true;
-
-
- }
- }
-}
-}
diff --git a/contrib/epee/include/pragma_comp_defs.h b/contrib/epee/include/pragma_comp_defs.h
deleted file mode 100644
index f4ef7057e..000000000
--- a/contrib/epee/include/pragma_comp_defs.h
+++ /dev/null
@@ -1,14 +0,0 @@
-#pragma once
-
-#if defined(__GNUC__)
- #define PRAGMA_WARNING_PUSH _Pragma("GCC diagnostic push")
- #define PRAGMA_WARNING_POP _Pragma("GCC diagnostic pop")
- #define PRAGMA_WARNING_DISABLE_VS(w)
- #define PRAGMA_GCC(w) _Pragma(w)
-#elif defined(_MSC_VER)
- #define PRAGMA_WARNING_PUSH __pragma(warning( push ))
- #define PRAGMA_WARNING_POP __pragma(warning( pop ))
- #define PRAGMA_WARNING_DISABLE_VS(w) __pragma( warning ( disable: w ))
- //#define PRAGMA_WARNING_DISABLE_GCC(w)
- #define PRAGMA_GCC(w)
-#endif
diff --git a/contrib/epee/include/profile_tools.h b/contrib/epee/include/profile_tools.h
index a0b5f77f4..76f794a36 100644
--- a/contrib/epee/include/profile_tools.h
+++ b/contrib/epee/include/profile_tools.h
@@ -28,7 +28,7 @@
#ifndef _PROFILE_TOOLS_H_
#define _PROFILE_TOOLS_H_
-#include "misc_os_dependent.h"
+#include "time_helper.h"
namespace epee
{
diff --git a/contrib/epee/include/reg_utils.h b/contrib/epee/include/reg_utils.h
deleted file mode 100644
index 22227a9b2..000000000
--- a/contrib/epee/include/reg_utils.h
+++ /dev/null
@@ -1,249 +0,0 @@
-// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * 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.
-// * Neither the name of the Andrey N. Sabelnikov 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 OWNER 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.
-//
-
-
-#ifndef _MUSC_UTILS_EX_H_
-#define _MUSC_UTILS_EX_H_
-
-namespace epee
-{
-namespace reg_utils
-{
- //-----------------------------------------------------------------------------------------------------------------------------------
- template<class T>
- bool RegSetPODValue(HKEY hParentKey, const char* pSubKey, const char* pValName, const T& valToSave, bool force_create = true)
- {
- HKEY hRegKey = 0;
- DWORD dw = 0;
-
- if( ::RegOpenKeyExA(hParentKey, pSubKey, 0, KEY_WRITE, &hRegKey) != ERROR_SUCCESS )
- if(force_create && (::RegCreateKeyExA(hParentKey, pSubKey, 0, "", REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hRegKey, &dw) != ERROR_SUCCESS) )
- return false;
-
-
- DWORD val_type = (sizeof(valToSave) == sizeof(DWORD)) ? REG_DWORD:REG_BINARY;
-
- BOOL res = ::RegSetValueExA( hRegKey, pValName, 0, val_type, (LPBYTE)&valToSave, sizeof(valToSave)) == ERROR_SUCCESS;
-
- ::RegCloseKey(hRegKey);
- return ERROR_SUCCESS==res ? true:false;
- }
- //-----------------------------------------------------------------------------------------------------------------------------------
- template<class T>
- bool RegGetPODValue(HKEY hParentKey, const char* pSubKey, const char* pValName, T& valToSave)
- {
- HKEY hRegKey = 0;
- LONG res = 0;
-
-
- if(::RegOpenKeyExA(hParentKey, pSubKey, 0, KEY_READ, &hRegKey) == ERROR_SUCCESS )
- {
- DWORD dwType, lSize = 0;
- res = ::RegQueryValueExA(hRegKey, pValName, 0, &dwType, NULL, &lSize);
- if(ERROR_SUCCESS!=res || (sizeof(valToSave) < lSize) )
- {
- ::RegCloseKey(hRegKey);
- return false;
- }
- res = ::RegQueryValueExA(hRegKey, pValName, 0, &dwType, (LPBYTE)&valToSave, &lSize);
- }
- return ERROR_SUCCESS==res ? true:false;
- }
- //-----------------------------------------------------------------------------------------------------------------------------------
- inline
- bool RegSetANSIString(HKEY hParentKey, const char* pSubKey, const char* pValName, const std::string& strToSave)
- {
- HKEY hRegKey = 0;
- DWORD dw = 0;
- DWORD res_ = 0;
- if( (res_ = ::RegCreateKeyExA(hParentKey, pSubKey, 0, "", REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hRegKey, &dw)) != ERROR_SUCCESS )
- if( (res_= ::RegOpenKeyExA(hParentKey, pSubKey, 0, KEY_WRITE, &hRegKey)) != ERROR_SUCCESS )
- return false;
-
- DWORD valType = REG_SZ;
- const char* pStr = strToSave.c_str();
- DWORD sizeOfStr = (DWORD)strToSave.size()+1;
- LSTATUS res = ::RegSetValueExA(hRegKey, pValName, 0, valType, (LPBYTE)pStr, sizeOfStr);
-
- ::RegCloseKey(hRegKey);
- return ERROR_SUCCESS==res ? true:false;
- }
- //-----------------------------------------------------------------------------------------------------------------------------------
- inline
- bool RegGetANSIString(HKEY hParentKey, const char* pSubKey, const char* pValName, std::string& strToSave)
- {
- HKEY hRegKey = 0;
- LONG res = 0;
-
-
- if((res = ::RegOpenKeyExA(hParentKey, pSubKey, 0, KEY_READ, &hRegKey)) == ERROR_SUCCESS )
- {
- DWORD dwType, lSize = 0;
- res = ::RegQueryValueExA(hRegKey, pValName, 0, &dwType, NULL, &lSize);
- if(ERROR_SUCCESS!=res)
- {
-
- ::RegCloseKey(hRegKey);
- return false;
- }
- char* pTmpStr = new char[lSize+2];
- memset(pTmpStr, 0, lSize+2);
- res = ::RegQueryValueExA(hRegKey, pValName, 0, &dwType, (LPBYTE)pTmpStr, &lSize);
- pTmpStr[lSize+1] = 0; //be happy ;)
- strToSave = pTmpStr;
- delete [] pTmpStr;
- ::RegCloseKey(hRegKey);
- }
- return ERROR_SUCCESS==res ? true:false;
- }
- //-----------------------------------------------------------------------------------------------------------------------------------
- template<class TMemoryObject>
- bool RegSetRAWValue(HKEY hKey, const char* pValName, const TMemoryObject& valToSave, DWORD valType = REG_BINARY)
- {
- LONG res = ::RegSetValueExA( hKey, pValName, 0, valType, (CONST BYTE*)valToSave.get(0), (DWORD)valToSave.get_size());
-
- return ERROR_SUCCESS==res ? true:false;
- }
- //----------------------------------------------------------------------------------------------------------------------------------
- bool RegSetRAWValue(HKEY hKey, const char* pValName, const std::string & valToSave, DWORD valType = REG_BINARY)
- {
- LONG res = ::RegSetValueExA( hKey, pValName, 0, valType, (CONST BYTE*)valToSave.data(), (DWORD)valToSave.size());
-
- return ERROR_SUCCESS==res ? true:false;
- }
- //-----------------------------------------------------------------------------------------------------------------------------------
- template<class TMemoryObject>
- bool RegGetRAWValue(HKEY hKey, const char* pValName, TMemoryObject& valToSave, DWORD* pRegType)
- {
- DWORD dwType, lSize = 0;
- LONG res = ::RegQueryValueExA(hKey, pValName, 0, &dwType, NULL, &lSize);
- if(ERROR_SUCCESS!=res || 0 >= lSize)
- {
- valToSave.release();
- return false;
- }
- if(valToSave.get_size() < lSize)
- valToSave.alloc_buff(lSize);
- res = ::RegQueryValueExA(hKey, pValName, 0, &dwType, (LPBYTE)valToSave.get(0), &lSize);
- if(pRegType) *pRegType = dwType;
-
- return ERROR_SUCCESS==res ? true:false;
- }
- //-----------------------------------------------------------------------------------------------------------------------------------
- bool RegGetRAWValue(HKEY hKey, const char* pValName, std::string& valToSave, DWORD* pRegType)
- {
- DWORD dwType, lSize = 0;
- LONG res = ::RegQueryValueExA(hKey, pValName, 0, &dwType, NULL, &lSize);
- if(ERROR_SUCCESS!=res || 0 >= lSize)
- {
- return false;
- }
-
- valToSave.resize(lSize);
- res = ::RegQueryValueExA(hKey, pValName, 0, &dwType, (LPBYTE)valToSave.data(), &lSize);
- if(pRegType) *pRegType = dwType;
-
- return ERROR_SUCCESS==res ? true:false;
- }
- //-----------------------------------------------------------------------------------------------------------------------------------
- template<class TMemoryObject>
- bool RegSetRAWValue(HKEY hParentKey, const char* pSubKey, const char* pValName, const TMemoryObject& valToSave, DWORD valType = REG_BINARY)
- {
- HKEY hRegKey = 0;
- DWORD dw = 0;
- bool res = false;
-
- if( ::RegCreateKeyExA(hParentKey, pSubKey, 0, "", REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hRegKey, &dw) != ERROR_SUCCESS )
- if( ::RegOpenKeyExA(hParentKey, pSubKey, 0, KEY_WRITE, &hRegKey) != ERROR_SUCCESS )
- return false;
-
- res = RegSetRAWValue(hRegKey, pValName, valToSave, valType);
-
- ::RegCloseKey(hRegKey);
- return res;
- }
- //-----------------------------------------------------------------------------------------------------------------------------------
- bool RegSetRAWValue(HKEY hParentKey, const char* pSubKey, const char* pValName, const std::string& valToSave, DWORD valType = REG_BINARY)
- {
- HKEY hRegKey = 0;
- DWORD dw = 0;
- bool res = false;
-
- if( ::RegCreateKeyExA(hParentKey, pSubKey, 0, "", REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hRegKey, &dw) != ERROR_SUCCESS )
- if( ::RegOpenKeyExA(hParentKey, pSubKey, 0, KEY_WRITE, &hRegKey) != ERROR_SUCCESS )
- return false;
-
- res = RegSetRAWValue(hRegKey, pValName, valToSave, valType);
-
- ::RegCloseKey(hRegKey);
- return res;
- }
- //-----------------------------------------------------------------------------------------------------------------------------------
- template<class TMemoryObject>
- bool RegGetRAWValue(HKEY hParentKey, const char* pSubKey, const char* pValName, TMemoryObject& valToSave, DWORD* pRegType)
- {
- HKEY hRegKey = 0;
- bool res = false;
-
- if(::RegOpenKeyExA(hParentKey, pSubKey, 0, KEY_READ, &hRegKey) == ERROR_SUCCESS )
- {
- res = RegGetRAWValue(hRegKey, pValName, valToSave, pRegType);
- ::RegCloseKey(hRegKey);
- }
- return res;
- }
- //-----------------------------------------------------------------------------------------------------------------------------------
- inline
- bool RegGetRAWValue(HKEY hParentKey, const char* pSubKey, const char* pValName, std::string& valToSave, DWORD* pRegType)
- {
- HKEY hRegKey = 0;
- bool res = false;
-
- if(::RegOpenKeyExA(hParentKey, pSubKey, 0, KEY_READ, &hRegKey) == ERROR_SUCCESS )
- {
- res = RegGetRAWValue(hRegKey, pValName, valToSave, pRegType);
- ::RegCloseKey(hRegKey);
- }
- return res;
- }
- //-----------------------------------------------------------------------------------------------------------------------------------
- inline
- bool RegRemoveValue(HKEY hParentKey, const char* pValName)
- {
- //CHECK_AND_ASSERT(hParentKey&&pValName, false);
- return ::RegDeleteValueA(hParentKey, pValName)==ERROR_SUCCESS ? true:false;
- }
- //-----------------------------------------------------------------------------------------------------------------------------------
- inline
- bool RegRemoveKey(HKEY hParentKey, const char* pKeyName)
- {
- //CHECK_AND_ASSERT(hParentKey&&pKeyName, false);
- return ::RegDeleteKeyA(hParentKey, pKeyName)==ERROR_SUCCESS ? true:false;
- }
-
-}
-}
-#endif //_MUSC_UTILS_EX_H_
diff --git a/contrib/epee/include/rolling_median.h b/contrib/epee/include/rolling_median.h
index 8965a8268..e230fd974 100644
--- a/contrib/epee/include/rolling_median.h
+++ b/contrib/epee/include/rolling_median.h
@@ -126,7 +126,6 @@ private:
protected:
rolling_median_t &operator=(const rolling_median_t&) = delete;
- rolling_median_t(const rolling_median_t&) = delete;
public:
//creates new rolling_median_t: to calculate `nItems` running median.
@@ -139,6 +138,20 @@ public:
clear();
}
+ rolling_median_t(const rolling_median_t &other)
+ {
+ N = other.N;
+ int size = N * (sizeof(Item) + sizeof(int) * 2);
+ data = (Item*)malloc(size);
+ memcpy(data, other.data, size);
+ pos = (int*) (data + N);
+ heap = pos + N + (N / 2); //points to middle of storage.
+ idx = other.idx;
+ minCt = other.minCt;
+ maxCt = other.maxCt;
+ sz = other.sz;
+ }
+
rolling_median_t(rolling_median_t &&m)
{
memcpy(this, &m, sizeof(rolling_median_t));
diff --git a/contrib/epee/include/serialization/serialize_base.h b/contrib/epee/include/serialization/serialize_base.h
deleted file mode 100644
index 84a1624cb..000000000
--- a/contrib/epee/include/serialization/serialize_base.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#pragma once
-
diff --git a/contrib/epee/include/service_impl_base.h b/contrib/epee/include/service_impl_base.h
deleted file mode 100644
index 6e9aefc46..000000000
--- a/contrib/epee/include/service_impl_base.h
+++ /dev/null
@@ -1,323 +0,0 @@
-// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * 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.
-// * Neither the name of the Andrey N. Sabelnikov 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 OWNER 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.
-//
-
-
-#ifndef _SERVICE_IMPL_BASE_H_
-#define _SERVICE_IMPL_BASE_H_
-
-#pragma comment(lib, "advapi32.lib")
-
-
-namespace epee
-{
-class service_impl_base {
- public:
- service_impl_base();
- virtual ~service_impl_base();
-
- virtual const char *get_name() = 0;
- virtual const char *get_caption() = 0;
- virtual const char *get_description() = 0;
-
- bool run_service();
- virtual bool install();
- virtual bool remove();
- virtual bool init();
- void set_control_accepted(unsigned controls);
- void set_status(unsigned state, unsigned pending = 0);
- unsigned get_control_accepted();
-
- private:
- virtual void service_main() = 0;
- virtual unsigned service_handler(unsigned control, unsigned event_code,
- void *pdata) = 0;
- //-------------------------------------------------------------------------
- static service_impl_base*& instance();
- //-------------------------------------------------------------------------
- static DWORD __stdcall _service_handler(DWORD control, DWORD event,
- void *pdata, void *pcontext);
- static void __stdcall service_entry(DWORD argc, char **pargs);
- virtual SERVICE_FAILURE_ACTIONSA* get_failure_actions();
-
- private:
- SC_HANDLE m_manager;
- SC_HANDLE m_service;
- SERVICE_STATUS_HANDLE m_status_handle;
- DWORD m_accepted_control;
-};
-
-inline service_impl_base::service_impl_base() {
- m_manager = 0;
- m_service = 0;
- m_status_handle = 0;
- m_accepted_control = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN
- | SERVICE_ACCEPT_PAUSE_CONTINUE;
-
- instance() = this;
-}
-//-----------------------------------------------------------------------------
-inline service_impl_base::~service_impl_base() {
- if (m_service) {
- ::CloseServiceHandle(m_service);
- }
- m_service = 0;
- if (m_manager) {
- ::CloseServiceHandle(m_manager);
- }
- m_manager = 0;
- instance() = 0;
-}
-//-----------------------------------------------------------------------------
-inline service_impl_base*& service_impl_base::instance() {
- static service_impl_base *pservice = NULL;
- return pservice;
-}
-//-----------------------------------------------------------------------------
-inline
-bool service_impl_base::install() {
- CHECK_AND_ASSERT(!m_service, false);
- const char *psz_descr = get_description();
- SERVICE_FAILURE_ACTIONSA* fail_acts = get_failure_actions();
-
- char sz_path[MAX_PATH];
- ::GetModuleFileNameA(0, sz_path, sizeof(sz_path));
- ::GetShortPathNameA(sz_path, sz_path, sizeof(sz_path));
-
- while (TRUE) {
- if (!m_manager) {
- m_manager = ::OpenSCManager(NULL, NULL, GENERIC_ALL);
- if (!m_manager) {
- int err = GetLastError();
- LOG_ERROR(
- "Failed to OpenSCManager(), last err="
- << log_space::get_win32_err_descr(err));
- break;
- }
- }
- m_service = ::CreateServiceA(m_manager, get_name(), get_caption(),
- SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS, SERVICE_DEMAND_START,
- SERVICE_ERROR_IGNORE, sz_path, 0, 0, 0, 0, 0);
- if (!m_service) {
- int err = GetLastError();
- LOG_ERROR(
- "Failed to CreateService(), last err="
- << log_space::get_win32_err_descr(err));
- break;
- }
-
- if (psz_descr) {
- SERVICE_DESCRIPTIONA sd = { (char*) psz_descr };
- if (!::ChangeServiceConfig2A(m_service, SERVICE_CONFIG_DESCRIPTION,
- &sd)) {
- int err = GetLastError();
- LOG_ERROR(
- "Failed to ChangeServiceConfig2(SERVICE_CONFIG_DESCRIPTION), last err="
- << log_space::get_win32_err_descr(err));
- break;
- }
- }
-
- if (fail_acts) {
- if (!::ChangeServiceConfig2A(m_service, SERVICE_CONFIG_FAILURE_ACTIONS,
- fail_acts)) {
- int err = GetLastError();
- LOG_ERROR(
- "Failed to ChangeServiceConfig2(SERVICE_CONFIG_FAILURE_ACTIONS), last err="
- << log_space::get_win32_err_descr(err));
- break;
- }
- }
- LOG_PRINT("Installed succesfully.", LOG_LEVEL_0);
- return true;
- }
- LOG_PRINT("Failed to install.", LOG_LEVEL_0);
- return false;
-}
-//-----------------------------------------------------------------------------
-inline
-bool service_impl_base::remove() {
- CHECK_AND_ASSERT(!m_service, false);
-
- while (TRUE) {
- if (!m_manager) {
- m_manager = ::OpenSCManager(0, 0, GENERIC_ALL);
- if (!m_manager) {
- int err = GetLastError();
- LOG_ERROR(
- "Failed to OpenSCManager(), last err="
- << log_space::get_win32_err_descr(err));
- break;
- }
- }
-
- if (!m_service) {
- m_service = ::OpenServiceA(m_manager, get_name(), SERVICE_STOP | DELETE);
- if (!m_service) {
- int err = GetLastError();
- LOG_ERROR(
- "Failed to OpenService(), last err="
- << log_space::get_win32_err_descr(err));
- break;
- }
- }
-
- SERVICE_STATUS status = { };
- if (!::ControlService(m_service, SERVICE_CONTROL_STOP, &status)) {
- int err = ::GetLastError();
- if (err == ERROR_SHUTDOWN_IN_PROGRESS)
- continue;
- else if (err != ERROR_SERVICE_NOT_ACTIVE) {
- LOG_ERROR(
- "Failed to ControlService(SERVICE_CONTROL_STOP), last err="
- << log_space::get_win32_err_descr(err));
- break;
- }
- }
-
- if (!::DeleteService(m_service)) {
- int err = ::GetLastError();
- LOG_ERROR(
- "Failed to ControlService(SERVICE_CONTROL_STOP), last err="
- << log_space::get_win32_err_descr(err));
- break;
- }
-
- LOG_PRINT("Removed successfully.", LOG_LEVEL_0);
- break;
- }
-
- return true;
-}
-//-----------------------------------------------------------------------------
-inline
-bool service_impl_base::init() {
- return true;
-}
-//-----------------------------------------------------------------------------
-inline
-bool service_impl_base::run_service() {
- CHECK_AND_ASSERT(!m_service, false);
-
- long error_code = 0;
-
- SERVICE_TABLE_ENTRYA service_table[2];
- ZeroMemory(&service_table, sizeof(service_table));
-
- service_table->lpServiceName = (char*) get_name();
- service_table->lpServiceProc = service_entry;
-
- LOG_PRINT("[+] Start service control dispatcher for \"" << get_name() << "\"",
- LOG_LEVEL_1);
-
- error_code = 1;
- BOOL res = ::StartServiceCtrlDispatcherA(service_table);
- if (!res) {
- int err = GetLastError();
- LOG_PRINT(
- "[+] Error starting service control dispatcher, err="
- << log_space::get_win32_err_descr(err), LOG_LEVEL_1);
- return false;
- } else {
- LOG_PRINT("[+] End service control dispatcher for \"" << get_name() << "\"",
- LOG_LEVEL_1);
- }
- return true;
-}
-//-----------------------------------------------------------------------------
-inline DWORD __stdcall service_impl_base::_service_handler(DWORD control,
- DWORD event, void *pdata, void *pcontext) {
- CHECK_AND_ASSERT(pcontext, ERROR_CALL_NOT_IMPLEMENTED);
-
- service_impl_base *pservice = (service_impl_base*) pcontext;
- return pservice->service_handler(control, event, pdata);
-}
-//-----------------------------------------------------------------------------
-inline
-void __stdcall service_impl_base::service_entry(DWORD argc, char **pargs) {
- service_impl_base *pme = instance();
- LOG_PRINT("instance: " << pme, LOG_LEVEL_4);
- if (!pme) {
- LOG_ERROR("Error: at service_entry() pme = NULL");
- return;
- }
- pme->m_status_handle = ::RegisterServiceCtrlHandlerExA(pme->get_name(),
- _service_handler, pme);
-
- pme->set_status(SERVICE_RUNNING);
- pme->service_main();
- pme->set_status(SERVICE_STOPPED);
-}
-//-----------------------------------------------------------------------------
-inline
-void service_impl_base::set_status(unsigned state, unsigned pending) {
- if (!m_status_handle)
- return;
-
- SERVICE_STATUS status = { 0 };
- status.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
- status.dwCurrentState = state;
- status.dwControlsAccepted = m_accepted_control;
- /*status.dwWin32ExitCode = NO_ERROR;
- status.dwServiceSpecificExitCode = ERROR_SERVICE_SPECIFIC_ERROR;
- status.dwCheckPoint = 0;
- status.dwWaitHint = 0;
-
- status.dwCurrentState = state;*/
-
- if (state == SERVICE_START_PENDING || state == SERVICE_STOP_PENDING
- || state == SERVICE_CONTINUE_PENDING || state == SERVICE_PAUSE_PENDING) {
- status.dwWaitHint = 2000;
- status.dwCheckPoint = pending;
- }
- ::SetServiceStatus(m_status_handle, &status);
-}
-//-----------------------------------------------------------------------------------------
-inline
-void service_impl_base::set_control_accepted(unsigned controls) {
- m_accepted_control = controls;
-}
-//-----------------------------------------------------------------------------------------
-inline
-unsigned service_impl_base::get_control_accepted() {
- return m_accepted_control;
-}
-//-----------------------------------------------------------------------------------------
-inline SERVICE_FAILURE_ACTIONSA* service_impl_base::get_failure_actions() {
- // first 3 failures in 30 minutes. Service will be restarted.
- // do nothing for next failures
- static SC_ACTION sa[] = { { SC_ACTION_RESTART, 3 * 1000 }, {
- SC_ACTION_RESTART, 3 * 1000 }, { SC_ACTION_RESTART, 3 * 1000 }, {
- SC_ACTION_NONE, 0 } };
-
- static SERVICE_FAILURE_ACTIONSA sfa = { 1800, // interval for failures counter - 30 min
- "", NULL, 4, (SC_ACTION*) &sa };
-
- // TODO: refactor this code, really unsafe!
- return &sfa;
-}
-}
-
-#endif //_SERVICE_IMPL_BASE_H_
diff --git a/contrib/epee/include/sha1.h b/contrib/epee/include/sha1.h
deleted file mode 100644
index ce42082f8..000000000
--- a/contrib/epee/include/sha1.h
+++ /dev/null
@@ -1,51 +0,0 @@
-
-/*
- Copyright (c) 2011, Micael Hildenborg
- All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are met:
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- * 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.
- * Neither the name of Micael Hildenborg 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 Micael Hildenborg ''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 Micael Hildenborg 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.
- */
-
-#ifndef SHA1_DEFINED
-#define SHA1_DEFINED
-
-namespace sha1 {
-
- /**
- @param src points to any kind of data to be hashed.
- @param bytelength the number of bytes to hash from the src pointer.
- @param hash should point to a buffer of at least 20 bytes of size for storing the sha1 result in.
- */
- void calc(const void* src, const int bytelength, unsigned char* hash);
-
- /**
- @param hash is 20 bytes of sha1 hash. This is the same data that is the result from the calc function.
- @param hexstring should point to a buffer of at least 41 bytes of size for storing the hexadecimal representation of the hash. A zero will be written at position 40, so the buffer will be a valid zero ended string.
- */
- void toHexString(const unsigned char* hash, char* hexstring);
-
-} // namespace sha1
-
-#include "sha1.inl"
-
-#endif // SHA1_DEFINED
diff --git a/contrib/epee/include/sha1.inl b/contrib/epee/include/sha1.inl
deleted file mode 100644
index d33202724..000000000
--- a/contrib/epee/include/sha1.inl
+++ /dev/null
@@ -1,179 +0,0 @@
-
-/*
- Copyright (c) 2011, Micael Hildenborg
- All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are met:
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- * 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.
- * Neither the name of Micael Hildenborg 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 Micael Hildenborg ''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 Micael Hildenborg 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.
- */
-
-/*
- Contributors:
- Gustav
- Several members in the gamedev.se forum.
- Gregory Petrosyan
- */
-
-#include "sha1.h"
-
-namespace sha1 {
-namespace {// local
-// Rotate an integer value to left.
-inline const unsigned int rol(const unsigned int value,
- const unsigned int steps) {
- return ((value << steps) | (value >> (32 - steps)));
-}
-
-// Sets the first 16 integers in the buffert to zero.
-// Used for clearing the W buffert.
-inline void clearWBuffert(unsigned int* buffert) {
- for (int pos = 16; --pos >= 0;)
- {
- buffert[pos] = 0;
- }
-}
-
-inline
-void innerHash(unsigned int* result, unsigned int* w) {
- unsigned int a = result[0];
- unsigned int b = result[1];
- unsigned int c = result[2];
- unsigned int d = result[3];
- unsigned int e = result[4];
-
- int round = 0;
-
-#define sha1macro(func,val) \
- { \
- const unsigned int t = rol(a, 5) + (func) + e + val + w[round]; \
- e = d; \
- d = c; \
- c = rol(b, 30); \
- b = a; \
- a = t; \
- }
-
- while (round < 16) {
- sha1macro((b & c) | (~b & d), 0x5a827999)
- ++round;
- }
- while (round < 20) {
- w[round] = rol(
- (w[round - 3] ^ w[round - 8] ^ w[round - 14] ^ w[round - 16]), 1);
- sha1macro((b & c) | (~b & d), 0x5a827999)
- ++round;
- }
- while (round < 40) {
- w[round] = rol(
- (w[round - 3] ^ w[round - 8] ^ w[round - 14] ^ w[round - 16]), 1);
- sha1macro(b ^ c ^ d, 0x6ed9eba1)
- ++round;
- }
- while (round < 60) {
- w[round] = rol(
- (w[round - 3] ^ w[round - 8] ^ w[round - 14] ^ w[round - 16]), 1);
- sha1macro((b & c) | (b & d) | (c & d), 0x8f1bbcdc)
- ++round;
- }
- while (round < 80) {
- w[round] = rol(
- (w[round - 3] ^ w[round - 8] ^ w[round - 14] ^ w[round - 16]), 1);
- sha1macro(b ^ c ^ d, 0xca62c1d6)
- ++round;
- }
-
-#undef sha1macro
-
- result[0] += a;
- result[1] += b;
- result[2] += c;
- result[3] += d;
- result[4] += e;
-}
-} // namespace
-
-inline
-void calc(const void* src, const int bytelength, unsigned char* hash) {
- // Init the result array.
- unsigned int result[5] = { 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476,
- 0xc3d2e1f0 };
-
- // Cast the void src pointer to be the byte array we can work with.
- const unsigned char* sarray = (const unsigned char*) src;
-
- // The reusable round buffer
- unsigned int w[80];
-
- // Loop through all complete 64byte blocks.
- const int endOfFullBlocks = bytelength - 64;
- int endCurrentBlock;
- int currentBlock(0);
-
- while (currentBlock <= endOfFullBlocks) {
- endCurrentBlock = currentBlock + 64;
-
- // Init the round buffer with the 64 byte block data.
- for (int roundPos = 0; currentBlock < endCurrentBlock; currentBlock += 4)
- {
- // This line will swap endian on big endian and keep endian on little endian.
- w[roundPos++] = (unsigned int) sarray[currentBlock + 3]
- | (((unsigned int) sarray[currentBlock + 2]) << 8)
- | (((unsigned int) sarray[currentBlock + 1]) << 16)
- | (((unsigned int) sarray[currentBlock]) << 24);
- }
- innerHash(result, w);
- }
-
- // Handle the last and not full 64 byte block if existing.
- endCurrentBlock = bytelength - currentBlock;
- clearWBuffert(w);
- int lastBlockBytes = 0;
- for (; lastBlockBytes < endCurrentBlock; ++lastBlockBytes) {
- w[lastBlockBytes >> 2] |= (unsigned int) sarray[lastBlockBytes
- + currentBlock] << ((3 - (lastBlockBytes & 3)) << 3);
- }
- w[lastBlockBytes >> 2] |= 0x80 << ((3 - (lastBlockBytes & 3)) << 3);
- if (endCurrentBlock >= 56) {
- innerHash(result, w);
- clearWBuffert(w);
- }
- w[15] = bytelength << 3;
- innerHash(result, w);
-
- // Store hash in result pointer, and make sure we get in in the correct order on both endian models.
- for (int hashByte = 20; --hashByte >= 0;) {
- hash[hashByte] = (result[hashByte >> 2] >> (((3 - hashByte) & 0x3) << 3))
- & 0xff;
- }
-}
-inline
-void toHexString(const unsigned char* hash, char* hexstring) {
- const char hexDigits[] = { "0123456789abcdef" };
-
- for (int hashByte = 20; --hashByte >= 0;)
- {
- hexstring[hashByte << 1] = hexDigits[(hash[hashByte] >> 4) & 0xf];
- hexstring[(hashByte << 1) + 1] = hexDigits[hash[hashByte] & 0xf];
- }
- hexstring[40] = 0;
-}
-} // namespace sha1
diff --git a/contrib/epee/include/soci_helper.h b/contrib/epee/include/soci_helper.h
deleted file mode 100644
index 1da5aa7e2..000000000
--- a/contrib/epee/include/soci_helper.h
+++ /dev/null
@@ -1,142 +0,0 @@
-// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * 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.
-// * Neither the name of the Andrey N. Sabelnikov 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 OWNER 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.
-//
-
-
-#pragma once
-#include "soci.h"
-#include "soci-postgresql.h"
-
-using namespace epee;
-namespace soci
-{
-
- template <>
- struct type_conversion<uint64_t>
- {
- typedef long long base_type;
-
- static void from_base(base_type a_, indicator ind, uint64_t & mi)
- {
- if (ind == i_null)
- {
- mi = 0;
- //throw soci_error("Null value not allowed for this type");
- }
- mi = (uint64_t)a_;
- //mi.set(i);
- }
-
- static void to_base(const uint64_t & mi, base_type & i, indicator & ind)
- {
- i = (base_type)mi;
- ind = i_ok;
- }
- };
-
-
-
- template <>
- struct type_conversion<bool>
- {
- typedef int base_type;
-
- static void from_base(base_type a_, indicator ind, bool& mi)
- {
- if (ind == i_null)
- {
- mi = false;
- //throw soci_error("Null value not allowed for this type");
- }
- mi = a_? true:false;
- //mi.set(i);
- }
-
- static void to_base(const bool & mi, base_type & i, indicator & ind)
- {
- i = mi? 1:0;
- ind = i_ok;
- }
- };
-
-
-
- class per_thread_session
- {
- public:
- bool init(const std::string& connection_string)
- {
- m_connection_string = connection_string;
-
- return true;
- }
-
- soci::session& get()
- {
-
- //soci::session
-
- m_db_connections_lock.lock();
- boost::shared_ptr<soci::session>& conn_ptr = m_db_connections[epee::misc_utils::get_thread_string_id()];
- m_db_connections_lock.unlock();
- if(!conn_ptr.get())
- {
- conn_ptr.reset(new soci::session(soci::postgresql, m_connection_string));
- }
- //init new connection
- return *conn_ptr.get();
- }
-
- bool reopen()
- {
- //soci::session
-
- m_db_connections_lock.lock();
- boost::shared_ptr<soci::session>& conn_ptr = m_db_connections[misc_utils::get_thread_string_id()];
- m_db_connections_lock.unlock();
- if(conn_ptr.get())
- {
- conn_ptr->close();
- conn_ptr.reset(new soci::session(soci::postgresql, m_connection_string));
- }
-
- //init new connection
- return true;
- }
-
- //----------------------------------------------------------------------------------------------
- bool check_status()
- {
- return true;
- }
-
- protected:
- private:
- std::map<std::string, boost::shared_ptr<soci::session> > m_db_connections;
- epee::critical_section m_db_connections_lock;
- std::string m_connection_string;
- };
-}
-/*}*/
diff --git a/contrib/epee/include/static_initializer.h b/contrib/epee/include/static_initializer.h
deleted file mode 100644
index 3463a5607..000000000
--- a/contrib/epee/include/static_initializer.h
+++ /dev/null
@@ -1,82 +0,0 @@
-// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * 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.
-// * Neither the name of the Andrey N. Sabelnikov 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 OWNER 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.
-//
-
-
-
-#ifndef _STATIC_INITIALIZER_H_
-#define _STATIC_INITIALIZER_H_
-
-
-namespace epee
-{
-/***********************************************************************
-class initializer - useful to initialize some static classes
- which have init() and un_init() static members
-************************************************************************/
-
-template<class to_initialize>
-class initializer
-{
-public:
- initializer()
- {
- to_initialize::init();
- //get_set_is_initialized(true, true);
- }
- ~initializer()
- {
- to_initialize::un_init();
- //get_set_is_uninitialized(true, true);
- }
-
- /*static inline bool is_initialized()
- {
- return get_set_is_initialized();
- }
- static inline bool is_uninitialized()
- {
- return get_set_is_uninitialized();
- }
-
-private:
- static inline bool get_set_is_initialized(bool need_to_set = false, bool val_to_set= false)
- {
- static bool val_is_initialized = false;
- if(need_to_set)
- val_is_initialized = val_to_set;
- return val_is_initialized;
- }
- static inline bool get_set_is_uninitialized(bool need_to_set = false, bool val_to_set = false)
- {
- static bool val_is_uninitialized = false;
- if(need_to_set)
- val_is_uninitialized = val_to_set;
- return val_is_uninitialized;
- }*/
-};
-
-}
-#endif //_STATIC_INITIALIZER_H_
diff --git a/contrib/epee/include/storages/crypted_storage.h b/contrib/epee/include/storages/crypted_storage.h
deleted file mode 100644
index 163728cfc..000000000
--- a/contrib/epee/include/storages/crypted_storage.h
+++ /dev/null
@@ -1,62 +0,0 @@
-// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * 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.
-// * Neither the name of the Andrey N. Sabelnikov 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 OWNER 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.
-//
-
-
-#ifndef _CRYPTED_STORAGE_H_
-#define _CRYPTED_STORAGE_H_
-
-#include "cryptopp_helper.h"
-
-namespace epee
-{
-template<class t_base_storage, class crypt_provider, class t_key_provider>
-class crypted_storage: public t_base_storage
-{
-public:
- size_t PackToSolidBuffer(std::string& targetObj)
- {
- size_t res = t_base_storage::PackToSolidBuffer(targetObj);
- if(res <= 0)
- return res;
-
- if(!crypt_provider::encrypt(targetObj, t_key_provider::get_storage_default_key()))
- return 0;
-
- return targetObj.size();
- }
-
- size_t LoadFromSolidBuffer(const std::string& pTargetObj)
- {
- std::string buff_to_decrypt = pTargetObj;
- if(crypt_provider::decrypt(buff_to_decrypt, t_key_provider::get_storage_default_key()))
- return t_base_storage::LoadFromSolidBuffer(buff_to_decrypt);
-
- return 0;
- }
-};
-}
-
-#endif //_CRYPTED_STORAGE_H_
diff --git a/contrib/epee/include/storages/gzipped_inmemstorage.h b/contrib/epee/include/storages/gzipped_inmemstorage.h
deleted file mode 100644
index 229a56da6..000000000
--- a/contrib/epee/include/storages/gzipped_inmemstorage.h
+++ /dev/null
@@ -1,68 +0,0 @@
-// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * 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.
-// * Neither the name of the Andrey N. Sabelnikov 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 OWNER 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.
-//
-
-
-#ifndef _GZIPPED_INMEMSTORAGE_H_
-#define _GZIPPED_INMEMSTORAGE_H_
-
-#include "zlib_helper.h"
-namespace epee
-{
-namespace StorageNamed
-{
-
- template<class t_base_storage>
- class gziped_storage: public t_base_storage
- {
- public:
- size_t PackToSolidBuffer(std::string& targetObj)
- {
- size_t res = t_base_storage::PackToSolidBuffer(targetObj);
- if(res <= 0)
- return res;
-
- if(!zlib_helper::pack(targetObj))
- return 0;
-
- return targetObj.size();
- }
-
- size_t LoadFromSolidBuffer(const std::string& pTargetObj)
- {
- std::string buff_to_ungzip = pTargetObj;
- if(zlib_helper::unpack(buff_to_ungzip))
- return t_base_storage::LoadFromSolidBuffer(buff_to_ungzip);
-
- return 0;
- }
-
- private:
- };
-
-}
-}
-
-#endif
diff --git a/contrib/epee/include/storages/levin_abstract_invoke2.h b/contrib/epee/include/storages/levin_abstract_invoke2.h
index 383d67cc2..7fd786a53 100644
--- a/contrib/epee/include/storages/levin_abstract_invoke2.h
+++ b/contrib/epee/include/storages/levin_abstract_invoke2.h
@@ -56,54 +56,6 @@ namespace epee
{
namespace net_utils
{
-#if 0
- template<class t_arg, class t_result, class t_transport>
- bool invoke_remote_command2(int command, const t_arg& out_struct, t_result& result_struct, t_transport& transport)
- {
- if(!transport.is_connected())
- return false;
-
- serialization::portable_storage stg;
- out_struct.store(stg);
- std::string buff_to_send, buff_to_recv;
- stg.store_to_binary(buff_to_send);
-
- int res = transport.invoke(command, buff_to_send, buff_to_recv);
- if( res <=0 )
- {
- MERROR("Failed to invoke command " << command << " return code " << res);
- return false;
- }
- serialization::portable_storage stg_ret;
- if(!stg_ret.load_from_binary(buff_to_recv, &default_levin_limits))
- {
- LOG_ERROR("Failed to load_from_binary on command " << command);
- return false;
- }
- return result_struct.load(stg_ret);
- }
-
- template<class t_arg, class t_transport>
- bool notify_remote_command2(int command, const t_arg& out_struct, t_transport& transport)
- {
- if(!transport.is_connected())
- return false;
-
- serialization::portable_storage stg;
- out_struct.store(&stg);
- std::string buff_to_send;
- stg.store_to_binary(buff_to_send);
-
- int res = transport.notify(command, buff_to_send);
- if(res <=0 )
- {
- LOG_ERROR("Failed to notify command " << command << " return code " << res);
- return false;
- }
- return true;
- }
-#endif
-
template<class t_arg, class t_result, class t_transport>
bool invoke_remote_command2(const epee::net_utils::connection_context_base context, int command, const t_arg& out_struct, t_result& result_struct, t_transport& transport)
{
diff --git a/contrib/epee/include/storages/portable_storage_to_bin.h b/contrib/epee/include/storages/portable_storage_to_bin.h
index b82cf532b..be4033dd8 100644
--- a/contrib/epee/include/storages/portable_storage_to_bin.h
+++ b/contrib/epee/include/storages/portable_storage_to_bin.h
@@ -28,7 +28,6 @@
#pragma once
-#include "pragma_comp_defs.h"
#include "misc_language.h"
#include "portable_storage_base.h"
#include "portable_storage_bin_utils.h"
@@ -49,12 +48,7 @@ namespace epee
return sizeof(pack_value);
}
- PRAGMA_WARNING_PUSH
- PRAGMA_GCC("GCC diagnostic ignored \"-Wstrict-aliasing\"")
-#ifdef __clang__
- PRAGMA_GCC("GCC diagnostic ignored \"-Wtautological-constant-out-of-range-compare\"")
-#endif
- template<class t_stream>
+ template<class t_stream>
size_t pack_varint(t_stream& strm, size_t val)
{ //the first two bits always reserved for size information
@@ -70,13 +64,13 @@ namespace epee
return pack_varint_t<uint32_t>(strm, PORTABLE_RAW_SIZE_MARK_DWORD, val);
}else
{
- CHECK_AND_ASSERT_THROW_MES(val <= 4611686018427387903, "failed to pack varint - too big amount = " << val);
+ // Same as checking val <= 4611686018427387903 except that it's portable for 32-bit size_t
+ CHECK_AND_ASSERT_THROW_MES(!(val >> 31 >> 31), "failed to pack varint - too big amount = " << val);
return pack_varint_t<uint64_t>(strm, PORTABLE_RAW_SIZE_MARK_INT64, val);
}
}
- PRAGMA_WARNING_POP
- template<class t_stream>
+ template<class t_stream>
bool put_string(t_stream& strm, const std::string& v)
{
pack_varint(strm, v.size());
diff --git a/contrib/epee/include/time_helper.h b/contrib/epee/include/time_helper.h
index 244b35800..b306880d9 100644
--- a/contrib/epee/include/time_helper.h
+++ b/contrib/epee/include/time_helper.h
@@ -28,132 +28,60 @@
#pragma once
-//#include <atltime.h>
-//#include <sqlext.h>
-#include <boost/date_time/posix_time/posix_time.hpp>
-#include <boost/date_time/local_time/local_time.hpp>
-#include "pragma_comp_defs.h"
+#include <chrono>
+#include <cstdio>
+#include <ctime>
+#include <string>
namespace epee
{
namespace misc_utils
{
-
-#ifdef __ATLTIME_H__
-
- inline
- bool get_time_t_from_ole_date(DATE src, time_t& res)
+ inline bool get_gmt_time(time_t t, struct tm &tm)
{
- SYSTEMTIME st = {0};
- if(TRUE != ::VariantTimeToSystemTime(src, &st))
- return false;
- ATL::CTime ss(st);
- res = ss.GetTime();
- return true;
- }
+#ifdef _WIN32
+ return gmtime_s(&tm, &t);
+#else
+ return gmtime_r(&t, &tm);
#endif
- inline
- std::string get_time_str(const time_t& time_)
- {
-
-
- char tmpbuf[200] = {0};
- tm* pt = NULL;
-PRAGMA_WARNING_PUSH
-PRAGMA_WARNING_DISABLE_VS(4996)
- pt = localtime(&time_);
-PRAGMA_WARNING_POP
-
- if(pt)
- strftime( tmpbuf, 199, "%d.%m.%Y %H:%M:%S", pt );
- else
- {
- std::stringstream strs;
- strs << "[wrong_time: " << std::hex << time_ << "]";
- return strs.str();
- }
- return tmpbuf;
}
- inline
- std::string get_time_str_v2(const time_t& time_)
- {
-
- char tmpbuf[200] = {0};
- tm* pt = NULL;
-PRAGMA_WARNING_PUSH
-PRAGMA_WARNING_DISABLE_VS(4996)
- pt = localtime(&time_);
-PRAGMA_WARNING_POP
-
- if(pt)
- strftime( tmpbuf, 199, "%Y_%m_%d %H_%M_%S", pt );
- else
- {
- std::stringstream strs;
- strs << "[wrong_time: " << std::hex << time_ << "]";
- return strs.str();
- }
- return tmpbuf;
- }
-
- inline
- std::string get_time_str_v3(const boost::posix_time::ptime& time_)
- {
- return boost::posix_time::to_simple_string(time_);
- }
-
-
-
inline std::string get_internet_time_str(const time_t& time_)
{
char tmpbuf[200] = {0};
- tm* pt = NULL;
-PRAGMA_WARNING_PUSH
-PRAGMA_WARNING_DISABLE_VS(4996)
- pt = gmtime(&time_);
-PRAGMA_WARNING_POP
- strftime( tmpbuf, 199, "%a, %d %b %Y %H:%M:%S GMT", pt );
+ struct tm pt;
+ get_gmt_time(time_, pt);
+ strftime(tmpbuf, 199, "%a, %d %b %Y %H:%M:%S GMT", &pt);
return tmpbuf;
}
inline std::string get_time_interval_string(const time_t& time_)
{
- std::string res;
time_t tail = time_;
-PRAGMA_WARNING_PUSH
-PRAGMA_WARNING_DISABLE_VS(4244)
- int days = tail/(60*60*24);
+ const int days = static_cast<int>(tail/(60*60*24));
tail = tail%(60*60*24);
- int hours = tail/(60*60);
+ const int hours = static_cast<int>(tail/(60*60));
tail = tail%(60*60);
- int minutes = tail/(60);
+ const int minutes = static_cast<int>(tail/60);
tail = tail%(60);
- int seconds = tail;
-PRAGMA_WARNING_POP
- res = std::string() + "d" + boost::lexical_cast<std::string>(days) + ".h" + boost::lexical_cast<std::string>(hours) + ".m" + boost::lexical_cast<std::string>(minutes) + ".s" + boost::lexical_cast<std::string>(seconds);
- return res;
+ const int seconds = static_cast<int>(tail);
+
+ char tmpbuf[64] = {0};
+ snprintf(tmpbuf, sizeof(tmpbuf) - 1, "d%d.h%d.m%d.s%d", days, hours, minutes, seconds);
+
+ return tmpbuf;
}
-#ifdef __SQLEXT
- inline
- bool odbc_time_to_oledb_taime(const SQL_TIMESTAMP_STRUCT& odbc_timestamp, DATE& oledb_date)
+ inline uint64_t get_ns_count()
{
-
- SYSTEMTIME st = {0};
- st.wYear = odbc_timestamp.year;
- st.wDay = odbc_timestamp.day;
- st.wHour = odbc_timestamp.hour ;
- st.wMilliseconds = (WORD)odbc_timestamp.fraction ;
- st.wMinute = odbc_timestamp.minute ;
- st.wMonth = odbc_timestamp.month ;
- st.wSecond = odbc_timestamp.second ;
-
- if(TRUE != ::SystemTimeToVariantTime(&st, &oledb_date))
- return false;
- return true;
+ typedef std::chrono::duration<uint64_t, std::nano> ns_duration;
+ const ns_duration ns_since_epoch = std::chrono::steady_clock::now().time_since_epoch();
+ return ns_since_epoch.count();
}
-#endif
+ inline uint64_t get_tick_count()
+ {
+ return get_ns_count() / 1000000;
+ }
}
}
diff --git a/contrib/epee/include/tiny_ini.h b/contrib/epee/include/tiny_ini.h
deleted file mode 100644
index 6ced548eb..000000000
--- a/contrib/epee/include/tiny_ini.h
+++ /dev/null
@@ -1,61 +0,0 @@
-// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * 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.
-// * Neither the name of the Andrey N. Sabelnikov 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 OWNER 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.
-//
-
-
-#ifndef _TINY_INI_H_
-#define _TINY_INI_H_
-
-#include "string_tools.h"
-
-namespace epee
-{
-namespace tiny_ini
-{
-
- bool get_param_value(const std::string& param_name, const std::string& ini_entry, std::string& res);
- inline std::string get_param_value(const std::string& param_name, const std::string& ini_entry)
- {
- std::string buff;
- get_param_value(param_name, ini_entry, buff);
- return buff;
- }
-
- template<class T>
- bool get_param_value_as_t(const std::string& param_name, const std::string& ini_entry, T& res)
- {
- std::string str_res = get_param_value(param_name, ini_entry);
-
- string_tools::trim(str_res);
- if(!str_res.size())
- return false;
-
- return string_tools::get_xtype_from_string(res, str_res);
- }
-
-}
-}
-
-#endif //_TINY_INI_H_
diff --git a/contrib/epee/include/to_nonconst_iterator.h b/contrib/epee/include/to_nonconst_iterator.h
deleted file mode 100644
index 729b0e8b2..000000000
--- a/contrib/epee/include/to_nonconst_iterator.h
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * 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.
-// * Neither the name of the Andrey N. Sabelnikov 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 OWNER 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.
-//
-
-
-
-#ifndef _TO_NONCONST_ITERATOR_H_
-#define _TO_NONCONST_ITERATOR_H_
-
-namespace epee
-{
-
-template<class Type>
-typename Type::iterator to_nonsonst_iterator(Type& obj, typename Type::const_iterator it)
-{
- typename Type::difference_type dist = std::distance(static_cast<typename Type::const_iterator>(obj.begin()), it);
- typename Type::iterator res_it = obj.begin()+dist;
- return res_it;
-}
-
-
-template<class Type>
-typename Type::iterator to_nonsonst_iterator(typename Type::iterator base_it, typename Type::const_iterator it)
-{
- typename Type::difference_type dist = std::distance(static_cast<typename Type::const_iterator>(base_it), it);
- typename Type::iterator res_it = base_it+dist;
- return res_it;
-}
-}//namespace epee
-#endif //_TO_NONCONST_ITERATOR_H_
diff --git a/contrib/epee/include/winobj.h b/contrib/epee/include/winobj.h
deleted file mode 100644
index 3279cdac6..000000000
--- a/contrib/epee/include/winobj.h
+++ /dev/null
@@ -1,227 +0,0 @@
-// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * 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.
-// * Neither the name of the Andrey N. Sabelnikov 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 OWNER 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.
-//
-
-
-#ifndef __WINH_OBJ_H__
-#define __WINH_OBJ_H__
-
-#include <boost/thread/locks.hpp>
-
-namespace epee
-{
-class critical_region;
-
-class critical_section {
-
- boost::mutex m_section;
-
-public:
-
- critical_section( const critical_section& section ) {
- InitializeCriticalSection( &m_section );
- }
-
- critical_section() {
- InitializeCriticalSection( &m_section );
- }
-
- ~critical_section() {
- DeleteCriticalSection( &m_section );
- }
-
- void lock() {
- EnterCriticalSection( &m_section );
- }
-
- void unlock() {
- LeaveCriticalSection( &m_section );
- }
-
- bool tryLock() {
- return TryEnterCriticalSection( &m_section )? true:false;
- }
-
- critical_section& operator=( const critical_section& section )
- {
- return *this;
- }
-
-
-};
-
-class critical_region {
-
- ::critical_section *m_locker;
-
- critical_region( const critical_region& ){}
-
-public:
-
- critical_region(critical_section &cs ) {
- m_locker = &cs;
- cs.lock();
- }
-
- ~critical_region()
- {
- m_locker->unlock();
- }
-};
-
-
-class shared_critical_section
-{
-public:
- shared_critical_section()
- {
- ::InitializeSRWLock(&m_srw_lock);
- }
- ~shared_critical_section()
- {}
-
- bool lock_shared()
- {
- AcquireSRWLockShared(&m_srw_lock);
- return true;
- }
- bool unlock_shared()
- {
- ReleaseSRWLockShared(&m_srw_lock);
- return true;
- }
- bool lock_exclusive()
- {
- ::AcquireSRWLockExclusive(&m_srw_lock);
- return true;
- }
- bool unlock_exclusive()
- {
- ::ReleaseSRWLockExclusive(&m_srw_lock);
- return true;
- }
-private:
- SRWLOCK m_srw_lock;
-
-};
-
-
-class shared_guard
-{
-public:
- shared_guard(shared_critical_section& ref_sec):m_ref_sec(ref_sec)
- {
- m_ref_sec.lock_shared();
- }
-
- ~shared_guard()
- {
- m_ref_sec.unlock_shared();
- }
-
-private:
- shared_critical_section& m_ref_sec;
-};
-
-
-class exclusive_guard
-{
-public:
- exclusive_guard(shared_critical_section& ref_sec):m_ref_sec(ref_sec)
- {
- m_ref_sec.lock_exclusive();
- }
-
- ~exclusive_guard()
- {
- m_ref_sec.unlock_exclusive();
- }
-
-private:
- shared_critical_section& m_ref_sec;
-};
-
-
-class event
-{
-public:
- event()
- {
- m_hevent = ::CreateEvent(NULL, FALSE, FALSE, NULL);
- }
- ~event()
- {
- ::CloseHandle(m_hevent);
-
- }
-
- bool set()
- {
- return ::SetEvent(m_hevent) ? true:false;
- }
-
- bool reset()
- {
- return ::ResetEvent(m_hevent) ? true:false;
- }
-
- HANDLE get_handle()
- {
- return m_hevent;
- }
-private:
- HANDLE m_hevent;
-
-};
-
-
-#define SHARED_CRITICAL_REGION_BEGIN(x) { shared_guard critical_region_var(x)
-#define EXCLUSIVE_CRITICAL_REGION_BEGIN(x) { exclusive_guard critical_region_var(x)
-
-
-
-#define CRITICAL_REGION_LOCAL(x) critical_region critical_region_var(x)
-#define CRITICAL_REGION_BEGIN(x) { critical_region critical_region_var(x)
-#define CRITICAL_REGION_END() }
-
-
- inline const char* get_wait_for_result_as_text(DWORD res)
- {
- switch(res)
- {
- case WAIT_ABANDONED: return "WAIT_ABANDONED";
- case WAIT_TIMEOUT: return "WAIT_TIMEOUT";
- case WAIT_OBJECT_0: return "WAIT_OBJECT_0";
- case WAIT_OBJECT_0+1: return "WAIT_OBJECT_1";
- case WAIT_OBJECT_0+2: return "WAIT_OBJECT_2";
- default:
- return "UNKNOWN CODE";
- }
-
- }
-
-}// namespace epee
-
-#endif
diff --git a/contrib/epee/include/zlib_helper.h b/contrib/epee/include/zlib_helper.h
deleted file mode 100644
index 46c7f48e6..000000000
--- a/contrib/epee/include/zlib_helper.h
+++ /dev/null
@@ -1,139 +0,0 @@
-// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * 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.
-// * Neither the name of the Andrey N. Sabelnikov 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 OWNER 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.
-//
-
-
-#pragma once
-extern "C" {
-#include "zlib/zlib.h"
-}
-#pragma comment(lib, "zlibstat.lib")
-
-namespace epee
-{
-namespace zlib_helper
-{
- inline
- bool pack(std::string& target){
- std::string result_packed_buff;
-
- z_stream zstream = {0};
- int ret = deflateInit(&zstream, Z_DEFAULT_COMPRESSION);
- if(target.size())
- {
-
-
- result_packed_buff.resize(target.size()*2, 'X');
-
- zstream.next_in = (Bytef*)target.data();
- zstream.avail_in = (uInt)target.size();
- zstream.next_out = (Bytef*)result_packed_buff.data();
- zstream.avail_out = (uInt)result_packed_buff.size();
-
- ret = deflate(&zstream, Z_FINISH);
- CHECK_AND_ASSERT_MES(ret>=0, false, "Failed to deflate. err = " << ret);
-
- if(result_packed_buff.size() != zstream.avail_out)
- result_packed_buff.resize(result_packed_buff.size()-zstream.avail_out);
-
-
- result_packed_buff.erase(0, 2);
- target.swap(result_packed_buff);
- }
-
- deflateEnd(& zstream );
- return true;
- }
-
- inline bool unpack(std::string& target)
- {
- z_stream zstream = {0};
- int ret = inflateInit(&zstream);//
-
- std::string decode_summary_buff;
- size_t ungzip_buff_size = target.size() * 0x30;
- std::string current_decode_buff(ungzip_buff_size, 'X');
-
- while(target.size())
- {
-
-
- zstream.next_out = (Bytef*)current_decode_buff.data();
- zstream.avail_out = (uInt)ungzip_buff_size;
-
- int flag = Z_SYNC_FLUSH;
-
- static char dummy_head[2] =
- {
- 0x8 + 0x7 * 0x10,
- (((0x8 + 0x7 * 0x10) * 0x100 + 30) / 31 * 31) & 0xFF,
- };
- zstream.next_in = (Bytef*) dummy_head;
- zstream.avail_in = sizeof(dummy_head);
- ret = inflate(&zstream, Z_NO_FLUSH);
- if (ret != Z_OK)
- {
- LOCAL_ASSERT(0);
- return false;
- }
-
- zstream.next_in = (Bytef*)target.data();
- zstream.avail_in = (uInt)target.size();
-
- ret = inflate(&zstream, Z_SYNC_FLUSH);
- if (ret != Z_OK && ret != Z_STREAM_END)
- {
- LOCAL_ASSERT(0);
- return false;
- }
-
-
- target.erase(0, target.size()-zstream.avail_in);
-
-
- if(ungzip_buff_size == zstream.avail_out)
- {
- LOG_ERROR("Can't unpack buffer");
- return false;
- }
-
-
- current_decode_buff.resize(ungzip_buff_size - zstream.avail_out);
- if(decode_summary_buff.size())
- decode_summary_buff += current_decode_buff;
- else
- current_decode_buff.swap(decode_summary_buff);
-
- current_decode_buff.resize(ungzip_buff_size);
- }
-
- inflateEnd(&zstream );
-
- decode_summary_buff.swap(target);
- return 1;
- }
-
-};
-}//namespace epee
diff --git a/contrib/epee/src/CMakeLists.txt b/contrib/epee/src/CMakeLists.txt
index e11df96d0..808b9f09e 100644
--- a/contrib/epee/src/CMakeLists.txt
+++ b/contrib/epee/src/CMakeLists.txt
@@ -35,11 +35,9 @@ monero_add_library(epee byte_slice.cpp byte_stream.cpp hex.cpp abstract_http_cli
wipeable_string.cpp levin_base.cpp memwipe.c connection_basic.cpp network_throttle.cpp network_throttle-detail.cpp mlocker.cpp buffer.cpp net_ssl.cpp
int-util.cpp portable_storage.cpp
misc_language.cpp
- misc_os_dependent.cpp
file_io_utils.cpp
net_parse_helpers.cpp
http_base.cpp
- tiny_ini.cpp
${EPEE_HEADERS_PUBLIC}
)
diff --git a/contrib/epee/src/connection_basic.cpp b/contrib/epee/src/connection_basic.cpp
index 85ff55587..b0a30f47f 100644
--- a/contrib/epee/src/connection_basic.cpp
+++ b/contrib/epee/src/connection_basic.cpp
@@ -39,7 +39,6 @@
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/thread/thread.hpp>
#include "misc_language.h"
-#include "pragma_comp_defs.h"
#include <iomanip>
#include <boost/asio/basic_socket.hpp>
diff --git a/contrib/epee/src/file_io_utils.cpp b/contrib/epee/src/file_io_utils.cpp
index 5072adcbc..a8348431c 100644
--- a/contrib/epee/src/file_io_utils.cpp
+++ b/contrib/epee/src/file_io_utils.cpp
@@ -102,29 +102,6 @@ namespace file_io_utils
}
- bool get_file_time(const std::string& path_to_file, time_t& ft)
- {
- boost::system::error_code ec;
- ft = boost::filesystem::last_write_time(boost::filesystem::path(path_to_file), ec);
- if(!ec)
- return true;
- else
- return false;
- }
-
-
- bool set_file_time(const std::string& path_to_file, const time_t& ft)
- {
- boost::system::error_code ec;
- boost::filesystem::last_write_time(boost::filesystem::path(path_to_file), ft, ec);
- if(!ec)
- return true;
- else
- return false;
- }
-
-
-
bool load_file_to_string(const std::string& path_to_file, std::string& target_str, size_t max_size)
{
#ifdef WIN32
@@ -174,26 +151,6 @@ namespace file_io_utils
}
- bool append_string_to_file(const std::string& path_to_file, const std::string& str)
- {
- // No special Windows implementation because so far not used in Monero code
- try
- {
- std::ofstream fstream;
- fstream.exceptions(std::ifstream::failbit | std::ifstream::badbit);
- fstream.open(path_to_file.c_str(), std::ios_base::binary | std::ios_base::out | std::ios_base::app);
- fstream << str;
- fstream.close();
- return true;
- }
-
- catch(...)
- {
- return false;
- }
- }
-
-
bool get_file_size(const std::string& path_to_file, uint64_t &size)
{
#ifdef WIN32
diff --git a/contrib/epee/src/misc_os_dependent.cpp b/contrib/epee/src/misc_os_dependent.cpp
deleted file mode 100644
index cd4967131..000000000
--- a/contrib/epee/src/misc_os_dependent.cpp
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * 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.
-// * Neither the name of the Andrey N. Sabelnikov 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 OWNER 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 "misc_os_dependent.h"
-#include <boost/lexical_cast.hpp>
-
-namespace epee
-{
-namespace misc_utils
-{
- // TODO: (vtnerd) This function is weird since boost::this_thread::get_id() exists but returns a different value.
- std::string get_thread_string_id()
- {
-#if defined(_WIN32)
- return boost::lexical_cast<std::string>(GetCurrentThreadId());
-#elif defined(__GNUC__)
- return boost::lexical_cast<std::string>(pthread_self());
-#endif
- }
-}
-}
diff --git a/contrib/epee/src/mlog.cpp b/contrib/epee/src/mlog.cpp
index bcde215be..092d41777 100644
--- a/contrib/epee/src/mlog.cpp
+++ b/contrib/epee/src/mlog.cpp
@@ -40,7 +40,7 @@
#include <boost/filesystem.hpp>
#include <boost/algorithm/string.hpp>
#include "string_tools.h"
-#include "misc_os_dependent.h"
+#include "time_helper.h"
#include "misc_log_ex.h"
#undef MONERO_DEFAULT_LOG_CATEGORY
diff --git a/contrib/epee/src/network_throttle-detail.cpp b/contrib/epee/src/network_throttle-detail.cpp
index 0374a449c..978572120 100644
--- a/contrib/epee/src/network_throttle-detail.cpp
+++ b/contrib/epee/src/network_throttle-detail.cpp
@@ -46,7 +46,6 @@
#include "misc_log_ex.h"
#include <boost/chrono.hpp>
#include "misc_language.h"
-#include "pragma_comp_defs.h"
#include <sstream>
#include <iomanip>
#include <algorithm>
diff --git a/contrib/epee/src/tiny_ini.cpp b/contrib/epee/src/tiny_ini.cpp
deleted file mode 100644
index 577ebf7c6..000000000
--- a/contrib/epee/src/tiny_ini.cpp
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * 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.
-// * Neither the name of the Andrey N. Sabelnikov 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 OWNER 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 "string_tools.h"
-#include <boost/regex.hpp>
-
-namespace epee
-{
-namespace tiny_ini
-{
- bool get_param_value(const std::string& param_name, const std::string& ini_entry, std::string& res)
- {
- std::string expr_str = std::string() + "^("+ param_name +") *=(.*?)$";
- const boost::regex match_ini_entry( expr_str, boost::regex::icase | boost::regex::normal);
- boost::smatch result;
- if(!boost::regex_search(ini_entry, result, match_ini_entry, boost::match_default))
- return false;
- res = result[2];
- string_tools::trim(res);
- return true;
- }
-}
-}
diff --git a/contrib/epee/tests/.gitignore b/contrib/epee/tests/.gitignore
deleted file mode 100644
index d9b4f015d..000000000
--- a/contrib/epee/tests/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-/build/*
diff --git a/contrib/epee/tests/data/storages/invalid_storage_1.bin b/contrib/epee/tests/data/storages/invalid_storage_1.bin
deleted file mode 100644
index f64bef38e..000000000
--- a/contrib/epee/tests/data/storages/invalid_storage_1.bin
+++ /dev/null
Binary files differ
diff --git a/contrib/epee/tests/data/storages/invalid_storage_2.bin b/contrib/epee/tests/data/storages/invalid_storage_2.bin
deleted file mode 100644
index a8c29f155..000000000
--- a/contrib/epee/tests/data/storages/invalid_storage_2.bin
+++ /dev/null
Binary files differ
diff --git a/contrib/epee/tests/data/storages/invalid_storage_3.bin b/contrib/epee/tests/data/storages/invalid_storage_3.bin
deleted file mode 100644
index 4233bf25c..000000000
--- a/contrib/epee/tests/data/storages/invalid_storage_3.bin
+++ /dev/null
@@ -1 +0,0 @@
-¢IMóÙŸˆm_bo
diff --git a/contrib/epee/tests/data/storages/invalid_storage_4.bin b/contrib/epee/tests/data/storages/invalid_storage_4.bin
deleted file mode 100644
index 69017244a..000000000
--- a/contrib/epee/tests/data/storages/invalid_storage_4.bin
+++ /dev/null
Binary files differ
diff --git a/contrib/epee/tests/data/storages/valid_storage.bin b/contrib/epee/tests/data/storages/valid_storage.bin
deleted file mode 100644
index 2af0abf50..000000000
--- a/contrib/epee/tests/data/storages/valid_storage.bin
+++ /dev/null
Binary files differ
diff --git a/contrib/epee/tests/generate_vc_proj.bat b/contrib/epee/tests/generate_vc_proj.bat
deleted file mode 100644
index 2b3fee953..000000000
--- a/contrib/epee/tests/generate_vc_proj.bat
+++ /dev/null
@@ -1,5 +0,0 @@
-mkdir build
-cd build
-cmake "-DBoost_USE_STATIC_LIBS=TRUE" -G "Visual Studio 11 Win64" ../src
-cd ..
-pause
diff --git a/contrib/epee/tests/src/CMakeLists.txt b/contrib/epee/tests/src/CMakeLists.txt
deleted file mode 100644
index e724b53f4..000000000
--- a/contrib/epee/tests/src/CMakeLists.txt
+++ /dev/null
@@ -1,40 +0,0 @@
-
-cmake_minimum_required(VERSION 3.5)
-
-set(CMAKE_C_STANDARD 11)
-set(CMAKE_C_STANDARD_REQUIRED ON)
-set(CMAKE_C_EXTENSIONS OFF)
-set(CMAKE_CXX_STANDARD 11)
-set(CMAKE_CXX_STANDARD_REQUIRED ON)
-set(CMAKE_CXX_EXTENSIONS OFF)
-
-set(Boost_USE_MULTITHREADED ON)
-
-include_directories(.)
-include_directories(../../include)
-
-find_package(Boost COMPONENTS system filesystem thread date_time chrono regex)
-include_directories( ${Boost_INCLUDE_DIRS} )
-
-IF (MSVC)
- add_definitions( "/W3 /D_CRT_SECURE_NO_WARNINGS /wd4996 /wd4345 /nologo /D_WIN32_WINNT=0x0600 /DWIN32_LEAN_AND_MEAN /bigobj" )
- include_directories(SYSTEM platform/msvc)
-ELSE()
- # set stuff for other systems
- SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall")
- SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wno-reorder")
-ENDIF()
-
-
-# Add folders to filters
-file(GLOB_RECURSE SRC RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
- ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/*.inl
- ${CMAKE_CURRENT_SOURCE_DIR}/*.h)
-
-source_group(general FILES ${SRC})
-
-
-add_executable(tests ${SRC} )
-target_link_libraries( tests ${Boost_LIBRARIES} )
-
diff --git a/contrib/epee/tests/src/misc/test_math.h b/contrib/epee/tests/src/misc/test_math.h
deleted file mode 100644
index 8b3064c2a..000000000
--- a/contrib/epee/tests/src/misc/test_math.h
+++ /dev/null
@@ -1,82 +0,0 @@
-// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * 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.
-// * Neither the name of the Andrey N. Sabelnikov 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 OWNER 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.
-//
-
-
-
-#pragma once
-
-#include "misc_language.h"
-
-namespace epee
-{
- namespace tests
- {
- bool test_median()
- {
- LOG_PRINT_L0("Testing median");
- std::vector<size_t> sz;
- size_t m = misc_utils::median(sz);
- CHECK_AND_ASSERT_MES(m == 0, false, "test failed");
- sz.push_back(1);
- m = misc_utils::median(sz);
- CHECK_AND_ASSERT_MES(m == 1, false, "test failed");
- sz.push_back(10);
- m = misc_utils::median(sz);
- CHECK_AND_ASSERT_MES(m == 5, false, "test failed");
-
- sz.clear();
- sz.resize(3);
- sz[0] = 0;
- sz[1] = 9;
- sz[2] = 3;
- m = misc_utils::median(sz);
- CHECK_AND_ASSERT_MES(m == 3, false, "test failed");
-
- sz.clear();
- sz.resize(4);
- sz[0] = 77;
- sz[1] = 9;
- sz[2] = 22;
- sz[3] = 60;
- m = misc_utils::median(sz);
- CHECK_AND_ASSERT_MES(m == 41, false, "test failed");
-
-
-
- sz.clear();
- sz.resize(5);
- sz[0] = 77;
- sz[1] = 9;
- sz[2] = 22;
- sz[3] = 60;
- sz[4] = 11;
- m = misc_utils::median(sz);
- CHECK_AND_ASSERT_MES(m == 22, false, "test failed");
- return true;
- }
- }
-}
-
diff --git a/contrib/epee/tests/src/net/test_net.h b/contrib/epee/tests/src/net/test_net.h
deleted file mode 100644
index f99639afc..000000000
--- a/contrib/epee/tests/src/net/test_net.h
+++ /dev/null
@@ -1,408 +0,0 @@
-// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * 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.
-// * Neither the name of the Andrey N. Sabelnikov 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 OWNER 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.
-//
-
-#pragma once
-
-#include <boost/thread.hpp>
-#include <boost/bind.hpp>
-
-#include "net/abstract_tcp_server2.h"
-#include "net/levin_protocol_handler.h"
-#include "net/levin_protocol_handler_async.h"
-#include "storages/abstract_invoke.h"
-
-namespace epee
-{
-namespace StorageNamed
-{
- typedef CInMemStorage DefaultStorageType;
-}
-namespace tests
-{
- struct some_subdata
- {
-
- std::string str1;
- std::list<uint64_t> array_of_id;
-
- BEGIN_NAMED_SERIALIZE_MAP()
- SERIALIZE_STL_ANSI_STRING(str1)
- SERIALIZE_STL_CONTAINER_POD(array_of_id)
- END_NAMED_SERIALIZE_MAP()
- };
-
-
- /************************************************************************/
- /* */
- /************************************************************************/
- struct COMMAND_EXAMPLE_1
- {
- const static int ID = 1000;
-
- struct request_t
- {
-
- std::string example_string_data;
- uint64_t example_id_data;
- some_subdata sub;
-
- BEGIN_NAMED_SERIALIZE_MAP()
- SERIALIZE_STL_ANSI_STRING(example_string_data)
- SERIALIZE_POD(example_id_data)
- SERIALIZE_T(sub)
- END_NAMED_SERIALIZE_MAP()
- };
- typedef epee::misc_utils::struct_init<request_t> request;
-
- struct response_t
- {
- bool m_success;
- uint64_t example_id_data;
- std::list<some_subdata> subs;
-
- BEGIN_NAMED_SERIALIZE_MAP()
- SERIALIZE_POD(m_success)
- SERIALIZE_POD(example_id_data)
- SERIALIZE_STL_CONTAINER_T(subs)
- END_NAMED_SERIALIZE_MAP()
- };
- typedef epee::misc_utils::struct_init<response_t> response;
- };
-
- struct COMMAND_EXAMPLE_2
- {
- const static int ID = 1001;
-
- struct request_t
- {
- std::string example_string_data2;
- uint64_t example_id_data;
-
- BEGIN_NAMED_SERIALIZE_MAP()
- SERIALIZE_POD(example_id_data)
- SERIALIZE_STL_ANSI_STRING(example_string_data2)
- END_NAMED_SERIALIZE_MAP()
- };
- typedef epee::misc_utils::struct_init<request_t> request;
-
- struct response_t
- {
- bool m_success;
- uint64_t example_id_data;
-
- BEGIN_NAMED_SERIALIZE_MAP()
- SERIALIZE_POD(example_id_data)
- SERIALIZE_POD(m_success)
- END_NAMED_SERIALIZE_MAP()
- };
- typedef epee::misc_utils::struct_init<response_t> response;
- };
- typedef boost::uuids::uuid uuid;
-
- class test_levin_server: public levin::levin_commands_handler<>
- {
- test_levin_server(const test_levin_server&){}
- public:
- test_levin_server(){}
- void set_thread_prefix(const std::string& pref)
- {
- m_net_server.set_threads_prefix(pref);
- }
- template<class calback_t>
- bool connect_async(const std::string adr, const std::string& port, uint32_t conn_timeot, calback_t cb, const std::string& bind_ip = "0.0.0.0")
- {
- return m_net_server.connect_async(adr, port, conn_timeot, cb, bind_ip);
- }
-
- bool connect(const std::string adr, const std::string& port, uint32_t conn_timeot, net_utils::connection_context_base& cn, const std::string& bind_ip = "0.0.0.0")
- {
- return m_net_server.connect(adr, port, conn_timeot, cn, bind_ip);
- }
- void close(net_utils::connection_context_base& cn)
- {
- m_net_server.get_config_object().close(cn.m_connection_id);
- }
-
- template<class t_request, class t_response>
- bool invoke(uuid con_id, int command, t_request& req, t_response& resp)
- {
- return invoke_remote_command(con_id, command, req, resp, m_net_server.get_config_object());
- }
-
- template< class t_response, class t_request, class callback_t>
- bool invoke_async(uuid con_id, int command, t_request& req, callback_t cb)
- {
- return async_invoke_remote_command<t_response>(con_id, command, req, m_net_server.get_config_object(), cb);
- }
-
- bool init(const std::string& bind_port = "", const std::string& bind_ip = "0.0.0.0")
- {
- m_net_server.get_config_object().set_handler(this);
- m_net_server.get_config_object().m_invoke_timeout = 1000;
- LOG_PRINT_L0("Binding on " << bind_ip << ":" << bind_port);
- return m_net_server.init_server(bind_port, bind_ip);
- }
-
- bool run()
- {
- //here you can set worker threads count
- int thrds_count = 4;
-
- //go to loop
- LOG_PRINT("Run net_service loop( " << thrds_count << " threads)...", LOG_LEVEL_0);
- if(!m_net_server.run_server(thrds_count))
- {
- LOG_ERROR("Failed to run net tcp server!");
- }
-
- LOG_PRINT("net_service loop stopped.", LOG_LEVEL_0);
- return true;
- }
-
- bool deinit()
- {
- return m_net_server.deinit_server();
- }
-
- bool send_stop_signal()
- {
- m_net_server.send_stop_signal();
- return true;
- }
-
- uint32_t get_binded_port()
- {
- return m_net_server.get_binded_port();
- }
- private:
-
-
- CHAIN_LEVIN_INVOKE_TO_MAP(); //move levin_commands_handler interface invoke(...) callbacks into invoke map
- CHAIN_LEVIN_NOTIFY_TO_STUB(); //move levin_commands_handler interface notify(...) callbacks into nothing
-
- BEGIN_INVOKE_MAP(test_levin_server)
- HANDLE_INVOKE_T(COMMAND_EXAMPLE_1, &test_levin_server::handle_1)
- HANDLE_INVOKE_T(COMMAND_EXAMPLE_2, &test_levin_server::handle_2)
- END_INVOKE_MAP()
-
- //----------------- commands handlers ----------------------------------------------
- int handle_1(int command, COMMAND_EXAMPLE_1::request& arg, COMMAND_EXAMPLE_1::response& rsp, const net_utils::connection_context_base& context)
- {
- LOG_PRINT_L0("on_command_1: id " << arg.example_id_data << "---->>");
- COMMAND_EXAMPLE_2::request arg_ = AUTO_VAL_INIT(arg_);
- arg_.example_id_data = arg.example_id_data;
- COMMAND_EXAMPLE_2::response rsp_ = AUTO_VAL_INIT(rsp_);
- invoke_async<COMMAND_EXAMPLE_2::response>(context.m_connection_id, COMMAND_EXAMPLE_2::ID, arg_, [](int code, const COMMAND_EXAMPLE_2::response& rsp, const net_utils::connection_context_base& context)
- {
- if(code < 0)
- {LOG_PRINT_RED_L0("on_command_1: command_2 failed to invoke");}
- else
- {LOG_PRINT_L0("on_command_1: command_2 response " << rsp.example_id_data);}
- });
- rsp.example_id_data = arg.example_id_data;
- LOG_PRINT_L0("on_command_1: id " << arg.example_id_data << "<<----");
- return true;
- }
- int handle_2(int command, COMMAND_EXAMPLE_2::request& arg, COMMAND_EXAMPLE_2::response& rsp, const net_utils::connection_context_base& context)
- {
- LOG_PRINT_L0("on_command_2: id "<< arg.example_id_data);
- rsp.example_id_data = arg.example_id_data;
- //misc_utils::sleep_no_w(6000);
- return true;
- }
- //----------------------------------------------------------------------------------
- net_utils::boosted_levin_async_server m_net_server;
- };
-
-
- inline
- bool do_run_test_server()
- {
-
- test_levin_server srv1, srv2;
-
-
- std::string bind_param = "0.0.0.0";
- std::string port = "";
-
- if(!srv1.init(port, bind_param))
- {
- LOG_ERROR("Failed to initialize srv!");
- return 1;
- }
-
- if(!srv2.init(port, bind_param))
- {
- LOG_ERROR("Failed to initialize srv!");
- return 1;
- }
-
- srv1.set_thread_prefix("SRV_A");
- srv2.set_thread_prefix("SRV_B");
-
- boost::thread th1( boost::bind(&test_levin_server::run, &srv1));
- boost::thread th2( boost::bind(&test_levin_server::run, &srv2));
-
- LOG_PRINT_L0("Initialized servers, waiting for worker threads started...");
- misc_utils::sleep_no_w(1000);
-
-
- LOG_PRINT_L0("Connecting to each other...");
- uint32_t port1 = srv1.get_binded_port();
- uint32_t port2 = srv2.get_binded_port();
-
- COMMAND_EXAMPLE_1::request arg;
- COMMAND_EXAMPLE_1::request resp;
-
- net_utils::connection_context_base cntxt_1;
- bool r = srv1.connect("127.0.0.1", string_tools::num_to_string_fast(port2), 5000, cntxt_1);
- CHECK_AND_ASSERT_MES(r, false, "connect to server failed");
-
- net_utils::connection_context_base cntxt_2;
- r = srv2.connect("127.0.0.1", string_tools::num_to_string_fast(port1), 5000, cntxt_2);
- CHECK_AND_ASSERT_MES(r, false, "connect to server failed");
-
- while(true)
- {
- LOG_PRINT_L0("Invoking from A to B...");
- int r = srv1.invoke(cntxt_1.m_connection_id, COMMAND_EXAMPLE_1::ID, arg, resp);
- if(r<=0)
- {
- LOG_ERROR("Failed tp invoke A to B");
- break;
- }
-
- LOG_PRINT_L0("Invoking from B to A...");
- r = srv2.invoke(cntxt_2.m_connection_id, COMMAND_EXAMPLE_1::ID, arg, resp);
- if(r<=0)
- {
- LOG_ERROR("Failed tp invoke B to A");
- break;
- }
- }
- srv1.send_stop_signal();
- srv2.send_stop_signal();
- th1.join();
- th1.join();
-
- return true;
- }
-
-
-
- inline bool do_test2_work_with_srv(test_levin_server& srv, int port)
- {
- uint64_t i = 0;
- boost::mutex wait_event;
- wait_event.lock();
- while(true)
- {
- net_utils::connection_context_base cntxt_local = AUTO_VAL_INIT(cntxt_local);
- bool r = srv.connect_async("127.0.0.1", string_tools::num_to_string_fast(port), 5000, [&srv, &port, &wait_event, &i, &cntxt_local](const net_utils::connection_context_base& cntxt, const boost::system::error_code& ec)
- {
- CHECK_AND_ASSERT_MES(!ec, void(), "Some problems at connect, message: " << ec.message() );
- cntxt_local = cntxt;
- LOG_PRINT_L0("Invoking command 1 to " << port);
- COMMAND_EXAMPLE_1::request arg = AUTO_VAL_INIT(arg);
- arg.example_id_data = i;
- /*vc2010 workaround*/
- int port_ = port;
- boost::mutex& wait_event_ = wait_event;
- int r = srv.invoke_async<COMMAND_EXAMPLE_1::request>(cntxt.m_connection_id, COMMAND_EXAMPLE_1::ID, arg, [port_, &wait_event_](int code, const COMMAND_EXAMPLE_1::request& rsp, const net_utils::connection_context_base& cntxt)
- {
- CHECK_AND_ASSERT_MES(code > 0, void(), "Failed to invoke");
- LOG_PRINT_L0("command 1 invoke to " << port_ << " OK.");
- wait_event_.unlock();
- });
- });
- wait_event.lock();
- srv.close(cntxt_local);
- ++i;
- }
- return true;
- }
-
- inline
- bool do_run_test_server_async_connect()
- {
- test_levin_server srv1, srv2;
-
-
- std::string bind_param = "0.0.0.0";
- std::string port = "";
-
- if(!srv1.init(port, bind_param))
- {
- LOG_ERROR("Failed to initialize srv!");
- return 1;
- }
-
- if(!srv2.init(port, bind_param))
- {
- LOG_ERROR("Failed to initialize srv!");
- return 1;
- }
-
- srv1.set_thread_prefix("SRV_A");
- srv2.set_thread_prefix("SRV_B");
-
- boost::thread thmain1( boost::bind(&test_levin_server::run, &srv1));
- boost::thread thmain2( boost::bind(&test_levin_server::run, &srv2));
-
- LOG_PRINT_L0("Initalized servers, waiting for worker threads started...");
- misc_utils::sleep_no_w(1000);
-
-
- LOG_PRINT_L0("Connecting to each other...");
- uint32_t port1 = srv1.get_binded_port();
- uint32_t port2 = srv2.get_binded_port();
-
- COMMAND_EXAMPLE_1::request arg;
- COMMAND_EXAMPLE_1::request resp;
-
-
- boost::thread work_1( boost::bind(do_test2_work_with_srv, boost::ref(srv1), port2));
- boost::thread work_2( boost::bind(do_test2_work_with_srv, boost::ref(srv2), port1));
- boost::thread work_3( boost::bind(do_test2_work_with_srv, boost::ref(srv1), port2));
- boost::thread work_4( boost::bind(do_test2_work_with_srv, boost::ref(srv2), port1));
- boost::thread work_5( boost::bind(do_test2_work_with_srv, boost::ref(srv1), port2));
- boost::thread work_6( boost::bind(do_test2_work_with_srv, boost::ref(srv2), port1));
- boost::thread work_7( boost::bind(do_test2_work_with_srv, boost::ref(srv1), port2));
- boost::thread work_8( boost::bind(do_test2_work_with_srv, boost::ref(srv2), port1));
-
-
- work_1.join();
- work_2.join();
- srv1.send_stop_signal();
- srv2.send_stop_signal();
- thmain1.join();
- thmain2.join();
-
- return true;
- }
-
-}
-}
diff --git a/contrib/epee/tests/src/storages/portable_storages_test.h b/contrib/epee/tests/src/storages/portable_storages_test.h
deleted file mode 100644
index 89f217d95..000000000
--- a/contrib/epee/tests/src/storages/portable_storages_test.h
+++ /dev/null
@@ -1,232 +0,0 @@
-// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * 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.
-// * Neither the name of the Andrey N. Sabelnikov 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 OWNER 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.
-//
-
-
-
-#pragma once
-
-#include <list>
-#include <string>
-#include "storages/serializeble_struct_helper.h"
-#include "serialization/keyvalue_serialization.h"
-#include "storages/portable_storage.h"
-#include "storages/portable_storage_template_helper.h"
-
-namespace epee
-{
- namespace tests
- {
-
- struct port_test_struct_sub
- {
- std::string m_str;
-
- BEGIN_KV_SERIALIZE_MAP()
- KV_SERIALIZE_VAL(m_str)
- END_KV_SERIALIZE_MAP()
- };
-
-#pragma pack (push, 1)
- struct some_pod_struct
- {
- uint64_t a;
- int32_t b;
- };
-#pragma pack(pop)
-
- struct port_test_struct
- {
- std::string m_str;
- uint64_t m_uint64;
- uint32_t m_uint32;
- uint16_t m_uint16;
- uint8_t m_uint8;
- int64_t m_int64;
- int32_t m_int32;
- int16_t m_int16;
- int8_t m_int8;
- double m_double;
- bool m_bool;
- some_pod_struct m_pod;
- std::list<std::string> m_list_of_str;
- std::list<uint64_t> m_list_of_uint64_t;
- std::list<uint32_t> m_list_of_uint32_t;
- std::list<uint16_t> m_list_of_uint16_t;
- std::list<uint8_t> m_list_of_uint8_t;
- std::list<int64_t> m_list_of_int64_t;
- std::list<int32_t> m_list_of_int32_t;
- std::list<int16_t> m_list_of_int16_t;
- std::list<int8_t> m_list_of_int8_t;
- std::list<double> m_list_of_double;
- std::list<bool> m_list_of_bool;
- port_test_struct_sub m_subobj;
- std::list<port_test_struct> m_list_of_self;
-
- BEGIN_KV_SERIALIZE_MAP()
- KV_SERIALIZE_VAL(m_str)
- KV_SERIALIZE_VAL(m_uint64)
- KV_SERIALIZE_VAL(m_uint32)
- KV_SERIALIZE_VAL(m_uint16)
- KV_SERIALIZE_VAL(m_uint8)
- KV_SERIALIZE_VAL(m_int64)
- KV_SERIALIZE_VAL(m_int32)
- KV_SERIALIZE_VAL(m_int16)
- KV_SERIALIZE_VAL(m_int8)
- KV_SERIALIZE_VAL(m_double)
- KV_SERIALIZE_VAL(m_bool)
- KV_SERIALIZE_VAL_POD_AS_BLOB(m_pod)
- KV_SERIALIZE_OBJ(m_subobj)
- KV_SERIALIZE_CONTAINER_VAL(m_list_of_str)
- KV_SERIALIZE_CONTAINER_VAL(m_list_of_uint64_t)
- KV_SERIALIZE_CONTAINER_VAL(m_list_of_uint32_t)
- KV_SERIALIZE_CONTAINER_VAL(m_list_of_uint16_t)
- KV_SERIALIZE_CONTAINER_VAL(m_list_of_uint8_t)
- KV_SERIALIZE_CONTAINER_VAL(m_list_of_int64_t)
- KV_SERIALIZE_CONTAINER_VAL(m_list_of_int32_t)
- KV_SERIALIZE_CONTAINER_VAL(m_list_of_int16_t)
- KV_SERIALIZE_CONTAINER_VAL(m_list_of_int8_t)
- KV_SERIALIZE_CONTAINER_VAL(m_list_of_double)
- KV_SERIALIZE_CONTAINER_VAL(m_list_of_bool)
- KV_SERIALIZE_CONTAINER_OBJ(m_list_of_self)
- END_KV_SERIALIZE_MAP()
- };
-
- bool operator != (const port_test_struct_sub& a, const port_test_struct_sub& b)
- {
- return b.m_str != a.m_str;
- }
-
- bool operator == (const port_test_struct& a, const port_test_struct& b)
- {
- if( b.m_str != a.m_str
- || b.m_uint64 != a.m_uint64
- || b.m_uint32 != a.m_uint32
- || b.m_uint16 != a.m_uint16
- || b.m_uint8 != a.m_uint8
- || b.m_int64 != a.m_int64
- || b.m_int32 != a.m_int32
- || b.m_int16 != a.m_int16
- || b.m_int8 != a.m_int8
- || b.m_double != a.m_double
- || b.m_bool != a.m_bool
- || b.m_pod.a != a.m_pod.a
- || b.m_pod.b != a.m_pod.b
- || b.m_list_of_str != a.m_list_of_str
- || b.m_list_of_uint64_t != a.m_list_of_uint64_t
- || b.m_list_of_uint32_t != a.m_list_of_uint32_t
- || b.m_list_of_uint16_t != a.m_list_of_uint16_t
- || b.m_list_of_uint8_t != a.m_list_of_uint8_t
- || b.m_list_of_int64_t != a.m_list_of_int64_t
- || b.m_list_of_int32_t != a.m_list_of_int32_t
- || b.m_list_of_int16_t != a.m_list_of_int16_t
- || b.m_list_of_int8_t != a.m_list_of_int8_t
- || b.m_list_of_double != a.m_list_of_double
- || b.m_list_of_bool != a.m_list_of_bool
- || b.m_subobj != a.m_subobj
- || b.m_list_of_self != a.m_list_of_self
- )
- return false;
- return true;
- }
-
- void fill_struct_with_test_values(port_test_struct& s)
- {
- s.m_str = "zuzuzuzuzuz";
- s.m_uint64 = 111111111111111;
- s.m_uint32 = 2222222;
- s.m_uint16 = 2222;
- s.m_uint8 = 22;
- s.m_int64 = -111111111111111;
- s.m_int32 = -2222222;
- s.m_int16 = -2222;
- s.m_int8 = -24;
- s.m_double = 0.11111;
- s.m_bool = true;
- s.m_pod.a = 32342342342342;
- s.m_pod.b = -342342;
- s.m_list_of_str.push_back("1112121");
- s.m_list_of_uint64_t.push_back(1111111111);
- s.m_list_of_uint64_t.push_back(2222222222);
- s.m_list_of_uint32_t.push_back(1111111);
- s.m_list_of_uint32_t.push_back(2222222);
- s.m_list_of_uint16_t.push_back(1111);
- s.m_list_of_uint16_t.push_back(2222);
- s.m_list_of_uint8_t.push_back(11);
- s.m_list_of_uint8_t.push_back(22);
-
-
- s.m_list_of_int64_t.push_back(-1111111111);
- s.m_list_of_int64_t.push_back(-222222222);
- s.m_list_of_int32_t.push_back(-1111111);
- s.m_list_of_int32_t.push_back(-2222222);
- s.m_list_of_int16_t.push_back(-1111);
- s.m_list_of_int16_t.push_back(-2222);
- s.m_list_of_int8_t.push_back(-11);
- s.m_list_of_int8_t.push_back(-22);
-
- s.m_list_of_double.push_back(0.11111);
- s.m_list_of_double.push_back(0.22222);
- s.m_list_of_bool.push_back(true);
- s.m_list_of_bool.push_back(false);
-
- s.m_subobj.m_str = "subszzzzzzzz";
- s.m_list_of_self.push_back(s);
- }
-
- bool test_portable_storages(const std::string& tests_folder)
- {
- serialization::portable_storage ps, ps2;
- port_test_struct s1, s2;
- fill_struct_with_test_values(s1);
-
- s1.store(ps);
- std::string binbuf;
- bool r = ps.store_to_binary(binbuf);
-
- ps2.load_from_binary(binbuf);
- s2.load(ps2);
- if(!(s1 == s2))
- {
- LOG_ERROR("Portable storage test failed!");
- return false;
- }
-
-
- port_test_struct ss1, ss2;
- fill_struct_with_test_values(ss1);
- std::string json_buff = epee::serialization::store_t_to_json(ss1);
- epee::serialization::load_t_from_json(ss2, json_buff);
- if(!(ss1 == ss2))
- {
- LOG_ERROR("Portable storage test failed!");
- return false;
- }
-
- return true;
- }
-
- }
-}
diff --git a/contrib/epee/tests/src/storages/storage_tests.h b/contrib/epee/tests/src/storages/storage_tests.h
deleted file mode 100644
index 522e589c4..000000000
--- a/contrib/epee/tests/src/storages/storage_tests.h
+++ /dev/null
@@ -1,142 +0,0 @@
-// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * 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.
-// * Neither the name of the Andrey N. Sabelnikov 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 OWNER 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.
-//
-
-
-
-#pragma once
-
-#include "storages/serializeble_struct_helper.h"
-#include "storages/portable_storage.h"
-
-namespace epee
-{
- namespace tests
- {
-
-
- struct test_struct
- {
-
- std::string m_str;
- unsigned int m_uint;
- bool m_bool;
- std::list<std::string> m_list_of_str;
- std::list<int> m_list_of_int;
- std::list<test_struct> m_list_of_self;
-
-
- BEGIN_NAMED_SERIALIZE_MAP()
- SERIALIZE_STL_ANSI_STRING(m_str)
- SERIALIZE_POD(m_uint)
- SERIALIZE_POD(m_bool)
- SERIALIZE_STL_CONTAINER_ANSII_STRING(m_list_of_str)
- SERIALIZE_STL_CONTAINER_POD(m_list_of_int)
- SERIALIZE_STL_CONTAINER_T(m_list_of_self)
- END_NAMED_SERIALIZE_MAP()
-
- };
-
-
- bool operator == (const test_struct& a, const test_struct& b)
- {
- if( b.m_str != a.m_str
- || b.m_uint != a.m_uint
- || b.m_bool != a.m_bool
- || b.m_list_of_str != a.m_list_of_str
- || b.m_list_of_int != a.m_list_of_int
- || b.m_list_of_self != a.m_list_of_self
- )
- return false;
- return true;
- }
-
- inline test_struct get_test_struct()
- {
- test_struct t = boost::value_initialized<test_struct>();
- t.m_bool = true;
- t.m_str = "ackamdc'kmecemcececmacmecmcm[aicm[oeicm[oeicm[qaicm[qoe";
- t.m_uint = 233242;
- for(int i = 0; i!=500; i++)
- t.m_list_of_int.push_back(i);
-
- for(int i = 0; i!=500; i++)
- t.m_list_of_str.push_back("ssccd");
-
- for(int i = 0; i!=5; i++)
- {
- t.m_list_of_self.push_back(t);
- }
- return t;
- }
-
- bool test_storages(const std::string& tests_folder)
- {
-
- epee::serialization::portable_storage ps;
- auto s = ps.open_section("zzz", nullptr);
- uint64_t i = 0;
- ps.get_value("afdsdf", i, s);
-
-
- LOG_PRINT_L0("Generating test struct...");
- boost::filesystem::path storage_folder = tests_folder;
- storage_folder /= "storages";
-
-
- test_struct t = get_test_struct();
-
- LOG_PRINT_L0("Loading test struct from storage...");
- test_struct t2;
- bool res = epee::StorageNamed::load_struct_from_storage_file(t2, (storage_folder /+ "valid_storage.bin").string());
- CHECK_AND_ASSERT_MES(res, false, "Failed to load valid_storage.bin");
-
- LOG_PRINT_L0("Comparing generated and loaded test struct...");
- if(!(t == t2))
- return false;
-
- LOG_PRINT_L0("Loading broken archive 1...");
- test_struct t3;
- res = epee::StorageNamed::load_struct_from_storage_file(t3, (storage_folder /+ "invalid_storage_1.bin").string());
- CHECK_AND_ASSERT_MES(!res, false, "invalid_storage_1.bin loaded, but should not ");
-
-
- LOG_PRINT_L0("Loading broken archive 2...");
- res = epee::StorageNamed::load_struct_from_storage_file(t3, (storage_folder /+ "invalid_storage_2.bin").string());
- CHECK_AND_ASSERT_MES(!res, false, "invalid_storage_2.bin loaded, but should not ");
-
- LOG_PRINT_L0("Loading broken archive 3...");
- res = epee::StorageNamed::load_struct_from_storage_file(t3, (storage_folder /+ "invalid_storage_3.bin").string());
- CHECK_AND_ASSERT_MES(!res, false, "invalid_storage_3.bin loaded, but should not ");
-
- LOG_PRINT_L0("Loading broken archive 4...");
- res = epee::StorageNamed::load_struct_from_storage_file(t3, (storage_folder /+ "invalid_storage_4.bin").string());
- CHECK_AND_ASSERT_MES(!res, false, "invalid_storage_3.bin loaded, but should not ");
-
- return true;
- }
- }
-}
-
diff --git a/contrib/epee/tests/src/tests.cpp b/contrib/epee/tests/src/tests.cpp
deleted file mode 100644
index 8d61334cc..000000000
--- a/contrib/epee/tests/src/tests.cpp
+++ /dev/null
@@ -1,59 +0,0 @@
-
-#include "include_base_utils.h"
-#include "storages/storage_tests.h"
-#include "misc/test_math.h"
-#include "storages/portable_storages_test.h"
-#include "net/test_net.h"
-
-using namespace epee;
-
-int main(int argc, char* argv[])
-{
-
- string_tools::set_module_name_and_folder(argv[0]);
-
- //set up logging options
- log_space::get_set_log_detalisation_level(true, LOG_LEVEL_2);
- log_space::log_singletone::add_logger(LOGGER_CONSOLE, NULL, NULL);
- log_space::log_singletone::add_logger(LOGGER_FILE,
- log_space::log_singletone::get_default_log_file().c_str(),
- log_space::log_singletone::get_default_log_folder().c_str());
-
-
- string_tools::command_line_params_a start_params;
- string_tools::parse_commandline(start_params, argc, argv);
- std::string tests_data_path;
- string_tools::get_xparam_from_command_line(start_params, std::string("/tests_folder"), tests_data_path);
-
- if(string_tools::have_in_command_line(start_params, std::string("/run_net_tests")))
- {
- if(!tests::do_run_test_server())
- {
- LOG_ERROR("net tests failed");
- return 1;
- }
- if(!tests::do_run_test_server_async_connect() )
- {
- LOG_ERROR("net tests failed");
- return 1;
- }
- }else if(string_tools::have_in_command_line(start_params, std::string("/run_unit_tests")))
- {
- if(!tests::test_median())
- {
- LOG_ERROR("median test failed");
- return 1;
- }
-
-
- if(!tests::test_storages(tests_data_path))
- {
- LOG_ERROR("storage test failed");
- return 1;
- }
- }else if(string_tools::have_in_command_line(start_params, std::string("/run_portable_storage_test")))
- {
- tests::test_portable_storages(tests_data_path);
- }
- return 1;
-}
diff --git a/external/randomx b/external/randomx
-Subproject 9efc398c196ef1c50d8e6f5e1f2c5ac02f1f6ce
+Subproject ae8e98b681766f31d49ac562dd6974906156e07
diff --git a/src/blockchain_db/CMakeLists.txt b/src/blockchain_db/CMakeLists.txt
index 6a1a143c1..14ed76295 100644
--- a/src/blockchain_db/CMakeLists.txt
+++ b/src/blockchain_db/CMakeLists.txt
@@ -33,10 +33,7 @@ set(blockchain_db_sources
set(blockchain_db_headers)
-set(blockchain_db_private_headers
- blockchain_db.h
- lmdb/db_lmdb.h
- )
+monero_find_all_headers(blockchain_db_private_headers "${CMAKE_CURRENT_SOURCE_DIR}")
monero_private_headers(blockchain_db
${crypto_private_headers})
diff --git a/src/blockchain_db/lmdb/db_lmdb.cpp b/src/blockchain_db/lmdb/db_lmdb.cpp
index 3522c4a1b..e2ac9df0b 100644
--- a/src/blockchain_db/lmdb/db_lmdb.cpp
+++ b/src/blockchain_db/lmdb/db_lmdb.cpp
@@ -1045,8 +1045,9 @@ uint64_t BlockchainLMDB::add_output(const crypto::hash& tx_hash,
CURSOR(output_txs)
CURSOR(output_amounts)
- if (tx_output.target.type() != typeid(txout_to_key))
- throw0(DB_ERROR("Wrong output type: expected txout_to_key"));
+ crypto::public_key output_public_key;
+ if (!get_output_public_key(tx_output, output_public_key))
+ throw0(DB_ERROR("Could not get an output public key from a tx output."));
if (tx_output.amount == 0 && !commitment)
throw0(DB_ERROR("RCT output without commitment"));
@@ -1074,7 +1075,7 @@ uint64_t BlockchainLMDB::add_output(const crypto::hash& tx_hash,
else
ok.amount_index = 0;
ok.output_id = m_num_outputs;
- ok.data.pubkey = boost::get < txout_to_key > (tx_output.target).key;
+ ok.data.pubkey = output_public_key;
ok.data.unlock_time = unlock_time;
ok.data.height = m_height;
if (tx_output.amount == 0)
diff --git a/src/checkpoints/CMakeLists.txt b/src/checkpoints/CMakeLists.txt
index 4464f142c..665441f62 100644
--- a/src/checkpoints/CMakeLists.txt
+++ b/src/checkpoints/CMakeLists.txt
@@ -41,8 +41,7 @@ set(checkpoints_sources
set(checkpoints_headers)
-set(checkpoints_private_headers
- checkpoints.h)
+monero_find_all_headers(checkpoints_private_headers "${CMAKE_CURRENT_SOURCE_DIR}")
monero_private_headers(checkpoints
${checkpoints_private_headers})
diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt
index cc0813fa5..b712ee6b1 100644
--- a/src/common/CMakeLists.txt
+++ b/src/common/CMakeLists.txt
@@ -58,36 +58,7 @@ endif()
set(common_headers)
-set(common_private_headers
- apply_permutation.h
- base58.h
- boost_serialization_helper.h
- command_line.h
- common_fwd.h
- dns_utils.h
- download.h
- error.h
- expect.h
- http_connection.h
- notify.h
- pod-class.h
- pruning.h
- rpc_client.h
- scoped_message_writer.h
- unordered_containers_boost_serialization.h
- util.h
- varint.h
- i18n.h
- password.h
- perf_timer.h
- spawn.h
- stack_trace.h
- threadpool.h
- updates.h
- aligned.h
- timings.h
- combinator.h
- utf8.h)
+monero_find_all_headers(common_private_headers "${CMAKE_CURRENT_SOURCE_DIR}")
monero_private_headers(common
${common_private_headers})
diff --git a/src/common/perf_timer.cpp b/src/common/perf_timer.cpp
index 1152bf25a..30164a557 100644
--- a/src/common/perf_timer.cpp
+++ b/src/common/perf_timer.cpp
@@ -27,7 +27,7 @@
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <vector>
-#include "misc_os_dependent.h"
+#include "time_helper.h"
#include "perf_timer.h"
#undef MONERO_DEFAULT_LOG_CATEGORY
diff --git a/src/common/util.cpp b/src/common/util.cpp
index d607d8f7f..89dcf4fef 100644
--- a/src/common/util.cpp
+++ b/src/common/util.cpp
@@ -59,7 +59,7 @@
#include "include_base_utils.h"
#include "file_io_utils.h"
#include "wipeable_string.h"
-#include "misc_os_dependent.h"
+#include "time_helper.h"
using namespace epee;
#include "crypto/crypto.h"
diff --git a/src/crypto/CMakeLists.txt b/src/crypto/CMakeLists.txt
index e423e2971..595c7f966 100644
--- a/src/crypto/CMakeLists.txt
+++ b/src/crypto/CMakeLists.txt
@@ -58,27 +58,7 @@ include_directories(${RANDOMX_INCLUDE})
set(crypto_headers)
-set(crypto_private_headers
- blake256.h
- chacha.h
- crypto-ops.h
- crypto.h
- generic-ops.h
- groestl.h
- groestl_tables.h
- hash-ops.h
- hash.h
- hmac-keccak.h
- initializer.h
- jh.h
- keccak.h
- oaes_config.h
- oaes_lib.h
- random.h
- skein.h
- skein_port.h
- CryptonightR_JIT.h
- CryptonightR_template.h)
+monero_find_all_headers(crypto_private_headers "${CMAKE_CURRENT_SOURCE_DIR}")
monero_private_headers(cncrypto
${crypto_private_headers})
diff --git a/src/crypto/crypto.cpp b/src/crypto/crypto.cpp
index 1f46164d7..77a36069a 100644
--- a/src/crypto/crypto.cpp
+++ b/src/crypto/crypto.cpp
@@ -749,4 +749,28 @@ POP_WARNINGS
sc_sub(&h, &h, &sum);
return sc_isnonzero(&h) == 0;
}
+
+ void crypto_ops::derive_view_tag(const key_derivation &derivation, size_t output_index, view_tag &view_tag) {
+ #pragma pack(push, 1)
+ struct {
+ char salt[8]; // view tag domain-separator
+ key_derivation derivation;
+ char output_index[(sizeof(size_t) * 8 + 6) / 7];
+ } buf;
+ #pragma pack(pop)
+
+ char *end = buf.output_index;
+ memcpy(buf.salt, "view_tag", 8); // leave off null terminator
+ buf.derivation = derivation;
+ tools::write_varint(end, output_index);
+ assert(end <= buf.output_index + sizeof buf.output_index);
+
+ // view_tag_full = H[salt|derivation|output_index]
+ hash view_tag_full;
+ cn_fast_hash(&buf, end - reinterpret_cast<char *>(&buf), view_tag_full);
+
+ // only need a slice of view_tag_full to realize optimal perf/space efficiency
+ static_assert(sizeof(crypto::view_tag) <= sizeof(view_tag_full), "view tag should not be larger than hash result");
+ memcpy(&view_tag, &view_tag_full, sizeof(crypto::view_tag));
+ }
}
diff --git a/src/crypto/crypto.h b/src/crypto/crypto.h
index 596090329..d8cd6c6a0 100644
--- a/src/crypto/crypto.h
+++ b/src/crypto/crypto.h
@@ -99,6 +99,10 @@ namespace crypto {
ec_scalar c, r;
friend class crypto_ops;
};
+
+ POD_CLASS view_tag {
+ char data;
+ };
#pragma pack(pop)
void hash_to_scalar(const void *data, size_t length, ec_scalar &res);
@@ -107,7 +111,7 @@ namespace crypto {
static_assert(sizeof(ec_point) == 32 && sizeof(ec_scalar) == 32 &&
sizeof(public_key) == 32 && sizeof(public_key_memsafe) == 32 && sizeof(secret_key) == 32 &&
sizeof(key_derivation) == 32 && sizeof(key_image) == 32 &&
- sizeof(signature) == 64, "Invalid structure size");
+ sizeof(signature) == 64 && sizeof(view_tag) == 1, "Invalid structure size");
class crypto_ops {
crypto_ops();
@@ -151,6 +155,8 @@ namespace crypto {
const public_key *const *, std::size_t, const signature *);
friend bool check_ring_signature(const hash &, const key_image &,
const public_key *const *, std::size_t, const signature *);
+ static void derive_view_tag(const key_derivation &, std::size_t, view_tag &);
+ friend void derive_view_tag(const key_derivation &, std::size_t, view_tag &);
};
void generate_random_bytes_thread_safe(size_t N, uint8_t *bytes);
@@ -297,6 +303,14 @@ namespace crypto {
return check_ring_signature(prefix_hash, image, pubs.data(), pubs.size(), sig);
}
+ /* Derive a 1-byte view tag from the sender-receiver shared secret to reduce scanning time.
+ * When scanning outputs that were not sent to the user, checking the view tag for a match removes the need to proceed with expensive EC operations
+ * for an expected 99.6% of outputs (expected false positive rate = 1/2^8 = 1/256 = 0.4% = 100% - 99.6%).
+ */
+ inline void derive_view_tag(const key_derivation &derivation, std::size_t output_index, view_tag &vt) {
+ crypto_ops::derive_view_tag(derivation, output_index, vt);
+ }
+
inline std::ostream &operator <<(std::ostream &o, const crypto::public_key &v) {
epee::to_hex::formatted(o, epee::as_byte_span(v)); return o;
}
@@ -312,6 +326,9 @@ namespace crypto {
inline std::ostream &operator <<(std::ostream &o, const crypto::signature &v) {
epee::to_hex::formatted(o, epee::as_byte_span(v)); return o;
}
+ inline std::ostream &operator <<(std::ostream &o, const crypto::view_tag &v) {
+ 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;
@@ -325,3 +342,4 @@ CRYPTO_MAKE_HASHABLE_CONSTANT_TIME(secret_key)
CRYPTO_MAKE_HASHABLE_CONSTANT_TIME(public_key_memsafe)
CRYPTO_MAKE_HASHABLE(key_image)
CRYPTO_MAKE_COMPARABLE(signature)
+CRYPTO_MAKE_COMPARABLE(view_tag)
diff --git a/src/cryptonote_basic/CMakeLists.txt b/src/cryptonote_basic/CMakeLists.txt
index f1ca4de62..1414be1b2 100644
--- a/src/cryptonote_basic/CMakeLists.txt
+++ b/src/cryptonote_basic/CMakeLists.txt
@@ -56,20 +56,7 @@ set(cryptonote_basic_sources
set(cryptonote_basic_headers)
-set(cryptonote_basic_private_headers
- account.h
- account_boost_serialization.h
- connection_context.h
- cryptonote_basic.h
- cryptonote_basic_impl.h
- cryptonote_boost_serialization.h
- cryptonote_format_utils.h
- difficulty.h
- hardfork.h
- merge_mining.h
- miner.h
- tx_extra.h
- verification_context.h)
+monero_find_all_headers(cryptonote_basic_private_headers "${CMAKE_CURRENT_SOURCE_DIR}")
monero_private_headers(cryptonote_basic
${cryptonote_basic_private_headers})
diff --git a/src/cryptonote_basic/connection_context.h b/src/cryptonote_basic/connection_context.h
index 11e54b479..818999a60 100644
--- a/src/cryptonote_basic/connection_context.h
+++ b/src/cryptonote_basic/connection_context.h
@@ -27,6 +27,7 @@
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers
+// Parts of this file are originally copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net
#pragma once
#include <unordered_set>
@@ -34,7 +35,6 @@
#include <algorithm>
#include <boost/date_time/posix_time/posix_time.hpp>
#include "net/net_utils_base.h"
-#include "copyable_atomic.h"
#include "crypto/hash.h"
namespace cryptonote
@@ -55,6 +55,37 @@ namespace cryptonote
state_normal
};
+ /*
+ This class was originally from the EPEE module. It is identical in function to std::atomic<uint32_t> except
+ that it has copy-construction and copy-assignment defined, which means that earliers devs didn't have to write
+ custom copy-contructors and copy-assingment operators for the outer class, cryptonote_connection_context.
+ cryptonote_connection_context should probably be refactored because it is both trying to be POD-like while
+ also (very loosely) controlling access to its atomic members.
+ */
+ class copyable_atomic: public std::atomic<uint32_t>
+ {
+ public:
+ copyable_atomic()
+ {};
+ copyable_atomic(uint32_t value)
+ { store(value); }
+ copyable_atomic(const copyable_atomic& a):std::atomic<uint32_t>(a.load())
+ {}
+ copyable_atomic& operator= (const copyable_atomic& a)
+ {
+ store(a.load());
+ return *this;
+ }
+ uint32_t operator++()
+ {
+ return std::atomic<uint32_t>::operator++();
+ }
+ uint32_t operator++(int fake)
+ {
+ return std::atomic<uint32_t>::operator++(fake);
+ }
+ };
+
static constexpr int handshake_command() noexcept { return 1001; }
bool handshake_complete() const noexcept { return m_state != state_before_handshake; }
@@ -67,7 +98,7 @@ namespace cryptonote
uint64_t m_remote_blockchain_height;
uint64_t m_last_response_height;
boost::posix_time::ptime m_last_request_time;
- epee::copyable_atomic m_callback_request_count; //in debug purpose: problem with double callback rise
+ copyable_atomic m_callback_request_count; //in debug purpose: problem with double callback rise
crypto::hash m_last_known_hash;
uint32_t m_pruning_seed;
uint16_t m_rpc_port;
@@ -77,8 +108,8 @@ namespace cryptonote
int m_expect_response;
uint64_t m_expect_height;
size_t m_num_requested;
- epee::copyable_atomic m_new_stripe_notification{0};
- epee::copyable_atomic m_idle_peer_notification{0};
+ copyable_atomic m_new_stripe_notification{0};
+ copyable_atomic m_idle_peer_notification{0};
};
inline std::string get_protocol_state_string(cryptonote_connection_context::state s)
diff --git a/src/cryptonote_basic/cryptonote_basic.h b/src/cryptonote_basic/cryptonote_basic.h
index 4ae29281a..127958796 100644
--- a/src/cryptonote_basic/cryptonote_basic.h
+++ b/src/cryptonote_basic/cryptonote_basic.h
@@ -74,6 +74,7 @@ namespace cryptonote
crypto::hash hash;
};
+ // outputs <= HF_VERSION_VIEW_TAGS
struct txout_to_key
{
txout_to_key() { }
@@ -81,6 +82,19 @@ namespace cryptonote
crypto::public_key key;
};
+ // outputs >= HF_VERSION_VIEW_TAGS
+ struct txout_to_tagged_key
+ {
+ txout_to_tagged_key() { }
+ txout_to_tagged_key(const crypto::public_key &_key, const crypto::view_tag &_view_tag) : key(_key), view_tag(_view_tag) { }
+ crypto::public_key key;
+ crypto::view_tag view_tag; // optimization to reduce scanning time
+
+ BEGIN_SERIALIZE_OBJECT()
+ FIELD(key)
+ FIELD(view_tag)
+ END_SERIALIZE()
+ };
/* inputs */
@@ -137,7 +151,7 @@ namespace cryptonote
typedef boost::variant<txin_gen, txin_to_script, txin_to_scripthash, txin_to_key> txin_v;
- typedef boost::variant<txout_to_script, txout_to_scripthash, txout_to_key> txout_target_v;
+ typedef boost::variant<txout_to_script, txout_to_scripthash, txout_to_key, txout_to_tagged_key> txout_target_v;
//typedef std::pair<uint64_t, txout> out_t;
struct tx_out
@@ -562,6 +576,7 @@ VARIANT_TAG(binary_archive, cryptonote::txin_to_key, 0x2);
VARIANT_TAG(binary_archive, cryptonote::txout_to_script, 0x0);
VARIANT_TAG(binary_archive, cryptonote::txout_to_scripthash, 0x1);
VARIANT_TAG(binary_archive, cryptonote::txout_to_key, 0x2);
+VARIANT_TAG(binary_archive, cryptonote::txout_to_tagged_key, 0x3);
VARIANT_TAG(binary_archive, cryptonote::transaction, 0xcc);
VARIANT_TAG(binary_archive, cryptonote::block, 0xbb);
@@ -572,6 +587,7 @@ VARIANT_TAG(json_archive, cryptonote::txin_to_key, "key");
VARIANT_TAG(json_archive, cryptonote::txout_to_script, "script");
VARIANT_TAG(json_archive, cryptonote::txout_to_scripthash, "scripthash");
VARIANT_TAG(json_archive, cryptonote::txout_to_key, "key");
+VARIANT_TAG(json_archive, cryptonote::txout_to_tagged_key, "tagged_key");
VARIANT_TAG(json_archive, cryptonote::transaction, "tx");
VARIANT_TAG(json_archive, cryptonote::block, "block");
@@ -582,5 +598,6 @@ VARIANT_TAG(debug_archive, cryptonote::txin_to_key, "key");
VARIANT_TAG(debug_archive, cryptonote::txout_to_script, "script");
VARIANT_TAG(debug_archive, cryptonote::txout_to_scripthash, "scripthash");
VARIANT_TAG(debug_archive, cryptonote::txout_to_key, "key");
+VARIANT_TAG(debug_archive, cryptonote::txout_to_tagged_key, "tagged_key");
VARIANT_TAG(debug_archive, cryptonote::transaction, "tx");
VARIANT_TAG(debug_archive, cryptonote::block, "block");
diff --git a/src/cryptonote_basic/cryptonote_boost_serialization.h b/src/cryptonote_basic/cryptonote_boost_serialization.h
index d7149b5c9..493c9d91d 100644
--- a/src/cryptonote_basic/cryptonote_boost_serialization.h
+++ b/src/cryptonote_basic/cryptonote_boost_serialization.h
@@ -71,7 +71,11 @@ namespace boost
{
a & reinterpret_cast<char (&)[sizeof(crypto::key_image)]>(x);
}
-
+ template <class Archive>
+ inline void serialize(Archive &a, crypto::view_tag &x, const boost::serialization::version_type ver)
+ {
+ a & reinterpret_cast<char (&)[sizeof(crypto::view_tag)]>(x);
+ }
template <class Archive>
inline void serialize(Archive &a, crypto::signature &x, const boost::serialization::version_type ver)
{
@@ -103,6 +107,13 @@ namespace boost
}
template <class Archive>
+ inline void serialize(Archive &a, cryptonote::txout_to_tagged_key &x, const boost::serialization::version_type ver)
+ {
+ a & x.key;
+ a & x.view_tag;
+ }
+
+ template <class Archive>
inline void serialize(Archive &a, cryptonote::txout_to_scripthash &x, const boost::serialization::version_type ver)
{
a & x.hash;
diff --git a/src/cryptonote_basic/cryptonote_format_utils.cpp b/src/cryptonote_basic/cryptonote_format_utils.cpp
index 1bc6b6377..432617a4f 100644
--- a/src/cryptonote_basic/cryptonote_format_utils.cpp
+++ b/src/cryptonote_basic/cryptonote_format_utils.cpp
@@ -155,12 +155,13 @@ namespace cryptonote
}
for (size_t n = 0; n < tx.rct_signatures.outPk.size(); ++n)
{
- if (tx.vout[n].target.type() != typeid(txout_to_key))
+ crypto::public_key output_public_key;
+ if (!get_output_public_key(tx.vout[n], output_public_key))
{
- LOG_PRINT_L1("Unsupported output type in tx " << get_transaction_hash(tx));
+ LOG_PRINT_L1("Failed to get output public key for output " << n << " in tx " << get_transaction_hash(tx));
return false;
}
- rv.outPk[n].dest = rct::pk2rct(boost::get<txout_to_key>(tx.vout[n].target).key);
+ rv.outPk[n].dest = rct::pk2rct(output_public_key);
}
if (!base_only)
@@ -852,16 +853,16 @@ namespace cryptonote
{
for(const tx_out& out: tx.vout)
{
- CHECK_AND_ASSERT_MES(out.target.type() == typeid(txout_to_key), false, "wrong variant type: "
- << out.target.type().name() << ", expected " << typeid(txout_to_key).name()
- << ", in transaction id=" << get_transaction_hash(tx));
+ crypto::public_key output_public_key;
+ CHECK_AND_ASSERT_MES(get_output_public_key(out, output_public_key), false, "Failed to get output public key (output type: "
+ << out.target.type().name() << "), in transaction id=" << get_transaction_hash(tx));
if (tx.version == 1)
{
CHECK_AND_NO_ASSERT_MES(0 < out.amount, false, "zero amount output in transaction id=" << get_transaction_hash(tx));
}
- if(!check_key(boost::get<txout_to_key>(out.target).key))
+ if(!check_key(output_public_key))
return false;
}
return true;
@@ -905,6 +906,30 @@ namespace cryptonote
return outputs_amount;
}
//---------------------------------------------------------------
+ bool get_output_public_key(const cryptonote::tx_out& out, crypto::public_key& output_public_key)
+ {
+ // before HF_VERSION_VIEW_TAGS, outputs with public keys are of type txout_to_key
+ // after HF_VERSION_VIEW_TAGS, outputs with public keys are of type txout_to_tagged_key
+ if (out.target.type() == typeid(txout_to_key))
+ output_public_key = boost::get< txout_to_key >(out.target).key;
+ else if (out.target.type() == typeid(txout_to_tagged_key))
+ output_public_key = boost::get< txout_to_tagged_key >(out.target).key;
+ else
+ {
+ LOG_ERROR("Unexpected output target type found: " << out.target.type().name());
+ return false;
+ }
+
+ return true;
+ }
+ //---------------------------------------------------------------
+ boost::optional<crypto::view_tag> get_output_view_tag(const cryptonote::tx_out& out)
+ {
+ return out.target.type() == typeid(txout_to_tagged_key)
+ ? boost::optional<crypto::view_tag>(boost::get< txout_to_tagged_key >(out.target).view_tag)
+ : boost::optional<crypto::view_tag>();
+ }
+ //---------------------------------------------------------------
std::string short_hash_str(const crypto::hash& h)
{
std::string res = string_tools::pod_to_hex(h);
@@ -914,45 +939,126 @@ namespace cryptonote
return res;
}
//---------------------------------------------------------------
- bool is_out_to_acc(const account_keys& acc, const txout_to_key& out_key, const crypto::public_key& tx_pub_key, const std::vector<crypto::public_key>& additional_tx_pub_keys, size_t output_index)
+ void set_tx_out(const uint64_t amount, const crypto::public_key& output_public_key, const bool use_view_tags, const crypto::view_tag& view_tag, tx_out& out)
+ {
+ out.amount = amount;
+ if (use_view_tags)
+ {
+ txout_to_tagged_key ttk;
+ ttk.key = output_public_key;
+ ttk.view_tag = view_tag;
+ out.target = ttk;
+ }
+ else
+ {
+ txout_to_key tk;
+ tk.key = output_public_key;
+ out.target = tk;
+ }
+ }
+ //---------------------------------------------------------------
+ bool check_output_types(const transaction& tx, const uint8_t hf_version)
+ {
+ for (const auto &o: tx.vout)
+ {
+ if (hf_version > HF_VERSION_VIEW_TAGS)
+ {
+ // from v15, require outputs have view tags
+ CHECK_AND_ASSERT_MES(o.target.type() == typeid(txout_to_tagged_key), false, "wrong variant type: "
+ << o.target.type().name() << ", expected txout_to_tagged_key in transaction id=" << get_transaction_hash(tx));
+ }
+ else if (hf_version < HF_VERSION_VIEW_TAGS)
+ {
+ // require outputs to be of type txout_to_key
+ CHECK_AND_ASSERT_MES(o.target.type() == typeid(txout_to_key), false, "wrong variant type: "
+ << o.target.type().name() << ", expected txout_to_key in transaction id=" << get_transaction_hash(tx));
+ }
+ else //(hf_version == HF_VERSION_VIEW_TAGS)
+ {
+ // require outputs be of type txout_to_key OR txout_to_tagged_key
+ // to allow grace period before requiring all to be txout_to_tagged_key
+ CHECK_AND_ASSERT_MES(o.target.type() == typeid(txout_to_key) || o.target.type() == typeid(txout_to_tagged_key), false, "wrong variant type: "
+ << o.target.type().name() << ", expected txout_to_key or txout_to_tagged_key in transaction id=" << get_transaction_hash(tx));
+
+ // require all outputs in a tx be of the same type
+ CHECK_AND_ASSERT_MES(o.target.type() == tx.vout[0].target.type(), false, "non-matching variant types: "
+ << o.target.type().name() << " and " << tx.vout[0].target.type().name() << ", "
+ << "expected matching variant types in transaction id=" << get_transaction_hash(tx));
+ }
+ }
+ return true;
+ }
+ //---------------------------------------------------------------
+ bool out_can_be_to_acc(const boost::optional<crypto::view_tag>& view_tag_opt, const crypto::key_derivation& derivation, const size_t output_index)
+ {
+ // If there is no view tag to check, the output can possibly belong to the account.
+ // Will need to derive the output pub key to be certain whether or not the output belongs to the account.
+ if (!view_tag_opt)
+ return true;
+
+ crypto::view_tag view_tag = *view_tag_opt;
+
+ // If the output's view tag does *not* match the derived view tag, the output should not belong to the account.
+ // Therefore can fail out early to avoid expensive crypto ops needlessly deriving output public key to
+ // determine if output belongs to the account.
+ crypto::view_tag derived_view_tag;
+ crypto::derive_view_tag(derivation, output_index, derived_view_tag);
+ return view_tag == derived_view_tag;
+ }
+ //---------------------------------------------------------------
+ bool is_out_to_acc(const account_keys& acc, const crypto::public_key& output_public_key, const crypto::public_key& tx_pub_key, const std::vector<crypto::public_key>& additional_tx_pub_keys, size_t output_index, const boost::optional<crypto::view_tag>& view_tag_opt)
{
crypto::key_derivation derivation;
bool r = acc.get_device().generate_key_derivation(tx_pub_key, acc.m_view_secret_key, derivation);
CHECK_AND_ASSERT_MES(r, false, "Failed to generate key derivation");
crypto::public_key pk;
- r = acc.get_device().derive_public_key(derivation, output_index, acc.m_account_address.m_spend_public_key, pk);
- CHECK_AND_ASSERT_MES(r, false, "Failed to derive public key");
- if (pk == out_key.key)
- return true;
+ if (out_can_be_to_acc(view_tag_opt, derivation, output_index))
+ {
+ r = acc.get_device().derive_public_key(derivation, output_index, acc.m_account_address.m_spend_public_key, pk);
+ CHECK_AND_ASSERT_MES(r, false, "Failed to derive public key");
+ if (pk == output_public_key)
+ return true;
+ }
+
// try additional tx pubkeys if available
if (!additional_tx_pub_keys.empty())
{
CHECK_AND_ASSERT_MES(output_index < additional_tx_pub_keys.size(), false, "wrong number of additional tx pubkeys");
r = acc.get_device().generate_key_derivation(additional_tx_pub_keys[output_index], acc.m_view_secret_key, derivation);
CHECK_AND_ASSERT_MES(r, false, "Failed to generate key derivation");
- r = acc.get_device().derive_public_key(derivation, output_index, acc.m_account_address.m_spend_public_key, pk);
- CHECK_AND_ASSERT_MES(r, false, "Failed to derive public key");
- return pk == out_key.key;
+ if (out_can_be_to_acc(view_tag_opt, derivation, output_index))
+ {
+ r = acc.get_device().derive_public_key(derivation, output_index, acc.m_account_address.m_spend_public_key, pk);
+ CHECK_AND_ASSERT_MES(r, false, "Failed to derive public key");
+ return pk == output_public_key;
+ }
}
return false;
}
//---------------------------------------------------------------
- boost::optional<subaddress_receive_info> is_out_to_acc_precomp(const std::unordered_map<crypto::public_key, subaddress_index>& subaddresses, const crypto::public_key& out_key, const crypto::key_derivation& derivation, const std::vector<crypto::key_derivation>& additional_derivations, size_t output_index, hw::device &hwdev)
+ boost::optional<subaddress_receive_info> is_out_to_acc_precomp(const std::unordered_map<crypto::public_key, subaddress_index>& subaddresses, const crypto::public_key& out_key, const crypto::key_derivation& derivation, const std::vector<crypto::key_derivation>& additional_derivations, size_t output_index, hw::device &hwdev, const boost::optional<crypto::view_tag>& view_tag_opt)
{
// try the shared tx pubkey
crypto::public_key subaddress_spendkey;
- hwdev.derive_subaddress_public_key(out_key, derivation, output_index, subaddress_spendkey);
- auto found = subaddresses.find(subaddress_spendkey);
- if (found != subaddresses.end())
- return subaddress_receive_info{ found->second, derivation };
+ if (out_can_be_to_acc(view_tag_opt, derivation, output_index))
+ {
+ hwdev.derive_subaddress_public_key(out_key, derivation, output_index, subaddress_spendkey);
+ auto found = subaddresses.find(subaddress_spendkey);
+ if (found != subaddresses.end())
+ return subaddress_receive_info{ found->second, derivation };
+ }
+
// try additional tx pubkeys if available
if (!additional_derivations.empty())
{
CHECK_AND_ASSERT_MES(output_index < additional_derivations.size(), boost::none, "wrong number of additional derivations");
- hwdev.derive_subaddress_public_key(out_key, additional_derivations[output_index], output_index, subaddress_spendkey);
- found = subaddresses.find(subaddress_spendkey);
- if (found != subaddresses.end())
- return subaddress_receive_info{ found->second, additional_derivations[output_index] };
+ if (out_can_be_to_acc(view_tag_opt, additional_derivations[output_index], output_index))
+ {
+ hwdev.derive_subaddress_public_key(out_key, additional_derivations[output_index], output_index, subaddress_spendkey);
+ auto found = subaddresses.find(subaddress_spendkey);
+ if (found != subaddresses.end())
+ return subaddress_receive_info{ found->second, additional_derivations[output_index] };
+ }
}
return boost::none;
}
@@ -973,8 +1079,9 @@ namespace cryptonote
size_t i = 0;
for(const tx_out& o: tx.vout)
{
- CHECK_AND_ASSERT_MES(o.target.type() == typeid(txout_to_key), false, "wrong type id in transaction out" );
- if(is_out_to_acc(acc, boost::get<txout_to_key>(o.target), tx_pub_key, additional_tx_pub_keys, i))
+ crypto::public_key output_public_key;
+ CHECK_AND_ASSERT_MES(get_output_public_key(o, output_public_key), false, "unable to get output public key from transaction out" );
+ if(is_out_to_acc(acc, output_public_key, tx_pub_key, additional_tx_pub_keys, i, get_output_view_tag(o)))
{
outs.push_back(i);
money_transfered += o.amount;
@@ -1064,6 +1171,69 @@ namespace cryptonote
return s;
}
//---------------------------------------------------------------
+ uint64_t round_money_up(uint64_t amount, unsigned significant_digits)
+ {
+ // round monetary amount up with the requested amount of significant digits
+
+ CHECK_AND_ASSERT_THROW_MES(significant_digits > 0, "significant_digits must not be 0");
+ static_assert(sizeof(unsigned long long) == sizeof(uint64_t), "Unexpected unsigned long long size");
+
+ // we don't need speed, so we do it via text, as it's easier to get right
+ char buf[32];
+ snprintf(buf, sizeof(buf), "%llu", (unsigned long long)amount);
+ const size_t len = strlen(buf);
+ if (len > significant_digits)
+ {
+ bool bump = false;
+ char *ptr;
+ for (ptr = buf + significant_digits; *ptr; ++ptr)
+ {
+ // bump digits by one if the following digits past significant digits were to be 5 or more
+ if (*ptr != '0')
+ {
+ bump = true;
+ *ptr = '0';
+ }
+ }
+ ptr = buf + significant_digits;
+ while (bump && ptr > buf)
+ {
+ --ptr;
+ // bumping a nine overflows
+ if (*ptr == '9')
+ *ptr = '0';
+ else
+ {
+ // bumping another digit means we can stop bumping (no carry)
+ ++*ptr;
+ bump = false;
+ }
+ }
+ if (bump)
+ {
+ // carry reached the highest digit, we need to add a 1 in front
+ size_t offset = strlen(buf);
+ for (size_t i = offset + 1; i > 0; --i)
+ buf[i] = buf[i - 1];
+ buf[0] = '1';
+ }
+ }
+ char *end = NULL;
+ errno = 0;
+ const unsigned long long ull = strtoull(buf, &end, 10);
+ CHECK_AND_ASSERT_THROW_MES(ull != ULONG_MAX || errno == 0, "Failed to parse rounded amount: " << buf);
+ CHECK_AND_ASSERT_THROW_MES(ull != 0 || amount == 0, "Overflow in rounding");
+ return ull;
+ }
+ //---------------------------------------------------------------
+ std::string round_money_up(const std::string &s, unsigned significant_digits)
+ {
+ uint64_t amount;
+ CHECK_AND_ASSERT_THROW_MES(parse_amount(amount, s), "Failed to parse amount: " << s);
+ amount = round_money_up(amount, significant_digits);
+ return print_money(amount);
+ }
+ //---------------------------------------------------------------
crypto::hash get_blob_hash(const blobdata& blob)
{
crypto::hash h = null_hash;
diff --git a/src/cryptonote_basic/cryptonote_format_utils.h b/src/cryptonote_basic/cryptonote_format_utils.h
index 25cd89e99..8f5459ca7 100644
--- a/src/cryptonote_basic/cryptonote_format_utils.h
+++ b/src/cryptonote_basic/cryptonote_format_utils.h
@@ -89,13 +89,16 @@ namespace cryptonote
void set_encrypted_payment_id_to_tx_extra_nonce(blobdata& extra_nonce, const crypto::hash8& payment_id);
bool get_payment_id_from_tx_extra_nonce(const blobdata& extra_nonce, crypto::hash& payment_id);
bool get_encrypted_payment_id_from_tx_extra_nonce(const blobdata& extra_nonce, crypto::hash8& payment_id);
- bool is_out_to_acc(const account_keys& acc, const txout_to_key& out_key, const crypto::public_key& tx_pub_key, const std::vector<crypto::public_key>& additional_tx_public_keys, size_t output_index);
+ void set_tx_out(const uint64_t amount, const crypto::public_key& output_public_key, const bool use_view_tags, const crypto::view_tag& view_tag, tx_out& out);
+ bool check_output_types(const transaction& tx, const uint8_t hf_version);
+ bool out_can_be_to_acc(const boost::optional<crypto::view_tag>& view_tag_opt, const crypto::key_derivation& derivation, const size_t output_index);
+ bool is_out_to_acc(const account_keys& acc, const crypto::public_key& output_public_key, const crypto::public_key& tx_pub_key, const std::vector<crypto::public_key>& additional_tx_public_keys, size_t output_index, const boost::optional<crypto::view_tag>& view_tag_opt = boost::optional<crypto::view_tag>());
struct subaddress_receive_info
{
subaddress_index index;
crypto::key_derivation derivation;
};
- boost::optional<subaddress_receive_info> is_out_to_acc_precomp(const std::unordered_map<crypto::public_key, subaddress_index>& subaddresses, const crypto::public_key& out_key, const crypto::key_derivation& derivation, const std::vector<crypto::key_derivation>& additional_derivations, size_t output_index, hw::device &hwdev);
+ boost::optional<subaddress_receive_info> is_out_to_acc_precomp(const std::unordered_map<crypto::public_key, subaddress_index>& subaddresses, const crypto::public_key& out_key, const crypto::key_derivation& derivation, const std::vector<crypto::key_derivation>& additional_derivations, size_t output_index, hw::device &hwdev, const boost::optional<crypto::view_tag>& view_tag_opt = boost::optional<crypto::view_tag>());
bool lookup_acc_outs(const account_keys& acc, const transaction& tx, const crypto::public_key& tx_pub_key, const std::vector<crypto::public_key>& additional_tx_public_keys, std::vector<size_t>& outs, uint64_t& money_transfered);
bool lookup_acc_outs(const account_keys& acc, const transaction& tx, std::vector<size_t>& outs, uint64_t& money_transfered);
bool get_tx_fee(const transaction& tx, uint64_t & fee);
@@ -126,6 +129,8 @@ namespace cryptonote
bool parse_and_validate_block_from_blob(const blobdata_ref& b_blob, block& b, crypto::hash &block_hash);
bool get_inputs_money_amount(const transaction& tx, uint64_t& money);
uint64_t get_outs_money_amount(const transaction& tx);
+ bool get_output_public_key(const cryptonote::tx_out& out, crypto::public_key& output_public_key);
+ boost::optional<crypto::view_tag> get_output_view_tag(const cryptonote::tx_out& out);
bool check_inputs_types_supported(const transaction& tx);
bool check_outs_valid(const transaction& tx);
bool parse_amount(uint64_t& amount, const std::string& str_amount);
@@ -144,6 +149,8 @@ namespace cryptonote
std::string get_unit(unsigned int decimal_point = -1);
std::string print_money(uint64_t amount, unsigned int decimal_point = -1);
std::string print_money(const boost::multiprecision::uint128_t &amount, unsigned int decimal_point = -1);
+ uint64_t round_money_up(uint64_t amount, unsigned significant_digits);
+ std::string round_money_up(const std::string &amount, unsigned significant_digits);
//---------------------------------------------------------------
template<class t_object>
bool t_serializable_object_from_blob(t_object& to, const blobdata& b_blob)
diff --git a/src/cryptonote_config.h b/src/cryptonote_config.h
index 5aee87897..f02eeee71 100644
--- a/src/cryptonote_config.h
+++ b/src/cryptonote_config.h
@@ -169,6 +169,7 @@
#define HF_VERSION_MIN_MIXIN_4 6
#define HF_VERSION_MIN_MIXIN_6 7
#define HF_VERSION_MIN_MIXIN_10 8
+#define HF_VERSION_MIN_MIXIN_15 15
#define HF_VERSION_ENFORCE_RCT 6
#define HF_VERSION_PER_BYTE_FEE 8
#define HF_VERSION_SMALLER_BP 10
@@ -183,8 +184,11 @@
#define HF_VERSION_CLSAG 13
#define HF_VERSION_DETERMINISTIC_UNLOCK_TIME 13
#define HF_VERSION_BULLETPROOF_PLUS 15
+#define HF_VERSION_VIEW_TAGS 15
+#define HF_VERSION_2021_SCALING 15
#define PER_KB_FEE_QUANTIZATION_DECIMALS 8
+#define CRYPTONOTE_SCALING_2021_FEE_ROUNDING_PLACES 2
#define HASH_OF_HASHES_STEP 512
diff --git a/src/cryptonote_core/CMakeLists.txt b/src/cryptonote_core/CMakeLists.txt
index 5f5d88356..e272b94f0 100644
--- a/src/cryptonote_core/CMakeLists.txt
+++ b/src/cryptonote_core/CMakeLists.txt
@@ -35,13 +35,7 @@ set(cryptonote_core_sources
set(cryptonote_core_headers)
-set(cryptonote_core_private_headers
- blockchain_storage_boost_serialization.h
- blockchain.h
- cryptonote_core.h
- tx_pool.h
- tx_sanity_check.h
- cryptonote_tx_utils.h)
+monero_find_all_headers(cryptonote_core_private_headers "${CMAKE_CURRENT_SOURCE_DIR}")
monero_private_headers(cryptonote_core
${cryptonote_core_private_headers})
diff --git a/src/cryptonote_core/blockchain.cpp b/src/cryptonote_core/blockchain.cpp
index 4eaca039c..5b7b4353d 100644
--- a/src/cryptonote_core/blockchain.cpp
+++ b/src/cryptonote_core/blockchain.cpp
@@ -1341,6 +1341,7 @@ difficulty_type Blockchain::get_next_difficulty_for_alternative_chain(const std:
// one input, of type txin_gen, with height set to the block's height
// correct miner tx unlock time
// a non-overflowing tx amount (dubious necessity on this check)
+// valid output types
bool Blockchain::prevalidate_miner_transaction(const block& b, uint64_t height, uint8_t hf_version)
{
LOG_PRINT_L3("Blockchain::" << __func__);
@@ -1369,6 +1370,8 @@ bool Blockchain::prevalidate_miner_transaction(const block& b, uint64_t height,
return false;
}
+ CHECK_AND_ASSERT_MES(check_output_types(b.miner_tx, hf_version), false, "miner transaction has invalid output type(s) in block " << get_block_hash(b));
+
return true;
}
//------------------------------------------------------------------
@@ -3044,12 +3047,14 @@ bool Blockchain::check_tx_outputs(const transaction& tx, tx_verification_context
// from v4, forbid invalid pubkeys
if (hf_version >= 4) {
for (const auto &o: tx.vout) {
- if (o.target.type() == typeid(txout_to_key)) {
- const txout_to_key& out_to_key = boost::get<txout_to_key>(o.target);
- if (!crypto::check_key(out_to_key.key)) {
- tvc.m_invalid_output = true;
- return false;
- }
+ crypto::public_key output_public_key;
+ if (!get_output_public_key(o, output_public_key)) {
+ tvc.m_invalid_output = true;
+ return false;
+ }
+ if (!crypto::check_key(output_public_key)) {
+ tvc.m_invalid_output = true;
+ return false;
}
}
}
@@ -3166,6 +3171,13 @@ bool Blockchain::check_tx_outputs(const transaction& tx, tx_verification_context
}
}
+ // from v15, require view tags on outputs
+ if (!check_output_types(tx, hf_version))
+ {
+ tvc.m_invalid_output = true;
+ return false;
+ }
+
return true;
}
//------------------------------------------------------------------
@@ -3309,7 +3321,7 @@ bool Blockchain::check_tx_inputs(transaction& tx, tx_verification_context &tvc,
size_t n_unmixable = 0, n_mixable = 0;
size_t min_actual_mixin = std::numeric_limits<size_t>::max();
size_t max_actual_mixin = 0;
- const size_t min_mixin = hf_version >= HF_VERSION_MIN_MIXIN_10 ? 10 : hf_version >= HF_VERSION_MIN_MIXIN_6 ? 6 : hf_version >= HF_VERSION_MIN_MIXIN_4 ? 4 : 2;
+ const size_t min_mixin = hf_version >= HF_VERSION_MIN_MIXIN_15 ? 15 : hf_version >= HF_VERSION_MIN_MIXIN_10 ? 10 : hf_version >= HF_VERSION_MIN_MIXIN_6 ? 6 : hf_version >= HF_VERSION_MIN_MIXIN_4 ? 4 : 2;
for (const auto& txin : tx.vin)
{
// non txin_to_key inputs will be rejected below
@@ -3352,14 +3364,11 @@ bool Blockchain::check_tx_inputs(transaction& tx, tx_verification_context &tvc,
}
}
- if (((hf_version == HF_VERSION_MIN_MIXIN_10 || hf_version == HF_VERSION_MIN_MIXIN_10+1) && min_actual_mixin != 10) || (hf_version >= HF_VERSION_MIN_MIXIN_10+2 && min_actual_mixin > 10))
- {
- MERROR_VER("Tx " << get_transaction_hash(tx) << " has invalid ring size (" << (min_actual_mixin + 1) << "), it should be 11");
- tvc.m_low_mixin = true;
- return false;
- }
-
- if (min_actual_mixin < min_mixin)
+ // The only circumstance where ring sizes less than expected are
+ // allowed is when spending unmixable non-RCT outputs in the chain.
+ // Caveat: at HF_VERSION_MIN_MIXIN_15, temporarily allow ring sizes
+ // of 11 to allow a grace period in the transition to larger ring size.
+ if (min_actual_mixin < min_mixin && !(hf_version == HF_VERSION_MIN_MIXIN_15 && min_actual_mixin == 10))
{
if (n_unmixable == 0)
{
@@ -3373,6 +3382,15 @@ bool Blockchain::check_tx_inputs(transaction& tx, tx_verification_context &tvc,
tvc.m_low_mixin = true;
return false;
}
+ } else if ((hf_version > HF_VERSION_MIN_MIXIN_15 && min_actual_mixin > 15)
+ || (hf_version == HF_VERSION_MIN_MIXIN_15 && min_actual_mixin != 15 && min_actual_mixin != 10) // grace period to allow either 15 or 10
+ || (hf_version < HF_VERSION_MIN_MIXIN_15 && hf_version >= HF_VERSION_MIN_MIXIN_10+2 && min_actual_mixin > 10)
+ || ((hf_version == HF_VERSION_MIN_MIXIN_10 || hf_version == HF_VERSION_MIN_MIXIN_10+1) && min_actual_mixin != 10)
+ )
+ {
+ MERROR_VER("Tx " << get_transaction_hash(tx) << " has invalid ring size (" << (min_actual_mixin + 1) << "), it should be " << (min_mixin + 1));
+ tvc.m_low_mixin = true;
+ return false;
}
// min/max tx version based on HF, and we accept v1 txes if having a non mixable
@@ -3710,11 +3728,24 @@ uint64_t Blockchain::get_dynamic_base_fee(uint64_t block_reward, size_t median_b
if (version >= HF_VERSION_PER_BYTE_FEE)
{
lo = mul128(block_reward, DYNAMIC_FEE_REFERENCE_TRANSACTION_WEIGHT, &hi);
- div128_64(hi, lo, min_block_weight, &hi, &lo, NULL, NULL);
div128_64(hi, lo, median_block_weight, &hi, &lo, NULL, NULL);
- assert(hi == 0);
- lo /= 5;
- return lo;
+ if (version >= HF_VERSION_2021_SCALING)
+ {
+ // min_fee_per_byte = round_up( 0.95 * block_reward * ref_weight / (fee_median^2) )
+ // note: since hardfork HF_VERSION_2021_SCALING, fee_median (a.k.a. median_block_weight) equals effective long term median
+ div128_64(hi, lo, median_block_weight, &hi, &lo, NULL, NULL);
+ assert(hi == 0);
+ lo -= lo / 20;
+ return lo;
+ }
+ else
+ {
+ // min_fee_per_byte = 0.2 * block_reward * ref_weight / (min_penalty_free_zone * fee_median)
+ div128_64(hi, lo, min_block_weight, &hi, &lo, NULL, NULL);
+ assert(hi == 0);
+ lo /= 5;
+ return lo;
+ }
}
const uint64_t fee_base = version >= 5 ? DYNAMIC_FEE_PER_KB_BASE_FEE_V5 : DYNAMIC_FEE_PER_KB_BASE_FEE;
@@ -3787,6 +3818,81 @@ bool Blockchain::check_fee(size_t tx_weight, uint64_t fee) const
}
//------------------------------------------------------------------
+void Blockchain::get_dynamic_base_fee_estimate_2021_scaling(uint64_t grace_blocks, uint64_t base_reward, uint64_t Mnw, uint64_t Mlw, std::vector<uint64_t> &fees) const
+{
+ // variable names and calculations as per https://github.com/ArticMine/Monero-Documents/blob/master/MoneroScaling2021-02.pdf
+ // from (earlier than) this fork, the base fee is per byte
+ const uint64_t Mfw = std::min(Mnw, Mlw);
+
+ // 3 kB divided by something ? It's going to be either 0 or *very* quantized, so fold it into integer steps below
+ //const uint64_t Brlw = DYNAMIC_FEE_REFERENCE_TRANSACTION_WEIGHT / Mfw;
+
+ // constant.... equal to 0, unless floating point, so fold it into integer steps below
+ //const uint64_t Br = DYNAMIC_FEE_REFERENCE_TRANSACTION_WEIGHT / CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V5
+
+ //const uint64_t Fl = base_reward * Brlw / Mfw; fold Brlw from above
+ const uint64_t Fl = base_reward * /*Brlw*/ DYNAMIC_FEE_REFERENCE_TRANSACTION_WEIGHT / (Mfw * Mfw);
+
+ // fold Fl into this for better precision (and to match the test cases in the PDF)
+ // const uint64_t Fn = 4 * Fl;
+ const uint64_t Fn = 4 * base_reward * /*Brlw*/ DYNAMIC_FEE_REFERENCE_TRANSACTION_WEIGHT / (Mfw * Mfw);
+
+ // const uint64_t Fm = 16 * base_reward * Br / Mfw; fold Br from above
+ const uint64_t Fm = 16 * base_reward * DYNAMIC_FEE_REFERENCE_TRANSACTION_WEIGHT / (CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V5 * Mfw);
+
+ // const uint64_t Fp = 2 * base_reward / Mnw;
+
+ // fold Br from above, move 4Fm in the max to decrease quantization effect
+ //const uint64_t Fh = 4 * Fm * std::max<uint64_t>(1, Mfw / (32 * DYNAMIC_FEE_REFERENCE_TRANSACTION_WEIGHT * Mnw / CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V5));
+ const uint64_t Fh = std::max<uint64_t>(4 * Fm, 4 * Fm * Mfw / (32 * DYNAMIC_FEE_REFERENCE_TRANSACTION_WEIGHT * Mnw / CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V5));
+
+ fees.resize(4);
+ fees[0] = cryptonote::round_money_up(Fl, CRYPTONOTE_SCALING_2021_FEE_ROUNDING_PLACES);
+ fees[1] = cryptonote::round_money_up(Fn, CRYPTONOTE_SCALING_2021_FEE_ROUNDING_PLACES);
+ fees[2] = cryptonote::round_money_up(Fm, CRYPTONOTE_SCALING_2021_FEE_ROUNDING_PLACES);
+ fees[3] = cryptonote::round_money_up(Fh, CRYPTONOTE_SCALING_2021_FEE_ROUNDING_PLACES);
+}
+
+void Blockchain::get_dynamic_base_fee_estimate_2021_scaling(uint64_t grace_blocks, std::vector<uint64_t> &fees) const
+{
+ const uint8_t version = get_current_hard_fork_version();
+ const uint64_t db_height = m_db->height();
+
+ // we want Mlw = median of max((min(Mbw, 1.7 * Ml), Zm), Ml / 1.7)
+ // Mbw: block weight for the last 99990 blocks, 0 for the next 10
+ // Ml: penalty free zone (dynamic), aka long_term_median, aka median of max((min(Mb, 1.7 * Ml), Zm), Ml / 1.7)
+ // Zm: 300000 (minimum penalty free zone)
+ //
+ // So we copy the current rolling median state, add 10 (grace_blocks) zeroes to it, and get back Mlw
+
+ epee::misc_utils::rolling_median_t<uint64_t> rm = m_long_term_block_weights_cache_rolling_median;
+ for (size_t i = 0; i < grace_blocks; ++i)
+ rm.insert(0);
+ const uint64_t Mlw_penalty_free_zone_for_wallet = std::max<uint64_t>(rm.median(), CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V5);
+
+ // Msw: median over [100 - grace blocks] past + [grace blocks] future blocks
+ CHECK_AND_ASSERT_THROW_MES(grace_blocks <= 100, "Grace blocks invalid In 2021 fee scaling estimate.");
+ std::vector<uint64_t> weights;
+ get_last_n_blocks_weights(weights, 100 - grace_blocks);
+ weights.reserve(100);
+ for (size_t i = 0; i < grace_blocks; ++i)
+ weights.push_back(0);
+ const uint64_t Msw_effective_short_term_median = std::max(epee::misc_utils::median(weights), Mlw_penalty_free_zone_for_wallet);
+
+ const uint64_t Mnw = std::min(Msw_effective_short_term_median, 50 * Mlw_penalty_free_zone_for_wallet);
+
+ uint64_t already_generated_coins = db_height ? m_db->get_block_already_generated_coins(db_height - 1) : 0;
+ uint64_t base_reward;
+ if (!get_block_reward(m_current_block_cumul_weight_limit / 2, 1, already_generated_coins, base_reward, version))
+ {
+ MERROR("Failed to determine block reward, using placeholder " << print_money(BLOCK_REWARD_OVERESTIMATE) << " as a high bound");
+ base_reward = BLOCK_REWARD_OVERESTIMATE;
+ }
+
+ get_dynamic_base_fee_estimate_2021_scaling(grace_blocks, base_reward, Mnw, Mlw_penalty_free_zone_for_wallet, fees);
+}
+
+//------------------------------------------------------------------
uint64_t Blockchain::get_dynamic_base_fee_estimate(uint64_t grace_blocks) const
{
const uint8_t version = get_current_hard_fork_version();
@@ -3798,6 +3904,13 @@ uint64_t Blockchain::get_dynamic_base_fee_estimate(uint64_t grace_blocks) const
if (grace_blocks >= CRYPTONOTE_REWARD_BLOCKS_WINDOW)
grace_blocks = CRYPTONOTE_REWARD_BLOCKS_WINDOW - 1;
+ if (version >= HF_VERSION_2021_SCALING)
+ {
+ std::vector<uint64_t> fees;
+ get_dynamic_base_fee_estimate_2021_scaling(grace_blocks, fees);
+ return fees[0];
+ }
+
const uint64_t min_block_weight = get_min_block_weight(version);
std::vector<uint64_t> weights;
get_last_n_blocks_weights(weights, CRYPTONOTE_REWARD_BLOCKS_WINDOW - grace_blocks);
@@ -3882,9 +3995,11 @@ bool Blockchain::check_tx_input(size_t tx_version, const txin_to_key& txin, cons
}
// The original code includes a check for the output corresponding to this input
- // to be a txout_to_key. This is removed, as the database does not store this info,
- // but only txout_to_key outputs are stored in the DB in the first place, done in
- // Blockchain*::add_output
+ // to be a txout_to_key. This is removed, as the database does not store this info.
+ // Only txout_to_key (and since HF_VERSION_VIEW_TAGS, txout_to_tagged_key)
+ // outputs are stored in the DB in the first place, done in Blockchain*::add_output.
+ // Additional type checks on outputs were also added via cryptonote::check_output_types
+ // and cryptonote::get_output_public_key (see Blockchain::check_tx_outputs).
m_output_keys.push_back(rct::ctkey({rct::pk2rct(pubkey), commitment}));
return true;
@@ -4472,6 +4587,7 @@ bool Blockchain::check_blockchain_pruning()
return m_db->check_pruning();
}
//------------------------------------------------------------------
+// returns min(Mb, 1.7*Ml) as per https://github.com/ArticMine/Monero-Documents/blob/master/MoneroScaling2021-02.pdf from HF_VERSION_LONG_TERM_BLOCK_WEIGHT
uint64_t Blockchain::get_next_long_term_block_weight(uint64_t block_weight) const
{
PERF_TIMER(get_next_long_term_block_weight);
@@ -4486,7 +4602,18 @@ uint64_t Blockchain::get_next_long_term_block_weight(uint64_t block_weight) cons
uint64_t long_term_median = get_long_term_block_weight_median(db_height - nblocks, nblocks);
uint64_t long_term_effective_median_block_weight = std::max<uint64_t>(CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V5, long_term_median);
- uint64_t short_term_constraint = long_term_effective_median_block_weight + long_term_effective_median_block_weight * 2 / 5;
+ uint64_t short_term_constraint;
+ if (hf_version >= HF_VERSION_2021_SCALING)
+ {
+ // long_term_block_weight = block_weight bounded to range [long-term-median/1.7, long-term-median*1.7]
+ block_weight = std::max<uint64_t>(block_weight, long_term_effective_median_block_weight * 10 / 17);
+ short_term_constraint = long_term_effective_median_block_weight + long_term_effective_median_block_weight * 7 / 10;
+ }
+ else
+ {
+ // long_term_block_weight = block_weight bounded to range [0, long-term-median*1.4]
+ short_term_constraint = long_term_effective_median_block_weight + long_term_effective_median_block_weight * 2 / 5;
+ }
uint64_t long_term_block_weight = std::min<uint64_t>(block_weight, short_term_constraint);
return long_term_block_weight;
@@ -4528,7 +4655,11 @@ bool Blockchain::update_next_cumulative_weight_limit(uint64_t *long_term_effecti
m_long_term_effective_median_block_weight = std::max<uint64_t>(CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V5, long_term_median);
- uint64_t short_term_constraint = m_long_term_effective_median_block_weight + m_long_term_effective_median_block_weight * 2 / 5;
+ uint64_t short_term_constraint = m_long_term_effective_median_block_weight;
+ if (hf_version >= HF_VERSION_2021_SCALING)
+ short_term_constraint += m_long_term_effective_median_block_weight * 7 / 10;
+ else
+ short_term_constraint += m_long_term_effective_median_block_weight * 2 / 5;
uint64_t long_term_block_weight = std::min<uint64_t>(block_weight, short_term_constraint);
if (db_height == 1)
@@ -4547,7 +4678,19 @@ bool Blockchain::update_next_cumulative_weight_limit(uint64_t *long_term_effecti
get_last_n_blocks_weights(weights, CRYPTONOTE_REWARD_BLOCKS_WINDOW);
uint64_t short_term_median = epee::misc_utils::median(weights);
- uint64_t effective_median_block_weight = std::min<uint64_t>(std::max<uint64_t>(CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V5, short_term_median), CRYPTONOTE_SHORT_TERM_BLOCK_WEIGHT_SURGE_FACTOR * m_long_term_effective_median_block_weight);
+ uint64_t effective_median_block_weight;
+ if (hf_version >= HF_VERSION_2021_SCALING)
+ {
+ // effective median = short_term_median bounded to range [long_term_median, 50*long_term_median], but it can't be smaller than the
+ // minimum penalty free zone (a.k.a. 'full reward zone')
+ effective_median_block_weight = std::min<uint64_t>(std::max<uint64_t>(m_long_term_effective_median_block_weight, short_term_median), CRYPTONOTE_SHORT_TERM_BLOCK_WEIGHT_SURGE_FACTOR * m_long_term_effective_median_block_weight);
+ }
+ else
+ {
+ // effective median = short_term_median bounded to range [0, 50*long_term_median], but it can't be smaller than the
+ // minimum penalty free zone (a.k.a. 'full reward zone')
+ effective_median_block_weight = std::min<uint64_t>(std::max<uint64_t>(CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V5, short_term_median), CRYPTONOTE_SHORT_TERM_BLOCK_WEIGHT_SURGE_FACTOR * m_long_term_effective_median_block_weight);
+ }
m_current_block_cumul_weight_median = effective_median_block_weight;
}
diff --git a/src/cryptonote_core/blockchain.h b/src/cryptonote_core/blockchain.h
index 5460d7761..7a94f6358 100644
--- a/src/cryptonote_core/blockchain.h
+++ b/src/cryptonote_core/blockchain.h
@@ -648,6 +648,22 @@ namespace cryptonote
* @return the fee estimate
*/
uint64_t get_dynamic_base_fee_estimate(uint64_t grace_blocks) const;
+ void get_dynamic_base_fee_estimate_2021_scaling(uint64_t grace_blocks, uint64_t base_reward, uint64_t Mnw, uint64_t Mlw, std::vector<uint64_t> &fees) const;
+
+ /**
+ * @brief get four levels of dynamic per byte fee estimate for the next few blocks
+ *
+ * The dynamic fee is based on the block weight in a past window, and
+ * the current block reward. It is expressed per byte, and is based on
+ * https://github.com/ArticMine/Monero-Documents/blob/master/MoneroScaling2021-02.pdf
+ * This function calculates an estimate for a dynamic fee which will be
+ * valid for the next grace_blocks
+ *
+ * @param grace_blocks number of blocks we want the fee to be valid for
+ *
+ * @return the fee estimates (4 of them)
+ */
+ void get_dynamic_base_fee_estimate_2021_scaling(uint64_t grace_blocks, std::vector<uint64_t> &fees) const;
/**
* @brief validate a transaction's fee
diff --git a/src/cryptonote_core/cryptonote_core.cpp b/src/cryptonote_core/cryptonote_core.cpp
index 2d2b1cbcf..a78f5d673 100644
--- a/src/cryptonote_core/cryptonote_core.cpp
+++ b/src/cryptonote_core/cryptonote_core.cpp
@@ -1177,7 +1177,8 @@ namespace cryptonote
return false;
}
- if (!check_tx_inputs_ring_members_diff(tx))
+ const uint8_t hf_version = m_blockchain_storage.get_current_hard_fork_version();
+ if (!check_tx_inputs_ring_members_diff(tx, hf_version))
{
MERROR_VER("tx uses duplicate ring members");
return false;
@@ -1189,6 +1190,12 @@ namespace cryptonote
return false;
}
+ if (!check_output_types(tx, hf_version))
+ {
+ MERROR_VER("tx does not use valid output type(s)");
+ return false;
+ }
+
return true;
}
//-----------------------------------------------------------------------------------------------
@@ -1295,10 +1302,9 @@ namespace cryptonote
return true;
}
//-----------------------------------------------------------------------------------------------
- bool core::check_tx_inputs_ring_members_diff(const transaction& tx) const
+ bool core::check_tx_inputs_ring_members_diff(const transaction& tx, const uint8_t hf_version) const
{
- const uint8_t version = m_blockchain_storage.get_current_hard_fork_version();
- if (version >= 6)
+ if (hf_version >= 6)
{
for(const auto& in: tx.vin)
{
diff --git a/src/cryptonote_core/cryptonote_core.h b/src/cryptonote_core/cryptonote_core.h
index 2e5248c5d..0b36730b6 100644
--- a/src/cryptonote_core/cryptonote_core.h
+++ b/src/cryptonote_core/cryptonote_core.h
@@ -1012,10 +1012,11 @@ namespace cryptonote
* @brief verify that each ring uses distinct members
*
* @param tx the transaction to check
+ * @param hf_version the hard fork version rules to use
*
* @return false if any ring uses duplicate members, true otherwise
*/
- bool check_tx_inputs_ring_members_diff(const transaction& tx) const;
+ bool check_tx_inputs_ring_members_diff(const transaction& tx, const uint8_t hf_version) const;
/**
* @brief verify that each input key image in a transaction is in
diff --git a/src/cryptonote_core/cryptonote_tx_utils.cpp b/src/cryptonote_core/cryptonote_tx_utils.cpp
index 76192be5d..1d2024a05 100644
--- a/src/cryptonote_core/cryptonote_tx_utils.cpp
+++ b/src/cryptonote_core/cryptonote_tx_utils.cpp
@@ -149,12 +149,17 @@ namespace cryptonote
r = crypto::derive_public_key(derivation, no, miner_address.m_spend_public_key, out_eph_public_key);
CHECK_AND_ASSERT_MES(r, false, "while creating outs: failed to derive_public_key(" << derivation << ", " << no << ", "<< miner_address.m_spend_public_key << ")");
- txout_to_key tk;
- tk.key = out_eph_public_key;
+ uint64_t amount = out_amounts[no];
+ summary_amounts += amount;
+
+ bool use_view_tags = hard_fork_version >= HF_VERSION_VIEW_TAGS;
+ crypto::view_tag view_tag;
+ if (use_view_tags)
+ crypto::derive_view_tag(derivation, no, view_tag);
tx_out out;
- summary_amounts += out.amount = out_amounts[no];
- out.target = tk;
+ cryptonote::set_tx_out(amount, out_eph_public_key, use_view_tags, view_tag, out);
+
tx.vout.push_back(out);
}
@@ -198,7 +203,7 @@ namespace cryptonote
return addr.m_view_public_key;
}
//---------------------------------------------------------------
- bool construct_tx_with_tx_key(const account_keys& sender_account_keys, const std::unordered_map<crypto::public_key, subaddress_index>& subaddresses, std::vector<tx_source_entry>& sources, std::vector<tx_destination_entry>& destinations, const boost::optional<cryptonote::account_public_address>& change_addr, const std::vector<uint8_t> &extra, transaction& tx, uint64_t unlock_time, const crypto::secret_key &tx_key, const std::vector<crypto::secret_key> &additional_tx_keys, bool rct, const rct::RCTConfig &rct_config, rct::multisig_out *msout, bool shuffle_outs)
+ bool construct_tx_with_tx_key(const account_keys& sender_account_keys, const std::unordered_map<crypto::public_key, subaddress_index>& subaddresses, std::vector<tx_source_entry>& sources, std::vector<tx_destination_entry>& destinations, const boost::optional<cryptonote::account_public_address>& change_addr, const std::vector<uint8_t> &extra, transaction& tx, uint64_t unlock_time, const crypto::secret_key &tx_key, const std::vector<crypto::secret_key> &additional_tx_keys, bool rct, const rct::RCTConfig &rct_config, rct::multisig_out *msout, bool shuffle_outs, bool use_view_tags)
{
hw::device &hwdev = sender_account_keys.get_device();
@@ -406,17 +411,16 @@ namespace cryptonote
{
CHECK_AND_ASSERT_MES(dst_entr.amount > 0 || tx.version > 1, false, "Destination with wrong amount: " << dst_entr.amount);
crypto::public_key out_eph_public_key;
+ crypto::view_tag view_tag;
hwdev.generate_output_ephemeral_keys(tx.version,sender_account_keys, txkey_pub, tx_key,
dst_entr, change_addr, output_index,
need_additional_txkeys, additional_tx_keys,
- additional_tx_public_keys, amount_keys, out_eph_public_key);
+ additional_tx_public_keys, amount_keys, out_eph_public_key,
+ use_view_tags, view_tag);
tx_out out;
- out.amount = dst_entr.amount;
- txout_to_key tk;
- tk.key = out_eph_public_key;
- out.target = tk;
+ cryptonote::set_tx_out(dst_entr.amount, out_eph_public_key, use_view_tags, view_tag, out);
tx.vout.push_back(out);
output_index++;
summary_outs_money += dst_entr.amount;
@@ -546,7 +550,9 @@ namespace cryptonote
}
for (size_t i = 0; i < tx.vout.size(); ++i)
{
- destinations.push_back(rct::pk2rct(boost::get<txout_to_key>(tx.vout[i].target).key));
+ crypto::public_key output_public_key;
+ get_output_public_key(tx.vout[i], output_public_key);
+ destinations.push_back(rct::pk2rct(output_public_key));
outamounts.push_back(tx.vout[i].amount);
amount_out += tx.vout[i].amount;
}
@@ -607,7 +613,7 @@ namespace cryptonote
return true;
}
//---------------------------------------------------------------
- bool construct_tx_and_get_tx_key(const account_keys& sender_account_keys, const std::unordered_map<crypto::public_key, subaddress_index>& subaddresses, std::vector<tx_source_entry>& sources, std::vector<tx_destination_entry>& destinations, const boost::optional<cryptonote::account_public_address>& change_addr, const std::vector<uint8_t> &extra, transaction& tx, uint64_t unlock_time, crypto::secret_key &tx_key, std::vector<crypto::secret_key> &additional_tx_keys, bool rct, const rct::RCTConfig &rct_config, rct::multisig_out *msout)
+ bool construct_tx_and_get_tx_key(const account_keys& sender_account_keys, const std::unordered_map<crypto::public_key, subaddress_index>& subaddresses, std::vector<tx_source_entry>& sources, std::vector<tx_destination_entry>& destinations, const boost::optional<cryptonote::account_public_address>& change_addr, const std::vector<uint8_t> &extra, transaction& tx, uint64_t unlock_time, crypto::secret_key &tx_key, std::vector<crypto::secret_key> &additional_tx_keys, bool rct, const rct::RCTConfig &rct_config, rct::multisig_out *msout, bool use_view_tags)
{
hw::device &hwdev = sender_account_keys.get_device();
hwdev.open_tx(tx_key);
@@ -627,7 +633,8 @@ namespace cryptonote
}
}
- bool r = construct_tx_with_tx_key(sender_account_keys, subaddresses, sources, destinations, change_addr, extra, tx, unlock_time, tx_key, additional_tx_keys, rct, rct_config, msout);
+ bool shuffle_outs = true;
+ bool r = construct_tx_with_tx_key(sender_account_keys, subaddresses, sources, destinations, change_addr, extra, tx, unlock_time, tx_key, additional_tx_keys, rct, rct_config, msout, shuffle_outs, use_view_tags);
hwdev.close_tx();
return r;
} catch(...) {
@@ -643,7 +650,7 @@ namespace cryptonote
crypto::secret_key tx_key;
std::vector<crypto::secret_key> additional_tx_keys;
std::vector<tx_destination_entry> destinations_copy = destinations;
- return construct_tx_and_get_tx_key(sender_account_keys, subaddresses, sources, destinations_copy, change_addr, extra, tx, unlock_time, tx_key, additional_tx_keys, false, { rct::RangeProofBorromean, 0}, NULL);
+ return construct_tx_and_get_tx_key(sender_account_keys, subaddresses, sources, destinations_copy, change_addr, extra, tx, unlock_time, tx_key, additional_tx_keys, false, { rct::RangeProofBorromean, 0}, NULL, false);
}
//---------------------------------------------------------------
bool generate_genesis_block(
diff --git a/src/cryptonote_core/cryptonote_tx_utils.h b/src/cryptonote_core/cryptonote_tx_utils.h
index be6a6d946..f4ffb98ff 100644
--- a/src/cryptonote_core/cryptonote_tx_utils.h
+++ b/src/cryptonote_core/cryptonote_tx_utils.h
@@ -119,21 +119,23 @@ namespace cryptonote
//---------------------------------------------------------------
crypto::public_key get_destination_view_key_pub(const std::vector<tx_destination_entry> &destinations, const boost::optional<cryptonote::account_public_address>& change_addr);
bool construct_tx(const account_keys& sender_account_keys, std::vector<tx_source_entry> &sources, const std::vector<tx_destination_entry>& destinations, const boost::optional<cryptonote::account_public_address>& change_addr, const std::vector<uint8_t> &extra, transaction& tx, uint64_t unlock_time);
- bool construct_tx_with_tx_key(const account_keys& sender_account_keys, const std::unordered_map<crypto::public_key, subaddress_index>& subaddresses, std::vector<tx_source_entry>& sources, std::vector<tx_destination_entry>& destinations, const boost::optional<cryptonote::account_public_address>& change_addr, const std::vector<uint8_t> &extra, transaction& tx, uint64_t unlock_time, const crypto::secret_key &tx_key, const std::vector<crypto::secret_key> &additional_tx_keys, bool rct = false, const rct::RCTConfig &rct_config = { rct::RangeProofBorromean, 0 }, rct::multisig_out *msout = NULL, bool shuffle_outs = true);
- bool construct_tx_and_get_tx_key(const account_keys& sender_account_keys, const std::unordered_map<crypto::public_key, subaddress_index>& subaddresses, std::vector<tx_source_entry>& sources, std::vector<tx_destination_entry>& destinations, const boost::optional<cryptonote::account_public_address>& change_addr, const std::vector<uint8_t> &extra, transaction& tx, uint64_t unlock_time, crypto::secret_key &tx_key, std::vector<crypto::secret_key> &additional_tx_keys, bool rct = false, const rct::RCTConfig &rct_config = { rct::RangeProofBorromean, 0 }, rct::multisig_out *msout = NULL);
+ 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, bool use_view_tags = false);
+ bool construct_tx_and_get_tx_key(const account_keys& sender_account_keys, const std::unordered_map<crypto::public_key, subaddress_index>& subaddresses, std::vector<tx_source_entry>& sources, std::vector<tx_destination_entry>& destinations, const boost::optional<cryptonote::account_public_address>& change_addr, const std::vector<uint8_t> &extra, transaction& tx, uint64_t unlock_time, crypto::secret_key &tx_key, std::vector<crypto::secret_key> &additional_tx_keys, bool rct = false, const rct::RCTConfig &rct_config = { rct::RangeProofBorromean, 0 }, rct::multisig_out *msout = NULL, bool use_view_tags = false);
bool generate_output_ephemeral_keys(const size_t tx_version, const cryptonote::account_keys &sender_account_keys, const crypto::public_key &txkey_pub, const crypto::secret_key &tx_key,
const cryptonote::tx_destination_entry &dst_entr, const boost::optional<cryptonote::account_public_address> &change_addr, const size_t output_index,
const bool &need_additional_txkeys, const std::vector<crypto::secret_key> &additional_tx_keys,
std::vector<crypto::public_key> &additional_tx_public_keys,
std::vector<rct::key> &amount_keys,
- crypto::public_key &out_eph_public_key) ;
+ crypto::public_key &out_eph_public_key,
+ const bool use_view_tags, crypto::view_tag &view_tag) ;
bool generate_output_ephemeral_keys(const size_t tx_version, const cryptonote::account_keys &sender_account_keys, const crypto::public_key &txkey_pub, const crypto::secret_key &tx_key,
const cryptonote::tx_destination_entry &dst_entr, const boost::optional<cryptonote::account_public_address> &change_addr, const size_t output_index,
const bool &need_additional_txkeys, const std::vector<crypto::secret_key> &additional_tx_keys,
std::vector<crypto::public_key> &additional_tx_public_keys,
std::vector<rct::key> &amount_keys,
- crypto::public_key &out_eph_public_key) ;
+ crypto::public_key &out_eph_public_key,
+ const bool use_view_tags, crypto::view_tag &view_tag) ;
bool generate_genesis_block(
block& bl
diff --git a/src/cryptonote_protocol/cryptonote_protocol_handler-base.cpp b/src/cryptonote_protocol/cryptonote_protocol_handler-base.cpp
index 4c21de7a5..92ee08054 100644
--- a/src/cryptonote_protocol/cryptonote_protocol_handler-base.cpp
+++ b/src/cryptonote_protocol/cryptonote_protocol_handler-base.cpp
@@ -43,7 +43,6 @@
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/thread/thread.hpp>
#include "misc_language.h"
-#include "pragma_comp_defs.h"
#include <algorithm>
diff --git a/src/daemon/CMakeLists.txt b/src/daemon/CMakeLists.txt
index b81d7c857..455f72472 100644
--- a/src/daemon/CMakeLists.txt
+++ b/src/daemon/CMakeLists.txt
@@ -37,30 +37,7 @@ set(daemon_sources
set(daemon_headers)
-set(daemon_private_headers
- command_parser_executor.h
- command_server.h
- core.h
- daemon.h
- executor.h
- p2p.h
- protocol.h
- rpc.h
- rpc_command_executor.h
-
- # cryptonote_protocol
- ../cryptonote_protocol/cryptonote_protocol_defs.h
- ../cryptonote_protocol/cryptonote_protocol_handler.h
- ../cryptonote_protocol/cryptonote_protocol_handler.inl
- ../cryptonote_protocol/cryptonote_protocol_handler_common.h
-
- # p2p
- ../p2p/net_node.h
- ../p2p/net_node_common.h
- ../p2p/net_peerlist.h
- ../p2p/net_peerlist_boost_serialization.h
- ../p2p/p2p_protocol_defs.h
- ../p2p/stdafx.h)
+monero_find_all_headers(daemon_private_headers "${CMAKE_CURRENT_SOURCE_DIR}")
monero_private_headers(daemon
${daemon_private_headers})
diff --git a/src/daemon/command_parser_executor.h b/src/daemon/command_parser_executor.h
index ac95c3afc..cd9e6544e 100644
--- a/src/daemon/command_parser_executor.h
+++ b/src/daemon/command_parser_executor.h
@@ -40,7 +40,6 @@
#include "daemon/rpc_command_executor.h"
#include "common/common_fwd.h"
-#include "net/net_fwd.h"
#include "rpc/core_rpc_server.h"
namespace daemonize {
diff --git a/src/daemon/command_server.h b/src/daemon/command_server.h
index 113f99cbc..babb8e85a 100644
--- a/src/daemon/command_server.h
+++ b/src/daemon/command_server.h
@@ -43,7 +43,6 @@ Passing RPC commands:
#include "common/common_fwd.h"
#include "console_handler.h"
#include "daemon/command_parser_executor.h"
-#include "net/net_fwd.h"
namespace daemonize {
diff --git a/src/daemon/rpc_command_executor.h b/src/daemon/rpc_command_executor.h
index 8cbb59716..ebd7eda85 100644
--- a/src/daemon/rpc_command_executor.h
+++ b/src/daemon/rpc_command_executor.h
@@ -43,7 +43,6 @@
#include "common/common_fwd.h"
#include "common/rpc_client.h"
#include "cryptonote_basic/cryptonote_basic.h"
-#include "net/net_fwd.h"
#include "rpc/core_rpc_server.h"
#undef MONERO_DEFAULT_LOG_CATEGORY
diff --git a/src/device/device.hpp b/src/device/device.hpp
index ba47115e7..eca91006f 100644
--- a/src/device/device.hpp
+++ b/src/device/device.hpp
@@ -222,7 +222,8 @@ namespace hw {
const bool &need_additional_txkeys, const std::vector<crypto::secret_key> &additional_tx_keys,
std::vector<crypto::public_key> &additional_tx_public_keys,
std::vector<rct::key> &amount_keys,
- crypto::public_key &out_eph_public_key) = 0;
+ crypto::public_key &out_eph_public_key,
+ const bool use_view_tags, crypto::view_tag &view_tag) = 0;
virtual bool mlsag_prehash(const std::string &blob, size_t inputs_size, size_t outputs_size, const rct::keyV &hashes, const rct::ctkeyV &outPk, rct::key &prehash) = 0;
virtual bool mlsag_prepare(const rct::key &H, const rct::key &xx, rct::key &a, rct::key &aG, rct::key &aHP, rct::key &rvII) = 0;
diff --git a/src/device/device_default.cpp b/src/device/device_default.cpp
index e7b452d40..d70ece229 100644
--- a/src/device/device_default.cpp
+++ b/src/device/device_default.cpp
@@ -263,6 +263,11 @@ namespace hw {
return true;
}
+ bool device_default::derive_view_tag(const crypto::key_derivation &derivation, const std::size_t output_index, crypto::view_tag &view_tag) {
+ crypto::derive_view_tag(derivation, output_index, view_tag);
+ return true;
+ }
+
bool device_default::conceal_derivation(crypto::key_derivation &derivation, const crypto::public_key &tx_pub_key, const std::vector<crypto::public_key> &additional_tx_pub_keys, const crypto::key_derivation &main_derivation, const std::vector<crypto::key_derivation> &additional_derivations){
return true;
}
@@ -291,7 +296,8 @@ namespace hw {
const cryptonote::tx_destination_entry &dst_entr, const boost::optional<cryptonote::account_public_address> &change_addr, const size_t output_index,
const bool &need_additional_txkeys, const std::vector<crypto::secret_key> &additional_tx_keys,
std::vector<crypto::public_key> &additional_tx_public_keys,
- std::vector<rct::key> &amount_keys, crypto::public_key &out_eph_public_key) {
+ std::vector<rct::key> &amount_keys, crypto::public_key &out_eph_public_key,
+ const bool use_view_tags, crypto::view_tag &view_tag) {
crypto::key_derivation derivation;
@@ -331,6 +337,12 @@ namespace hw {
derivation_to_scalar(derivation, output_index, scalar1);
amount_keys.push_back(rct::sk2rct(scalar1));
}
+
+ if (use_view_tags)
+ {
+ derive_view_tag(derivation, output_index, view_tag);
+ }
+
r = derive_public_key(derivation, output_index, dst_entr.addr.m_spend_public_key, out_eph_public_key);
CHECK_AND_ASSERT_MES(r, false, "at creation outs: failed to derive_public_key(" << derivation << ", " << output_index << ", "<< dst_entr.addr.m_spend_public_key << ")");
diff --git a/src/device/device_default.hpp b/src/device/device_default.hpp
index 60d2ba203..7d3543652 100644
--- a/src/device/device_default.hpp
+++ b/src/device/device_default.hpp
@@ -101,6 +101,7 @@ namespace hw {
bool derive_public_key(const crypto::key_derivation &derivation, const std::size_t output_index, const crypto::public_key &pub, crypto::public_key &derived_pub) override;
bool secret_key_to_public_key(const crypto::secret_key &sec, crypto::public_key &pub) override;
bool generate_key_image(const crypto::public_key &pub, const crypto::secret_key &sec, crypto::key_image &image) override;
+ bool derive_view_tag(const crypto::key_derivation &derivation, const std::size_t output_index, crypto::view_tag &view_tag);
/* ======================================================================= */
@@ -126,7 +127,8 @@ namespace hw {
const bool &need_additional_txkeys, const std::vector<crypto::secret_key> &additional_tx_keys,
std::vector<crypto::public_key> &additional_tx_public_keys,
std::vector<rct::key> &amount_keys,
- crypto::public_key &out_eph_public_key) override;
+ crypto::public_key &out_eph_public_key,
+ bool use_view_tags, crypto::view_tag &view_tag) override;
bool mlsag_prehash(const std::string &blob, size_t inputs_size, size_t outputs_size, const rct::keyV &hashes, const rct::ctkeyV &outPk, rct::key &prehash) override;
bool mlsag_prepare(const rct::key &H, const rct::key &xx, rct::key &a, rct::key &aG, rct::key &aHP, rct::key &rvII) override;
diff --git a/src/device/device_ledger.cpp b/src/device/device_ledger.cpp
index 378d9f533..51e65dfa5 100644
--- a/src/device/device_ledger.cpp
+++ b/src/device/device_ledger.cpp
@@ -524,6 +524,7 @@ namespace hw {
static const std::vector<hw::io::hid_conn_params> known_devices {
{0x2c97, 0x0001, 0, 0xffa0},
{0x2c97, 0x0004, 0, 0xffa0},
+ {0x2c97, 0x0005, 0, 0xffa0},
};
bool device_ledger::connect(void) {
@@ -1527,7 +1528,8 @@ namespace hw {
const bool &need_additional_txkeys, const std::vector<crypto::secret_key> &additional_tx_keys,
std::vector<crypto::public_key> &additional_tx_public_keys,
std::vector<rct::key> &amount_keys,
- crypto::public_key &out_eph_public_key) {
+ crypto::public_key &out_eph_public_key,
+ bool use_view_tags, crypto::view_tag &view_tag) {
AUTO_LOCK_CMD();
#ifdef DEBUG_HWDEVICE
@@ -1541,6 +1543,8 @@ namespace hw {
const boost::optional<cryptonote::account_public_address> change_addr_x = change_addr;
const size_t output_index_x = output_index;
const bool need_additional_txkeys_x = need_additional_txkeys;
+ const bool use_view_tags_x = use_view_tags;
+ const crypto::view_tag view_tag_x = view_tag;
std::vector<crypto::secret_key> additional_tx_keys_x;
for (const auto &k: additional_tx_keys) {
@@ -1568,7 +1572,7 @@ namespace hw {
log_hexbuffer("generate_output_ephemeral_keys: [[IN]] additional_tx_keys[oi]", additional_tx_keys_x[output_index].data, 32);
}
this->controle_device->generate_output_ephemeral_keys(tx_version_x, sender_account_keys_x, txkey_pub_x, tx_key_x, dst_entr_x, change_addr_x, output_index_x, need_additional_txkeys_x, additional_tx_keys_x,
- additional_tx_public_keys_x, amount_keys_x, out_eph_public_key_x);
+ additional_tx_public_keys_x, amount_keys_x, out_eph_public_key_x, use_view_tags_x, view_tag_x);
if(need_additional_txkeys_x) {
log_hexbuffer("additional_tx_public_keys_x: [[OUT]] additional_tx_public_keys_x", additional_tx_public_keys_x.back().data, 32);
}
diff --git a/src/device/device_ledger.hpp b/src/device/device_ledger.hpp
index 06521a56f..074bfaa8d 100644
--- a/src/device/device_ledger.hpp
+++ b/src/device/device_ledger.hpp
@@ -273,7 +273,8 @@ namespace hw {
const bool &need_additional_txkeys, const std::vector<crypto::secret_key> &additional_tx_keys,
std::vector<crypto::public_key> &additional_tx_public_keys,
std::vector<rct::key> &amount_keys,
- crypto::public_key &out_eph_public_key) override;
+ crypto::public_key &out_eph_public_key,
+ const bool use_view_tags, crypto::view_tag &view_tag) override;
bool mlsag_prehash(const std::string &blob, size_t inputs_size, size_t outputs_size, const rct::keyV &hashes, const rct::ctkeyV &outPk, rct::key &prehash) override;
bool mlsag_prepare(const rct::key &H, const rct::key &xx, rct::key &a, rct::key &aG, rct::key &aHP, rct::key &rvII) override;
diff --git a/src/device_trezor/trezor/protocol.cpp b/src/device_trezor/trezor/protocol.cpp
index 31a242604..a400e82c7 100644
--- a/src/device_trezor/trezor/protocol.cpp
+++ b/src/device_trezor/trezor/protocol.cpp
@@ -154,8 +154,7 @@ namespace ki {
res.emplace_back();
auto & cres = res.back();
-
- cres.set_out_key(key_to_string(boost::get<cryptonote::txout_to_key>(td.m_tx.vout[td.m_internal_output_index].target).key));
+ cres.set_out_key(key_to_string(td.get_public_key()));
cres.set_tx_pub_key(key_to_string(tx_pub_key));
cres.set_internal_output_index(td.m_internal_output_index);
cres.set_sub_addr_major(td.m_subaddr_index.major);
diff --git a/src/hardforks/CMakeLists.txt b/src/hardforks/CMakeLists.txt
index 8ce6de021..81a3d694b 100644
--- a/src/hardforks/CMakeLists.txt
+++ b/src/hardforks/CMakeLists.txt
@@ -29,8 +29,7 @@
set(hardforks_sources
hardforks.cpp)
-set(hardforks_headers
- hardforks.h)
+monero_find_all_headers(hardforks_headers "${CMAKE_CURRENT_SOURCE_DIR}")
set(hardforks_private_headers)
diff --git a/src/lmdb/CMakeLists.txt b/src/lmdb/CMakeLists.txt
index e0a3de147..a26c48ad5 100644
--- a/src/lmdb/CMakeLists.txt
+++ b/src/lmdb/CMakeLists.txt
@@ -27,7 +27,7 @@
# THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
set(lmdb_sources database.cpp error.cpp table.cpp value_stream.cpp)
-set(lmdb_headers database.h error.h key_stream.h table.h transaction.h util.h value_stream.h)
+monero_find_all_headers(lmdb_headers "${CMAKE_CURRENT_SOURCE_DIR}")
monero_add_library(lmdb_lib ${lmdb_sources} ${lmdb_headers})
target_link_libraries(lmdb_lib common ${LMDB_LIBRARY})
diff --git a/src/mnemonics/CMakeLists.txt b/src/mnemonics/CMakeLists.txt
index d8d1072a7..738633ef5 100644
--- a/src/mnemonics/CMakeLists.txt
+++ b/src/mnemonics/CMakeLists.txt
@@ -31,23 +31,7 @@ set(mnemonics_sources
set(mnemonics_headers)
-set(mnemonics_private_headers
- electrum-words.h
- chinese_simplified.h
- english.h
- dutch.h
- french.h
- german.h
- italian.h
- japanese.h
- language_base.h
- english_old.h
- portuguese.h
- russian.h
- singleton.h
- spanish.h
- esperanto.h
- lojban.h)
+monero_find_all_headers(mnemonics_private_headers "${CMAKE_CURRENT_SOURCE_DIR}")
monero_private_headers(mnemonics
${mnemonics_private_headers})
diff --git a/src/multisig/CMakeLists.txt b/src/multisig/CMakeLists.txt
index 71b5c8e9b..294a1721f 100644
--- a/src/multisig/CMakeLists.txt
+++ b/src/multisig/CMakeLists.txt
@@ -34,10 +34,7 @@ set(multisig_sources
set(multisig_headers)
-set(multisig_private_headers
- multisig.h
- multisig_account.h
- multisig_kex_msg.h)
+monero_find_all_headers(multisig_private_headers "${CMAKE_CURRENT_SOURCE_DIR}")
monero_private_headers(multisig
${multisig_private_headers})
diff --git a/src/net/CMakeLists.txt b/src/net/CMakeLists.txt
index f4c24ab12..a4d31eedf 100644
--- a/src/net/CMakeLists.txt
+++ b/src/net/CMakeLists.txt
@@ -29,8 +29,7 @@
set(net_sources dandelionpp.cpp error.cpp http.cpp i2p_address.cpp parse.cpp resolve.cpp
socks.cpp socks_connect.cpp tor_address.cpp zmq.cpp)
-set(net_headers dandelionpp.h error.h http.cpp i2p_address.h parse.h socks.h resolve.h
- socks_connect.h tor_address.h zmq.h)
+monero_find_all_headers(net_headers "${CMAKE_CURRENT_SOURCE_DIR}")
monero_add_library(net ${net_sources} ${net_headers})
target_link_libraries(net common epee ${ZMQ_LIB} ${Boost_ASIO_LIBRARY})
diff --git a/src/p2p/net_node.inl b/src/p2p/net_node.inl
index 5c61ede3f..a3bc3bf24 100644
--- a/src/p2p/net_node.inl
+++ b/src/p2p/net_node.inl
@@ -55,7 +55,6 @@
#include "math_helper.h"
#include "misc_log_ex.h"
#include "p2p_protocol_defs.h"
-#include "net/local_ip.h"
#include "crypto/crypto.h"
#include "storages/levin_abstract_invoke2.h"
#include "cryptonote_core/cryptonote_core.h"
diff --git a/src/p2p/net_peerlist.h b/src/p2p/net_peerlist.h
index 2cb85d270..dc480462d 100644
--- a/src/p2p/net_peerlist.h
+++ b/src/p2p/net_peerlist.h
@@ -31,6 +31,7 @@
#pragma once
#include <iosfwd>
+#include <iterator>
#include <list>
#include <string>
#include <vector>
@@ -46,7 +47,6 @@
#include "crypto/crypto.h"
#include "cryptonote_config.h"
#include "net/enums.h"
-#include "net/local_ip.h"
#include "p2p_protocol_defs.h"
#include "syncobj.h"
@@ -184,6 +184,7 @@ namespace nodetool
private:
void trim_white_peerlist();
void trim_gray_peerlist();
+ static peerlist_entry get_nth_latest_peer(peers_indexed& peerlist, size_t n);
friend class boost::serialization::access;
epee::critical_section m_peerlist_lock;
@@ -214,6 +215,16 @@ namespace nodetool
}
}
//--------------------------------------------------------------------------------------------------
+ inline
+ peerlist_entry peerlist_manager::get_nth_latest_peer(peers_indexed& peerlist, const size_t n)
+ {
+ // Is not thread-safe nor does it check bounds. Do this before calling. Indexing starts at 0.
+ peers_indexed::index<by_time>::type& by_time_index = peerlist.get<by_time>();
+ auto by_time_it = --by_time_index.end();
+ std::advance(by_time_it, -static_cast<long long>(n));
+ return *by_time_it;
+ }
+ //--------------------------------------------------------------------------------------------------
inline
bool peerlist_manager::merge_peerlist(const std::vector<peerlist_entry>& outer_bs, const std::function<bool(const peerlist_entry&)> &f)
{
@@ -235,8 +246,7 @@ namespace nodetool
if(i >= m_peers_white.size())
return false;
- peers_indexed::index<by_time>::type& by_time_index = m_peers_white.get<by_time>();
- p = *epee::misc_utils::move_it_backward(--by_time_index.end(), i);
+ p = peerlist_manager::get_nth_latest_peer(m_peers_white, i);
return true;
}
//--------------------------------------------------------------------------------------------------
@@ -247,8 +257,7 @@ namespace nodetool
if(i >= m_peers_gray.size())
return false;
- peers_indexed::index<by_time>::type& by_time_index = m_peers_gray.get<by_time>();
- p = *epee::misc_utils::move_it_backward(--by_time_index.end(), i);
+ p = peerlist_manager::get_nth_latest_peer(m_peers_gray, i);
return true;
}
//--------------------------------------------------------------------------------------------------
@@ -437,9 +446,7 @@ namespace nodetool
}
size_t random_index = crypto::rand_idx(m_peers_gray.size());
-
- peers_indexed::index<by_time>::type& by_time_index = m_peers_gray.get<by_time>();
- pe = *epee::misc_utils::move_it_backward(--by_time_index.end(), random_index);
+ pe = peerlist_manager::get_nth_latest_peer(m_peers_gray, random_index);
return true;
diff --git a/src/p2p/p2p_protocol_defs.h b/src/p2p/p2p_protocol_defs.h
index fbeef6e62..8b9cd0f09 100644
--- a/src/p2p/p2p_protocol_defs.h
+++ b/src/p2p/p2p_protocol_defs.h
@@ -30,6 +30,7 @@
#pragma once
+#include <iomanip>
#include <boost/uuid/uuid.hpp>
#include <boost/serialization/version.hpp>
#include "serialization/keyvalue_serialization.h"
diff --git a/src/ringct/CMakeLists.txt b/src/ringct/CMakeLists.txt
index 1824c189f..d415e6409 100644
--- a/src/ringct/CMakeLists.txt
+++ b/src/ringct/CMakeLists.txt
@@ -34,12 +34,7 @@ set(ringct_basic_sources
bulletproofs.cc
bulletproofs_plus.cc)
-set(ringct_basic_private_headers
- rctOps.h
- rctTypes.h
- multiexp.h
- bulletproofs.h
- bulletproofs_plus.h)
+monero_find_all_headers(ringct_basic_private_headers "${CMAKE_CURRENT_SOURCE_DIR}")
monero_private_headers(ringct_basic
${crypto_private_headers})
diff --git a/src/rpc/core_rpc_server.cpp b/src/rpc/core_rpc_server.cpp
index d23d5cddb..bbcfa6168 100644
--- a/src/rpc/core_rpc_server.cpp
+++ b/src/rpc/core_rpc_server.cpp
@@ -48,6 +48,7 @@ using namespace epee;
#include "cryptonote_basic/merge_mining.h"
#include "cryptonote_core/tx_sanity_check.h"
#include "misc_language.h"
+#include "net/local_ip.h"
#include "net/parse.h"
#include "storages/http_abstract_invoke.h"
#include "crypto/hash.h"
@@ -2890,7 +2891,17 @@ namespace cryptonote
return r;
CHECK_PAYMENT(req, res, COST_PER_FEE_ESTIMATE);
- res.fee = m_core.get_blockchain_storage().get_dynamic_base_fee_estimate(req.grace_blocks);
+
+ const uint8_t version = m_core.get_blockchain_storage().get_current_hard_fork_version();
+ if (version >= HF_VERSION_2021_SCALING)
+ {
+ m_core.get_blockchain_storage().get_dynamic_base_fee_estimate_2021_scaling(req.grace_blocks, res.fees);
+ res.fee = res.fees[0];
+ }
+ else
+ {
+ res.fee = m_core.get_blockchain_storage().get_dynamic_base_fee_estimate(req.grace_blocks);
+ }
res.quantization_mask = Blockchain::get_fee_quantization_mask();
res.status = CORE_RPC_STATUS_OK;
return true;
diff --git a/src/rpc/core_rpc_server_commands_defs.h b/src/rpc/core_rpc_server_commands_defs.h
index 9206b5e21..1be2610ff 100644
--- a/src/rpc/core_rpc_server_commands_defs.h
+++ b/src/rpc/core_rpc_server_commands_defs.h
@@ -2191,11 +2191,13 @@ namespace cryptonote
{
uint64_t fee;
uint64_t quantization_mask;
+ std::vector<uint64_t> fees;
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE_PARENT(rpc_access_response_base)
KV_SERIALIZE(fee)
KV_SERIALIZE_OPT(quantization_mask, (uint64_t)1)
+ KV_SERIALIZE(fees)
END_KV_SERIALIZE_MAP()
};
typedef epee::misc_utils::struct_init<response_t> response;
diff --git a/src/serialization/CMakeLists.txt b/src/serialization/CMakeLists.txt
index f1fd9a31c..d3b9e57ca 100644
--- a/src/serialization/CMakeLists.txt
+++ b/src/serialization/CMakeLists.txt
@@ -31,8 +31,7 @@ set(serialization_sources
set(serialization_headers)
-set(serialization_private_headers
- json_object.h)
+monero_find_all_headers(serialization_private_headers "${CMAKE_CURRENT_SOURCE_DIR}")
monero_private_headers(serialization
${serialization_private_headers})
diff --git a/src/serialization/crypto.h b/src/serialization/crypto.h
index 7be04c910..c2a4846ee 100644
--- a/src/serialization/crypto.h
+++ b/src/serialization/crypto.h
@@ -85,6 +85,7 @@ BLOB_SERIALIZER(crypto::secret_key);
BLOB_SERIALIZER(crypto::key_derivation);
BLOB_SERIALIZER(crypto::key_image);
BLOB_SERIALIZER(crypto::signature);
+BLOB_SERIALIZER(crypto::view_tag);
VARIANT_TAG(debug_archive, crypto::hash, "hash");
VARIANT_TAG(debug_archive, crypto::hash8, "hash8");
VARIANT_TAG(debug_archive, crypto::public_key, "public_key");
@@ -92,4 +93,5 @@ VARIANT_TAG(debug_archive, crypto::secret_key, "secret_key");
VARIANT_TAG(debug_archive, crypto::key_derivation, "key_derivation");
VARIANT_TAG(debug_archive, crypto::key_image, "key_image");
VARIANT_TAG(debug_archive, crypto::signature, "signature");
+VARIANT_TAG(debug_archive, crypto::view_tag, "view_tag");
diff --git a/src/serialization/json_object.cpp b/src/serialization/json_object.cpp
index e98e327e5..8de5860f6 100644
--- a/src/serialization/json_object.cpp
+++ b/src/serialization/json_object.cpp
@@ -563,6 +563,27 @@ void fromJsonValue(const rapidjson::Value& val, cryptonote::txout_to_key& txout)
GET_FROM_JSON_OBJECT(val, txout.key, key);
}
+void toJsonValue(rapidjson::Writer<epee::byte_stream>& dest, const cryptonote::txout_to_tagged_key& txout)
+{
+ dest.StartObject();
+
+ INSERT_INTO_JSON_OBJECT(dest, key, txout.key);
+ INSERT_INTO_JSON_OBJECT(dest, view_tag, txout.view_tag);
+
+ dest.EndObject();
+}
+
+void fromJsonValue(const rapidjson::Value& val, cryptonote::txout_to_tagged_key& txout)
+{
+ if (!val.IsObject())
+ {
+ throw WRONG_TYPE("json object");
+ }
+
+ GET_FROM_JSON_OBJECT(val, txout.key, key);
+ GET_FROM_JSON_OBJECT(val, txout.view_tag, view_tag);
+}
+
void toJsonValue(rapidjson::Writer<epee::byte_stream>& dest, const cryptonote::tx_out& txout)
{
dest.StartObject();
@@ -578,6 +599,10 @@ void toJsonValue(rapidjson::Writer<epee::byte_stream>& dest, const cryptonote::t
{
INSERT_INTO_JSON_OBJECT(dest, to_key, output);
}
+ void operator()(cryptonote::txout_to_tagged_key const& output) const
+ {
+ INSERT_INTO_JSON_OBJECT(dest, to_tagged_key, output);
+ }
void operator()(cryptonote::txout_to_script const& output) const
{
INSERT_INTO_JSON_OBJECT(dest, to_script, output);
@@ -616,6 +641,12 @@ void fromJsonValue(const rapidjson::Value& val, cryptonote::tx_out& txout)
fromJsonValue(elem.value, tmpVal);
txout.target = std::move(tmpVal);
}
+ else if (elem.name == "to_tagged_key")
+ {
+ cryptonote::txout_to_tagged_key tmpVal;
+ fromJsonValue(elem.value, tmpVal);
+ txout.target = std::move(tmpVal);
+ }
else if (elem.name == "to_script")
{
cryptonote::txout_to_script tmpVal;
diff --git a/src/serialization/json_object.h b/src/serialization/json_object.h
index e7caa8377..968707165 100644
--- a/src/serialization/json_object.h
+++ b/src/serialization/json_object.h
@@ -230,6 +230,9 @@ void fromJsonValue(const rapidjson::Value& val, cryptonote::txout_to_scripthash&
void toJsonValue(rapidjson::Writer<epee::byte_stream>& dest, const cryptonote::txout_to_key& txout);
void fromJsonValue(const rapidjson::Value& val, cryptonote::txout_to_key& txout);
+void toJsonValue(rapidjson::Writer<epee::byte_stream>& dest, const cryptonote::txout_to_tagged_key& txout);
+void fromJsonValue(const rapidjson::Value& val, cryptonote::txout_to_tagged_key& txout);
+
void toJsonValue(rapidjson::Writer<epee::byte_stream>& dest, const cryptonote::tx_out& txout);
void fromJsonValue(const rapidjson::Value& val, cryptonote::tx_out& txout);
diff --git a/src/simplewallet/CMakeLists.txt b/src/simplewallet/CMakeLists.txt
index efec8a6f0..b659d9f48 100644
--- a/src/simplewallet/CMakeLists.txt
+++ b/src/simplewallet/CMakeLists.txt
@@ -31,8 +31,7 @@ set(simplewallet_sources
set(simplewallet_headers)
-set(simplewallet_private_headers
- simplewallet.h)
+monero_find_all_headers(simplewallet_private_headers "${CMAKE_CURRENT_SOURCE_DIR}")
monero_private_headers(simplewallet
${simplewallet_private_headers})
diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp
index 38cf6f757..f30225e1d 100644
--- a/src/simplewallet/simplewallet.cpp
+++ b/src/simplewallet/simplewallet.cpp
@@ -99,10 +99,6 @@ typedef cryptonote::simple_wallet sw;
#define EXTENDED_LOGS_FILE "wallet_details.log"
-#define DEFAULT_MIX 10
-
-#define MIN_RING_SIZE 11 // Used to inform user about min ring size -- does not track actual protocol
-
#define OLD_AGE_WARN_THRESHOLD (30 * 86400 / DIFFICULTY_TARGET_V2) // 30 days
#define LOCK_IDLE_SCOPE() \
@@ -2472,59 +2468,6 @@ bool simple_wallet::set_store_tx_info(const std::vector<std::string> &args/* = s
return true;
}
-bool simple_wallet::set_default_ring_size(const std::vector<std::string> &args/* = std::vector<std::string>()*/)
-{
- if (m_wallet->watch_only())
- {
- fail_msg_writer() << tr("wallet is watch-only and cannot transfer");
- return true;
- }
- try
- {
- if (strchr(args[1].c_str(), '-'))
- {
- fail_msg_writer() << tr("ring size must be an integer >= ") << MIN_RING_SIZE;
- return true;
- }
- uint32_t ring_size = boost::lexical_cast<uint32_t>(args[1]);
- if (ring_size < MIN_RING_SIZE && ring_size != 0)
- {
- fail_msg_writer() << tr("ring size must be an integer >= ") << MIN_RING_SIZE;
- return true;
- }
-
- if (ring_size != 0 && ring_size != DEFAULT_MIX+1)
- {
- if (m_wallet->use_fork_rules(8, 0))
- {
- message_writer() << tr("WARNING: from v8, ring size will be fixed and this setting will be ignored.");
- }
- else
- {
- message_writer() << tr("WARNING: this is a non default ring size, which may harm your privacy. Default is recommended.");
- }
- }
-
- const auto pwd_container = get_and_verify_password();
- if (pwd_container)
- {
- m_wallet->default_mixin(ring_size > 0 ? ring_size - 1 : 0);
- m_wallet->rewrite(m_wallet_file, pwd_container->password());
- }
- return true;
- }
- catch(const boost::bad_lexical_cast &)
- {
- fail_msg_writer() << tr("ring size must be an integer >= ") << MIN_RING_SIZE;
- return true;
- }
- catch(...)
- {
- fail_msg_writer() << tr("could not change default ring size");
- return true;
- }
-}
-
bool simple_wallet::set_default_priority(const std::vector<std::string> &args/* = std::vector<std::string>()*/)
{
uint32_t priority = 0;
@@ -3386,8 +3329,6 @@ simple_wallet::simple_wallet()
" Whether to print detailed information about ring members during confirmation.\n "
"store-tx-info <1|0>\n "
" Whether to store outgoing tx info (destination address, payment ID, tx secret key) for future reference.\n "
- "default-ring-size <n>\n "
- " Set the default ring size (obsolete).\n "
"auto-refresh <1|0>\n "
" Whether to automatically synchronize new blocks from the daemon.\n "
"refresh-type <full|optimize-coinbase|no-coinbase|default>\n "
@@ -3896,7 +3837,6 @@ bool simple_wallet::set_variable(const std::vector<std::string> &args)
CHECK_SIMPLE_VARIABLE("always-confirm-transfers", set_always_confirm_transfers, tr("0 or 1"));
CHECK_SIMPLE_VARIABLE("print-ring-members", set_print_ring_members, tr("0 or 1"));
CHECK_SIMPLE_VARIABLE("store-tx-info", set_store_tx_info, tr("0 or 1"));
- 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, or one of ") << join_priority_strings(", "));
@@ -6539,7 +6479,8 @@ bool simple_wallet::transfer_main(int transfer_type, const std::vector<std::stri
priority = m_wallet->adjust_priority(priority);
- size_t fake_outs_count = DEFAULT_MIX;
+ const size_t min_ring_size = m_wallet->get_min_ring_size();
+ size_t fake_outs_count = min_ring_size - 1;
if(local_args.size() > 0) {
size_t ring_size;
if(!epee::string_tools::get_xtype_from_string(ring_size, local_args[0]))
@@ -6862,7 +6803,7 @@ bool simple_wallet::transfer_main(int transfer_type, const std::vector<std::stri
if (vin.type() == typeid(txin_to_key))
{
const txin_to_key& in_to_key = boost::get<txin_to_key>(vin);
- if (in_to_key.key_offsets.size() != DEFAULT_MIX + 1)
+ if (in_to_key.key_offsets.size() != min_ring_size)
default_ring_size = false;
}
}
@@ -7140,7 +7081,7 @@ bool simple_wallet::sweep_main(uint32_t account, uint64_t below, bool locked, co
priority = m_wallet->adjust_priority(priority);
- size_t fake_outs_count = DEFAULT_MIX;
+ size_t fake_outs_count = m_wallet->get_min_ring_size() - 1;
if(local_args.size() > 0) {
size_t ring_size;
if(!epee::string_tools::get_xtype_from_string(ring_size, local_args[0]))
@@ -7417,7 +7358,7 @@ bool simple_wallet::sweep_single(const std::vector<std::string> &args_)
priority = m_wallet->adjust_priority(priority);
- size_t fake_outs_count = DEFAULT_MIX;
+ size_t fake_outs_count = m_wallet->get_min_ring_size() - 1;
if(local_args.size() > 0) {
size_t ring_size;
if(!epee::string_tools::get_xtype_from_string(ring_size, local_args[0]))
@@ -9820,7 +9761,7 @@ bool simple_wallet::print_integrated_address(const std::vector<std::string> &arg
{
if (info.has_payment_id)
{
- success_msg_writer() << boost::format(tr("Integrated address: %s, payment ID: %s")) %
+ success_msg_writer() << boost::format(tr("Standard address: %s, payment ID: %s")) %
get_account_address_as_str(m_wallet->nettype(), false, info.address) % epee::string_tools::pod_to_hex(info.payment_id);
device_show_integrated(info.payment_id);
}
diff --git a/src/simplewallet/simplewallet.h b/src/simplewallet/simplewallet.h
index 473120eac..4c005c53a 100644
--- a/src/simplewallet/simplewallet.h
+++ b/src/simplewallet/simplewallet.h
@@ -125,7 +125,6 @@ namespace cryptonote
bool set_always_confirm_transfers(const std::vector<std::string> &args = std::vector<std::string>());
bool set_print_ring_members(const std::vector<std::string> &args = std::vector<std::string>());
bool set_store_tx_info(const std::vector<std::string> &args = std::vector<std::string>());
- bool set_default_ring_size(const std::vector<std::string> &args = std::vector<std::string>());
bool set_auto_refresh(const std::vector<std::string> &args = std::vector<std::string>());
bool set_refresh_type(const std::vector<std::string> &args = std::vector<std::string>());
bool set_confirm_missing_payment_id(const std::vector<std::string> &args = std::vector<std::string>());
diff --git a/src/wallet/api/wallet.cpp b/src/wallet/api/wallet.cpp
index 014aed0e7..7cd8656e1 100644
--- a/src/wallet/api/wallet.cpp
+++ b/src/wallet/api/wallet.cpp
@@ -1743,8 +1743,8 @@ uint64_t WalletImpl::estimateTransactionFee(const std::vector<std::pair<std::str
m_wallet->use_fork_rules(8, 0),
m_wallet->use_fork_rules(HF_VERSION_CLSAG, 0),
m_wallet->use_fork_rules(HF_VERSION_BULLETPROOF_PLUS, 0),
+ m_wallet->use_fork_rules(HF_VERSION_VIEW_TAGS, 0),
m_wallet->get_base_fee(),
- m_wallet->get_fee_multiplier(m_wallet->adjust_priority(static_cast<uint32_t>(priority))),
m_wallet->get_fee_quantization_mask());
}
diff --git a/src/wallet/node_rpc_proxy.cpp b/src/wallet/node_rpc_proxy.cpp
index 7635c5646..7810abdd2 100644
--- a/src/wallet/node_rpc_proxy.cpp
+++ b/src/wallet/node_rpc_proxy.cpp
@@ -70,6 +70,7 @@ void NodeRPCProxy::invalidate()
m_dynamic_base_fee_estimate = 0;
m_dynamic_base_fee_estimate_cached_height = 0;
m_dynamic_base_fee_estimate_grace_blocks = 0;
+ m_dynamic_base_fee_estimate_vector.clear();
m_fee_quantization_mask = 1;
m_rpc_version = 0;
m_target_height = 0;
@@ -210,7 +211,7 @@ boost::optional<std::string> NodeRPCProxy::get_earliest_height(uint8_t version,
return boost::optional<std::string>();
}
-boost::optional<std::string> NodeRPCProxy::get_dynamic_base_fee_estimate(uint64_t grace_blocks, uint64_t &fee)
+boost::optional<std::string> NodeRPCProxy::get_dynamic_base_fee_estimate_2021_scaling(uint64_t grace_blocks, std::vector<uint64_t> &fees)
{
uint64_t height;
@@ -238,13 +239,24 @@ boost::optional<std::string> NodeRPCProxy::get_dynamic_base_fee_estimate(uint64_
m_dynamic_base_fee_estimate = resp_t.fee;
m_dynamic_base_fee_estimate_cached_height = height;
m_dynamic_base_fee_estimate_grace_blocks = grace_blocks;
+ m_dynamic_base_fee_estimate_vector = !resp_t.fees.empty() ? std::move(resp_t.fees) : std::vector<uint64_t>{m_dynamic_base_fee_estimate};
m_fee_quantization_mask = resp_t.quantization_mask;
}
- fee = m_dynamic_base_fee_estimate;
+ fees = m_dynamic_base_fee_estimate_vector;
return boost::optional<std::string>();
}
+boost::optional<std::string> NodeRPCProxy::get_dynamic_base_fee_estimate(uint64_t grace_blocks, uint64_t &fee)
+{
+ std::vector<uint64_t> fees;
+ auto res = get_dynamic_base_fee_estimate_2021_scaling(grace_blocks, fees);
+ if (res)
+ return res;
+ fee = fees[0];
+ return boost::none;
+}
+
boost::optional<std::string> NodeRPCProxy::get_fee_quantization_mask(uint64_t &fee_quantization_mask)
{
uint64_t height;
diff --git a/src/wallet/node_rpc_proxy.h b/src/wallet/node_rpc_proxy.h
index 20f4263a6..07675cdb0 100644
--- a/src/wallet/node_rpc_proxy.h
+++ b/src/wallet/node_rpc_proxy.h
@@ -56,6 +56,7 @@ public:
boost::optional<std::string> get_adjusted_time(uint64_t &adjusted_time);
boost::optional<std::string> get_earliest_height(uint8_t version, uint64_t &earliest_height);
boost::optional<std::string> get_dynamic_base_fee_estimate(uint64_t grace_blocks, uint64_t &fee);
+ boost::optional<std::string> get_dynamic_base_fee_estimate_2021_scaling(uint64_t grace_blocks, std::vector<uint64_t> &fees);
boost::optional<std::string> get_fee_quantization_mask(uint64_t &fee_quantization_mask);
boost::optional<std::string> get_rpc_payment_info(bool mining, bool &payment_required, uint64_t &credits, uint64_t &diff, uint64_t &credits_per_hash_found, cryptonote::blobdata &blob, uint64_t &height, uint64_t &seed_height, crypto::hash &seed_hash, crypto::hash &next_seed_hash, uint32_t &cookie);
@@ -85,6 +86,7 @@ private:
uint64_t m_dynamic_base_fee_estimate;
uint64_t m_dynamic_base_fee_estimate_cached_height;
uint64_t m_dynamic_base_fee_estimate_grace_blocks;
+ std::vector<uint64_t> m_dynamic_base_fee_estimate_vector;
uint64_t m_fee_quantization_mask;
uint64_t m_adjusted_time;
uint32_t m_rpc_version;
diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp
index a53a1b615..f0b29b9a2 100644
--- a/src/wallet/wallet2.cpp
+++ b/src/wallet/wallet2.cpp
@@ -290,15 +290,15 @@ void do_prepare_file_names(const std::string& file_path, std::string& keys_file,
mms_file = file_path + ".mms";
}
-uint64_t calculate_fee(uint64_t fee_per_kb, size_t bytes, uint64_t fee_multiplier)
+uint64_t calculate_fee(uint64_t fee_per_kb, size_t bytes)
{
uint64_t kB = (bytes + 1023) / 1024;
- return kB * fee_per_kb * fee_multiplier;
+ return kB * fee_per_kb;
}
-uint64_t calculate_fee_from_weight(uint64_t base_fee, uint64_t weight, uint64_t fee_multiplier, uint64_t fee_quantization_mask)
+uint64_t calculate_fee_from_weight(uint64_t base_fee, uint64_t weight, uint64_t fee_quantization_mask)
{
- uint64_t fee = weight * base_fee * fee_multiplier;
+ uint64_t fee = weight * base_fee;
fee = (fee + fee_quantization_mask - 1) / fee_quantization_mask * fee_quantization_mask;
return fee;
}
@@ -781,7 +781,7 @@ void drop_from_short_history(std::list<crypto::hash> &short_chain_history, size_
}
}
-size_t estimate_rct_tx_size(int n_inputs, int mixin, int n_outputs, size_t extra_size, bool bulletproof, bool clsag, bool bulletproof_plus)
+size_t estimate_rct_tx_size(int n_inputs, int mixin, int n_outputs, size_t extra_size, bool bulletproof, bool clsag, bool bulletproof_plus, bool use_view_tags)
{
size_t size = 0;
@@ -821,6 +821,9 @@ size_t estimate_rct_tx_size(int n_inputs, int mixin, int n_outputs, size_t extra
else
size += n_inputs * (64 * (mixin+1) + 32);
+ if (use_view_tags)
+ size += n_outputs * sizeof(crypto::view_tag);
+
// mixRing - not serialized, can be reconstructed
/* size += 2 * 32 * (mixin+1) * n_inputs; */
@@ -837,17 +840,17 @@ size_t estimate_rct_tx_size(int n_inputs, int mixin, int n_outputs, size_t extra
return size;
}
-size_t estimate_tx_size(bool use_rct, int n_inputs, int mixin, int n_outputs, size_t extra_size, bool bulletproof, bool clsag, bool bulletproof_plus)
+size_t estimate_tx_size(bool use_rct, int n_inputs, int mixin, int n_outputs, size_t extra_size, bool bulletproof, bool clsag, bool bulletproof_plus, bool use_view_tags)
{
if (use_rct)
- return estimate_rct_tx_size(n_inputs, mixin, n_outputs, extra_size, bulletproof, clsag, bulletproof_plus);
+ return estimate_rct_tx_size(n_inputs, mixin, n_outputs, extra_size, bulletproof, clsag, bulletproof_plus, use_view_tags);
else
- return n_inputs * (mixin+1) * APPROXIMATE_INPUT_BYTES + extra_size;
+ return n_inputs * (mixin+1) * APPROXIMATE_INPUT_BYTES + extra_size + (use_view_tags ? (n_outputs * sizeof(crypto::view_tag)) : 0);
}
-uint64_t estimate_tx_weight(bool use_rct, int n_inputs, int mixin, int n_outputs, size_t extra_size, bool bulletproof, bool clsag, bool bulletproof_plus)
+uint64_t estimate_tx_weight(bool use_rct, int n_inputs, int mixin, int n_outputs, size_t extra_size, bool bulletproof, bool clsag, bool bulletproof_plus, bool use_view_tags)
{
- size_t size = estimate_tx_size(use_rct, n_inputs, mixin, n_outputs, extra_size, bulletproof, clsag, bulletproof_plus);
+ size_t size = estimate_tx_size(use_rct, n_inputs, mixin, n_outputs, extra_size, bulletproof, clsag, bulletproof_plus, use_view_tags);
if (use_rct && (bulletproof || bulletproof_plus) && n_outputs > 2)
{
const uint64_t bp_base = (32 * ((bulletproof_plus ? 6 : 9) + 7 * 2)) / 2; // notional size of a 2 output proof, normalized to 1 proof (ie, divided by 2)
@@ -878,12 +881,17 @@ uint8_t get_clsag_fork()
return HF_VERSION_CLSAG;
}
-uint64_t calculate_fee(bool use_per_byte_fee, const cryptonote::transaction &tx, size_t blob_size, uint64_t base_fee, uint64_t fee_multiplier, uint64_t fee_quantization_mask)
+uint8_t get_view_tag_fork()
+{
+ return HF_VERSION_VIEW_TAGS;
+}
+
+uint64_t calculate_fee(bool use_per_byte_fee, const cryptonote::transaction &tx, size_t blob_size, uint64_t base_fee, uint64_t fee_quantization_mask)
{
if (use_per_byte_fee)
- return calculate_fee_from_weight(base_fee, cryptonote::get_transaction_weight(tx, blob_size), fee_multiplier, fee_quantization_mask);
+ return calculate_fee_from_weight(base_fee, cryptonote::get_transaction_weight(tx, blob_size), fee_quantization_mask);
else
- return calculate_fee(base_fee, blob_size, fee_multiplier);
+ return calculate_fee(base_fee, blob_size);
}
bool get_short_payment_id(crypto::hash8 &payment_id8, const tools::wallet2::pending_tx &ptx, hw::device &hwdev)
@@ -1765,13 +1773,14 @@ void wallet2::check_acc_out_precomp(const tx_out &o, const crypto::key_derivatio
hw::device &hwdev = m_account.get_device();
boost::unique_lock<hw::device> hwdev_lock (hwdev);
hwdev.set_mode(hw::device::TRANSACTION_PARSE);
- if (o.target.type() != typeid(txout_to_key))
+ crypto::public_key output_public_key;
+ if (!get_output_public_key(o, output_public_key))
{
tx_scan_info.error = true;
LOG_ERROR("wrong type id in transaction out");
return;
}
- tx_scan_info.received = is_out_to_acc_precomp(m_subaddresses, boost::get<txout_to_key>(o.target).key, derivation, additional_derivations, i, hwdev);
+ tx_scan_info.received = is_out_to_acc_precomp(m_subaddresses, output_public_key, derivation, additional_derivations, i, hwdev, get_output_view_tag(o));
if(tx_scan_info.received)
{
tx_scan_info.money_transfered = o.amount; // may be 0 for ringct outputs
@@ -1856,17 +1865,20 @@ void wallet2::scan_output(const cryptonote::transaction &tx, bool miner_tx, cons
}
}
+ crypto::public_key output_public_key;
+ THROW_WALLET_EXCEPTION_IF(!get_output_public_key(tx.vout[i], output_public_key), error::wallet_internal_error, "Failed to get output public key");
+
if (m_multisig)
{
- tx_scan_info.in_ephemeral.pub = boost::get<cryptonote::txout_to_key>(tx.vout[i].target).key;
+ tx_scan_info.in_ephemeral.pub = output_public_key;
tx_scan_info.in_ephemeral.sec = crypto::null_skey;
tx_scan_info.ki = rct::rct2ki(rct::zero());
}
else
{
- bool r = cryptonote::generate_key_image_helper_precomp(m_account.get_keys(), boost::get<cryptonote::txout_to_key>(tx.vout[i].target).key, tx_scan_info.received->derivation, i, tx_scan_info.received->index, tx_scan_info.in_ephemeral, tx_scan_info.ki, m_account.get_device());
+ bool r = cryptonote::generate_key_image_helper_precomp(m_account.get_keys(), output_public_key, tx_scan_info.received->derivation, i, tx_scan_info.received->index, tx_scan_info.in_ephemeral, tx_scan_info.ki, m_account.get_device());
THROW_WALLET_EXCEPTION_IF(!r, error::wallet_internal_error, "Failed to generate key image");
- THROW_WALLET_EXCEPTION_IF(tx_scan_info.in_ephemeral.pub != boost::get<cryptonote::txout_to_key>(tx.vout[i].target).key,
+ THROW_WALLET_EXCEPTION_IF(tx_scan_info.in_ephemeral.pub != output_public_key,
error::wallet_internal_error, "key_image generated ephemeral public key not matched with output_key");
}
@@ -1993,8 +2005,6 @@ void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote
int num_vouts_received = 0;
tx_pub_key = pub_key_field.pub_key;
- tools::threadpool& tpool = tools::threadpool::getInstance();
- tools::threadpool::waiter waiter(tpool);
const cryptonote::account_keys& keys = m_account.get_keys();
crypto::key_derivation derivation;
@@ -2064,10 +2074,8 @@ void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote
// the first one was already checked
for (size_t i = 1; i < tx.vout.size(); ++i)
{
- tpool.submit(&waiter, boost::bind(&wallet2::check_acc_out_precomp_once, this, std::cref(tx.vout[i]), std::cref(derivation), std::cref(additional_derivations), i,
- std::cref(is_out_data_ptr), std::ref(tx_scan_info[i]), std::ref(output_found[i])), true);
+ check_acc_out_precomp_once(tx.vout[i], derivation, additional_derivations, i, is_out_data_ptr, tx_scan_info[i], output_found[i]);
}
- THROW_WALLET_EXCEPTION_IF(!waiter.wait(), error::wallet_internal_error, "Exception in thread pool");
// then scan all outputs from 0
hw::device &hwdev = m_account.get_device();
boost::unique_lock<hw::device> hwdev_lock (hwdev);
@@ -2087,32 +2095,6 @@ void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote
}
}
}
- else if (tx.vout.size() > 1 && tools::threadpool::getInstance().get_max_concurrency() > 1 && !is_out_data_ptr)
- {
- for (size_t i = 0; i < tx.vout.size(); ++i)
- {
- tpool.submit(&waiter, boost::bind(&wallet2::check_acc_out_precomp_once, this, std::cref(tx.vout[i]), std::cref(derivation), std::cref(additional_derivations), i,
- std::cref(is_out_data_ptr), std::ref(tx_scan_info[i]), std::ref(output_found[i])), true);
- }
- THROW_WALLET_EXCEPTION_IF(!waiter.wait(), error::wallet_internal_error, "Exception in thread pool");
-
- hw::device &hwdev = m_account.get_device();
- boost::unique_lock<hw::device> hwdev_lock (hwdev);
- hwdev.set_mode(hw::device::NONE);
- for (size_t i = 0; i < tx.vout.size(); ++i)
- {
- THROW_WALLET_EXCEPTION_IF(tx_scan_info[i].error, error::acc_outs_lookup_error, tx, tx_pub_key, m_account.get_keys());
- if (tx_scan_info[i].received)
- {
- hwdev.conceal_derivation(tx_scan_info[i].received->derivation, tx_pub_key, additional_tx_pub_keys.data, derivation, additional_derivations);
- scan_output(tx, miner_tx, tx_pub_key, i, tx_scan_info[i], num_vouts_received, tx_money_got_in_outs, outs, pool);
- if (!tx_scan_info[i].error)
- {
- tx_amounts_individual_outs[tx_scan_info[i].received->index].push_back(tx_scan_info[i].money_transfered);
- }
- }
- }
- }
else
{
for (size_t i = 0; i < tx.vout.size(); ++i)
@@ -2793,25 +2775,34 @@ void wallet2::process_parsed_blocks(uint64_t start_height, const std::vector<cry
for (size_t k = 0; k < n_vouts; ++k)
{
const auto &o = tx.vout[k];
- if (o.target.type() == typeid(cryptonote::txout_to_key))
+ crypto::public_key output_public_key;
+ if (get_output_public_key(o, output_public_key))
{
std::vector<crypto::key_derivation> additional_derivations;
additional_derivations.reserve(tx_cache_data[txidx].additional.size());
for (const auto &iod: tx_cache_data[txidx].additional)
additional_derivations.push_back(iod.derivation);
- const auto &key = boost::get<txout_to_key>(o.target).key;
for (size_t l = 0; l < tx_cache_data[txidx].primary.size(); ++l)
{
THROW_WALLET_EXCEPTION_IF(tx_cache_data[txidx].primary[l].received.size() != n_vouts,
error::wallet_internal_error, "Unexpected received array size");
- tx_cache_data[txidx].primary[l].received[k] = is_out_to_acc_precomp(m_subaddresses, key, tx_cache_data[txidx].primary[l].derivation, additional_derivations, k, hwdev);
+ tx_cache_data[txidx].primary[l].received[k] = is_out_to_acc_precomp(m_subaddresses, output_public_key, tx_cache_data[txidx].primary[l].derivation, additional_derivations, k, hwdev, get_output_view_tag(o));
additional_derivations.clear();
}
}
}
};
+ struct geniod_params
+ {
+ const cryptonote::transaction &tx;
+ size_t n_outs;
+ size_t txidx;
+ };
+ std::vector<geniod_params> geniods;
+ geniods.reserve(num_txes);
txidx = 0;
+ uint8_t hf_version_view_tags = get_view_tag_fork();
for (size_t i = 0; i < blocks.size(); ++i)
{
if (should_skip_block(parsed_blocks[i].block, start_height + i))
@@ -2825,18 +2816,51 @@ void wallet2::process_parsed_blocks(uint64_t start_height, const std::vector<cry
THROW_WALLET_EXCEPTION_IF(txidx >= tx_cache_data.size(), error::wallet_internal_error, "txidx out of range");
const cryptonote::transaction& tx = parsed_blocks[i].block.miner_tx;
const size_t n_vouts = (m_refresh_type == RefreshType::RefreshOptimizeCoinbase && tx.version < 2) ? 1 : tx.vout.size();
- tpool.submit(&waiter, [&, n_vouts, txidx](){ geniod(tx, n_vouts, txidx); }, true);
+ if (parsed_blocks[i].block.major_version >= hf_version_view_tags)
+ geniods.push_back(geniod_params{ tx, n_vouts, txidx });
+ else
+ tpool.submit(&waiter, [&, n_vouts, txidx](){ geniod(tx, n_vouts, txidx); }, true);
}
++txidx;
for (size_t j = 0; j < parsed_blocks[i].txes.size(); ++j)
{
THROW_WALLET_EXCEPTION_IF(txidx >= tx_cache_data.size(), error::wallet_internal_error, "txidx out of range");
- tpool.submit(&waiter, [&, i, j, txidx](){ geniod(parsed_blocks[i].txes[j], parsed_blocks[i].txes[j].vout.size(), txidx); }, true);
+ if (parsed_blocks[i].block.major_version >= hf_version_view_tags)
+ geniods.push_back(geniod_params{ parsed_blocks[i].txes[j], parsed_blocks[i].txes[j].vout.size(), txidx });
+ else
+ tpool.submit(&waiter, [&, i, j, txidx](){ geniod(parsed_blocks[i].txes[j], parsed_blocks[i].txes[j].vout.size(), txidx); }, true);
++txidx;
}
}
THROW_WALLET_EXCEPTION_IF(txidx != tx_cache_data.size(), error::wallet_internal_error, "txidx did not reach expected value");
+
+ // View tags significantly speed up the geniod function that determines if an output belongs to the account.
+ // Because the speedup is so large, the overhead from submitting individual geniods to the thread pool eats into
+ // the benefit of executing in parallel. So to maximize the benefit from threads when view tags are enabled,
+ // the wallet starts submitting geniod function calls to the thread pool in batches of size GENIOD_BATCH_SIZE.
+ if (geniods.size())
+ {
+ size_t GENIOD_BATCH_SIZE = 100;
+ size_t num_batch_txes = 0;
+ size_t batch_start = 0;
+ while (batch_start < geniods.size())
+ {
+ size_t batch_end = std::min(batch_start + GENIOD_BATCH_SIZE, geniods.size());
+ THROW_WALLET_EXCEPTION_IF(batch_end < batch_start, error::wallet_internal_error, "Thread batch end overflow");
+ tpool.submit(&waiter, [&geniods, &geniod, batch_start, batch_end]() {
+ for (size_t i = batch_start; i < batch_end; ++i)
+ {
+ const geniod_params &gp = geniods[i];
+ geniod(gp.tx, gp.n_outs, gp.txidx);
+ }
+ }, true);
+ num_batch_txes += batch_end - batch_start;
+ batch_start = batch_end;
+ }
+ THROW_WALLET_EXCEPTION_IF(num_batch_txes != geniods.size(), error::wallet_internal_error, "txes batched for thread pool did not reach expected value");
+ }
THROW_WALLET_EXCEPTION_IF(!waiter.wait(), error::wallet_internal_error, "Exception in thread pool");
+
hwdev.set_mode(hw::device::NONE);
size_t tx_cache_data_offset = 0;
@@ -6613,7 +6637,7 @@ bool wallet2::sign_tx(unsigned_tx_set &exported_txs, std::vector<wallet2::pendin
crypto::secret_key tx_key;
std::vector<crypto::secret_key> additional_tx_keys;
rct::multisig_out msout;
- bool r = cryptonote::construct_tx_and_get_tx_key(m_account.get_keys(), m_subaddresses, sd.sources, sd.splitted_dsts, sd.change_dts.addr, sd.extra, ptx.tx, sd.unlock_time, tx_key, additional_tx_keys, sd.use_rct, rct_config, m_multisig ? &msout : NULL);
+ bool r = cryptonote::construct_tx_and_get_tx_key(m_account.get_keys(), m_subaddresses, sd.sources, sd.splitted_dsts, sd.change_dts.addr, sd.extra, ptx.tx, sd.unlock_time, tx_key, additional_tx_keys, sd.use_rct, rct_config, m_multisig ? &msout : NULL, sd.use_view_tags);
THROW_WALLET_EXCEPTION_IF(!r, error::tx_not_constructed, sd.sources, sd.splitted_dsts, sd.unlock_time, m_nettype);
// we don't test tx size, because we don't know the current limit, due to not having a blockchain,
// and it's a bit pointless to fail there anyway, since it'd be a (good) guess only. We sign anyway,
@@ -6698,16 +6722,17 @@ bool wallet2::sign_tx(unsigned_tx_set &exported_txs, std::vector<wallet2::pendin
for (size_t i = 0; i < tx.vout.size(); ++i)
{
- if (tx.vout[i].target.type() != typeid(cryptonote::txout_to_key))
+ crypto::public_key output_public_key;
+ if (!get_output_public_key(tx.vout[i], output_public_key))
continue;
- const cryptonote::txout_to_key &out = boost::get<cryptonote::txout_to_key>(tx.vout[i].target);
+
// if this output is back to this wallet, we can calculate its key image already
- if (!is_out_to_acc_precomp(m_subaddresses, out.key, derivation, additional_derivations, i, hwdev))
+ if (!is_out_to_acc_precomp(m_subaddresses, output_public_key, derivation, additional_derivations, i, hwdev, get_output_view_tag(tx.vout[i])))
continue;
crypto::key_image ki;
cryptonote::keypair in_ephemeral;
- if (generate_key_image_helper(keys, m_subaddresses, out.key, tx_pub_key, additional_tx_pub_keys, i, in_ephemeral, ki, hwdev))
- signed_txes.tx_key_images[out.key] = ki;
+ if (generate_key_image_helper(keys, m_subaddresses, output_public_key, tx_pub_key, additional_tx_pub_keys, i, in_ephemeral, ki, hwdev))
+ signed_txes.tx_key_images[output_public_key] = ki;
else
MERROR("Failed to calculate key image");
}
@@ -7132,7 +7157,8 @@ bool wallet2::sign_multisig_tx(multisig_tx_set &exported_txs, std::vector<crypto
rct::multisig_out msout = ptx.multisig_sigs.front().msout;
auto sources = sd.sources;
rct::RCTConfig rct_config = sd.rct_config;
- bool r = cryptonote::construct_tx_with_tx_key(m_account.get_keys(), m_subaddresses, sources, sd.splitted_dsts, ptx.change_dts.addr, sd.extra, tx, sd.unlock_time, ptx.tx_key, ptx.additional_tx_keys, sd.use_rct, rct_config, &msout, false);
+ bool shuffle_outs = false;
+ bool r = cryptonote::construct_tx_with_tx_key(m_account.get_keys(), m_subaddresses, sources, sd.splitted_dsts, ptx.change_dts.addr, sd.extra, tx, sd.unlock_time, ptx.tx_key, ptx.additional_tx_keys, sd.use_rct, rct_config, &msout, shuffle_outs, sd.use_view_tags);
THROW_WALLET_EXCEPTION_IF(!r, error::tx_not_constructed, sd.sources, sd.splitted_dsts, sd.unlock_time, m_nettype);
THROW_WALLET_EXCEPTION_IF(get_transaction_prefix_hash (tx) != get_transaction_prefix_hash(ptx.tx),
@@ -7232,17 +7258,17 @@ bool wallet2::sign_multisig_tx_from_file(const std::string &filename, std::vecto
return sign_multisig_tx_to_file(exported_txs, filename, txids);
}
//----------------------------------------------------------------------------------------------------
-uint64_t wallet2::estimate_fee(bool use_per_byte_fee, bool use_rct, int n_inputs, int mixin, int n_outputs, size_t extra_size, bool bulletproof, bool clsag, bool bulletproof_plus, uint64_t base_fee, uint64_t fee_multiplier, uint64_t fee_quantization_mask) const
+uint64_t wallet2::estimate_fee(bool use_per_byte_fee, bool use_rct, int n_inputs, int mixin, int n_outputs, size_t extra_size, bool bulletproof, bool clsag, bool bulletproof_plus, bool use_view_tags, uint64_t base_fee, uint64_t fee_quantization_mask) const
{
if (use_per_byte_fee)
{
- const size_t estimated_tx_weight = estimate_tx_weight(use_rct, n_inputs, mixin, n_outputs, extra_size, bulletproof, clsag, bulletproof_plus);
- return calculate_fee_from_weight(base_fee, estimated_tx_weight, fee_multiplier, fee_quantization_mask);
+ const size_t estimated_tx_weight = estimate_tx_weight(use_rct, n_inputs, mixin, n_outputs, extra_size, bulletproof, clsag, bulletproof_plus, use_view_tags);
+ return calculate_fee_from_weight(base_fee, estimated_tx_weight, fee_quantization_mask);
}
else
{
- const size_t estimated_tx_size = estimate_tx_size(use_rct, n_inputs, mixin, n_outputs, extra_size, bulletproof, clsag, bulletproof_plus);
- return calculate_fee(base_fee, estimated_tx_size, fee_multiplier);
+ const size_t estimated_tx_size = estimate_tx_size(use_rct, n_inputs, mixin, n_outputs, extra_size, bulletproof, clsag, bulletproof_plus, use_view_tags);
+ return calculate_fee(base_fee, estimated_tx_size);
}
}
@@ -7315,6 +7341,40 @@ uint64_t wallet2::get_base_fee()
return get_dynamic_base_fee_estimate();
}
//----------------------------------------------------------------------------------------------------
+uint64_t wallet2::get_base_fee(uint32_t priority)
+{
+ const bool use_2021_scaling = use_fork_rules(HF_VERSION_2021_SCALING, -30 * 1);
+ if (use_2021_scaling)
+ {
+ // clamp and map to 0..3 indices, mapping 0 (default, but should not end up here) to 0, and 1..4 to 0..3
+ if (priority == 0)
+ priority = 1;
+ else if (priority > 4)
+ priority = 4;
+ --priority;
+
+ std::vector<uint64_t> fees;
+ boost::optional<std::string> result = m_node_rpc_proxy.get_dynamic_base_fee_estimate_2021_scaling(FEE_ESTIMATE_GRACE_BLOCKS, fees);
+ if (result)
+ {
+ MERROR("Failed to determine base fee, using default");
+ return FEE_PER_BYTE;
+ }
+ if (priority >= fees.size())
+ {
+ MERROR("Failed to determine base fee for priority " << priority << ", using default");
+ return FEE_PER_BYTE;
+ }
+ return fees[priority];
+ }
+ else
+ {
+ const uint64_t base_fee = get_base_fee();
+ const uint64_t fee_multiplier = get_fee_multiplier(priority);
+ return base_fee * fee_multiplier;
+ }
+}
+//----------------------------------------------------------------------------------------------------
uint64_t wallet2::get_fee_quantization_mask()
{
if(m_light_wallet)
@@ -7346,6 +7406,8 @@ int wallet2::get_fee_algorithm()
//------------------------------------------------------------------------------------------------------------------------------
uint64_t wallet2::get_min_ring_size()
{
+ if (use_fork_rules(HF_VERSION_MIN_MIXIN_15, 0))
+ return 16;
if (use_fork_rules(8, 10))
return 11;
if (use_fork_rules(7, 10))
@@ -7359,6 +7421,8 @@ uint64_t wallet2::get_min_ring_size()
//------------------------------------------------------------------------------------------------------------------------------
uint64_t wallet2::get_max_ring_size()
{
+ if (use_fork_rules(HF_VERSION_MIN_MIXIN_15, 0))
+ return 16;
if (use_fork_rules(8, 10))
return 11;
return 0;
@@ -7389,9 +7453,8 @@ uint32_t wallet2::adjust_priority(uint32_t priority)
{
// check if there's a backlog in the tx pool
const bool use_per_byte_fee = use_fork_rules(HF_VERSION_PER_BYTE_FEE, 0);
- const uint64_t base_fee = get_base_fee();
- const uint64_t fee_multiplier = get_fee_multiplier(1);
- const double fee_level = fee_multiplier * base_fee * (use_per_byte_fee ? 1 : (12/(double)13 / (double)1024));
+ const uint64_t base_fee = get_base_fee(1);
+ const double fee_level = base_fee * (use_per_byte_fee ? 1 : (12/(double)13 / (double)1024));
const std::vector<std::pair<uint64_t, uint64_t>> blocks = estimate_backlog({std::make_pair(fee_level, fee_level)});
if (blocks.size() != 1)
{
@@ -8428,7 +8491,7 @@ void wallet2::get_outs(std::vector<std::vector<tools::wallet2::get_outs_entry>>
{
size_t i = base + n;
if (req.outputs[i].index == td.m_global_output_index)
- if (daemon_resp.outs[i].key == boost::get<txout_to_key>(td.m_tx.vout[td.m_internal_output_index].target).key)
+ if (daemon_resp.outs[i].key == td.get_public_key())
if (daemon_resp.outs[i].mask == mask)
if (daemon_resp.outs[i].unlocked)
real_out_found = true;
@@ -8437,7 +8500,7 @@ void wallet2::get_outs(std::vector<std::vector<tools::wallet2::get_outs_entry>>
"Daemon response did not include the requested real output");
// pick real out first (it will be sorted when done)
- outs.back().push_back(std::make_tuple(td.m_global_output_index, boost::get<txout_to_key>(td.m_tx.vout[td.m_internal_output_index].target).key, mask));
+ outs.back().push_back(std::make_tuple(td.m_global_output_index, td.get_public_key(), mask));
// then pick outs from an existing ring, if any
if (td.m_key_image_known && !td.m_key_image_partial)
@@ -8528,7 +8591,8 @@ void wallet2::get_outs(std::vector<std::vector<tools::wallet2::get_outs_entry>>
template<typename T>
void wallet2::transfer_selected(const std::vector<cryptonote::tx_destination_entry>& dsts, const std::vector<size_t>& selected_transfers, size_t fake_outputs_count,
std::vector<std::vector<tools::wallet2::get_outs_entry>> &outs,
- uint64_t unlock_time, uint64_t fee, const std::vector<uint8_t>& extra, T destination_split_strategy, const tx_dust_policy& dust_policy, cryptonote::transaction& tx, pending_tx &ptx)
+ uint64_t 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 use_view_tags)
{
using namespace cryptonote;
// throw if attempting a transaction with no destinations
@@ -8601,7 +8665,7 @@ void wallet2::transfer_selected(const std::vector<cryptonote::tx_destination_ent
tx_output_entry real_oe;
real_oe.first = td.m_global_output_index;
- real_oe.second.dest = rct::pk2rct(boost::get<txout_to_key>(td.m_tx.vout[td.m_internal_output_index].target).key);
+ real_oe.second.dest = rct::pk2rct(td.get_public_key());
real_oe.second.mask = rct::commit(td.amount(), td.m_mask);
*it_to_replace = real_oe;
src.real_out_tx_key = get_tx_pub_key_from_extra(td.m_tx, td.m_pk_index);
@@ -8639,7 +8703,7 @@ void wallet2::transfer_selected(const std::vector<cryptonote::tx_destination_ent
std::vector<crypto::secret_key> additional_tx_keys;
rct::multisig_out msout;
LOG_PRINT_L2("constructing tx");
- bool r = cryptonote::construct_tx_and_get_tx_key(m_account.get_keys(), m_subaddresses, sources, splitted_dsts, change_dts.addr, extra, tx, unlock_time, tx_key, additional_tx_keys, false, {}, m_multisig ? &msout : NULL);
+ bool r = cryptonote::construct_tx_and_get_tx_key(m_account.get_keys(), m_subaddresses, sources, splitted_dsts, change_dts.addr, extra, tx, unlock_time, tx_key, additional_tx_keys, false, {}, m_multisig ? &msout : NULL, use_view_tags);
LOG_PRINT_L2("constructed tx, r="<<r);
THROW_WALLET_EXCEPTION_IF(!r, error::tx_not_constructed, sources, splitted_dsts, unlock_time, m_nettype);
THROW_WALLET_EXCEPTION_IF(upper_transaction_weight_limit <= get_transaction_weight(tx), error::tx_too_big, tx, upper_transaction_weight_limit);
@@ -8677,6 +8741,7 @@ void wallet2::transfer_selected(const std::vector<cryptonote::tx_destination_ent
ptx.construction_data.unlock_time = unlock_time;
ptx.construction_data.use_rct = false;
ptx.construction_data.rct_config = { rct::RangeProofBorromean, 0 };
+ ptx.construction_data.use_view_tags = use_view_tags;
ptx.construction_data.dests = dsts;
// record which subaddress indices are being used as inputs
ptx.construction_data.subaddr_account = subaddr_account;
@@ -8688,7 +8753,7 @@ void wallet2::transfer_selected(const std::vector<cryptonote::tx_destination_ent
void wallet2::transfer_selected_rct(std::vector<cryptonote::tx_destination_entry> dsts, const std::vector<size_t>& selected_transfers, size_t fake_outputs_count,
std::vector<std::vector<tools::wallet2::get_outs_entry>> &outs,
- uint64_t unlock_time, uint64_t fee, const std::vector<uint8_t>& extra, cryptonote::transaction& tx, pending_tx &ptx, const rct::RCTConfig &rct_config)
+ uint64_t unlock_time, uint64_t fee, const std::vector<uint8_t>& extra, cryptonote::transaction& tx, pending_tx &ptx, const rct::RCTConfig &rct_config, bool use_view_tags)
{
using namespace cryptonote;
// throw if attempting a transaction with no destinations
@@ -8873,7 +8938,7 @@ void wallet2::transfer_selected_rct(std::vector<cryptonote::tx_destination_entry
rct::multisig_out msout;
LOG_PRINT_L2("constructing tx");
auto sources_copy = sources;
- bool r = cryptonote::construct_tx_and_get_tx_key(m_account.get_keys(), m_subaddresses, sources, splitted_dsts, change_dts.addr, extra, tx, unlock_time, tx_key, additional_tx_keys, true, rct_config, m_multisig ? &msout : NULL);
+ bool r = cryptonote::construct_tx_and_get_tx_key(m_account.get_keys(), m_subaddresses, sources, splitted_dsts, change_dts.addr, extra, tx, unlock_time, tx_key, additional_tx_keys, true, rct_config, m_multisig ? &msout : NULL, use_view_tags);
LOG_PRINT_L2("constructed tx, r="<<r);
THROW_WALLET_EXCEPTION_IF(!r, error::tx_not_constructed, sources, dsts, unlock_time, m_nettype);
THROW_WALLET_EXCEPTION_IF(upper_transaction_weight_limit <= get_transaction_weight(tx), error::tx_too_big, tx, upper_transaction_weight_limit);
@@ -8918,7 +8983,8 @@ void wallet2::transfer_selected_rct(std::vector<cryptonote::tx_destination_entry
LOG_PRINT_L2("Creating supplementary multisig transaction");
cryptonote::transaction ms_tx;
auto sources_copy_copy = sources_copy;
- bool r = cryptonote::construct_tx_with_tx_key(m_account.get_keys(), m_subaddresses, sources_copy_copy, splitted_dsts, change_dts.addr, extra, ms_tx, unlock_time,tx_key, additional_tx_keys, true, rct_config, &msout, false);
+ bool shuffle_outs = false;
+ bool r = cryptonote::construct_tx_with_tx_key(m_account.get_keys(), m_subaddresses, sources_copy_copy, splitted_dsts, change_dts.addr, extra, ms_tx, unlock_time,tx_key, additional_tx_keys, true, rct_config, &msout, shuffle_outs, use_view_tags);
LOG_PRINT_L2("constructed tx, r="<<r);
THROW_WALLET_EXCEPTION_IF(!r, error::tx_not_constructed, sources, splitted_dsts, unlock_time, m_nettype);
THROW_WALLET_EXCEPTION_IF(upper_transaction_weight_limit <= get_transaction_weight(tx), error::tx_too_big, tx, upper_transaction_weight_limit);
@@ -8965,6 +9031,7 @@ void wallet2::transfer_selected_rct(std::vector<cryptonote::tx_destination_entry
rct::RangeProofPaddedBulletproof,
use_fork_rules(HF_VERSION_BULLETPROOF_PLUS, -10) ? 4 : 3
};
+ ptx.construction_data.use_view_tags = use_fork_rules(get_view_tag_fork(), 0);
ptx.construction_data.dests = dsts;
// record which subaddress indices are being used as inputs
ptx.construction_data.subaddr_account = subaddr_account;
@@ -9664,9 +9731,9 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryp
rct::RangeProofPaddedBulletproof,
bulletproof_plus ? 4 : 3
};
+ const bool use_view_tags = use_fork_rules(get_view_tag_fork(), 0);
- const uint64_t base_fee = get_base_fee();
- const uint64_t fee_multiplier = get_fee_multiplier(priority, get_fee_algorithm());
+ const uint64_t base_fee = get_base_fee(priority);
const uint64_t fee_quantization_mask = get_fee_quantization_mask();
// throw if attempting a transaction with no destinations
@@ -9698,7 +9765,7 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryp
// early out if we know we can't make it anyway
// we could also check for being within FEE_PER_KB, but if the fee calculation
// ever changes, this might be missed, so let this go through
- const uint64_t min_fee = (fee_multiplier * base_fee * estimate_tx_size(use_rct, 1, fake_outs_count, 2, extra.size(), bulletproof, clsag, bulletproof_plus));
+ const uint64_t min_fee = (base_fee * estimate_tx_size(use_rct, 1, fake_outs_count, 2, extra.size(), bulletproof, clsag, bulletproof_plus, use_view_tags));
uint64_t balance_subtotal = 0;
uint64_t unlocked_balance_subtotal = 0;
for (uint32_t index_minor : subaddr_indices)
@@ -9716,11 +9783,11 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryp
LOG_PRINT_L2("Candidate subaddress index for spending: " << i);
// determine threshold for fractional amount
- const size_t tx_weight_one_ring = estimate_tx_weight(use_rct, 1, fake_outs_count, 2, 0, bulletproof, clsag, bulletproof_plus);
- const size_t tx_weight_two_rings = estimate_tx_weight(use_rct, 2, fake_outs_count, 2, 0, bulletproof, clsag, bulletproof_plus);
+ const size_t tx_weight_one_ring = estimate_tx_weight(use_rct, 1, fake_outs_count, 2, 0, bulletproof, clsag, bulletproof_plus, use_view_tags);
+ const size_t tx_weight_two_rings = estimate_tx_weight(use_rct, 2, fake_outs_count, 2, 0, bulletproof, clsag, bulletproof_plus, use_view_tags);
THROW_WALLET_EXCEPTION_IF(tx_weight_one_ring > tx_weight_two_rings, error::wallet_internal_error, "Estimated tx weight with 1 input is larger than with 2 inputs!");
const size_t tx_weight_per_ring = tx_weight_two_rings - tx_weight_one_ring;
- const uint64_t fractional_threshold = (fee_multiplier * base_fee * tx_weight_per_ring) / (use_per_byte_fee ? 1 : 1024);
+ const uint64_t fractional_threshold = (base_fee * tx_weight_per_ring) / (use_per_byte_fee ? 1 : 1024);
// gather all dust and non-dust outputs belonging to specified subaddresses
size_t num_nondust_outputs = 0;
@@ -9814,7 +9881,7 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryp
{
// this is used to build a tx that's 1 or 2 inputs, and 2 outputs, which
// will get us a known fee.
- uint64_t estimated_fee = estimate_fee(use_per_byte_fee, use_rct, 2, fake_outs_count, 2, extra.size(), bulletproof, clsag, bulletproof_plus, base_fee, fee_multiplier, fee_quantization_mask);
+ uint64_t estimated_fee = estimate_fee(use_per_byte_fee, use_rct, 2, fake_outs_count, 2, extra.size(), bulletproof, clsag, bulletproof_plus, use_view_tags, base_fee, fee_quantization_mask);
preferred_inputs = pick_preferred_rct_inputs(needed_money + estimated_fee, subaddr_account, subaddr_indices);
if (!preferred_inputs.empty())
{
@@ -9927,7 +9994,7 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryp
}
else
{
- while (!dsts.empty() && dsts[0].amount <= available_amount && estimate_tx_weight(use_rct, tx.selected_transfers.size(), fake_outs_count, tx.dsts.size()+1, extra.size(), bulletproof, clsag, bulletproof_plus) < TX_WEIGHT_TARGET(upper_transaction_weight_limit))
+ while (!dsts.empty() && dsts[0].amount <= available_amount && estimate_tx_weight(use_rct, tx.selected_transfers.size(), fake_outs_count, tx.dsts.size()+1, extra.size(), bulletproof, clsag, bulletproof_plus, use_view_tags) < TX_WEIGHT_TARGET(upper_transaction_weight_limit))
{
// we can fully pay that destination
LOG_PRINT_L2("We can fully pay " << get_account_address_as_str(m_nettype, dsts[0].is_subaddress, dsts[0].addr) <<
@@ -9945,7 +10012,7 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryp
}
if (!out_slots_exhausted && available_amount > 0 && !dsts.empty() &&
- estimate_tx_weight(use_rct, tx.selected_transfers.size(), fake_outs_count, tx.dsts.size()+1, extra.size(), bulletproof, clsag, bulletproof_plus) < TX_WEIGHT_TARGET(upper_transaction_weight_limit)) {
+ estimate_tx_weight(use_rct, tx.selected_transfers.size(), fake_outs_count, tx.dsts.size()+1, extra.size(), bulletproof, clsag, bulletproof_plus, use_view_tags) < TX_WEIGHT_TARGET(upper_transaction_weight_limit)) {
// we can partially fill that destination
LOG_PRINT_L2("We can partially pay " << get_account_address_as_str(m_nettype, dsts[0].is_subaddress, dsts[0].addr) <<
" for " << print_money(available_amount) << "/" << print_money(dsts[0].amount));
@@ -9983,7 +10050,7 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryp
}
else
{
- const size_t estimated_rct_tx_weight = estimate_tx_weight(use_rct, tx.selected_transfers.size(), fake_outs_count, tx.dsts.size()+1, extra.size(), bulletproof, clsag, bulletproof_plus);
+ const size_t estimated_rct_tx_weight = estimate_tx_weight(use_rct, tx.selected_transfers.size(), fake_outs_count, tx.dsts.size()+1, extra.size(), bulletproof, clsag, bulletproof_plus, use_view_tags);
try_tx = dsts.empty() || (estimated_rct_tx_weight >= TX_WEIGHT_TARGET(upper_transaction_weight_limit));
THROW_WALLET_EXCEPTION_IF(try_tx && tx.dsts.empty(), error::tx_too_big, estimated_rct_tx_weight, upper_transaction_weight_limit);
}
@@ -9994,7 +10061,7 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryp
pending_tx test_ptx;
const size_t num_outputs = get_num_outputs(tx.dsts, m_transfers, tx.selected_transfers);
- needed_fee = estimate_fee(use_per_byte_fee, use_rct ,tx.selected_transfers.size(), fake_outs_count, num_outputs, extra.size(), bulletproof, clsag, bulletproof_plus, base_fee, fee_multiplier, fee_quantization_mask);
+ needed_fee = estimate_fee(use_per_byte_fee, use_rct ,tx.selected_transfers.size(), fake_outs_count, num_outputs, extra.size(), bulletproof, clsag, bulletproof_plus, use_view_tags, base_fee, fee_quantization_mask);
auto try_carving_from_partial_payment = [&](uint64_t needed_fee, uint64_t available_for_fee)
{
@@ -10043,12 +10110,12 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryp
tx.selected_transfers.size() << " inputs");
if (use_rct)
transfer_selected_rct(tx.dsts, tx.selected_transfers, fake_outs_count, outs, unlock_time, needed_fee, extra,
- test_tx, test_ptx, rct_config);
+ test_tx, test_ptx, rct_config, use_view_tags);
else
transfer_selected(tx.dsts, tx.selected_transfers, fake_outs_count, outs, unlock_time, needed_fee, extra,
- detail::digit_split_strategy, tx_dust_policy(::config::DEFAULT_DUST_THRESHOLD), test_tx, test_ptx);
+ detail::digit_split_strategy, tx_dust_policy(::config::DEFAULT_DUST_THRESHOLD), test_tx, test_ptx, use_view_tags);
auto txBlob = t_serializable_object_to_blob(test_ptx.tx);
- needed_fee = calculate_fee(use_per_byte_fee, test_ptx.tx, txBlob.size(), base_fee, fee_multiplier, fee_quantization_mask);
+ needed_fee = calculate_fee(use_per_byte_fee, test_ptx.tx, txBlob.size(), base_fee, fee_quantization_mask);
available_for_fee = test_ptx.fee + test_ptx.change_dts.amount + (!test_ptx.dust_added_to_fee ? test_ptx.dust : 0);
LOG_PRINT_L2("Made a " << get_weight_string(test_ptx.tx, txBlob.size()) << " tx, with " << print_money(available_for_fee) << " available for fee (" <<
print_money(needed_fee) << " needed)");
@@ -10068,12 +10135,12 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryp
while (needed_fee > test_ptx.fee) {
if (use_rct)
transfer_selected_rct(tx.dsts, tx.selected_transfers, fake_outs_count, outs, unlock_time, needed_fee, extra,
- test_tx, test_ptx, rct_config);
+ test_tx, test_ptx, rct_config, use_view_tags);
else
transfer_selected(tx.dsts, tx.selected_transfers, fake_outs_count, outs, unlock_time, needed_fee, extra,
- detail::digit_split_strategy, tx_dust_policy(::config::DEFAULT_DUST_THRESHOLD), test_tx, test_ptx);
+ detail::digit_split_strategy, tx_dust_policy(::config::DEFAULT_DUST_THRESHOLD), test_tx, test_ptx, use_view_tags);
txBlob = t_serializable_object_to_blob(test_ptx.tx);
- needed_fee = calculate_fee(use_per_byte_fee, test_ptx.tx, txBlob.size(), base_fee, fee_multiplier, fee_quantization_mask);
+ needed_fee = calculate_fee(use_per_byte_fee, test_ptx.tx, txBlob.size(), base_fee, fee_quantization_mask);
LOG_PRINT_L2("Made an attempt at a final " << get_weight_string(test_ptx.tx, txBlob.size()) << " tx, with " << print_money(test_ptx.fee) <<
" fee and " << print_money(test_ptx.change_dts.amount) << " change");
}
@@ -10141,7 +10208,8 @@ skip_tx:
extra, /* const std::vector<uint8_t>& extra, */
test_tx, /* OUT cryptonote::transaction& tx, */
test_ptx, /* OUT cryptonote::transaction& tx, */
- rct_config);
+ rct_config,
+ use_view_tags); /* const bool use_view_tags */
} else {
transfer_selected(tx.dsts,
tx.selected_transfers,
@@ -10153,7 +10221,8 @@ skip_tx:
detail::digit_split_strategy,
tx_dust_policy(::config::DEFAULT_DUST_THRESHOLD),
test_tx,
- test_ptx);
+ test_ptx,
+ use_view_tags);
}
auto txBlob = t_serializable_object_to_blob(test_ptx.tx);
tx.tx = test_tx;
@@ -10256,13 +10325,13 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_all(uint64_t below
const bool bulletproof = use_fork_rules(get_bulletproof_fork(), 0);
const bool bulletproof_plus = use_fork_rules(get_bulletproof_plus_fork(), 0);
const bool clsag = use_fork_rules(get_clsag_fork(), 0);
- const uint64_t base_fee = get_base_fee();
- const uint64_t fee_multiplier = get_fee_multiplier(priority, get_fee_algorithm());
- const size_t tx_weight_one_ring = estimate_tx_weight(use_rct, 1, fake_outs_count, 2, 0, bulletproof, clsag, bulletproof_plus);
- const size_t tx_weight_two_rings = estimate_tx_weight(use_rct, 2, fake_outs_count, 2, 0, bulletproof, clsag, bulletproof_plus);
+ const bool use_view_tags = use_fork_rules(get_view_tag_fork(), 0);
+ const uint64_t base_fee = get_base_fee(priority);
+ const size_t tx_weight_one_ring = estimate_tx_weight(use_rct, 1, fake_outs_count, 2, 0, bulletproof, clsag, bulletproof_plus, use_view_tags);
+ const size_t tx_weight_two_rings = estimate_tx_weight(use_rct, 2, fake_outs_count, 2, 0, bulletproof, clsag, bulletproof_plus, use_view_tags);
THROW_WALLET_EXCEPTION_IF(tx_weight_one_ring > tx_weight_two_rings, error::wallet_internal_error, "Estimated tx weight with 1 input is larger than with 2 inputs!");
const size_t tx_weight_per_ring = tx_weight_two_rings - tx_weight_one_ring;
- const uint64_t fractional_threshold = (fee_multiplier * base_fee * tx_weight_per_ring) / (use_per_byte_fee ? 1 : 1024);
+ const uint64_t fractional_threshold = (base_fee * tx_weight_per_ring) / (use_per_byte_fee ? 1 : 1024);
THROW_WALLET_EXCEPTION_IF(unlocked_balance(subaddr_account, false) == 0, error::wallet_internal_error, "No unlocked balance in the specified account");
@@ -10371,8 +10440,8 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_from(const crypton
rct::RangeProofPaddedBulletproof,
bulletproof_plus ? 4 : 3
};
- const uint64_t base_fee = get_base_fee();
- const uint64_t fee_multiplier = get_fee_multiplier(priority, get_fee_algorithm());
+ const bool use_view_tags = use_fork_rules(get_view_tag_fork(), 0);
+ const uint64_t base_fee = get_base_fee(priority);
const uint64_t fee_quantization_mask = get_fee_quantization_mask();
LOG_PRINT_L2("Starting with " << unused_transfers_indices.size() << " non-dust outputs and " << unused_dust_indices.size() << " dust outputs");
@@ -10398,12 +10467,12 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_from(const crypton
uint64_t fee_dust_threshold;
if (use_fork_rules(HF_VERSION_PER_BYTE_FEE))
{
- const uint64_t estimated_tx_weight_with_one_extra_output = estimate_tx_weight(use_rct, tx.selected_transfers.size() + 1, fake_outs_count, tx.dsts.size()+1, extra.size(), bulletproof, clsag, bulletproof_plus);
- fee_dust_threshold = calculate_fee_from_weight(base_fee, estimated_tx_weight_with_one_extra_output, fee_multiplier, fee_quantization_mask);
+ const uint64_t estimated_tx_weight_with_one_extra_output = estimate_tx_weight(use_rct, tx.selected_transfers.size() + 1, fake_outs_count, tx.dsts.size()+1, extra.size(), bulletproof, clsag, bulletproof_plus, use_view_tags);
+ fee_dust_threshold = calculate_fee_from_weight(base_fee, estimated_tx_weight_with_one_extra_output, fee_quantization_mask);
}
else
{
- fee_dust_threshold = base_fee * fee_multiplier * (upper_transaction_weight_limit + 1023) / 1024;
+ fee_dust_threshold = base_fee * (upper_transaction_weight_limit + 1023) / 1024;
}
size_t idx =
@@ -10429,7 +10498,7 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_from(const crypton
// here, check if we need to sent tx and start a new one
LOG_PRINT_L2("Considering whether to create a tx now, " << tx.selected_transfers.size() << " inputs, tx limit "
<< upper_transaction_weight_limit);
- const size_t estimated_rct_tx_weight = estimate_tx_weight(use_rct, tx.selected_transfers.size(), fake_outs_count, tx.dsts.size() + 2, extra.size(), bulletproof, clsag, bulletproof_plus);
+ const size_t estimated_rct_tx_weight = estimate_tx_weight(use_rct, tx.selected_transfers.size(), fake_outs_count, tx.dsts.size() + 2, extra.size(), bulletproof, clsag, bulletproof_plus, use_view_tags);
bool try_tx = (unused_dust_indices.empty() && unused_transfers_indices.empty()) || ( estimated_rct_tx_weight >= TX_WEIGHT_TARGET(upper_transaction_weight_limit));
if (try_tx) {
@@ -10437,7 +10506,7 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_from(const crypton
pending_tx test_ptx;
const size_t num_outputs = get_num_outputs(tx.dsts, m_transfers, tx.selected_transfers);
- needed_fee = estimate_fee(use_per_byte_fee, use_rct, tx.selected_transfers.size(), fake_outs_count, num_outputs, extra.size(), bulletproof, clsag, bulletproof_plus, base_fee, fee_multiplier, fee_quantization_mask);
+ needed_fee = estimate_fee(use_per_byte_fee, use_rct, tx.selected_transfers.size(), fake_outs_count, num_outputs, extra.size(), bulletproof, clsag, bulletproof_plus, use_view_tags, base_fee, fee_quantization_mask);
// add N - 1 outputs for correct initial fee estimation
for (size_t i = 0; i < ((outputs > 1) ? outputs - 1 : outputs); ++i)
@@ -10447,12 +10516,12 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_from(const crypton
tx.selected_transfers.size() << " outputs");
if (use_rct)
transfer_selected_rct(tx.dsts, tx.selected_transfers, fake_outs_count, outs, unlock_time, needed_fee, extra,
- test_tx, test_ptx, rct_config);
+ test_tx, test_ptx, rct_config, use_view_tags);
else
transfer_selected(tx.dsts, tx.selected_transfers, fake_outs_count, outs, unlock_time, needed_fee, extra,
- detail::digit_split_strategy, tx_dust_policy(::config::DEFAULT_DUST_THRESHOLD), test_tx, test_ptx);
+ detail::digit_split_strategy, tx_dust_policy(::config::DEFAULT_DUST_THRESHOLD), test_tx, test_ptx, use_view_tags);
auto txBlob = t_serializable_object_to_blob(test_ptx.tx);
- needed_fee = calculate_fee(use_per_byte_fee, test_ptx.tx, txBlob.size(), base_fee, fee_multiplier, fee_quantization_mask);
+ needed_fee = calculate_fee(use_per_byte_fee, test_ptx.tx, txBlob.size(), base_fee, fee_quantization_mask);
available_for_fee = test_ptx.fee + test_ptx.change_dts.amount;
for (auto &dt: test_ptx.dests)
available_for_fee += dt.amount;
@@ -10484,12 +10553,12 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_from(const crypton
}
if (use_rct)
transfer_selected_rct(tx.dsts, tx.selected_transfers, fake_outs_count, outs, unlock_time, needed_fee, extra,
- test_tx, test_ptx, rct_config);
+ test_tx, test_ptx, rct_config, use_view_tags);
else
transfer_selected(tx.dsts, tx.selected_transfers, fake_outs_count, outs, unlock_time, needed_fee, extra,
- detail::digit_split_strategy, tx_dust_policy(::config::DEFAULT_DUST_THRESHOLD), test_tx, test_ptx);
+ detail::digit_split_strategy, tx_dust_policy(::config::DEFAULT_DUST_THRESHOLD), test_tx, test_ptx, use_view_tags);
txBlob = t_serializable_object_to_blob(test_ptx.tx);
- needed_fee = calculate_fee(use_per_byte_fee, test_ptx.tx, txBlob.size(), base_fee, fee_multiplier, fee_quantization_mask);
+ needed_fee = calculate_fee(use_per_byte_fee, test_ptx.tx, txBlob.size(), base_fee, fee_quantization_mask);
LOG_PRINT_L2("Made an attempt at a final " << get_weight_string(test_ptx.tx, txBlob.size()) << " tx, with " << print_money(test_ptx.fee) <<
" fee and " << print_money(test_ptx.change_dts.amount) << " change");
} while (needed_fee > test_ptx.fee);
@@ -10523,10 +10592,10 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_from(const crypton
pending_tx test_ptx;
if (use_rct) {
transfer_selected_rct(tx.dsts, tx.selected_transfers, fake_outs_count, tx.outs, unlock_time, tx.needed_fee, extra,
- test_tx, test_ptx, rct_config);
+ test_tx, test_ptx, rct_config, use_view_tags);
} else {
transfer_selected(tx.dsts, tx.selected_transfers, fake_outs_count, tx.outs, unlock_time, tx.needed_fee, extra,
- detail::digit_split_strategy, tx_dust_policy(::config::DEFAULT_DUST_THRESHOLD), test_tx, test_ptx);
+ detail::digit_split_strategy, tx_dust_policy(::config::DEFAULT_DUST_THRESHOLD), test_tx, test_ptx, use_view_tags);
}
auto txBlob = t_serializable_object_to_blob(test_ptx.tx);
tx.tx = test_tx;
@@ -10595,7 +10664,7 @@ void wallet2::cold_sign_tx(const std::vector<pending_tx>& ptx_vector, signed_tx_
hw::wallet_shim wallet_shim;
setup_shim(&wallet_shim, this);
aux_data.tx_recipients = dsts_info;
- aux_data.bp_version = (use_fork_rules(HF_VERSION_CLSAG, -10) ? 3 : use_fork_rules(HF_VERSION_SMALLER_BP, -10) ? 2 : 1);
+ aux_data.bp_version = (use_fork_rules(HF_VERSION_BULLETPROOF_PLUS, -10) ? 4 : use_fork_rules(HF_VERSION_CLSAG, -10) ? 3 : use_fork_rules(HF_VERSION_SMALLER_BP, -10) ? 2 : 1);
aux_data.hard_fork = get_current_hard_fork();
dev_cold->tx_sign(&wallet_shim, txs, exported_txs, aux_data);
tx_device_aux = aux_data.tx_device_aux;
@@ -10816,7 +10885,7 @@ std::vector<wallet2::pending_tx> wallet2::create_unmixable_sweep_transactions()
const bool hf1_rules = use_fork_rules(2, 10); // first hard fork has version 2
tx_dust_policy dust_policy(hf1_rules ? 0 : ::config::DEFAULT_DUST_THRESHOLD);
- const uint64_t base_fee = get_base_fee();
+ const uint64_t base_fee = get_base_fee(1);
// may throw
std::vector<size_t> unmixable_outputs = select_available_unmixable_outputs();
@@ -11065,13 +11134,12 @@ std::string wallet2::get_spend_proof(const crypto::hash &txid, const std::string
// derive the real output keypair
const transfer_details& in_td = m_transfers[found->second];
- const txout_to_key* const in_tx_out_pkey = boost::get<txout_to_key>(std::addressof(in_td.m_tx.vout[in_td.m_internal_output_index].target));
- THROW_WALLET_EXCEPTION_IF(in_tx_out_pkey == nullptr, error::wallet_internal_error, "Output is not txout_to_key");
+ crypto::public_key in_tx_out_pkey = in_td.get_public_key();
const crypto::public_key in_tx_pub_key = get_tx_pub_key_from_extra(in_td.m_tx, in_td.m_pk_index);
const std::vector<crypto::public_key> in_additionakl_tx_pub_keys = get_additional_tx_pub_keys_from_extra(in_td.m_tx);
keypair in_ephemeral;
crypto::key_image in_img;
- THROW_WALLET_EXCEPTION_IF(!generate_key_image_helper(m_account.get_keys(), m_subaddresses, in_tx_out_pkey->key, in_tx_pub_key, in_additionakl_tx_pub_keys, in_td.m_internal_output_index, in_ephemeral, in_img, m_account.get_device()),
+ THROW_WALLET_EXCEPTION_IF(!generate_key_image_helper(m_account.get_keys(), m_subaddresses, in_tx_out_pkey, in_tx_pub_key, in_additionakl_tx_pub_keys, in_td.m_internal_output_index, in_ephemeral, in_img, m_account.get_device()),
error::wallet_internal_error, "failed to generate key image");
THROW_WALLET_EXCEPTION_IF(in_key->k_image != in_img, error::wallet_internal_error, "key image mismatch");
@@ -11270,24 +11338,12 @@ void wallet2::check_tx_key_helper(const cryptonote::transaction &tx, const crypt
for (size_t n = 0; n < tx.vout.size(); ++n)
{
- const cryptonote::txout_to_key* const out_key = boost::get<cryptonote::txout_to_key>(std::addressof(tx.vout[n].target));
- if (!out_key)
+ crypto::public_key output_public_key;
+ if (!get_output_public_key(tx.vout[n], output_public_key))
continue;
- crypto::public_key derived_out_key;
- bool r = crypto::derive_public_key(derivation, n, address.m_spend_public_key, derived_out_key);
- THROW_WALLET_EXCEPTION_IF(!r, error::wallet_internal_error, "Failed to derive public key");
- bool found = out_key->key == derived_out_key;
- crypto::key_derivation found_derivation = derivation;
- if (!found && !additional_derivations.empty())
- {
- r = crypto::derive_public_key(additional_derivations[n], n, address.m_spend_public_key, derived_out_key);
- THROW_WALLET_EXCEPTION_IF(!r, error::wallet_internal_error, "Failed to derive public key");
- found = out_key->key == derived_out_key;
- found_derivation = additional_derivations[n];
- }
-
- if (found)
+ crypto::key_derivation found_derivation;
+ if (is_out_to_acc(address, output_public_key, derivation, additional_derivations, n, get_output_view_tag(tx.vout[n]), found_derivation))
{
uint64_t amount;
if (tx.version == 1 || tx.rct_signatures.type == rct::RCTTypeNull)
@@ -11381,6 +11437,42 @@ void wallet2::check_tx_key_helper(const crypto::hash &txid, const crypto::key_de
}
}
+bool wallet2::is_out_to_acc(const cryptonote::account_public_address &address, const crypto::public_key& out_key, const crypto::key_derivation &derivation, const std::vector<crypto::key_derivation> &additional_derivations, const size_t output_index, const boost::optional<crypto::view_tag> &view_tag_opt, crypto::key_derivation &found_derivation) const
+{
+ crypto::public_key derived_out_key;
+ bool found = false;
+ bool r;
+ // first run quick check if output has matching view tag, otherwise output should not belong to account
+ if (out_can_be_to_acc(view_tag_opt, derivation, output_index))
+ {
+ // if view tag match, run slower check deriving output pub key and comparing to expected
+ r = crypto::derive_public_key(derivation, output_index, address.m_spend_public_key, derived_out_key);
+ THROW_WALLET_EXCEPTION_IF(!r, error::wallet_internal_error, "Failed to derive public key");
+ if (out_key == derived_out_key)
+ {
+ found = true;
+ found_derivation = derivation;
+ }
+ }
+
+ if (!found && !additional_derivations.empty())
+ {
+ const crypto::key_derivation &additional_derivation = additional_derivations[output_index];
+ if (out_can_be_to_acc(view_tag_opt, additional_derivation, output_index))
+ {
+ r = crypto::derive_public_key(additional_derivation, output_index, address.m_spend_public_key, derived_out_key);
+ THROW_WALLET_EXCEPTION_IF(!r, error::wallet_internal_error, "Failed to derive public key");
+ if (out_key == derived_out_key)
+ {
+ found = true;
+ found_derivation = additional_derivation;
+ }
+ }
+ }
+
+ return found;
+}
+
std::string wallet2::get_tx_proof(const crypto::hash &txid, const cryptonote::account_public_address &address, bool is_subaddress, const std::string &message)
{
// fetch tx pubkey from the daemon
@@ -11917,8 +12009,8 @@ bool wallet2::check_reserve_proof(const cryptonote::account_public_address &addr
THROW_WALLET_EXCEPTION_IF(proof.index_in_tx >= tx.vout.size(), error::wallet_internal_error, "index_in_tx is out of bound");
- const cryptonote::txout_to_key* const out_key = boost::get<cryptonote::txout_to_key>(std::addressof(tx.vout[proof.index_in_tx].target));
- THROW_WALLET_EXCEPTION_IF(!out_key, error::wallet_internal_error, "Output key wasn't found")
+ crypto::public_key output_public_key;
+ THROW_WALLET_EXCEPTION_IF(!get_output_public_key(tx.vout[proof.index_in_tx], output_public_key), error::wallet_internal_error, "Output key wasn't found");
// get tx pub key
const crypto::public_key tx_pub_key = get_tx_pub_key_from_extra(tx);
@@ -11933,7 +12025,7 @@ bool wallet2::check_reserve_proof(const cryptonote::account_public_address &addr
return false;
// check signature for key image
- const std::vector<const crypto::public_key*> pubs = { &out_key->key };
+ const std::vector<const crypto::public_key*> pubs = { &output_public_key };
ok = crypto::check_ring_signature(prefix_hash, proof.key_image, &pubs[0], 1, &proof.key_image_sig);
if (!ok)
return false;
@@ -11942,7 +12034,7 @@ bool wallet2::check_reserve_proof(const cryptonote::account_public_address &addr
crypto::key_derivation derivation;
THROW_WALLET_EXCEPTION_IF(!crypto::generate_key_derivation(proof.shared_secret, rct::rct2sk(rct::I), derivation), error::wallet_internal_error, "Failed to generate key derivation");
crypto::public_key subaddr_spendkey;
- crypto::derive_subaddress_public_key(out_key->key, derivation, proof.index_in_tx, subaddr_spendkey);
+ crypto::derive_subaddress_public_key(output_public_key, derivation, proof.index_in_tx, subaddr_spendkey);
THROW_WALLET_EXCEPTION_IF(subaddr_spendkeys.count(subaddr_spendkey) == 0, error::wallet_internal_error,
"The address doesn't seem to have received the fund");
@@ -12396,11 +12488,7 @@ std::pair<uint64_t, std::vector<std::pair<crypto::key_image, crypto::signature>>
const transfer_details &td = m_transfers[n];
// get ephemeral public key
- const cryptonote::tx_out &out = td.m_tx.vout[td.m_internal_output_index];
- THROW_WALLET_EXCEPTION_IF(out.target.type() != typeid(txout_to_key), error::wallet_internal_error,
- "Output is not txout_to_key");
- const cryptonote::txout_to_key &o = boost::get<const cryptonote::txout_to_key>(out.target);
- const crypto::public_key pkey = o.key;
+ const crypto::public_key pkey = td.get_public_key();
// get tx pub key
std::vector<tx_extra_field> tx_extra_fields;
@@ -12517,11 +12605,7 @@ uint64_t wallet2::import_key_images(const std::vector<std::pair<crypto::key_imag
const crypto::signature &signature = signed_key_images[n].second;
// get ephemeral public key
- const cryptonote::tx_out &out = td.m_tx.vout[td.m_internal_output_index];
- THROW_WALLET_EXCEPTION_IF(out.target.type() != typeid(txout_to_key), error::wallet_internal_error,
- "Non txout_to_key output found");
- const cryptonote::txout_to_key &o = boost::get<cryptonote::txout_to_key>(out.target);
- const crypto::public_key pkey = o.key;
+ const crypto::public_key pkey = td.get_public_key();
if (!td.m_key_image_known || !(key_image == td.m_key_image))
{
@@ -12977,9 +13061,7 @@ process:
THROW_WALLET_EXCEPTION_IF(td.m_internal_output_index >= td.m_tx.vout.size(),
error::wallet_internal_error, "Internal index is out of range");
- THROW_WALLET_EXCEPTION_IF(td.m_tx.vout[td.m_internal_output_index].target.type() != typeid(cryptonote::txout_to_key),
- error::wallet_internal_error, "Unsupported output type");
- const crypto::public_key& out_key = boost::get<cryptonote::txout_to_key>(td.m_tx.vout[td.m_internal_output_index].target).key;
+ crypto::public_key out_key = td.get_public_key();
bool r = cryptonote::generate_key_image_helper(m_account.get_keys(), m_subaddresses, out_key, tx_pub_key, additional_tx_pub_keys, td.m_internal_output_index, in_ephemeral, td.m_key_image, m_account.get_device());
THROW_WALLET_EXCEPTION_IF(!r, error::wallet_internal_error, "Failed to generate key image");
if (should_expand(td.m_subaddr_index))
@@ -14205,8 +14287,9 @@ std::pair<size_t, uint64_t> wallet2::estimate_tx_size_and_weight(bool use_rct, i
const bool bulletproof = use_fork_rules(get_bulletproof_fork(), 0);
const bool bulletproof_plus = use_fork_rules(get_bulletproof_plus_fork(), 0);
const bool clsag = use_fork_rules(get_clsag_fork(), 0);
- size_t size = estimate_tx_size(use_rct, n_inputs, ring_size - 1, n_outputs, extra_size, bulletproof, clsag, bulletproof_plus);
- uint64_t weight = estimate_tx_weight(use_rct, n_inputs, ring_size - 1, n_outputs, extra_size, bulletproof, clsag, bulletproof_plus);
+ const bool use_view_tags = use_fork_rules(get_view_tag_fork(), 0);
+ size_t size = estimate_tx_size(use_rct, n_inputs, ring_size - 1, n_outputs, extra_size, bulletproof, clsag, bulletproof_plus, use_view_tags);
+ uint64_t weight = estimate_tx_weight(use_rct, n_inputs, ring_size - 1, n_outputs, extra_size, bulletproof, clsag, bulletproof_plus, use_view_tags);
return std::make_pair(size, weight);
}
//----------------------------------------------------------------------------------------------------
diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h
index f5da348a9..660e6a14b 100644
--- a/src/wallet/wallet2.h
+++ b/src/wallet/wallet2.h
@@ -347,7 +347,12 @@ private:
bool is_rct() const { return m_rct; }
uint64_t amount() const { return m_amount; }
- const crypto::public_key &get_public_key() const { return boost::get<const cryptonote::txout_to_key>(m_tx.vout[m_internal_output_index].target).key; }
+ const crypto::public_key get_public_key() const {
+ crypto::public_key output_public_key;
+ THROW_WALLET_EXCEPTION_IF(!get_output_public_key(m_tx.vout[m_internal_output_index], output_public_key),
+ error::wallet_internal_error, "Unable to get output public key from output");
+ return output_public_key;
+ };
BEGIN_SERIALIZE_OBJECT()
FIELD(m_block_height)
@@ -529,10 +534,21 @@ private:
uint64_t unlock_time;
bool use_rct;
rct::RCTConfig rct_config;
+ bool use_view_tags;
std::vector<cryptonote::tx_destination_entry> dests; // original setup, does not include change
uint32_t subaddr_account; // subaddress account of your wallet to be used in this transfer
std::set<uint32_t> subaddr_indices; // set of address indices used as inputs in this transfer
+ enum construction_flags_ : uint8_t
+ {
+ _use_rct = 1 << 0, // 00000001
+ _use_view_tags = 1 << 1 // 00000010
+ // next flag = 1 << 2 // 00000100
+ // ...
+ // final flag = 1 << 7 // 10000000
+ };
+ uint8_t construction_flags;
+
BEGIN_SERIALIZE_OBJECT()
FIELD(sources)
FIELD(change_dts)
@@ -540,7 +556,26 @@ private:
FIELD(selected_transfers)
FIELD(extra)
FIELD(unlock_time)
- FIELD(use_rct)
+
+ // converted `use_rct` field into construction_flags when view tags
+ // were introduced to maintain backwards compatibility
+ if (!typename Archive<W>::is_saving())
+ {
+ FIELD_N("use_rct", construction_flags)
+ use_rct = (construction_flags & _use_rct) > 0;
+ use_view_tags = (construction_flags & _use_view_tags) > 0;
+ }
+ else
+ {
+ construction_flags = 0;
+ if (use_rct)
+ construction_flags ^= _use_rct;
+ if (use_view_tags)
+ construction_flags ^= _use_view_tags;
+
+ FIELD_N("use_rct", construction_flags)
+ }
+
FIELD(rct_config)
FIELD(dests)
FIELD(subaddr_account)
@@ -967,10 +1002,10 @@ private:
template<typename T>
void transfer_selected(const std::vector<cryptonote::tx_destination_entry>& dsts, const std::vector<size_t>& selected_transfers, size_t fake_outputs_count,
std::vector<std::vector<tools::wallet2::get_outs_entry>> &outs,
- uint64_t unlock_time, uint64_t fee, const std::vector<uint8_t>& extra, T destination_split_strategy, const tx_dust_policy& dust_policy, cryptonote::transaction& tx, pending_tx &ptx);
+ uint64_t unlock_time, uint64_t fee, const std::vector<uint8_t>& extra, T destination_split_strategy, const tx_dust_policy& dust_policy, cryptonote::transaction& tx, pending_tx &ptx, const bool use_view_tags);
void transfer_selected_rct(std::vector<cryptonote::tx_destination_entry> dsts, const std::vector<size_t>& selected_transfers, size_t fake_outputs_count,
std::vector<std::vector<tools::wallet2::get_outs_entry>> &outs,
- uint64_t unlock_time, uint64_t fee, const std::vector<uint8_t>& extra, cryptonote::transaction& tx, pending_tx &ptx, const rct::RCTConfig &rct_config);
+ uint64_t unlock_time, uint64_t fee, const std::vector<uint8_t>& extra, cryptonote::transaction& tx, pending_tx &ptx, const rct::RCTConfig &rct_config, const bool use_view_tags);
void commit_tx(pending_tx& ptx_vector);
void commit_tx(std::vector<pending_tx>& ptx_vector);
@@ -1090,9 +1125,7 @@ private:
for (size_t i = 0; i < m_transfers.size(); ++i)
{
const transfer_details &td = m_transfers[i];
- const cryptonote::tx_out &out = td.m_tx.vout[td.m_internal_output_index];
- const cryptonote::txout_to_key &o = boost::get<const cryptonote::txout_to_key>(out.target);
- m_pub_keys.emplace(o.key, i);
+ m_pub_keys.emplace(td.get_public_key(), i);
}
return;
}
@@ -1271,6 +1304,7 @@ private:
void check_tx_key(const crypto::hash &txid, const crypto::secret_key &tx_key, const std::vector<crypto::secret_key> &additional_tx_keys, const cryptonote::account_public_address &address, uint64_t &received, bool &in_pool, uint64_t &confirmations);
void check_tx_key_helper(const crypto::hash &txid, const crypto::key_derivation &derivation, const std::vector<crypto::key_derivation> &additional_derivations, const cryptonote::account_public_address &address, uint64_t &received, bool &in_pool, uint64_t &confirmations);
void check_tx_key_helper(const cryptonote::transaction &tx, const crypto::key_derivation &derivation, const std::vector<crypto::key_derivation> &additional_derivations, const cryptonote::account_public_address &address, uint64_t &received) const;
+ bool is_out_to_acc(const cryptonote::account_public_address &address, const crypto::public_key& out_key, const crypto::key_derivation &derivation, const std::vector<crypto::key_derivation> &additional_derivations, const size_t output_index, const boost::optional<crypto::view_tag> &view_tag_opt, crypto::key_derivation &found_derivation) const;
std::string get_tx_proof(const crypto::hash &txid, const cryptonote::account_public_address &address, bool is_subaddress, const std::string &message);
std::string get_tx_proof(const cryptonote::transaction &tx, const crypto::secret_key &tx_key, const std::vector<crypto::secret_key> &additional_tx_keys, const cryptonote::account_public_address &address, bool is_subaddress, const std::string &message) const;
bool check_tx_proof(const crypto::hash &txid, const cryptonote::account_public_address &address, bool is_subaddress, const std::string &message, const std::string &sig_str, uint64_t &received, bool &in_pool, uint64_t &confirmations);
@@ -1427,8 +1461,9 @@ private:
std::vector<std::pair<uint64_t, uint64_t>> estimate_backlog(const std::vector<std::pair<double, double>> &fee_levels);
std::vector<std::pair<uint64_t, uint64_t>> estimate_backlog(uint64_t min_tx_weight, uint64_t max_tx_weight, const std::vector<uint64_t> &fees);
- uint64_t estimate_fee(bool use_per_byte_fee, bool use_rct, int n_inputs, int mixin, int n_outputs, size_t extra_size, bool bulletproof, bool clsag, bool bulletproof_plus, uint64_t base_fee, uint64_t fee_multiplier, uint64_t fee_quantization_mask) const;
+ uint64_t estimate_fee(bool use_per_byte_fee, bool use_rct, int n_inputs, int mixin, int n_outputs, size_t extra_size, bool bulletproof, bool clsag, bool bulletproof_plus, bool use_view_tags, uint64_t base_fee, uint64_t fee_quantization_mask) const;
uint64_t get_fee_multiplier(uint32_t priority, int fee_algorithm = -1);
+ uint64_t get_base_fee(uint32_t priority);
uint64_t get_base_fee();
uint64_t get_fee_quantization_mask();
uint64_t get_min_ring_size();
diff --git a/tests/core_tests/block_validation.cpp b/tests/core_tests/block_validation.cpp
index 28f1de7d0..711f67b41 100644
--- a/tests/core_tests/block_validation.cpp
+++ b/tests/core_tests/block_validation.cpp
@@ -671,3 +671,127 @@ bool gen_block_low_coinbase::generate(std::vector<test_event_entry>& events) con
return true;
}
+
+bool gen_block_miner_tx_out_has_no_view_tag_before_hf_view_tags::generate(std::vector<test_event_entry>& events) const
+{
+ bool use_view_tags = false;
+
+ BLOCK_VALIDATION_INIT_GENERATE();
+
+ MAKE_MINER_TX_MANUALLY(miner_tx, blk_0);
+
+ CHECK_AND_ASSERT_MES(!cryptonote::get_output_view_tag(miner_tx.vout[0]), false, "output should not have a view tag");
+
+ crypto::public_key output_public_key;
+ crypto::view_tag view_tag;
+ cryptonote::get_output_public_key(miner_tx.vout[0], output_public_key);
+
+ // explicitly call the setter to ensure it does not set a view tag on the miner tx output
+ cryptonote::set_tx_out(miner_tx.vout[0].amount, output_public_key, use_view_tags, view_tag, miner_tx.vout[0]);
+ CHECK_AND_ASSERT_MES(!cryptonote::get_output_view_tag(miner_tx.vout[0]), false, "output should still not have a view tag");
+
+ block blk_1;
+ generator.construct_block_manually(blk_1, blk_0, miner_account, test_generator::bf_miner_tx, 0, 0, 0, crypto::hash(), 0, miner_tx);
+ events.push_back(blk_1);
+
+ DO_CALLBACK(events, "check_block_accepted");
+
+ return true;
+}
+
+bool gen_block_miner_tx_out_has_no_view_tag_from_hf_view_tags::generate(std::vector<test_event_entry>& events) const
+{
+ bool use_view_tags = false;
+
+ BLOCK_VALIDATION_INIT_GENERATE();
+
+ keypair txkey;
+ MAKE_MINER_TX_AND_KEY_AT_HF_MANUALLY(miner_tx, blk_0, HF_VERSION_VIEW_TAGS+1, &txkey);
+
+ crypto::public_key output_public_key;
+ crypto::view_tag view_tag;
+ cryptonote::get_output_public_key(miner_tx.vout[0], output_public_key);
+
+ // remove the view tag that is currently set on the miner tx output at this point
+ cryptonote::set_tx_out(miner_tx.vout[0].amount, output_public_key, use_view_tags, view_tag, miner_tx.vout[0]);
+ CHECK_AND_ASSERT_MES(!cryptonote::get_output_view_tag(miner_tx.vout[0]), false, "output should not have a view tag");
+
+ block blk_1;
+ generator.construct_block_manually(blk_1, blk_0, miner_account,
+ test_generator::bf_major_ver | test_generator::bf_minor_ver | test_generator::bf_miner_tx,
+ HF_VERSION_VIEW_TAGS+1, HF_VERSION_VIEW_TAGS+1, 0, crypto::hash(), 0, miner_tx);
+ events.push_back(blk_1);
+
+ DO_CALLBACK(events, "check_block_purged");
+
+ return true;
+}
+
+bool gen_block_miner_tx_out_has_view_tag_before_hf_view_tags::generate(std::vector<test_event_entry>& events) const
+{
+ bool use_view_tags = true;
+
+ BLOCK_VALIDATION_INIT_GENERATE();
+
+ keypair txkey;
+ MAKE_MINER_TX_AND_KEY_MANUALLY(miner_tx, blk_0, &txkey);
+
+ // derive the view tag for the miner tx output
+ crypto::key_derivation derivation;
+ crypto::public_key output_public_key;
+ crypto::view_tag view_tag;
+ crypto::generate_key_derivation(miner_account.get_keys().m_account_address.m_view_public_key, txkey.sec, derivation);
+ crypto::derive_public_key(derivation, 0, miner_account.get_keys().m_account_address.m_spend_public_key, output_public_key);
+ crypto::derive_view_tag(derivation, 0, view_tag);
+
+ // set the view tag on the miner tx output
+ cryptonote::set_tx_out(miner_tx.vout[0].amount, output_public_key, use_view_tags, view_tag, miner_tx.vout[0]);
+ boost::optional<crypto::view_tag> actual_vt = cryptonote::get_output_view_tag(miner_tx.vout[0]);
+ CHECK_AND_ASSERT_MES(actual_vt && *actual_vt == view_tag, false, "unexpected output view tag");
+
+ block blk_1;
+ generator.construct_block_manually(blk_1, blk_0, miner_account, test_generator::bf_miner_tx, 0, 0, 0, crypto::hash(), 0, miner_tx);
+ events.push_back(blk_1);
+
+ DO_CALLBACK(events, "check_block_purged");
+
+ return true;
+}
+
+bool gen_block_miner_tx_out_has_view_tag_from_hf_view_tags::generate(std::vector<test_event_entry>& events) const
+{
+ bool use_view_tags = true;
+
+ BLOCK_VALIDATION_INIT_GENERATE();
+
+ keypair txkey;
+ MAKE_MINER_TX_AND_KEY_AT_HF_MANUALLY(miner_tx, blk_0, HF_VERSION_VIEW_TAGS, &txkey);
+
+ CHECK_AND_ASSERT_MES(cryptonote::get_output_view_tag(miner_tx.vout[0]), false, "output should have a view tag");
+
+ // derive the view tag for the miner tx output
+ crypto::key_derivation derivation;
+ crypto::public_key output_public_key;
+ crypto::view_tag view_tag;
+ crypto::generate_key_derivation(miner_account.get_keys().m_account_address.m_view_public_key, txkey.sec, derivation);
+ crypto::derive_public_key(derivation, 0, miner_account.get_keys().m_account_address.m_spend_public_key, output_public_key);
+ crypto::derive_view_tag(derivation, 0, view_tag);
+
+ boost::optional<crypto::view_tag> actual_vt = cryptonote::get_output_view_tag(miner_tx.vout[0]);
+ CHECK_AND_ASSERT_MES(actual_vt && *actual_vt == view_tag, false, "unexpected output view tag");
+
+ // set the view tag on the miner tx output
+ cryptonote::set_tx_out(miner_tx.vout[0].amount, output_public_key, use_view_tags, view_tag, miner_tx.vout[0]);
+ boost::optional<crypto::view_tag> actual_vt_after_setting = cryptonote::get_output_view_tag(miner_tx.vout[0]);
+ CHECK_AND_ASSERT_MES(actual_vt_after_setting && *actual_vt_after_setting == view_tag, false, "unexpected output view tag after setting");
+
+ block blk_1;
+ generator.construct_block_manually(blk_1, blk_0, miner_account,
+ test_generator::bf_major_ver | test_generator::bf_minor_ver | test_generator::bf_miner_tx,
+ HF_VERSION_VIEW_TAGS, HF_VERSION_VIEW_TAGS, 0, crypto::hash(), 0, miner_tx);
+ events.push_back(blk_1);
+
+ DO_CALLBACK(events, "check_block_accepted");
+
+ return true;
+}
diff --git a/tests/core_tests/block_validation.h b/tests/core_tests/block_validation.h
index 2535039fb..3a157aaa9 100644
--- a/tests/core_tests/block_validation.h
+++ b/tests/core_tests/block_validation.h
@@ -230,3 +230,37 @@ struct get_test_options<gen_block_low_coinbase> {
hard_forks, 0
};
};
+
+struct gen_block_miner_tx_out_has_no_view_tag_before_hf_view_tags : public gen_block_accepted_base<2>
+{
+ bool generate(std::vector<test_event_entry>& events) const;
+};
+
+struct gen_block_miner_tx_out_has_no_view_tag_from_hf_view_tags : public gen_block_verification_base<1>
+{
+ bool generate(std::vector<test_event_entry>& events) const;
+};
+template<>
+struct get_test_options<gen_block_miner_tx_out_has_no_view_tag_from_hf_view_tags> {
+ const std::pair<uint8_t, uint64_t> hard_forks[3] = {std::make_pair(1, 0), std::make_pair(HF_VERSION_VIEW_TAGS+1, 1), std::make_pair(0, 0)};
+ const cryptonote::test_options test_options = {
+ hard_forks, 0
+ };
+};
+
+struct gen_block_miner_tx_out_has_view_tag_before_hf_view_tags : public gen_block_verification_base<1>
+{
+ bool generate(std::vector<test_event_entry>& events) const;
+};
+
+struct gen_block_miner_tx_out_has_view_tag_from_hf_view_tags : public gen_block_accepted_base<2>
+{
+ bool generate(std::vector<test_event_entry>& events) const;
+};
+template<>
+struct get_test_options<gen_block_miner_tx_out_has_view_tag_from_hf_view_tags> {
+ const std::pair<uint8_t, uint64_t> hard_forks[3] = {std::make_pair(1, 0), std::make_pair(HF_VERSION_VIEW_TAGS, 1), std::make_pair(0, 0)};
+ const cryptonote::test_options test_options = {
+ hard_forks, 0
+ };
+};
diff --git a/tests/core_tests/chaingen.cpp b/tests/core_tests/chaingen.cpp
index 689b6801b..61195c7b0 100644
--- a/tests/core_tests/chaingen.cpp
+++ b/tests/core_tests/chaingen.cpp
@@ -462,7 +462,9 @@ bool init_output_indices(map_output_idx_t& outs, std::map<uint64_t, std::vector<
size_t tx_global_idx = outs[out.amount].size() - 1;
outs[out.amount][tx_global_idx].idx = tx_global_idx;
// Is out to me?
- if (is_out_to_acc(from.get_keys(), boost::get<txout_to_key>(out.target), get_tx_pub_key_from_extra(tx), get_additional_tx_pub_keys_from_extra(tx), j)) {
+ crypto::public_key output_public_key;
+ cryptonote::get_output_public_key(out, output_public_key);
+ if (is_out_to_acc(from.get_keys(), output_public_key, get_tx_pub_key_from_extra(tx), get_additional_tx_pub_keys_from_extra(tx), j)) {
outs_mine[out.amount].push_back(tx_global_idx);
}
}
@@ -972,7 +974,7 @@ std::vector<cryptonote::tx_destination_entry> build_dsts(std::initializer_list<d
bool construct_miner_tx_manually(size_t height, uint64_t already_generated_coins,
const account_public_address& miner_address, transaction& tx, uint64_t fee,
- keypair* p_txkey/* = 0*/)
+ uint8_t hf_version/* = 1*/, keypair* p_txkey/* = 0*/)
{
keypair txkey;
txkey = keypair::generate(hw::get_device("default"));
@@ -987,7 +989,7 @@ bool construct_miner_tx_manually(size_t height, uint64_t already_generated_coins
// This will work, until size of constructed block is less then CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE
uint64_t block_reward;
- if (!get_block_reward(0, 0, already_generated_coins, block_reward, 1))
+ if (!get_block_reward(0, 0, already_generated_coins, block_reward, hf_version))
{
LOG_PRINT_L0("Block is too big");
return false;
@@ -999,12 +1001,20 @@ bool construct_miner_tx_manually(size_t height, uint64_t already_generated_coins
crypto::generate_key_derivation(miner_address.m_view_public_key, txkey.sec, derivation);
crypto::derive_public_key(derivation, 0, miner_address.m_spend_public_key, out_eph_public_key);
+ bool use_view_tags = hf_version >= HF_VERSION_VIEW_TAGS;
+ crypto::view_tag view_tag;
+ if (use_view_tags)
+ crypto::derive_view_tag(derivation, 0, view_tag);
+
tx_out out;
- out.amount = block_reward;
- out.target = txout_to_key(out_eph_public_key);
+ cryptonote::set_tx_out(block_reward, out_eph_public_key, use_view_tags, view_tag, out);
+
tx.vout.push_back(out);
- tx.version = 1;
+ if (hf_version >= HF_VERSION_DYNAMIC_FEE)
+ tx.version = 2;
+ else
+ tx.version = 1;
tx.unlock_time = height + CRYPTONOTE_MINED_MONEY_UNLOCK_WINDOW;
return true;
diff --git a/tests/core_tests/chaingen.h b/tests/core_tests/chaingen.h
index c1e592b86..5c8c9f79f 100644
--- a/tests/core_tests/chaingen.h
+++ b/tests/core_tests/chaingen.h
@@ -423,7 +423,8 @@ uint64_t sum_amount(const std::vector<cryptonote::tx_source_entry>& sources);
bool construct_miner_tx_manually(size_t height, uint64_t already_generated_coins,
const cryptonote::account_public_address& miner_address, cryptonote::transaction& tx,
- uint64_t fee, cryptonote::keypair* p_txkey = nullptr);
+ uint64_t fee, uint8_t hf_version = 1,
+ cryptonote::keypair* p_txkey = nullptr);
bool construct_tx_to_key(const std::vector<test_event_entry>& events, cryptonote::transaction& tx,
const cryptonote::block& blk_head, const cryptonote::account_base& from, const var_addr_t& to, uint64_t amount,
@@ -967,12 +968,14 @@ inline bool do_replay_file(const std::string& filename)
std::list<cryptonote::transaction> SET_NAME; \
MAKE_TX_MIX_LIST_RCT(VEC_EVENTS, SET_NAME, FROM, TO, AMOUNT, NMIX, HEAD);
-#define MAKE_MINER_TX_AND_KEY_MANUALLY(TX, BLK, KEY) \
+#define MAKE_MINER_TX_AND_KEY_AT_HF_MANUALLY(TX, BLK, HF_VERSION, KEY) \
transaction TX; \
if (!construct_miner_tx_manually(get_block_height(BLK) + 1, generator.get_already_generated_coins(BLK), \
- miner_account.get_keys().m_account_address, TX, 0, KEY)) \
+ miner_account.get_keys().m_account_address, TX, 0, HF_VERSION, KEY)) \
return false;
+#define MAKE_MINER_TX_AND_KEY_MANUALLY(TX, BLK, KEY) MAKE_MINER_TX_AND_KEY_AT_HF_MANUALLY(TX, BLK, 1, KEY)
+
#define MAKE_MINER_TX_MANUALLY(TX, BLK) MAKE_MINER_TX_AND_KEY_MANUALLY(TX, BLK, 0)
#define SET_EVENT_VISITOR_SETT(VEC_EVENTS, SETT) VEC_EVENTS.push_back(event_visitor_settings(SETT));
diff --git a/tests/core_tests/chaingen_main.cpp b/tests/core_tests/chaingen_main.cpp
index 2e2d170ff..b89dff445 100644
--- a/tests/core_tests/chaingen_main.cpp
+++ b/tests/core_tests/chaingen_main.cpp
@@ -133,6 +133,10 @@ int main(int argc, char* argv[])
GENERATE_AND_PLAY(gen_block_miner_tx_out_is_big);
GENERATE_AND_PLAY(gen_block_miner_tx_has_no_out);
GENERATE_AND_PLAY(gen_block_miner_tx_has_out_to_alice);
+ GENERATE_AND_PLAY(gen_block_miner_tx_out_has_no_view_tag_before_hf_view_tags);
+ GENERATE_AND_PLAY(gen_block_miner_tx_out_has_no_view_tag_from_hf_view_tags);
+ GENERATE_AND_PLAY(gen_block_miner_tx_out_has_view_tag_before_hf_view_tags);
+ GENERATE_AND_PLAY(gen_block_miner_tx_out_has_view_tag_from_hf_view_tags);
GENERATE_AND_PLAY(gen_block_has_invalid_tx);
GENERATE_AND_PLAY(gen_block_is_too_big);
GENERATE_AND_PLAY(gen_block_invalid_binary_format); // Takes up to 3 hours, if CRYPTONOTE_MINED_MONEY_UNLOCK_WINDOW == 500, up to 30 minutes, if CRYPTONOTE_MINED_MONEY_UNLOCK_WINDOW == 10
@@ -219,6 +223,15 @@ int main(int argc, char* argv[])
GENERATE_AND_PLAY(gen_rct_tx_pre_rct_increase_vin_and_fee);
GENERATE_AND_PLAY(gen_rct_tx_pre_rct_altered_extra);
GENERATE_AND_PLAY(gen_rct_tx_rct_altered_extra);
+ GENERATE_AND_PLAY(gen_rct_tx_pre_rct_has_no_view_tag_before_hf_view_tags);
+ // TODO: base test needs to be restructured to handle pre rct outputs after HF v12
+ // GENERATE_AND_PLAY(gen_rct_tx_pre_rct_has_no_view_tag_from_hf_view_tags);
+ GENERATE_AND_PLAY(gen_rct_tx_pre_rct_has_view_tag_before_hf_view_tags);
+ // GENERATE_AND_PLAY(gen_rct_tx_pre_rct_has_view_tag_from_hf_view_tags);
+ GENERATE_AND_PLAY(gen_rct_tx_rct_has_no_view_tag_before_hf_view_tags);
+ GENERATE_AND_PLAY(gen_rct_tx_rct_has_no_view_tag_from_hf_view_tags);
+ GENERATE_AND_PLAY(gen_rct_tx_rct_has_view_tag_before_hf_view_tags);
+ GENERATE_AND_PLAY(gen_rct_tx_rct_has_view_tag_from_hf_view_tags);
GENERATE_AND_PLAY(gen_rct_tx_uses_output_too_early);
GENERATE_AND_PLAY(gen_multisig_tx_valid_22_1_2);
diff --git a/tests/core_tests/rct.cpp b/tests/core_tests/rct.cpp
index 3a26de4c2..0926483fe 100644
--- a/tests/core_tests/rct.cpp
+++ b/tests/core_tests/rct.cpp
@@ -41,7 +41,7 @@ using namespace cryptonote;
// Tests
bool gen_rct_tx_validation_base::generate_with_full(std::vector<test_event_entry>& events,
- const int *out_idx, int mixin, uint64_t amount_paid, size_t second_rewind, uint8_t last_version, const rct::RCTConfig &rct_config, bool valid,
+ const int *out_idx, int mixin, uint64_t amount_paid, size_t second_rewind, uint8_t last_version, const rct::RCTConfig &rct_config, bool use_view_tags, bool valid,
const std::function<void(std::vector<tx_source_entry> &sources, std::vector<tx_destination_entry> &destinations)> &pre_tx,
const std::function<void(transaction &tx)> &post_tx) const
{
@@ -98,7 +98,9 @@ bool gen_rct_tx_validation_base::generate_with_full(std::vector<test_event_entry
const size_t index_in_tx = 5;
src.amount = 30000000000000;
for (int m = 0; m < 4; ++m) {
- src.push_output(m, boost::get<txout_to_key>(blocks[m].miner_tx.vout[index_in_tx].target).key, src.amount);
+ crypto::public_key output_public_key;
+ cryptonote::get_output_public_key(blocks[m].miner_tx.vout[index_in_tx], output_public_key);
+ src.push_output(m, output_public_key, src.amount);
}
src.real_out_tx_key = cryptonote::get_tx_pub_key_from_extra(blocks[n].miner_tx);
src.real_output = n;
@@ -139,10 +141,13 @@ bool gen_rct_tx_validation_base::generate_with_full(std::vector<test_event_entry
rct::decodeRct(rct_txes[n].rct_signatures, rct::sk2rct(amount_key), o, rct_tx_masks[o+n*4], hw::get_device("default"));
}
+ uint64_t fee = 0;
+ get_tx_fee(rct_txes[n], fee);
+
CHECK_AND_ASSERT_MES(generator.construct_block_manually(blk_txes[n], blk_last, miner_account,
- test_generator::bf_major_ver | test_generator::bf_minor_ver | test_generator::bf_timestamp | test_generator::bf_tx_hashes | test_generator::bf_hf_version | test_generator::bf_max_outs,
+ test_generator::bf_major_ver | test_generator::bf_minor_ver | test_generator::bf_timestamp | test_generator::bf_tx_hashes | test_generator::bf_hf_version | test_generator::bf_max_outs | test_generator::bf_tx_fees,
4, 4, blk_last.timestamp + DIFFICULTY_BLOCKS_ESTIMATE_TIMESPAN * 2, // v2 has blocks twice as long
- crypto::hash(), 0, transaction(), starting_rct_tx_hashes, 0, 6, 4),
+ crypto::hash(), 0, transaction(), starting_rct_tx_hashes, 0, 6, 4, fee),
false, "Failed to generate block");
events.push_back(blk_txes[n]);
blk_last = blk_txes[n];
@@ -224,7 +229,7 @@ bool gen_rct_tx_validation_base::generate_with_full(std::vector<test_event_entry
std::vector<crypto::secret_key> additional_tx_keys;
std::unordered_map<crypto::public_key, cryptonote::subaddress_index> subaddresses;
subaddresses[miner_accounts[0].get_keys().m_account_address.m_spend_public_key] = {0,0};
- bool r = construct_tx_and_get_tx_key(miner_accounts[0].get_keys(), subaddresses, sources, destinations, cryptonote::account_public_address{}, std::vector<uint8_t>(), tx, 0, tx_key, additional_tx_keys, true, rct_config);
+ bool r = construct_tx_and_get_tx_key(miner_accounts[0].get_keys(), subaddresses, sources, destinations, cryptonote::account_public_address{}, std::vector<uint8_t>(), tx, 0, tx_key, additional_tx_keys, true, rct_config, NULL, use_view_tags);
CHECK_AND_ASSERT_MES(r, false, "failed to construct transaction");
if (post_tx)
@@ -244,7 +249,8 @@ bool gen_rct_tx_validation_base::generate_with(std::vector<test_event_entry>& ev
const std::function<void(transaction &tx)> &post_tx) const
{
const rct::RCTConfig rct_config { rct::RangeProofBorromean, 0 };
- return generate_with_full(events, out_idx, mixin, amount_paid, CRYPTONOTE_DEFAULT_TX_SPENDABLE_AGE, 4, rct_config, valid, pre_tx, post_tx);
+ bool use_view_tags = false;
+ return generate_with_full(events, out_idx, mixin, amount_paid, CRYPTONOTE_DEFAULT_TX_SPENDABLE_AGE, 4, rct_config, use_view_tags, valid, pre_tx, post_tx);
}
bool gen_rct_tx_valid_from_pre_rct::generate(std::vector<test_event_entry>& events) const
@@ -517,11 +523,99 @@ bool gen_rct_tx_rct_altered_extra::generate(std::vector<test_event_entry>& event
NULL, [&failed](transaction &tx) {std::string extra_nonce; crypto::hash pid = crypto::null_hash; set_payment_id_to_tx_extra_nonce(extra_nonce, pid); if (!add_extra_nonce_to_tx_extra(tx.extra, extra_nonce)) failed = true; }) && !failed;
}
+bool gen_rct_tx_pre_rct_has_no_view_tag_before_hf_view_tags::generate(std::vector<test_event_entry>& events) const
+{
+ const int mixin = 2;
+ const int out_idx[] = {0, -1};
+ const uint64_t amount_paid = 10000;
+ bool use_view_tags = false;
+ bool valid = true;
+ return generate_with_full(events, out_idx, mixin, amount_paid, 0, 0, {}, use_view_tags, valid, NULL, NULL);
+}
+
+bool gen_rct_tx_pre_rct_has_no_view_tag_from_hf_view_tags::generate(std::vector<test_event_entry>& events) const
+{
+ const int mixin = 10;
+ const int out_idx[] = {0, -1};
+ const uint64_t amount_paid = 10000;
+ const rct::RCTConfig rct_config { rct::RangeProofPaddedBulletproof, 3 };
+ bool use_view_tags = false;
+ bool valid = false;
+ return generate_with_full(events, out_idx, mixin, amount_paid, CRYPTONOTE_DEFAULT_TX_SPENDABLE_AGE, HF_VERSION_VIEW_TAGS, rct_config, use_view_tags, valid, NULL, NULL);
+}
+
+bool gen_rct_tx_pre_rct_has_view_tag_before_hf_view_tags::generate(std::vector<test_event_entry>& events) const
+{
+ const int mixin = 2;
+ const int out_idx[] = {0, -1};
+ const uint64_t amount_paid = 10000;
+ bool use_view_tags = true;
+ bool valid = false;
+ return generate_with_full(events, out_idx, mixin, amount_paid, 0, 0, {}, use_view_tags, valid, NULL, NULL);
+}
+
+bool gen_rct_tx_pre_rct_has_view_tag_from_hf_view_tags::generate(std::vector<test_event_entry>& events) const
+{
+ const int mixin = 10;
+ const int out_idx[] = {0, -1};
+ const uint64_t amount_paid = 10000;
+ const rct::RCTConfig rct_config { rct::RangeProofPaddedBulletproof, 3 };
+ bool use_view_tags = true;
+ bool valid = true;
+ return generate_with_full(events, out_idx, mixin, amount_paid, CRYPTONOTE_DEFAULT_TX_SPENDABLE_AGE, HF_VERSION_VIEW_TAGS, rct_config, use_view_tags, valid, NULL, NULL);
+}
+
+bool gen_rct_tx_rct_has_no_view_tag_before_hf_view_tags::generate(std::vector<test_event_entry>& events) const
+{
+ const int mixin = 2;
+ const int out_idx[] = {1, -1};
+ const uint64_t amount_paid = 10000;
+ const rct::RCTConfig rct_config { rct::RangeProofBorromean, 0 };
+ bool use_view_tags = false;
+ bool valid = true;
+ return generate_with_full(events, out_idx, mixin, amount_paid, 0, 0, rct_config, use_view_tags, valid, NULL, NULL);
+}
+
+bool gen_rct_tx_rct_has_no_view_tag_from_hf_view_tags::generate(std::vector<test_event_entry>& events) const
+{
+ const int mixin = 10;
+ const int out_idx[] = {1, -1};
+ const uint64_t amount_paid = 10000;
+ const rct::RCTConfig rct_config { rct::RangeProofPaddedBulletproof, 3 };
+ bool use_view_tags = false;
+ bool valid = false;
+ return generate_with_full(events, out_idx, mixin, amount_paid, CRYPTONOTE_DEFAULT_TX_SPENDABLE_AGE, HF_VERSION_VIEW_TAGS+1, rct_config, use_view_tags, valid, NULL, NULL);
+}
+
+bool gen_rct_tx_rct_has_view_tag_before_hf_view_tags::generate(std::vector<test_event_entry>& events) const
+{
+ const int mixin = 2;
+ const int out_idx[] = {1, -1};
+ const uint64_t amount_paid = 10000;
+ const rct::RCTConfig rct_config { rct::RangeProofBorromean, 0 };
+ bool use_view_tags = true;
+ bool valid = false;
+ return generate_with_full(events, out_idx, mixin, amount_paid, 0, 0, rct_config, use_view_tags, valid, NULL, NULL);
+}
+
+bool gen_rct_tx_rct_has_view_tag_from_hf_view_tags::generate(std::vector<test_event_entry>& events) const
+{
+ const int mixin = 10;
+ const int out_idx[] = {1, -1};
+ const uint64_t amount_paid = 10000;
+ const rct::RCTConfig rct_config { rct::RangeProofPaddedBulletproof, 3 };
+ bool use_view_tags = true;
+ bool valid = true;
+ return generate_with_full(events, out_idx, mixin, amount_paid, CRYPTONOTE_DEFAULT_TX_SPENDABLE_AGE, HF_VERSION_VIEW_TAGS, rct_config, use_view_tags, valid, NULL, NULL);
+}
+
bool gen_rct_tx_uses_output_too_early::generate(std::vector<test_event_entry>& events) const
{
const int mixin = 10;
const int out_idx[] = {1, -1};
const uint64_t amount_paid = 10000;
const rct::RCTConfig rct_config { rct::RangeProofPaddedBulletproof, 2 };
- return generate_with_full(events, out_idx, mixin, amount_paid, CRYPTONOTE_DEFAULT_TX_SPENDABLE_AGE-3, HF_VERSION_ENFORCE_MIN_AGE, rct_config, false, NULL, NULL);
+ bool use_view_tags = false;
+ bool valid = false;
+ return generate_with_full(events, out_idx, mixin, amount_paid, CRYPTONOTE_DEFAULT_TX_SPENDABLE_AGE-3, HF_VERSION_ENFORCE_MIN_AGE, rct_config, use_view_tags, valid, NULL, NULL);
}
diff --git a/tests/core_tests/rct.h b/tests/core_tests/rct.h
index dee074e4c..c20e8a580 100644
--- a/tests/core_tests/rct.h
+++ b/tests/core_tests/rct.h
@@ -70,7 +70,7 @@ struct gen_rct_tx_validation_base : public test_chain_unit_base
}
bool generate_with_full(std::vector<test_event_entry>& events, const int *out_idx, int mixin,
- uint64_t amount_paid, size_t second_rewind, uint8_t last_version, const rct::RCTConfig &rct_config, bool valid,
+ uint64_t amount_paid, size_t second_rewind, uint8_t last_version, const rct::RCTConfig &rct_config, bool use_view_tags, bool valid,
const std::function<void(std::vector<cryptonote::tx_source_entry> &sources, std::vector<cryptonote::tx_destination_entry> &destinations)> &pre_tx,
const std::function<void(cryptonote::transaction &tx)> &post_tx) const;
bool generate_with(std::vector<test_event_entry>& events, const int *out_idx, int mixin,
@@ -266,6 +266,74 @@ struct gen_rct_tx_rct_altered_extra : public gen_rct_tx_validation_base
};
template<> struct get_test_options<gen_rct_tx_rct_altered_extra>: public get_test_options<gen_rct_tx_validation_base> {};
+struct gen_rct_tx_pre_rct_has_no_view_tag_before_hf_view_tags : public gen_rct_tx_validation_base
+{
+ bool generate(std::vector<test_event_entry>& events) const;
+};
+template<> struct get_test_options<gen_rct_tx_pre_rct_has_no_view_tag_before_hf_view_tags>: public get_test_options<gen_rct_tx_validation_base> {};
+
+struct gen_rct_tx_pre_rct_has_no_view_tag_from_hf_view_tags : public gen_rct_tx_validation_base
+{
+ bool generate(std::vector<test_event_entry>& events) const;
+};
+template<> struct get_test_options<gen_rct_tx_pre_rct_has_no_view_tag_from_hf_view_tags> {
+ const std::pair<uint8_t, uint64_t> hard_forks[5] = {std::make_pair(1, 0), std::make_pair(2, 1), std::make_pair(4, 65), std::make_pair(HF_VERSION_VIEW_TAGS, 69), std::make_pair(0, 0)};
+ const cryptonote::test_options test_options = {
+ hard_forks, 0
+ };
+};
+
+struct gen_rct_tx_pre_rct_has_view_tag_before_hf_view_tags : public gen_rct_tx_validation_base
+{
+ bool generate(std::vector<test_event_entry>& events) const;
+};
+template<> struct get_test_options<gen_rct_tx_pre_rct_has_view_tag_before_hf_view_tags>: public get_test_options<gen_rct_tx_validation_base> {};
+
+struct gen_rct_tx_pre_rct_has_view_tag_from_hf_view_tags : public gen_rct_tx_validation_base
+{
+ bool generate(std::vector<test_event_entry>& events) const;
+};
+template<> struct get_test_options<gen_rct_tx_pre_rct_has_view_tag_from_hf_view_tags> {
+ const std::pair<uint8_t, uint64_t> hard_forks[5] = {std::make_pair(1, 0), std::make_pair(2, 1), std::make_pair(4, 65), std::make_pair(HF_VERSION_VIEW_TAGS, 69), std::make_pair(0, 0)};
+ const cryptonote::test_options test_options = {
+ hard_forks, 0
+ };
+};
+
+struct gen_rct_tx_rct_has_no_view_tag_before_hf_view_tags : public gen_rct_tx_validation_base
+{
+ bool generate(std::vector<test_event_entry>& events) const;
+};
+template<> struct get_test_options<gen_rct_tx_rct_has_no_view_tag_before_hf_view_tags>: public get_test_options<gen_rct_tx_validation_base> {};
+
+struct gen_rct_tx_rct_has_no_view_tag_from_hf_view_tags : public gen_rct_tx_validation_base
+{
+ bool generate(std::vector<test_event_entry>& events) const;
+};
+template<> struct get_test_options<gen_rct_tx_rct_has_no_view_tag_from_hf_view_tags> {
+ const std::pair<uint8_t, uint64_t> hard_forks[5] = {std::make_pair(1, 0), std::make_pair(2, 1), std::make_pair(4, 65), std::make_pair(HF_VERSION_VIEW_TAGS+1, 69), std::make_pair(0, 0)};
+ const cryptonote::test_options test_options = {
+ hard_forks, 0
+ };
+};
+
+struct gen_rct_tx_rct_has_view_tag_before_hf_view_tags : public gen_rct_tx_validation_base
+{
+ bool generate(std::vector<test_event_entry>& events) const;
+};
+template<> struct get_test_options<gen_rct_tx_rct_has_view_tag_before_hf_view_tags>: public get_test_options<gen_rct_tx_validation_base> {};
+
+struct gen_rct_tx_rct_has_view_tag_from_hf_view_tags : public gen_rct_tx_validation_base
+{
+ bool generate(std::vector<test_event_entry>& events) const;
+};
+template<> struct get_test_options<gen_rct_tx_rct_has_view_tag_from_hf_view_tags> {
+ const std::pair<uint8_t, uint64_t> hard_forks[5] = {std::make_pair(1, 0), std::make_pair(2, 1), std::make_pair(4, 65), std::make_pair(HF_VERSION_VIEW_TAGS, 69), std::make_pair(0, 0)};
+ const cryptonote::test_options test_options = {
+ hard_forks, 0
+ };
+};
+
struct gen_rct_tx_uses_output_too_early : public gen_rct_tx_validation_base
{
bool generate(std::vector<test_event_entry>& events) const;
diff --git a/tests/crypto/main.cpp b/tests/crypto/main.cpp
index 59a2a7d77..045ffc08d 100644
--- a/tests/crypto/main.cpp
+++ b/tests/crypto/main.cpp
@@ -260,7 +260,6 @@ int main(int argc, char *argv[]) {
goto error;
}
} else if (cmd == "check_ge_p3_identity") {
- cerr << "Testing: " << cmd << endl;
public_key point;
bool expected_bad, expected_good, result_badfunc, result_goodfunc;
get(input, point, expected_bad, expected_good);
@@ -269,6 +268,15 @@ int main(int argc, char *argv[]) {
if (expected_bad != result_badfunc || expected_good != result_goodfunc) {
goto error;
}
+ } else if (cmd == "derive_view_tag") {
+ key_derivation derivation;
+ size_t output_index;
+ view_tag expected, actual;
+ get(input, derivation, output_index, expected);
+ derive_view_tag(derivation, output_index, actual);
+ if (expected != actual) {
+ goto error;
+ }
} else {
throw ios_base::failure("Unknown function: " + cmd);
}
diff --git a/tests/crypto/tests.txt b/tests/crypto/tests.txt
index 3a7fe5453..d387aa09d 100644
--- a/tests/crypto/tests.txt
+++ b/tests/crypto/tests.txt
@@ -5473,3 +5473,59 @@ check_ge_p3_identity 046e1450f147f3ade34d149973913cc75d4e7b9669eb1ed61da0f1d4a0b
check_ge_p3_identity ca8a2f621cfc7aa3efcd7ddf55dce5352e757b38aca0869b050c0a27824e5c5e true true
check_ge_p3_identity 64a247eef6087d86e1e9fa048a3c181fdb1728431f29ba738634bdc38f02a859 true true
check_ge_p3_identity cff0c7170a41395b0658ee42b76545c45360736b973ab2f31f6f227b9415df67 true true
+derive_view_tag 0fc47054f355ced4d67de73bfa12e4c78ff19089548fffa7d07a674741860f97 0 76
+derive_view_tag 0fc47054f355ced4d67de73bfa12e4c78ff19089548fffa7d07a674741860f97 1 d6
+derive_view_tag 0fc47054f355ced4d67de73bfa12e4c78ff19089548fffa7d07a674741860f97 2 87
+derive_view_tag 0fc47054f355ced4d67de73bfa12e4c78ff19089548fffa7d07a674741860f97 3 1b
+derive_view_tag 0fc47054f355ced4d67de73bfa12e4c78ff19089548fffa7d07a674741860f97 12 d6
+derive_view_tag 0fc47054f355ced4d67de73bfa12e4c78ff19089548fffa7d07a674741860f97 13 e9
+derive_view_tag 0fc47054f355ced4d67de73bfa12e4c78ff19089548fffa7d07a674741860f97 14 12
+derive_view_tag 0fc47054f355ced4d67de73bfa12e4c78ff19089548fffa7d07a674741860f97 15 26
+derive_view_tag a36ba7b4d31349ad278a6df8f77adb76748b59f4929348e67dd92adb9fa174dc 0 70
+derive_view_tag a36ba7b4d31349ad278a6df8f77adb76748b59f4929348e67dd92adb9fa174dc 1 81
+derive_view_tag a36ba7b4d31349ad278a6df8f77adb76748b59f4929348e67dd92adb9fa174dc 2 a0
+derive_view_tag a36ba7b4d31349ad278a6df8f77adb76748b59f4929348e67dd92adb9fa174dc 3 ec
+derive_view_tag a36ba7b4d31349ad278a6df8f77adb76748b59f4929348e67dd92adb9fa174dc 12 22
+derive_view_tag a36ba7b4d31349ad278a6df8f77adb76748b59f4929348e67dd92adb9fa174dc 13 0a
+derive_view_tag a36ba7b4d31349ad278a6df8f77adb76748b59f4929348e67dd92adb9fa174dc 14 87
+derive_view_tag a36ba7b4d31349ad278a6df8f77adb76748b59f4929348e67dd92adb9fa174dc 15 76
+derive_view_tag 7498d5bf0b69e08653f6d420a17f866dd2bd490ab43074f46065cb501fe7e2d8 0 93
+derive_view_tag 7498d5bf0b69e08653f6d420a17f866dd2bd490ab43074f46065cb501fe7e2d8 1 67
+derive_view_tag 7498d5bf0b69e08653f6d420a17f866dd2bd490ab43074f46065cb501fe7e2d8 2 9d
+derive_view_tag 7498d5bf0b69e08653f6d420a17f866dd2bd490ab43074f46065cb501fe7e2d8 3 2d
+derive_view_tag 7498d5bf0b69e08653f6d420a17f866dd2bd490ab43074f46065cb501fe7e2d8 12 63
+derive_view_tag 7498d5bf0b69e08653f6d420a17f866dd2bd490ab43074f46065cb501fe7e2d8 13 cf
+derive_view_tag 7498d5bf0b69e08653f6d420a17f866dd2bd490ab43074f46065cb501fe7e2d8 14 ef
+derive_view_tag 7498d5bf0b69e08653f6d420a17f866dd2bd490ab43074f46065cb501fe7e2d8 15 10
+derive_view_tag fe7770c4b076e95ddb8026affcfab39d31c7c4a2266e0e25e343bc4badc907d0 0 90
+derive_view_tag fe7770c4b076e95ddb8026affcfab39d31c7c4a2266e0e25e343bc4badc907d0 1 5a
+derive_view_tag fe7770c4b076e95ddb8026affcfab39d31c7c4a2266e0e25e343bc4badc907d0 2 de
+derive_view_tag fe7770c4b076e95ddb8026affcfab39d31c7c4a2266e0e25e343bc4badc907d0 3 21
+derive_view_tag fe7770c4b076e95ddb8026affcfab39d31c7c4a2266e0e25e343bc4badc907d0 12 57
+derive_view_tag fe7770c4b076e95ddb8026affcfab39d31c7c4a2266e0e25e343bc4badc907d0 13 52
+derive_view_tag fe7770c4b076e95ddb8026affcfab39d31c7c4a2266e0e25e343bc4badc907d0 14 6f
+derive_view_tag fe7770c4b076e95ddb8026affcfab39d31c7c4a2266e0e25e343bc4badc907d0 15 eb
+derive_view_tag ea9337d0ddf480abdc4fc56a0cb223702729cb230ae7b9de50243ad25ce90e8d 0 c6
+derive_view_tag ea9337d0ddf480abdc4fc56a0cb223702729cb230ae7b9de50243ad25ce90e8d 1 60
+derive_view_tag ea9337d0ddf480abdc4fc56a0cb223702729cb230ae7b9de50243ad25ce90e8d 2 f0
+derive_view_tag ea9337d0ddf480abdc4fc56a0cb223702729cb230ae7b9de50243ad25ce90e8d 3 71
+derive_view_tag ea9337d0ddf480abdc4fc56a0cb223702729cb230ae7b9de50243ad25ce90e8d 12 0e
+derive_view_tag ea9337d0ddf480abdc4fc56a0cb223702729cb230ae7b9de50243ad25ce90e8d 13 42
+derive_view_tag ea9337d0ddf480abdc4fc56a0cb223702729cb230ae7b9de50243ad25ce90e8d 14 b2
+derive_view_tag ea9337d0ddf480abdc4fc56a0cb223702729cb230ae7b9de50243ad25ce90e8d 15 61
+derive_view_tag 25d538315bcb81aff9574189ea65f418aeb0392f5cbbc84cd8a33c7ade31ef0a 0 4c
+derive_view_tag 25d538315bcb81aff9574189ea65f418aeb0392f5cbbc84cd8a33c7ade31ef0a 1 9b
+derive_view_tag 25d538315bcb81aff9574189ea65f418aeb0392f5cbbc84cd8a33c7ade31ef0a 2 64
+derive_view_tag 25d538315bcb81aff9574189ea65f418aeb0392f5cbbc84cd8a33c7ade31ef0a 3 ff
+derive_view_tag 25d538315bcb81aff9574189ea65f418aeb0392f5cbbc84cd8a33c7ade31ef0a 12 e3
+derive_view_tag 25d538315bcb81aff9574189ea65f418aeb0392f5cbbc84cd8a33c7ade31ef0a 13 24
+derive_view_tag 25d538315bcb81aff9574189ea65f418aeb0392f5cbbc84cd8a33c7ade31ef0a 14 ea
+derive_view_tag 25d538315bcb81aff9574189ea65f418aeb0392f5cbbc84cd8a33c7ade31ef0a 15 3b
+derive_view_tag 8edfabada2b24ef4d8d915826c9ff0245910e4b835b59c2cf8ed8fc991b2e1e8 0 74
+derive_view_tag 8edfabada2b24ef4d8d915826c9ff0245910e4b835b59c2cf8ed8fc991b2e1e8 1 77
+derive_view_tag 8edfabada2b24ef4d8d915826c9ff0245910e4b835b59c2cf8ed8fc991b2e1e8 2 a9
+derive_view_tag 8edfabada2b24ef4d8d915826c9ff0245910e4b835b59c2cf8ed8fc991b2e1e8 3 44
+derive_view_tag 8edfabada2b24ef4d8d915826c9ff0245910e4b835b59c2cf8ed8fc991b2e1e8 12 75
+derive_view_tag 8edfabada2b24ef4d8d915826c9ff0245910e4b835b59c2cf8ed8fc991b2e1e8 13 05
+derive_view_tag 8edfabada2b24ef4d8d915826c9ff0245910e4b835b59c2cf8ed8fc991b2e1e8 14 ca
+derive_view_tag 8edfabada2b24ef4d8d915826c9ff0245910e4b835b59c2cf8ed8fc991b2e1e8 15 00
diff --git a/tests/functional_tests/blockchain.py b/tests/functional_tests/blockchain.py
index 4c8f367c0..328c225ff 100755
--- a/tests/functional_tests/blockchain.py
+++ b/tests/functional_tests/blockchain.py
@@ -81,10 +81,10 @@ class BlockchainTest():
assert ok
res = daemon.get_fee_estimate()
- assert res.fee == 234562
+ assert res.fee == 1200000
assert res.quantization_mask == 10000
res = daemon.get_fee_estimate(10)
- assert res.fee <= 234562
+ assert res.fee <= 1200000
# generate blocks
res_generateblocks = daemon.generateblocks('42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm', blocks)
@@ -243,10 +243,10 @@ class BlockchainTest():
assert res.histogram[i].recent_instances == 0
res = daemon.get_fee_estimate()
- assert res.fee == 234560
+ assert res.fee == 1200000
assert res.quantization_mask == 10000
res = daemon.get_fee_estimate(10)
- assert res.fee <= 234560
+ assert res.fee <= 1200000
def _test_alt_chains(self):
print('Testing alt chains')
diff --git a/tests/functional_tests/cold_signing.py b/tests/functional_tests/cold_signing.py
index 2233f19e7..31d5780bb 100755
--- a/tests/functional_tests/cold_signing.py
+++ b/tests/functional_tests/cold_signing.py
@@ -101,7 +101,7 @@ class ColdSigningTest():
res = self.cold_wallet.export_key_images(True)
self.hot_wallet.import_key_images(res.signed_key_images, offset = res.offset)
- res = self.hot_wallet.transfer([dst], ring_size = 11, get_tx_key = False)
+ res = self.hot_wallet.transfer([dst], ring_size = 16, get_tx_key = False)
assert len(res.tx_hash) == 32*2
txid = res.tx_hash
assert len(res.tx_key) == 0
@@ -121,7 +121,7 @@ class ColdSigningTest():
desc = res.desc[0]
assert desc.amount_in >= amount + fee
assert desc.amount_out == desc.amount_in - fee
- assert desc.ring_size == 11
+ assert desc.ring_size == 16
assert desc.unlock_time == 0
assert desc.payment_id in ['', '0000000000000000']
assert desc.change_amount == desc.amount_in - 1000000000000 - fee
diff --git a/tests/functional_tests/main.cpp b/tests/functional_tests/main.cpp
index d3b7a9592..41c55e4d4 100644
--- a/tests/functional_tests/main.cpp
+++ b/tests/functional_tests/main.cpp
@@ -51,7 +51,7 @@ namespace
const command_line::arg_descriptor<std::string> arg_daemon_addr_b = {"daemon-addr-b", "", "127.0.0.1:8082"};
const command_line::arg_descriptor<uint64_t> arg_transfer_amount = {"transfer_amount", "", 60000000000000};
- const command_line::arg_descriptor<size_t> arg_mix_in_factor = {"mix-in-factor", "", 10};
+ const command_line::arg_descriptor<size_t> arg_mix_in_factor = {"mix-in-factor", "", 15};
const command_line::arg_descriptor<size_t> arg_tx_count = {"tx-count", "", 100};
const command_line::arg_descriptor<size_t> arg_tx_per_second = {"tx-per-second", "", 20};
const command_line::arg_descriptor<size_t> arg_test_repeat_count = {"test_repeat_count", "", 1};
diff --git a/tests/functional_tests/multisig.py b/tests/functional_tests/multisig.py
index 17b94494a..c1b50b1e2 100755
--- a/tests/functional_tests/multisig.py
+++ b/tests/functional_tests/multisig.py
@@ -44,7 +44,7 @@ class MultisigTest():
self.mine('41mro238grj56GnrWkakAKTkBy2yDcXYsUZ2iXCM9pe5Ueajd2RRc6Fhh3uBXT2UAKhAsUJ7Fg5zjjF2U1iGciFk5ief4ZP', 5)
self.mine('44vZSprQKJQRFe6t1VHgU4ESvq2dv7TjBLVGE7QscKxMdFSiyyPCEV64NnKUQssFPyWxc2meyt7j63F2S2qtCTRL6dakeff', 5)
self.mine('47puypSwsV1gvUDratmX4y58fSwikXVehEiBhVLxJA1gRCxHyrRgTDr4NnKUQssFPyWxc2meyt7j63F2S2qtCTRL6aRPj5U', 5)
- self.mine('42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm', 60)
+ self.mine('42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm', 80)
self.test_states()
@@ -261,7 +261,7 @@ class MultisigTest():
desc = res.desc[0]
assert desc.amount_in >= amount + fee
assert desc.amount_out == desc.amount_in - fee
- assert desc.ring_size == 11
+ assert desc.ring_size == 16
assert desc.unlock_time == 0
assert not 'payment_id' in desc or desc.payment_id in ['', '0000000000000000']
assert desc.change_amount == desc.amount_in - 1000000000000 - fee
diff --git a/tests/functional_tests/transfer.py b/tests/functional_tests/transfer.py
index 5314b045d..dd15369d3 100755
--- a/tests/functional_tests/transfer.py
+++ b/tests/functional_tests/transfer.py
@@ -82,11 +82,11 @@ class TransferTest():
res = daemon.get_info()
height = res.height
- daemon.generateblocks('42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm', 80)
+ daemon.generateblocks('42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm', 100)
for i in range(len(self.wallet)):
self.wallet[i].refresh()
res = self.wallet[i].get_height()
- assert res.height == height + 80
+ assert res.height == height + 100
def transfer(self):
daemon = Daemon()
@@ -110,23 +110,23 @@ class TransferTest():
print ('Checking short payment IDs cannot be used when not in an integrated address')
ok = False
- try: self.wallet[0].transfer([dst], ring_size = 11, payment_id = '1234567812345678', get_tx_key = False)
+ try: self.wallet[0].transfer([dst], ring_size = 16, payment_id = '1234567812345678', get_tx_key = False)
except: ok = True
assert ok
print ('Checking long payment IDs are rejected')
ok = False
- try: self.wallet[0].transfer([dst], ring_size = 11, payment_id = payment_id, get_tx_key = False, get_tx_hex = True)
+ try: self.wallet[0].transfer([dst], ring_size = 16, payment_id = payment_id, get_tx_key = False, get_tx_hex = True)
except: ok = True
assert ok
print ('Checking empty destination is rejected')
ok = False
- try: self.wallet[0].transfer([], ring_size = 11, get_tx_key = False)
+ try: self.wallet[0].transfer([], ring_size = 16, get_tx_key = False)
except: ok = True
assert ok
- res = self.wallet[0].transfer([dst], ring_size = 11, get_tx_key = False, get_tx_hex = True)
+ res = self.wallet[0].transfer([dst], ring_size = 16, get_tx_key = False, get_tx_hex = True)
assert len(res.tx_hash) == 32*2
txid = res.tx_hash
assert len(res.tx_key) == 0
@@ -231,7 +231,7 @@ class TransferTest():
print("Creating transfer to another, manual relay")
dst = {'address': '44Kbx4sJ7JDRDV5aAhLJzQCjDz2ViLRduE3ijDZu3osWKBjMGkV1XPk4pfDUMqt1Aiezvephdqm6YD19GKFD9ZcXVUTp6BW', 'amount': 1000000000000}
- res = self.wallet[0].transfer([dst], ring_size = 11, get_tx_key = True, do_not_relay = True, get_tx_hex = True)
+ res = self.wallet[0].transfer([dst], ring_size = 16, get_tx_key = True, do_not_relay = True, get_tx_hex = True)
assert len(res.tx_hash) == 32*2
txid = res.tx_hash
assert len(res.tx_key) == 32*2
@@ -321,7 +321,7 @@ class TransferTest():
dst0 = {'address': '42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm', 'amount': 1000000000000}
dst1 = {'address': '44Kbx4sJ7JDRDV5aAhLJzQCjDz2ViLRduE3ijDZu3osWKBjMGkV1XPk4pfDUMqt1Aiezvephdqm6YD19GKFD9ZcXVUTp6BW', 'amount': 1100000000000}
dst2 = {'address': '46r4nYSevkfBUMhuykdK3gQ98XDqDTYW1hNLaXNvjpsJaSbNtdXh1sKMsdVgqkaihChAzEy29zEDPMR3NHQvGoZCLGwTerK', 'amount': 1200000000000}
- res = self.wallet[0].transfer([dst0, dst1, dst2], ring_size = 11, get_tx_key = True)
+ res = self.wallet[0].transfer([dst0, dst1, dst2], ring_size = 16, get_tx_key = True)
assert len(res.tx_hash) == 32*2
txid = res.tx_hash
assert len(res.tx_key) == 32*2
diff --git a/tests/performance_tests/CMakeLists.txt b/tests/performance_tests/CMakeLists.txt
index 03b124981..c079afe3a 100644
--- a/tests/performance_tests/CMakeLists.txt
+++ b/tests/performance_tests/CMakeLists.txt
@@ -43,6 +43,7 @@ set(performance_tests_headers
generate_keypair.h
signature.h
is_out_to_acc.h
+ out_can_be_to_acc.h
subaddress_expand.h
range_proof.h
bulletproof.h
diff --git a/src/p2p/stdafx.h b/tests/performance_tests/derive_view_tag.h
index 27157c8cd..ee4efb16d 100644
--- a/src/p2p/stdafx.h
+++ b/tests/performance_tests/derive_view_tag.h
@@ -1,21 +1,21 @@
-// Copyright (c) 2014-2022, The Monero Project
-//
+// Copyright (c) 2014-2021, 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
@@ -25,29 +25,38 @@
// 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.
-//
+//
// Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers
#pragma once
-#include "targetver.h"
+#include "crypto/crypto.h"
+#include "cryptonote_basic/cryptonote_basic.h"
+#include "single_tx_test_base.h"
-#if !defined(__GNUC__)
-#define _CRTDBG_MAP_ALLOC
-#include <stdlib.h>
-#include <crtdbg.h>
-#endif
+class test_derive_view_tag : public single_tx_test_base
+{
+public:
+ static const size_t loop_count = 10000;
+ bool init()
+ {
+ if (!single_tx_test_base::init())
+ return false;
+ crypto::generate_key_derivation(m_tx_pub_key, m_bob.get_keys().m_view_secret_key, m_key_derivation);
-#include <stdio.h>
-
-
-#define BOOST_FILESYSTEM_VERSION 3
-#define ENABLE_RELEASE_LOGGING
-#include "log_opt_defs.h"
-#include "misc_log_ex.h"
-
+ return true;
+ }
+ bool test()
+ {
+ crypto::view_tag view_tag;
+ crypto::derive_view_tag(m_key_derivation, 0, view_tag);
+ return true;
+ }
+private:
+ crypto::key_derivation m_key_derivation;
+};
diff --git a/tests/performance_tests/is_out_to_acc.h b/tests/performance_tests/is_out_to_acc.h
index d1204ee68..75d4a5c46 100644
--- a/tests/performance_tests/is_out_to_acc.h
+++ b/tests/performance_tests/is_out_to_acc.h
@@ -43,8 +43,9 @@ public:
bool test()
{
- const cryptonote::txout_to_key& tx_out = boost::get<cryptonote::txout_to_key>(m_tx.vout[0].target);
- return cryptonote::is_out_to_acc(m_bob.get_keys(), tx_out, m_tx_pub_key, m_additional_tx_pub_keys, 0);
+ crypto::public_key output_public_key;
+ cryptonote::get_output_public_key(m_tx.vout[0], output_public_key);
+ return cryptonote::is_out_to_acc(m_bob.get_keys(), output_public_key, m_tx_pub_key, m_additional_tx_pub_keys, 0);
}
};
diff --git a/tests/performance_tests/main.cpp b/tests/performance_tests/main.cpp
index 8bd1008cb..71c736977 100644
--- a/tests/performance_tests/main.cpp
+++ b/tests/performance_tests/main.cpp
@@ -42,6 +42,7 @@
#include "cn_slow_hash.h"
#include "derive_public_key.h"
#include "derive_secret_key.h"
+#include "derive_view_tag.h"
#include "ge_frombytes_vartime.h"
#include "ge_tobytes.h"
#include "generate_key_derivation.h"
@@ -50,6 +51,7 @@
#include "generate_keypair.h"
#include "signature.h"
#include "is_out_to_acc.h"
+#include "out_can_be_to_acc.h"
#include "subaddress_expand.h"
#include "sc_reduce32.h"
#include "sc_check.h"
@@ -194,6 +196,9 @@ int main(int argc, char** argv)
TEST_PERFORMANCE0(filter, p, test_is_out_to_acc);
TEST_PERFORMANCE0(filter, p, test_is_out_to_acc_precomp);
+ TEST_PERFORMANCE2(filter, p, test_out_can_be_to_acc, false, true); // no view tag, owned
+ TEST_PERFORMANCE2(filter, p, test_out_can_be_to_acc, true, false); // use view tag, not owned
+ TEST_PERFORMANCE2(filter, p, test_out_can_be_to_acc, true, true); // use view tag, owned
TEST_PERFORMANCE0(filter, p, test_generate_key_image_helper);
TEST_PERFORMANCE0(filter, p, test_generate_key_derivation);
TEST_PERFORMANCE0(filter, p, test_generate_key_image);
@@ -206,6 +211,7 @@ int main(int argc, char** argv)
TEST_PERFORMANCE0(filter, p, test_sc_check);
TEST_PERFORMANCE1(filter, p, test_signature, false);
TEST_PERFORMANCE1(filter, p, test_signature, true);
+ TEST_PERFORMANCE0(filter, p, test_derive_view_tag);
TEST_PERFORMANCE2(filter, p, test_wallet2_expand_subaddresses, 50, 200);
diff --git a/tests/performance_tests/out_can_be_to_acc.h b/tests/performance_tests/out_can_be_to_acc.h
new file mode 100644
index 000000000..86e236b7b
--- /dev/null
+++ b/tests/performance_tests/out_can_be_to_acc.h
@@ -0,0 +1,103 @@
+// Copyright (c) 2014-2021, 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.
+//
+// Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers
+
+#pragma once
+
+#include "crypto/crypto.h"
+#include "cryptonote_basic/cryptonote_basic.h"
+
+#include "single_tx_test_base.h"
+
+using namespace crypto;
+
+// use_view_tags: whether to enable view tag checking
+// is_owned: whether the output is owned by us
+template<bool use_view_tags, bool is_owned>
+class test_out_can_be_to_acc : public single_tx_test_base
+{
+ public:
+ static const size_t loop_count = 1000;
+
+ bool init()
+ {
+ if (!single_tx_test_base::init())
+ return false;
+
+ crypto::key_derivation key_derivation;
+ crypto::view_tag vt;
+
+ m_output_index = 0;
+ m_view_secret_key = m_bob.get_keys().m_view_secret_key;
+ m_spend_public_key = m_bob.get_keys().m_account_address.m_spend_public_key;
+
+ cryptonote::get_output_public_key(m_tx.vout[m_output_index], m_output_public_key);
+
+ if (use_view_tags)
+ {
+ crypto::generate_key_derivation(m_tx_pub_key, m_view_secret_key, key_derivation);
+ crypto::derive_view_tag(key_derivation, m_output_index, vt);
+ m_view_tag_opt = vt;
+ }
+ else
+ m_view_tag_opt = boost::optional<crypto::view_tag>();
+
+ return true;
+ }
+
+ bool test()
+ {
+ // include key derivation to demonstrate performance improvement when using view tags
+ crypto::key_derivation key_derivation;
+ crypto::generate_key_derivation(m_tx_pub_key, m_view_secret_key, key_derivation);
+
+ // if using view tags, this ensures we computed the view tag properly
+ if (!cryptonote::out_can_be_to_acc(m_view_tag_opt, key_derivation, m_output_index))
+ return false;
+
+ // if user owns output, this tests the output public key matches the derived
+ if (is_owned)
+ {
+ crypto::public_key output_public_key;
+ crypto::derive_public_key(key_derivation, m_output_index, m_spend_public_key, output_public_key);
+
+ if (m_output_public_key != output_public_key)
+ return false;
+ }
+
+ return true;
+ }
+
+ private:
+ size_t m_output_index;
+ crypto::secret_key m_view_secret_key;
+ crypto::public_key m_spend_public_key;
+ crypto::public_key m_output_public_key;
+ boost::optional<crypto::view_tag> m_view_tag_opt;
+};
diff --git a/tests/unit_tests/CMakeLists.txt b/tests/unit_tests/CMakeLists.txt
index b5ee7af01..55818dc93 100644
--- a/tests/unit_tests/CMakeLists.txt
+++ b/tests/unit_tests/CMakeLists.txt
@@ -77,6 +77,7 @@ set(unit_tests_sources
pruning.cpp
random.cpp
rolling_median.cpp
+ scaling_2021.cpp
serialization.cpp
sha256.cpp
slow_memmem.cpp
diff --git a/tests/unit_tests/epee_utils.cpp b/tests/unit_tests/epee_utils.cpp
index 1ba0e49ab..1c756e77c 100644
--- a/tests/unit_tests/epee_utils.cpp
+++ b/tests/unit_tests/epee_utils.cpp
@@ -31,6 +31,7 @@
#include <boost/endian/conversion.hpp>
#include <boost/range/algorithm/equal.hpp>
#include <boost/range/algorithm_ext/iota.hpp>
+#include <boost/range/iterator_range.hpp>
#include <cstdint>
#include <gtest/gtest.h>
#include <iterator>
diff --git a/tests/unit_tests/rolling_median.cpp b/tests/unit_tests/rolling_median.cpp
index 4d99bbb0d..07da0f0ef 100644
--- a/tests/unit_tests/rolling_median.cpp
+++ b/tests/unit_tests/rolling_median.cpp
@@ -211,3 +211,21 @@ TEST(rolling_median, size)
ASSERT_EQ(m.size(), std::min<int>(10, i + 2));
}
}
+
+TEST(rolling_median, copy)
+{
+ epee::misc_utils::rolling_median_t<uint64_t> m(100);
+
+ for (int i = 0; i < 100; ++i)
+ m.insert(rand());
+
+ epee::misc_utils::rolling_median_t<uint64_t> copy(m);
+
+ for (int i = 0; i < 5000; ++i)
+ {
+ uint64_t v = rand();
+ m.insert(v);
+ copy.insert(v);
+ ASSERT_EQ(m.median(), copy.median());
+ }
+}
diff --git a/tests/unit_tests/scaling_2021.cpp b/tests/unit_tests/scaling_2021.cpp
new file mode 100644
index 000000000..9e8d15544
--- /dev/null
+++ b/tests/unit_tests/scaling_2021.cpp
@@ -0,0 +1,187 @@
+// Copyright (c) 2019-2020, 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.
+
+// References:
+// - https://github.com/ArticMine/Monero-Documents/blob/master/MoneroScaling2021.pdf
+// - https://github.com/monero-project/research-lab/issues/70
+
+#define IN_UNIT_TESTS
+
+#include "gtest/gtest.h"
+#include "cryptonote_core/blockchain.h"
+#include "cryptonote_core/tx_pool.h"
+#include "cryptonote_core/cryptonote_core.h"
+#include "blockchain_db/testdb.h"
+
+namespace
+{
+
+class TestDB: public cryptonote::BaseTestDB
+{
+public:
+ TestDB() { m_open = true; }
+};
+
+}
+
+#define PREFIX_WINDOW(hf_version,window) \
+ std::unique_ptr<cryptonote::Blockchain> bc; \
+ cryptonote::tx_memory_pool txpool(*bc); \
+ bc.reset(new cryptonote::Blockchain(txpool)); \
+ struct get_test_options { \
+ const std::pair<uint8_t, uint64_t> hard_forks[3]; \
+ const cryptonote::test_options test_options = { \
+ hard_forks, \
+ window, \
+ }; \
+ get_test_options(): hard_forks{std::make_pair(1, (uint64_t)0), std::make_pair((uint8_t)hf_version, (uint64_t)1), std::make_pair((uint8_t)0, (uint64_t)0)} {} \
+ } opts; \
+ cryptonote::Blockchain *blockchain = bc.get(); \
+ bool r = blockchain->init(new TestDB(), cryptonote::FAKECHAIN, true, &opts.test_options, 0, NULL); \
+ ASSERT_TRUE(r)
+
+#define PREFIX(hf_version) PREFIX_WINDOW(hf_version, TEST_LONG_TERM_BLOCK_WEIGHT_WINDOW)
+
+TEST(fee_2021_scaling, relay_fee_cases_from_pdf)
+{
+ PREFIX_WINDOW(HF_VERSION_2021_SCALING, CRYPTONOTE_LONG_TERM_BLOCK_WEIGHT_WINDOW_SIZE);
+
+ ASSERT_EQ(bc->get_dynamic_base_fee(1200000000000, 300000, HF_VERSION_2021_SCALING-1), 8000);
+ ASSERT_EQ(bc->get_dynamic_base_fee(1200000000000, 300000, HF_VERSION_2021_SCALING), 38000);
+ ASSERT_EQ(bc->get_dynamic_base_fee(1200000000000, 1425000, HF_VERSION_2021_SCALING-1), 1684 /*1680*/);
+ ASSERT_EQ(bc->get_dynamic_base_fee(1200000000000, 1425000, HF_VERSION_2021_SCALING), 1684 /*1680*/);
+ ASSERT_EQ(bc->get_dynamic_base_fee(1200000000000, 1500000, HF_VERSION_2021_SCALING-1), 1600);
+ ASSERT_EQ(bc->get_dynamic_base_fee(1200000000000, 1500000, HF_VERSION_2021_SCALING), 1520);
+
+ ASSERT_EQ(bc->get_dynamic_base_fee(600000000000, 300000, HF_VERSION_2021_SCALING-1), 4000);
+ ASSERT_EQ(bc->get_dynamic_base_fee(600000000000, 300000, HF_VERSION_2021_SCALING), 19000);
+ ASSERT_EQ(bc->get_dynamic_base_fee(600000000000, 1425000, HF_VERSION_2021_SCALING-1), 842 /*840*/);
+ ASSERT_EQ(bc->get_dynamic_base_fee(600000000000, 1425000, HF_VERSION_2021_SCALING), 842 /*840*/);
+ ASSERT_EQ(bc->get_dynamic_base_fee(600000000000, 1500000, HF_VERSION_2021_SCALING-1), 800);
+ ASSERT_EQ(bc->get_dynamic_base_fee(600000000000, 1500000, HF_VERSION_2021_SCALING), 760);
+}
+
+TEST(fee_2021_scaling, wallet_fee_cases_from_pdf)
+{
+ PREFIX_WINDOW(HF_VERSION_2021_SCALING, CRYPTONOTE_LONG_TERM_BLOCK_WEIGHT_WINDOW_SIZE);
+ std::vector<uint64_t> fees;
+
+ fees.clear();
+ bc->get_dynamic_base_fee_estimate_2021_scaling(10, 600000000000, 300000, 300000, fees);
+ ASSERT_EQ(fees.size(), 4);
+ ASSERT_EQ(fees[0], 20000);
+ ASSERT_EQ(fees[1], 80000);
+ ASSERT_EQ(fees[2], 320000);
+ ASSERT_EQ(fees[3], 4000000);
+
+ fees.clear();
+ bc->get_dynamic_base_fee_estimate_2021_scaling(10, 600000000000, 15000000, 300000, fees);
+ ASSERT_EQ(fees.size(), 4);
+ ASSERT_EQ(fees[0], 20000);
+ ASSERT_EQ(fees[1], 80000);
+ ASSERT_EQ(fees[2], 320000);
+ ASSERT_EQ(fees[3], 1300000);
+
+ fees.clear();
+ bc->get_dynamic_base_fee_estimate_2021_scaling(10, 600000000000, 1425000, 1425000, fees);
+ ASSERT_EQ(fees.size(), 4);
+ ASSERT_EQ(fees[0], 890);
+ ASSERT_EQ(fees[1], 3600);
+ ASSERT_EQ(fees[2], 68000);
+ ASSERT_EQ(fees[3], 850000 /* 842000 */);
+
+ fees.clear();
+ bc->get_dynamic_base_fee_estimate_2021_scaling(10, 600000000000, 1500000, 1500000, fees);
+ ASSERT_EQ(fees.size(), 4);
+ ASSERT_EQ(fees[0], 800);
+ ASSERT_EQ(fees[1], 3200);
+ ASSERT_EQ(fees[2], 64000);
+ ASSERT_EQ(fees[3], 800000);
+
+ fees.clear();
+ bc->get_dynamic_base_fee_estimate_2021_scaling(10, 600000000000, 75000000, 1500000, fees);
+ ASSERT_EQ(fees.size(), 4);
+ ASSERT_EQ(fees[0], 800);
+ ASSERT_EQ(fees[1], 3200);
+ ASSERT_EQ(fees[2], 64000);
+ ASSERT_EQ(fees[3], 260000);
+}
+
+TEST(fee_2021_scaling, rounding)
+{
+ ASSERT_EQ(cryptonote::round_money_up("27810", 3), "27900.000000000000");
+ ASSERT_EQ(cryptonote::round_money_up("37.94", 3), "38.000000000000");
+ ASSERT_EQ(cryptonote::round_money_up("0.5555", 3), "0.556000000000");
+ ASSERT_EQ(cryptonote::round_money_up("0.002342", 3), "0.002350000000");
+
+ ASSERT_EQ(cryptonote::round_money_up("27810", 2), "28000.000000000000");
+ ASSERT_EQ(cryptonote::round_money_up("37.94", 2), "38.000000000000");
+ ASSERT_EQ(cryptonote::round_money_up("0.5555", 2), "0.560000000000");
+ ASSERT_EQ(cryptonote::round_money_up("0.002342", 2), "0.002400000000");
+
+ ASSERT_EQ(cryptonote::round_money_up("0", 8), "0.000000000000");
+ ASSERT_EQ(cryptonote::round_money_up("0.0", 8), "0.000000000000");
+ ASSERT_EQ(cryptonote::round_money_up("50.0", 8), "50.000000000000");
+ ASSERT_EQ(cryptonote::round_money_up("0.002342", 8), "0.002342000000");
+ ASSERT_EQ(cryptonote::round_money_up("0.002342", 1), "0.003000000000");
+ ASSERT_EQ(cryptonote::round_money_up("12345", 8), "12345.000000000000");
+ ASSERT_EQ(cryptonote::round_money_up("45678", 1), "50000.000000000000");
+ ASSERT_EQ(cryptonote::round_money_up("1.234", 1), "2.000000000000");
+ ASSERT_EQ(cryptonote::round_money_up("1.0000001", 4), "1.001000000000");
+ ASSERT_EQ(cryptonote::round_money_up("1.0020001", 4), "1.003000000000");
+
+ ASSERT_EQ(cryptonote::round_money_up("1.999999", 1), "2.000000000000");
+ ASSERT_EQ(cryptonote::round_money_up("1.999999", 2), "2.000000000000");
+ ASSERT_EQ(cryptonote::round_money_up("1.999999", 3), "2.000000000000");
+ ASSERT_EQ(cryptonote::round_money_up("1.999999", 4), "2.000000000000");
+ ASSERT_EQ(cryptonote::round_money_up("1.999999", 5), "2.000000000000");
+ ASSERT_EQ(cryptonote::round_money_up("1.999999", 6), "2.000000000000");
+ ASSERT_EQ(cryptonote::round_money_up("1.999999", 7), "1.999999000000");
+ ASSERT_EQ(cryptonote::round_money_up("1.999999", 8), "1.999999000000");
+ ASSERT_EQ(cryptonote::round_money_up("1.999999", 9), "1.999999000000");
+
+ ASSERT_EQ(cryptonote::round_money_up("2.000001", 1), "3.000000000000");
+ ASSERT_EQ(cryptonote::round_money_up("2.000001", 2), "2.100000000000");
+ ASSERT_EQ(cryptonote::round_money_up("2.000001", 3), "2.010000000000");
+ ASSERT_EQ(cryptonote::round_money_up("2.000001", 4), "2.001000000000");
+ ASSERT_EQ(cryptonote::round_money_up("2.000001", 5), "2.000100000000");
+ ASSERT_EQ(cryptonote::round_money_up("2.000001", 6), "2.000010000000");
+ ASSERT_EQ(cryptonote::round_money_up("2.000001", 7), "2.000001000000");
+ ASSERT_EQ(cryptonote::round_money_up("2.000001", 8), "2.000001000000");
+ ASSERT_EQ(cryptonote::round_money_up("2.000001", 9), "2.000001000000");
+ ASSERT_EQ(cryptonote::round_money_up("2.000001", 4000), "2.000001000000");
+
+ ASSERT_EQ(cryptonote::round_money_up("999", 2), "1000.000000000000");
+
+ ASSERT_THROW(cryptonote::round_money_up("1.23", 0), std::runtime_error);
+ ASSERT_THROW(cryptonote::round_money_up("18446744.073709551615", 1), std::runtime_error);
+ ASSERT_THROW(cryptonote::round_money_up("18446744.073709551615", 2), std::runtime_error);
+ ASSERT_THROW(cryptonote::round_money_up("18446744.073709551615", 12), std::runtime_error);
+ ASSERT_THROW(cryptonote::round_money_up("18446744.073709551615", 19), std::runtime_error);
+ ASSERT_EQ(cryptonote::round_money_up("18446744.073709551615", 20), "18446744.073709551615");
+}